From c278400c52c14203894c5dc0d63cf385239d8329 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 10:54:51 -0400 Subject: C6X: build infrastructure Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/Kconfig | 174 ++++++++++++++++++++++++++++++++++++ arch/c6x/Makefile | 60 +++++++++++++ arch/c6x/boot/Makefile | 30 +++++++ arch/c6x/configs/dsk6455_defconfig | 44 +++++++++ arch/c6x/configs/evmc6457_defconfig | 41 +++++++++ arch/c6x/configs/evmc6472_defconfig | 42 +++++++++ arch/c6x/configs/evmc6474_defconfig | 42 +++++++++ arch/c6x/include/asm/Kbuild | 54 +++++++++++ arch/c6x/kernel/Makefile | 12 +++ arch/c6x/kernel/vmlinux.lds.S | 162 +++++++++++++++++++++++++++++++++ arch/c6x/lib/Makefile | 7 ++ arch/c6x/mm/Makefile | 5 ++ arch/c6x/platforms/Kconfig | 16 ++++ arch/c6x/platforms/Makefile | 12 +++ 14 files changed, 701 insertions(+) create mode 100644 arch/c6x/Kconfig create mode 100644 arch/c6x/Makefile create mode 100644 arch/c6x/boot/Makefile create mode 100644 arch/c6x/configs/dsk6455_defconfig create mode 100644 arch/c6x/configs/evmc6457_defconfig create mode 100644 arch/c6x/configs/evmc6472_defconfig create mode 100644 arch/c6x/configs/evmc6474_defconfig create mode 100644 arch/c6x/include/asm/Kbuild create mode 100644 arch/c6x/kernel/Makefile create mode 100644 arch/c6x/kernel/vmlinux.lds.S create mode 100644 arch/c6x/lib/Makefile create mode 100644 arch/c6x/mm/Makefile create mode 100644 arch/c6x/platforms/Kconfig create mode 100644 arch/c6x/platforms/Makefile (limited to 'arch') diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig new file mode 100644 index 000000000000..26e67f0f0051 --- /dev/null +++ b/arch/c6x/Kconfig @@ -0,0 +1,174 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# + +config TMS320C6X + def_bool y + select CLKDEV_LOOKUP + select GENERIC_IRQ_SHOW + select HAVE_ARCH_TRACEHOOK + select HAVE_DMA_API_DEBUG + select HAVE_GENERIC_HARDIRQS + select HAVE_MEMBLOCK + select HAVE_SPARSE_IRQ + select OF + select OF_EARLY_FLATTREE + +config MMU + def_bool n + +config ZONE_DMA + def_bool y + +config FPU + def_bool n + +config HIGHMEM + def_bool n + +config NUMA + def_bool n + +config RWSEM_GENERIC_SPINLOCK + def_bool y + +config RWSEM_XCHGADD_ALGORITHM + def_bool n + +config GENERIC_CALIBRATE_DELAY + def_bool y + +config GENERIC_HWEIGHT + def_bool y + +config GENERIC_CLOCKEVENTS + def_bool y + +config GENERIC_CLOCKEVENTS_BROADCAST + bool + +config GENERIC_BUG + def_bool y + +config COMMON_CLKDEV + def_bool y + +config C6X_BIG_KERNEL + bool "Build a big kernel" + help + The C6X function call instruction has a limited range of +/- 2MiB. + This is sufficient for most kernels, but some kernel configurations + with lots of compiled-in functionality may require a larger range + for function calls. Use this option to have the compiler generate + function calls with 32-bit range. This will make the kernel both + larger and slower. + + If unsure, say N. + +source "init/Kconfig" + +# Use the generic interrupt handling code in kernel/irq/ + +source "kernel/Kconfig.freezer" + +config CMDLINE_BOOL + bool "Default bootloader kernel arguments" + +config CMDLINE + string "Kernel command line" + depends on CMDLINE_BOOL + default "console=ttyS0,57600" + help + On some architectures there is currently no way for the boot loader + to pass arguments to the kernel. For these architectures, you should + supply some command-line options at build time by entering them + here. + +config CMDLINE_FORCE + bool "Force default kernel command string" + depends on CMDLINE_BOOL + default n + help + Set this to have arguments from the default kernel command string + override those passed by the boot loader. + +config CPU_BIG_ENDIAN + bool "Build big-endian kernel" + default n + help + Say Y if you plan on running a kernel in big-endian mode. + Note that your board must be properly built and your board + port must properly enable any big-endian related features + of your chipset/board/processor. + +config FORCE_MAX_ZONEORDER + int "Maximum zone order" + default "13" + help + The kernel memory allocator divides physically contiguous memory + blocks into "zones", where each zone is a power of two number of + pages. This option selects the largest power of two that the kernel + keeps in the memory allocator. If you need to allocate very large + blocks of physically contiguous memory, then you may need to + increase this value. + + This config option is actually maximum order plus one. For example, + a value of 11 means that the largest free memory block is 2^10 pages. + +menu "Processor type and features" + +source "arch/c6x/platforms/Kconfig" + +config TMS320C6X_CACHES_ON + bool "L2 cache support" + default y + +config KERNEL_RAM_BASE_ADDRESS + hex "Virtual address of memory base" + default 0xe0000000 if SOC_TMS320C6455 + default 0xe0000000 if SOC_TMS320C6457 + default 0xe0000000 if SOC_TMS320C6472 + default 0x80000000 + +source "mm/Kconfig" + +source "kernel/Kconfig.preempt" + +source "kernel/Kconfig.hz" +source "kernel/time/Kconfig" + +endmenu + +menu "Executable file formats" + +source "fs/Kconfig.binfmt" + +endmenu + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" + +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +config ACCESS_CHECK + bool "Check the user pointer address" + default y + help + Usually the pointer transfer from user space is checked to see if its + address is in the kernel space. + + Say N here to disable that check to improve the performance. + +endmenu diff --git a/arch/c6x/Makefile b/arch/c6x/Makefile new file mode 100644 index 000000000000..1d08dd070277 --- /dev/null +++ b/arch/c6x/Makefile @@ -0,0 +1,60 @@ +# +# linux/arch/c6x/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# + +cflags-y += -mno-dsbt -msdata=none + +cflags-$(CONFIG_C6X_BIG_KERNEL) += -mlong-calls + +CFLAGS_MODULE += -mlong-calls -mno-dsbt -msdata=none + +CHECKFLAGS += + +KBUILD_CFLAGS += $(cflags-y) +KBUILD_AFLAGS += $(cflags-y) + +ifdef CONFIG_CPU_BIG_ENDIAN +KBUILD_CFLAGS += -mbig-endian +KBUILD_AFLAGS += -mbig-endian +LINKFLAGS += -mbig-endian +KBUILD_LDFLAGS += -mbig-endian +LDFLAGS += -EB +endif + +head-y := arch/c6x/kernel/head.o +core-y += arch/c6x/kernel/ arch/c6x/mm/ arch/c6x/platforms/ +libs-y += arch/c6x/lib/ + +# Default to vmlinux.bin, override when needed +all: vmlinux.bin + +boot := arch/$(ARCH)/boot + +# Are we making a dtbImage. target? If so, crack out the boardname +DTB:=$(subst dtbImage.,,$(filter dtbImage.%, $(MAKECMDGOALS))) +export DTB + +ifneq ($(DTB),) +core-y += $(boot)/ +endif + +# With make 3.82 we cannot mix normal and wildcard targets + +vmlinux.bin: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + +dtbImage.%: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + +define archhelp + @echo ' vmlinux.bin - Binary kernel image (arch/$(ARCH)/boot/vmlinux.bin)' + @echo ' dtbImage.
- ELF image with $(arch)/boot/dts/
.dts linked in' + @echo ' - stripped elf with fdt blob' +endef diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile new file mode 100644 index 000000000000..ecca820e6041 --- /dev/null +++ b/arch/c6x/boot/Makefile @@ -0,0 +1,30 @@ +# +# Makefile for bootable kernel images +# + +OBJCOPYFLAGS_vmlinux.bin := -O binary +$(obj)/vmlinux.bin: vmlinux FORCE + $(call if_changed,objcopy) + +DTC_FLAGS ?= -p 1024 + +ifneq ($(DTB),) +obj-y += linked_dtb.o +endif + +$(obj)/%.dtb: $(src)/dts/%.dts FORCE + $(call cmd,dtc) + +quiet_cmd_cp = CP $< $@$2 + cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false) + +# Generate builtin.dtb from $(DTB).dtb +$(obj)/builtin.dtb: $(obj)/$(DTB).dtb + $(call if_changed,cp) + +$(obj)/linked_dtb.o: $(obj)/builtin.dtb + +$(obj)/dtbImage.%: vmlinux + $(call if_changed,objcopy) + +clean-files := $(obj)/*.dtb diff --git a/arch/c6x/configs/dsk6455_defconfig b/arch/c6x/configs/dsk6455_defconfig new file mode 100644 index 000000000000..4663487c67a1 --- /dev/null +++ b/arch/c6x/configs/dsk6455_defconfig @@ -0,0 +1,44 @@ +CONFIG_SOC_TMS320C6455=y +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_SPARSE_IRQ=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_FUTEX is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="" +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=17000 +CONFIG_MISC_DEVICES=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_CRC16=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_MTD=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP_OF=y diff --git a/arch/c6x/configs/evmc6457_defconfig b/arch/c6x/configs/evmc6457_defconfig new file mode 100644 index 000000000000..bba40e195ec4 --- /dev/null +++ b/arch/c6x/configs/evmc6457_defconfig @@ -0,0 +1,41 @@ +CONFIG_SOC_TMS320C6457=y +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_SPARSE_IRQ=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_FUTEX is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="" +CONFIG_BOARD_EVM6457=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=17000 +CONFIG_MISC_DEVICES=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_CRC16=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/configs/evmc6472_defconfig b/arch/c6x/configs/evmc6472_defconfig new file mode 100644 index 000000000000..8c46155f6d31 --- /dev/null +++ b/arch/c6x/configs/evmc6472_defconfig @@ -0,0 +1,42 @@ +CONFIG_SOC_TMS320C6472=y +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_SPARSE_IRQ=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_FUTEX is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="" +# CONFIG_CMDLINE_FORCE is not set +CONFIG_BOARD_EVM6472=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=17000 +CONFIG_MISC_DEVICES=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_CRC16=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/configs/evmc6474_defconfig b/arch/c6x/configs/evmc6474_defconfig new file mode 100644 index 000000000000..15533f632313 --- /dev/null +++ b/arch/c6x/configs/evmc6474_defconfig @@ -0,0 +1,42 @@ +CONFIG_SOC_TMS320C6474=y +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_SPARSE_IRQ=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_FUTEX is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="" +# CONFIG_CMDLINE_FORCE is not set +CONFIG_BOARD_EVM6474=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=17000 +CONFIG_MISC_DEVICES=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_CRC16=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild new file mode 100644 index 000000000000..13dcf78adf91 --- /dev/null +++ b/arch/c6x/include/asm/Kbuild @@ -0,0 +1,54 @@ +include include/asm-generic/Kbuild.asm + +generic-y += atomic.h +generic-y += auxvec.h +generic-y += bitsperlong.h +generic-y += bug.h +generic-y += bugs.h +generic-y += cputime.h +generic-y += current.h +generic-y += device.h +generic-y += div64.h +generic-y += dma.h +generic-y += emergency-restart.h +generic-y += errno.h +generic-y += fb.h +generic-y += fcntl.h +generic-y += futex.h +generic-y += hw_irq.h +generic-y += io.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += ipcbuf.h +generic-y += irq_regs.h +generic-y += kdebug.h +generic-y += kmap_types.h +generic-y += local.h +generic-y += mman.h +generic-y += mmu_context.h +generic-y += msgbuf.h +generic-y += param.h +generic-y += pci.h +generic-y += percpu.h +generic-y += pgalloc.h +generic-y += poll.h +generic-y += posix_types.h +generic-y += resource.h +generic-y += scatterlist.h +generic-y += segment.h +generic-y += sembuf.h +generic-y += shmbuf.h +generic-y += shmparam.h +generic-y += siginfo.h +generic-y += socket.h +generic-y += sockios.h +generic-y += stat.h +generic-y += statfs.h +generic-y += termbits.h +generic-y += termios.h +generic-y += tlbflush.h +generic-y += topology.h +generic-y += types.h +generic-y += ucontext.h +generic-y += user.h +generic-y += vga.h diff --git a/arch/c6x/kernel/Makefile b/arch/c6x/kernel/Makefile new file mode 100644 index 000000000000..580a515a9443 --- /dev/null +++ b/arch/c6x/kernel/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for arch/c6x/kernel/ +# + +extra-y := head.o vmlinux.lds + +obj-y := process.o traps.o irq.o signal.o ptrace.o +obj-y += setup.o sys_c6x.o time.o devicetree.o +obj-y += switch_to.o entry.o vectors.o c6x_ksyms.o +obj-y += soc.o dma.o + +obj-$(CONFIG_MODULES) += module.o diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..1d81c4c129ec --- /dev/null +++ b/arch/c6x/kernel/vmlinux.lds.S @@ -0,0 +1,162 @@ +/* + * ld script for the c6x kernel + * + * Copyright (C) 2010, 2011 Texas Instruments Incorporated + * Mark Salter + */ +#include +#include +#include + +ENTRY(_c_int00) + +#if defined(CONFIG_CPU_BIG_ENDIAN) +jiffies = jiffies_64 + 4; +#else +jiffies = jiffies_64; +#endif + +#define READONLY_SEGMENT_START \ + . = PAGE_OFFSET; +#define READWRITE_SEGMENT_START \ + . = ALIGN(128); \ + _data_lma = .; + +SECTIONS +{ + /* + * Start kernel read only segment + */ + READONLY_SEGMENT_START + + .vectors : + { + _vectors_start = .; + *(.vectors) + . = ALIGN(0x400); + _vectors_end = .; + } + + . = ALIGN(0x1000); + .cmdline : + { + *(.cmdline) + } + + /* + * This section contains data which may be shared with other + * cores. It needs to be a fixed offset from PAGE_OFFSET + * regardless of kernel configuration. + */ + .virtio_ipc_dev : + { + *(.virtio_ipc_dev) + } + + . = ALIGN(PAGE_SIZE); + .init : + { + _stext = .; + _sinittext = .; + HEAD_TEXT + INIT_TEXT + _einittext = .; + } + + __init_begin = _stext; + INIT_DATA_SECTION(16) + + PERCPU_SECTION(128) + + . = ALIGN(PAGE_SIZE); + __init_end = .; + + .text : + { + _text = .; + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT + IRQENTRY_TEXT + KPROBES_TEXT + *(.fixup) + *(.gnu.warning) + } + + EXCEPTION_TABLE(16) + NOTES + + RO_DATA_SECTION(PAGE_SIZE) + .const : + { + *(.const .const.* .gnu.linkonce.r.*) + *(.switch) + } + + . = ALIGN (8) ; + __fdt_blob : AT(ADDR(__fdt_blob) - LOAD_OFFSET) + { + _fdt_start = . ; /* place for fdt blob */ + *(__fdt_blob) ; /* Any link-placed DTB */ + BYTE(0); /* section always has contents */ + . = _fdt_start + 0x4000; /* Pad up to 16kbyte */ + _fdt_end = . ; + } + + _etext = .; + + /* + * Start kernel read-write segment. + */ + READWRITE_SEGMENT_START + _sdata = .; + + .fardata : AT(ADDR(.fardata) - LOAD_OFFSET) + { + INIT_TASK_DATA(THREAD_SIZE) + NOSAVE_DATA + PAGE_ALIGNED_DATA(PAGE_SIZE) + CACHELINE_ALIGNED_DATA(128) + READ_MOSTLY_DATA(128) + DATA_DATA + CONSTRUCTORS + *(.data1) + *(.fardata .fardata.*) + *(.data.debug_bpt) + } + + .neardata ALIGN(8) : AT(ADDR(.neardata) - LOAD_OFFSET) + { + *(.neardata2 .neardata2.* .gnu.linkonce.s2.*) + *(.neardata .neardata.* .gnu.linkonce.s.*) + . = ALIGN(8); + } + + _edata = .; + + __bss_start = .; + SBSS(8) + BSS(8) + .far : + { + . = ALIGN(8); + *(.dynfar) + *(.far .far.* .gnu.linkonce.b.*) + . = ALIGN(8); + } + __bss_stop = .; + + _end = .; + + DWARF_DEBUG + + /DISCARD/ : + { + EXIT_TEXT + EXIT_DATA + EXIT_CALL + *(.discard) + *(.discard.*) + *(.interp) + } +} diff --git a/arch/c6x/lib/Makefile b/arch/c6x/lib/Makefile new file mode 100644 index 000000000000..ffd3c659091a --- /dev/null +++ b/arch/c6x/lib/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for arch/c6x/lib/ +# + +lib-y := divu.o divi.o pop_rts.o push_rts.o remi.o remu.o strasgi.o llshru.o +lib-y += llshr.o llshl.o negll.o mpyll.o divremi.o divremu.o +lib-y += checksum.o csum_64plus.o memcpy_64plus.o strasgi_64plus.o diff --git a/arch/c6x/mm/Makefile b/arch/c6x/mm/Makefile new file mode 100644 index 000000000000..136a97576c61 --- /dev/null +++ b/arch/c6x/mm/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the linux c6x-specific parts of the memory manager. +# + +obj-y := init.o dma-coherent.o diff --git a/arch/c6x/platforms/Kconfig b/arch/c6x/platforms/Kconfig new file mode 100644 index 000000000000..401ee678fd01 --- /dev/null +++ b/arch/c6x/platforms/Kconfig @@ -0,0 +1,16 @@ + +config SOC_TMS320C6455 + bool "TMS320C6455" + default n + +config SOC_TMS320C6457 + bool "TMS320C6457" + default n + +config SOC_TMS320C6472 + bool "TMS320C6472" + default n + +config SOC_TMS320C6474 + bool "TMS320C6474" + default n diff --git a/arch/c6x/platforms/Makefile b/arch/c6x/platforms/Makefile new file mode 100644 index 000000000000..9a95b9bca8d0 --- /dev/null +++ b/arch/c6x/platforms/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for arch/c6x/platforms +# +# Copyright 2010, 2011 Texas Instruments Incorporated +# + +obj-y = platform.o cache.o megamod-pic.o pll.o plldata.o timer64.o +obj-y += dscr.o + +# SoC objects +obj-$(CONFIG_SOC_TMS320C6455) += emif.o +obj-$(CONFIG_SOC_TMS320C6457) += emif.o -- cgit v1.2.3 From c1a144d77a6ca3a14ba3c0fec30bc4fd20b3d817 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:00:02 -0400 Subject: C6X: early boot code Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter This patch provides the early boot code for C6X architecture. There is a 16 entry vector table which is used to direct reset and interrupt events. The vector table entries contain a small amount of code (maximum of 8 opcodes) which simply branches to the actual event handling code. The head.S code simply clears BSS, setups up a few control registers, and calls machine_init followed by start_kernel. The machine_init code in setup.c does the early flat tree parsing (memory, commandline, etc). At setup_arch time, the code does the usual memory setup and minimally scans the devicetree for any needed information. Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/kernel/head.S | 84 ++++++++ arch/c6x/kernel/setup.c | 498 ++++++++++++++++++++++++++++++++++++++++++++++ arch/c6x/kernel/vectors.S | 81 ++++++++ 3 files changed, 663 insertions(+) create mode 100644 arch/c6x/kernel/head.S create mode 100644 arch/c6x/kernel/setup.c create mode 100644 arch/c6x/kernel/vectors.S (limited to 'arch') diff --git a/arch/c6x/kernel/head.S b/arch/c6x/kernel/head.S new file mode 100644 index 000000000000..133eab6edf6b --- /dev/null +++ b/arch/c6x/kernel/head.S @@ -0,0 +1,84 @@ +; +; Port on Texas Instruments TMS320C6x architecture +; +; Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated +; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include + + __HEAD +ENTRY(_c_int00) + ;; Save magic and pointer + MV .S1 A4,A10 + MV .S2 B4,B10 + MVKL .S2 __bss_start,B5 + MVKH .S2 __bss_start,B5 + MVKL .S2 __bss_stop,B6 + MVKH .S2 __bss_stop,B6 + SUB .L2 B6,B5,B6 ; bss size + + ;; Set the stack pointer + MVKL .S2 current_ksp,B0 + MVKH .S2 current_ksp,B0 + LDW .D2T2 *B0,B15 + + ;; clear bss + SHR .S2 B6,3,B0 ; number of dwords to clear + ZERO .L2 B13 + ZERO .L2 B12 +bss_loop: + BDEC .S2 bss_loop,B0 + NOP 3 + CMPLT .L2 B0,0,B1 + [!B1] STDW .D2T2 B13:B12,*B5++[1] + + NOP 4 + AND .D2 ~7,B15,B15 + + ;; Clear GIE and PGIE + MVC .S2 CSR,B2 + CLR .S2 B2,0,1,B2 + MVC .S2 B2,CSR + MVC .S2 TSR,B2 + CLR .S2 B2,0,1,B2 + MVC .S2 B2,TSR + MVC .S2 ITSR,B2 + CLR .S2 B2,0,1,B2 + MVC .S2 B2,ITSR + MVC .S2 NTSR,B2 + CLR .S2 B2,0,1,B2 + MVC .S2 B2,NTSR + + ;; pass DTB pointer to machine_init (or zero if none) + MVKL .S1 OF_DT_HEADER,A0 + MVKH .S1 OF_DT_HEADER,A0 + CMPEQ .L1 A10,A0,A0 + [A0] MV .S1X B10,A4 + [!A0] MVK .S1 0,A4 + +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 machine_init,A0 + MVKH .S1 machine_init,A0 + B .S2X A0 + ADDKPC .S2 0f,B3,4 +0: +#else + CALLP .S2 machine_init,B3 +#endif + + ;; Jump to Linux init +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 start_kernel,A0 + MVKH .S1 start_kernel,A0 + B .S2X A0 +#else + B .S2 start_kernel +#endif + NOP 5 +L1: BNOP .S2 L1,5 diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c new file mode 100644 index 000000000000..3c2858f0d91e --- /dev/null +++ b/arch/c6x/kernel/setup.c @@ -0,0 +1,498 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include + +static const char *c6x_soc_name; + +int c6x_num_cores; +EXPORT_SYMBOL_GPL(c6x_num_cores); + +unsigned int c6x_silicon_rev; +EXPORT_SYMBOL_GPL(c6x_silicon_rev); + +/* + * Device status register. This holds information + * about device configuration needed by some drivers. + */ +unsigned int c6x_devstat; +EXPORT_SYMBOL_GPL(c6x_devstat); + +/* + * Some SoCs have fuse registers holding a unique MAC + * address. This is parsed out of the device tree with + * the resulting MAC being held here. + */ +unsigned char c6x_fuse_mac[6]; + +unsigned long memory_start; +unsigned long memory_end; + +unsigned long ram_start; +unsigned long ram_end; + +/* Uncached memory for DMA consistent use (memdma=) */ +static unsigned long dma_start __initdata; +static unsigned long dma_size __initdata; + +char c6x_command_line[COMMAND_LINE_SIZE]; + +#if defined(CONFIG_CMDLINE_BOOL) +static const char default_command_line[COMMAND_LINE_SIZE] __section(.cmdline) = + CONFIG_CMDLINE; +#endif + +struct cpuinfo_c6x { + const char *cpu_name; + const char *cpu_voltage; + const char *mmu; + const char *fpu; + char *cpu_rev; + unsigned int core_id; + char __cpu_rev[5]; +}; + +static DEFINE_PER_CPU(struct cpuinfo_c6x, cpu_data); + +unsigned int ticks_per_ns_scaled; +EXPORT_SYMBOL(ticks_per_ns_scaled); + +unsigned int c6x_core_freq; + +static void __init get_cpuinfo(void) +{ + unsigned cpu_id, rev_id, csr; + struct clk *coreclk = clk_get_sys(NULL, "core"); + unsigned long core_khz; + u64 tmp; + struct cpuinfo_c6x *p; + struct device_node *node, *np; + + p = &per_cpu(cpu_data, smp_processor_id()); + + if (!IS_ERR(coreclk)) + c6x_core_freq = clk_get_rate(coreclk); + else { + printk(KERN_WARNING + "Cannot find core clock frequency. Using 700MHz\n"); + c6x_core_freq = 700000000; + } + + core_khz = c6x_core_freq / 1000; + + tmp = (uint64_t)core_khz << C6X_NDELAY_SCALE; + do_div(tmp, 1000000); + ticks_per_ns_scaled = tmp; + + csr = get_creg(CSR); + cpu_id = csr >> 24; + rev_id = (csr >> 16) & 0xff; + + p->mmu = "none"; + p->fpu = "none"; + p->cpu_voltage = "unknown"; + + switch (cpu_id) { + case 0: + p->cpu_name = "C67x"; + p->fpu = "yes"; + break; + case 2: + p->cpu_name = "C62x"; + break; + case 8: + p->cpu_name = "C64x"; + break; + case 12: + p->cpu_name = "C64x"; + break; + case 16: + p->cpu_name = "C64x+"; + p->cpu_voltage = "1.2"; + break; + default: + p->cpu_name = "unknown"; + break; + } + + if (cpu_id < 16) { + switch (rev_id) { + case 0x1: + if (cpu_id > 8) { + p->cpu_rev = "DM640/DM641/DM642/DM643"; + p->cpu_voltage = "1.2 - 1.4"; + } else { + p->cpu_rev = "C6201"; + p->cpu_voltage = "2.5"; + } + break; + case 0x2: + p->cpu_rev = "C6201B/C6202/C6211"; + p->cpu_voltage = "1.8"; + break; + case 0x3: + p->cpu_rev = "C6202B/C6203/C6204/C6205"; + p->cpu_voltage = "1.5"; + break; + case 0x201: + p->cpu_rev = "C6701 revision 0 (early CPU)"; + p->cpu_voltage = "1.8"; + break; + case 0x202: + p->cpu_rev = "C6701/C6711/C6712"; + p->cpu_voltage = "1.8"; + break; + case 0x801: + p->cpu_rev = "C64x"; + p->cpu_voltage = "1.5"; + break; + default: + p->cpu_rev = "unknown"; + } + } else { + p->cpu_rev = p->__cpu_rev; + snprintf(p->__cpu_rev, sizeof(p->__cpu_rev), "0x%x", cpu_id); + } + + p->core_id = get_coreid(); + + node = of_find_node_by_name(NULL, "cpus"); + if (node) { + for_each_child_of_node(node, np) + if (!strcmp("cpu", np->name)) + ++c6x_num_cores; + of_node_put(node); + } + + node = of_find_node_by_name(NULL, "soc"); + if (node) { + if (of_property_read_string(node, "model", &c6x_soc_name)) + c6x_soc_name = "unknown"; + of_node_put(node); + } else + c6x_soc_name = "unknown"; + + printk(KERN_INFO "CPU%d: %s rev %s, %s volts, %uMHz\n", + p->core_id, p->cpu_name, p->cpu_rev, + p->cpu_voltage, c6x_core_freq / 1000000); +} + +/* + * Early parsing of the command line + */ +static u32 mem_size __initdata; + +/* "mem=" parsing. */ +static int __init early_mem(char *p) +{ + if (!p) + return -EINVAL; + + mem_size = memparse(p, &p); + /* don't remove all of memory when handling "mem={invalid}" */ + if (mem_size == 0) + return -EINVAL; + + return 0; +} +early_param("mem", early_mem); + +/* "memdma=[@
]" parsing. */ +static int __init early_memdma(char *p) +{ + if (!p) + return -EINVAL; + + dma_size = memparse(p, &p); + if (*p == '@') + dma_start = memparse(p, &p); + + return 0; +} +early_param("memdma", early_memdma); + +int __init c6x_add_memory(phys_addr_t start, unsigned long size) +{ + static int ram_found __initdata; + + /* We only handle one bank (the one with PAGE_OFFSET) for now */ + if (ram_found) + return -EINVAL; + + if (start > PAGE_OFFSET || PAGE_OFFSET >= (start + size)) + return 0; + + ram_start = start; + ram_end = start + size; + + ram_found = 1; + return 0; +} + +/* + * Do early machine setup and device tree parsing. This is called very + * early on the boot process. + */ +notrace void __init machine_init(unsigned long dt_ptr) +{ + struct boot_param_header *dtb = __va(dt_ptr); + struct boot_param_header *fdt = (struct boot_param_header *)_fdt_start; + + /* interrupts must be masked */ + set_creg(IER, 2); + + /* + * Set the Interrupt Service Table (IST) to the beginning of the + * vector table. + */ + set_ist(_vectors_start); + + lockdep_init(); + + /* + * dtb is passed in from bootloader. + * fdt is linked in blob. + */ + if (dtb && dtb != fdt) + fdt = dtb; + + /* Do some early initialization based on the flat device tree */ + early_init_devtree(fdt); + + /* parse_early_param needs a boot_command_line */ + strlcpy(boot_command_line, c6x_command_line, COMMAND_LINE_SIZE); + parse_early_param(); +} + +void __init setup_arch(char **cmdline_p) +{ + int bootmap_size; + struct memblock_region *reg; + + printk(KERN_INFO "Initializing kernel\n"); + + /* Initialize command line */ + *cmdline_p = c6x_command_line; + + memblock_init(); + + memory_end = ram_end; + memory_end &= ~(PAGE_SIZE - 1); + + if (mem_size && (PAGE_OFFSET + PAGE_ALIGN(mem_size)) < memory_end) + memory_end = PAGE_OFFSET + PAGE_ALIGN(mem_size); + + /* add block that this kernel can use */ + memblock_add(PAGE_OFFSET, memory_end - PAGE_OFFSET); + + /* reserve kernel text/data/bss */ + memblock_reserve(PAGE_OFFSET, + PAGE_ALIGN((unsigned long)&_end - PAGE_OFFSET)); + + if (dma_size) { + /* align to cacheability granularity */ + dma_size = CACHE_REGION_END(dma_size); + + if (!dma_start) + dma_start = memory_end - dma_size; + + /* align to cacheability granularity */ + dma_start = CACHE_REGION_START(dma_start); + + /* reserve DMA memory taken from kernel memory */ + if (memblock_is_region_memory(dma_start, dma_size)) + memblock_reserve(dma_start, dma_size); + } + + memory_start = PAGE_ALIGN((unsigned int) &_end); + + printk(KERN_INFO "Memory Start=%08lx, Memory End=%08lx\n", + memory_start, memory_end); + +#ifdef CONFIG_BLK_DEV_INITRD + /* + * Reserve initrd memory if in kernel memory. + */ + if (initrd_start < initrd_end) + if (memblock_is_region_memory(initrd_start, + initrd_end - initrd_start)) + memblock_reserve(initrd_start, + initrd_end - initrd_start); +#endif + + init_mm.start_code = (unsigned long) &_stext; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = memory_start; + init_mm.brk = memory_start; + + /* + * Give all the memory to the bootmap allocator, tell it to put the + * boot mem_map at the start of memory + */ + bootmap_size = init_bootmem_node(NODE_DATA(0), + memory_start >> PAGE_SHIFT, + PAGE_OFFSET >> PAGE_SHIFT, + memory_end >> PAGE_SHIFT); + memblock_reserve(memory_start, bootmap_size); + + memblock_analyze(); + unflatten_device_tree(); + + c6x_cache_init(); + + /* Set the whole external memory as non-cacheable */ + disable_caching(ram_start, ram_end - 1); + + /* Set caching of external RAM used by Linux */ + for_each_memblock(memory, reg) + enable_caching(CACHE_REGION_START(reg->base), + CACHE_REGION_START(reg->base + reg->size - 1)); + +#ifdef CONFIG_BLK_DEV_INITRD + /* + * Enable caching for initrd which falls outside kernel memory. + */ + if (initrd_start < initrd_end) { + if (!memblock_is_region_memory(initrd_start, + initrd_end - initrd_start)) + enable_caching(CACHE_REGION_START(initrd_start), + CACHE_REGION_START(initrd_end - 1)); + } +#endif + + /* + * Disable caching for dma coherent memory taken from kernel memory. + */ + if (dma_size && memblock_is_region_memory(dma_start, dma_size)) + disable_caching(dma_start, + CACHE_REGION_START(dma_start + dma_size - 1)); + + /* Initialize the coherent memory allocator */ + coherent_mem_init(dma_start, dma_size); + + /* + * Free all memory as a starting point. + */ + free_bootmem(PAGE_OFFSET, memory_end - PAGE_OFFSET); + + /* + * Then reserve memory which is already being used. + */ + for_each_memblock(reserved, reg) { + pr_debug("reserved - 0x%08x-0x%08x\n", + (u32) reg->base, (u32) reg->size); + reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); + } + + max_low_pfn = PFN_DOWN(memory_end); + min_low_pfn = PFN_UP(memory_start); + max_mapnr = max_low_pfn - min_low_pfn; + + /* Get kmalloc into gear */ + paging_init(); + + /* + * Probe for Device State Configuration Registers. + * We have to do this early in case timer needs to be enabled + * through DSCR. + */ + dscr_probe(); + + /* We do this early for timer and core clock frequency */ + c64x_setup_clocks(); + + /* Get CPU info */ + get_cpuinfo(); + +#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +} + +#define cpu_to_ptr(n) ((void *)((long)(n)+1)) +#define ptr_to_cpu(p) ((long)(p) - 1) + +static int show_cpuinfo(struct seq_file *m, void *v) +{ + int n = ptr_to_cpu(v); + struct cpuinfo_c6x *p = &per_cpu(cpu_data, n); + + if (n == 0) { + seq_printf(m, + "soc\t\t: %s\n" + "soc revision\t: 0x%x\n" + "soc cores\t: %d\n", + c6x_soc_name, c6x_silicon_rev, c6x_num_cores); + } + + seq_printf(m, + "\n" + "processor\t: %d\n" + "cpu\t\t: %s\n" + "core revision\t: %s\n" + "core voltage\t: %s\n" + "core id\t\t: %d\n" + "mmu\t\t: %s\n" + "fpu\t\t: %s\n" + "cpu MHz\t\t: %u\n" + "bogomips\t: %lu.%02lu\n\n", + n, + p->cpu_name, p->cpu_rev, p->cpu_voltage, + p->core_id, p->mmu, p->fpu, + (c6x_core_freq + 500000) / 1000000, + (loops_per_jiffy/(500000/HZ)), + (loops_per_jiffy/(5000/HZ))%100); + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < nr_cpu_ids ? cpu_to_ptr(*pos) : NULL; +} +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} +static void c_stop(struct seq_file *m, void *v) +{ +} + +const struct seq_operations cpuinfo_op = { + c_start, + c_stop, + c_next, + show_cpuinfo +}; diff --git a/arch/c6x/kernel/vectors.S b/arch/c6x/kernel/vectors.S new file mode 100644 index 000000000000..c95c66fc71e8 --- /dev/null +++ b/arch/c6x/kernel/vectors.S @@ -0,0 +1,81 @@ +; +; Port on Texas Instruments TMS320C6x architecture +; +; Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated +; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. +; +; This section handles all the interrupt vector routines. +; At RESET the processor sets up the DRAM timing parameters and +; branches to the label _c_int00 which handles initialization for the C code. +; + +#define ALIGNMENT 5 + + .macro IRQVEC name, handler + .align ALIGNMENT + .hidden \name + .global \name +\name: +#ifdef CONFIG_C6X_BIG_KERNEL + STW .D2T1 A0,*B15--[2] + || MVKL .S1 \handler,A0 + MVKH .S1 \handler,A0 + B .S2X A0 + LDW .D2T1 *++B15[2],A0 + NOP 4 + NOP + NOP + .endm +#else /* CONFIG_C6X_BIG_KERNEL */ + B .S2 \handler + NOP + NOP + NOP + NOP + NOP + NOP + NOP + .endm +#endif /* CONFIG_C6X_BIG_KERNEL */ + + .sect ".vectors","ax" + .align ALIGNMENT + .global RESET + .hidden RESET +RESET: +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 _c_int00,A0 ; branch to _c_int00 + MVKH .S1 _c_int00,A0 + B .S2X A0 +#else + B .S2 _c_int00 + NOP + NOP +#endif + NOP + NOP + NOP + NOP + NOP + + + IRQVEC NMI,_nmi_handler ; NMI interrupt + IRQVEC AINT,_bad_interrupt ; reserved + IRQVEC MSGINT,_bad_interrupt ; reserved + + IRQVEC INT4,_int4_handler + IRQVEC INT5,_int5_handler + IRQVEC INT6,_int6_handler + IRQVEC INT7,_int7_handler + IRQVEC INT8,_int8_handler + IRQVEC INT9,_int9_handler + IRQVEC INT10,_int10_handler + IRQVEC INT11,_int11_handler + IRQVEC INT12,_int12_handler + IRQVEC INT13,_int13_handler + IRQVEC INT14,_int14_handler + IRQVEC INT15,_int15_handler -- cgit v1.2.3 From 041cadca7008f08fb4785f2288c8127c16faa529 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Tue, 4 Oct 2011 12:12:20 -0400 Subject: C6X: devicetree support This is the basic devicetree support for C6X. Currently, four boards are supported. Each one uses a different SoC part. Two of the four supported SoCs are multicore. One with 3 cores and the other with 6 cores. There is no coherency between the core-level caches, so SMP is not an option. It is possible to run separate kernel instances on the various cores. There is currently no C6X bootloader support for device trees so we build in the DTB for now. There are some interesting twists to the hardware which are of note for device tree support. Each core has its own interrupt controller which is controlled by special purpose core registers. This core controller provides 12 general purpose prioritized interrupt sources. Each core is contained within a hardware "module" which provides L1 and L2 caches, power control, and another interrupt controller which cascades into the core interrupt controller. These core module functions are controlled by memory mapped registers. The addresses for these registers are the same for each core. That is, when coreN accesses a module-level MMIO register at a given address, it accesses the register for coreN even though other cores would use the same address to access the register in the module containing those cores. Other hardware modules (timers, enet, etc) which are memory mapped can be accessed by all cores. The timers need some further explanation for multicore SoCs. Even though all timer control registers are visible to all cores, interrupt routing or other considerations may make a given timer more suitable for use by a core than some other timer. Because of this and the desire to have the same image run on more than one core, the timer nodes have a "ti,core-mask" property which is used by the driver to scan for a suitable timer to use. Signed-off-by: Mark Salter Signed-off-by: Aurelien Jacquiot Acked-by: Arnd Bergmann --- Documentation/devicetree/bindings/c6x/clocks.txt | 40 ++++++ Documentation/devicetree/bindings/c6x/dscr.txt | 127 +++++++++++++++++++ Documentation/devicetree/bindings/c6x/emifa.txt | 62 ++++++++++ .../devicetree/bindings/c6x/interrupt.txt | 104 ++++++++++++++++ Documentation/devicetree/bindings/c6x/soc.txt | 28 +++++ Documentation/devicetree/bindings/c6x/timer64.txt | 26 ++++ arch/c6x/boot/dts/dsk6455.dts | 62 ++++++++++ arch/c6x/boot/dts/evmc6457.dts | 48 ++++++++ arch/c6x/boot/dts/evmc6472.dts | 73 +++++++++++ arch/c6x/boot/dts/evmc6474.dts | 58 +++++++++ arch/c6x/boot/dts/tms320c6455.dtsi | 96 +++++++++++++++ arch/c6x/boot/dts/tms320c6457.dtsi | 68 +++++++++++ arch/c6x/boot/dts/tms320c6472.dtsi | 134 +++++++++++++++++++++ arch/c6x/boot/dts/tms320c6474.dtsi | 89 ++++++++++++++ arch/c6x/boot/linked_dtb.S | 2 + arch/c6x/kernel/devicetree.c | 53 ++++++++ arch/c6x/platforms/platform.c | 17 +++ 17 files changed, 1087 insertions(+) create mode 100644 Documentation/devicetree/bindings/c6x/clocks.txt create mode 100644 Documentation/devicetree/bindings/c6x/dscr.txt create mode 100644 Documentation/devicetree/bindings/c6x/emifa.txt create mode 100644 Documentation/devicetree/bindings/c6x/interrupt.txt create mode 100644 Documentation/devicetree/bindings/c6x/soc.txt create mode 100644 Documentation/devicetree/bindings/c6x/timer64.txt create mode 100644 arch/c6x/boot/dts/dsk6455.dts create mode 100644 arch/c6x/boot/dts/evmc6457.dts create mode 100644 arch/c6x/boot/dts/evmc6472.dts create mode 100644 arch/c6x/boot/dts/evmc6474.dts create mode 100644 arch/c6x/boot/dts/tms320c6455.dtsi create mode 100644 arch/c6x/boot/dts/tms320c6457.dtsi create mode 100644 arch/c6x/boot/dts/tms320c6472.dtsi create mode 100644 arch/c6x/boot/dts/tms320c6474.dtsi create mode 100644 arch/c6x/boot/linked_dtb.S create mode 100644 arch/c6x/kernel/devicetree.c create mode 100644 arch/c6x/platforms/platform.c (limited to 'arch') diff --git a/Documentation/devicetree/bindings/c6x/clocks.txt b/Documentation/devicetree/bindings/c6x/clocks.txt new file mode 100644 index 000000000000..a04f5fd30122 --- /dev/null +++ b/Documentation/devicetree/bindings/c6x/clocks.txt @@ -0,0 +1,40 @@ +C6X PLL Clock Controllers +------------------------- + +This is a first-cut support for the SoC clock controllers. This is still +under development and will probably change as the common device tree +clock support is added to the kernel. + +Required properties: + +- compatible: "ti,c64x+pll" + May also have SoC-specific value to support SoC-specific initialization + in the driver. One of: + "ti,c6455-pll" + "ti,c6457-pll" + "ti,c6472-pll" + "ti,c6474-pll" + +- reg: base address and size of register area +- clock-frequency: input clock frequency in hz + + +Optional properties: + +- ti,c64x+pll-bypass-delay: CPU cycles to delay when entering bypass mode + +- ti,c64x+pll-reset-delay: CPU cycles to delay after PLL reset + +- ti,c64x+pll-lock-delay: CPU cycles to delay after PLL frequency change + +Example: + + clock-controller@29a0000 { + compatible = "ti,c6472-pll", "ti,c64x+pll"; + reg = <0x029a0000 0x200>; + clock-frequency = <25000000>; + + ti,c64x+pll-bypass-delay = <200>; + ti,c64x+pll-reset-delay = <12000>; + ti,c64x+pll-lock-delay = <80000>; + }; diff --git a/Documentation/devicetree/bindings/c6x/dscr.txt b/Documentation/devicetree/bindings/c6x/dscr.txt new file mode 100644 index 000000000000..d847758f2b20 --- /dev/null +++ b/Documentation/devicetree/bindings/c6x/dscr.txt @@ -0,0 +1,127 @@ +Device State Configuration Registers +------------------------------------ + +TI C6X SoCs contain a region of miscellaneous registers which provide various +function for SoC control or status. Details vary considerably among from SoC +to SoC with no two being alike. + +In general, the Device State Configuraion Registers (DSCR) will provide one or +more configuration registers often protected by a lock register where one or +more key values must be written to a lock register in order to unlock the +configuration register for writes. These configuration register may be used to +enable (and disable in some cases) SoC pin drivers, select peripheral clock +sources (internal or pin), etc. In some cases, a configuration register is +write once or the individual bits are write once. In addition to device config, +the DSCR block may provide registers which which are used to reset peripherals, +provide device ID information, provide ethernet MAC addresses, as well as other +miscellaneous functions. + +For device state control (enable/disable), each device control is assigned an +id which is used by individual device drivers to control the state as needed. + +Required properties: + +- compatible: must be "ti,c64x+dscr" +- reg: register area base and size + +Optional properties: + + NOTE: These are optional in that not all SoCs will have all properties. For + SoCs which do support a given property, leaving the property out of the + device tree will result in reduced functionality or possibly driver + failure. + +- ti,dscr-devstat + offset of the devstat register + +- ti,dscr-silicon-rev + offset, start bit, and bitsize of silicon revision field + +- ti,dscr-rmii-resets + offset and bitmask of RMII reset field. May have multiple tuples if more + than one ethernet port is available. + +- ti,dscr-locked-regs + possibly multiple tuples describing registers which are write protected by + a lock register. Each tuple consists of the register offset, lock register + offsset, and the key value used to unlock the register. + +- ti,dscr-kick-regs + offset and key values of two "kick" registers used to write protect other + registers in DSCR. On SoCs using kick registers, the first key must be + written to the first kick register and the second key must be written to + the second register before other registers in the area are write-enabled. + +- ti,dscr-mac-fuse-regs + MAC addresses are contained in two registers. Each element of a MAC address + is contained in a single byte. This property has two tuples. Each tuple has + a register offset and four cells representing bytes in the register from + most significant to least. The value of these four cells is the MAC byte + index (1-6) of the byte within the register. A value of 0 means the byte + is unused in the MAC address. + +- ti,dscr-devstate-ctl-regs + This property describes the bitfields used to control the state of devices. + Each tuple describes a range of identical bitfields used to control one or + more devices (one bitfield per device). The layout of each tuple is: + + start_id num_ids reg enable disable start_bit nbits + + Where: + start_id is device id for the first device control in the range + num_ids is the number of device controls in the range + reg is the offset of the register holding the control bits + enable is the value to enable a device + disable is the value to disable a device (0xffffffff if cannot disable) + start_bit is the bit number of the first bit in the range + nbits is the number of bits per device control + +- ti,dscr-devstate-stat-regs + This property describes the bitfields used to provide device state status + for device states controlled by the DSCR. Each tuple describes a range of + identical bitfields used to provide status for one or more devices (one + bitfield per device). The layout of each tuple is: + + start_id num_ids reg enable disable start_bit nbits + + Where: + start_id is device id for the first device status in the range + num_ids is the number of devices covered by the range + reg is the offset of the register holding the status bits + enable is the value indicating device is enabled + disable is the value indicating device is disabled + start_bit is the bit number of the first bit in the range + nbits is the number of bits per device status + +- ti,dscr-privperm + Offset and default value for register used to set access privilege for + some SoC devices. + + +Example: + + device-state-config-regs@2a80000 { + compatible = "ti,c64x+dscr"; + reg = <0x02a80000 0x41000>; + + ti,dscr-devstat = <0>; + ti,dscr-silicon-rev = <8 28 0xf>; + ti,dscr-rmii-resets = <0x40020 0x00040000>; + + ti,dscr-locked-regs = <0x40008 0x40004 0x0f0a0b00>; + ti,dscr-devstate-ctl-regs = + <0 12 0x40008 1 0 0 2 + 12 1 0x40008 3 0 30 2 + 13 2 0x4002c 1 0xffffffff 0 1>; + ti,dscr-devstate-stat-regs = + <0 10 0x40014 1 0 0 3 + 10 2 0x40018 1 0 0 3>; + + ti,dscr-mac-fuse-regs = <0x700 1 2 3 4 + 0x704 5 6 0 0>; + + ti,dscr-privperm = <0x41c 0xaaaaaaaa>; + + ti,dscr-kick-regs = <0x38 0x83E70B13 + 0x3c 0x95A4F1E0>; + }; diff --git a/Documentation/devicetree/bindings/c6x/emifa.txt b/Documentation/devicetree/bindings/c6x/emifa.txt new file mode 100644 index 000000000000..0ff6e9b9a13f --- /dev/null +++ b/Documentation/devicetree/bindings/c6x/emifa.txt @@ -0,0 +1,62 @@ +External Memory Interface +------------------------- + +The emifa node describes a simple external bus controller found on some C6X +SoCs. This interface provides external busses with a number of chip selects. + +Required properties: + +- compatible: must be "ti,c64x+emifa", "simple-bus" +- reg: register area base and size +- #address-cells: must be 2 (chip-select + offset) +- #size-cells: must be 1 +- ranges: mapping from EMIFA space to parent space + + +Optional properties: + +- ti,dscr-dev-enable: Device ID if EMIF is enabled/disabled from DSCR + +- ti,emifa-burst-priority: + Number of memory transfers after which the EMIF will elevate the priority + of the oldest command in the command FIFO. Setting this field to 255 + disables this feature, thereby allowing old commands to stay in the FIFO + indefinitely. + +- ti,emifa-ce-config: + Configuration values for each of the supported chip selects. + +Example: + + emifa@70000000 { + compatible = "ti,c64x+emifa", "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + reg = <0x70000000 0x100>; + ranges = <0x2 0x0 0xa0000000 0x00000008 + 0x3 0x0 0xb0000000 0x00400000 + 0x4 0x0 0xc0000000 0x10000000 + 0x5 0x0 0xD0000000 0x10000000>; + + ti,dscr-dev-enable = <13>; + ti,emifa-burst-priority = <255>; + ti,emifa-ce-config = <0x00240120 + 0x00240120 + 0x00240122 + 0x00240122>; + + flash@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x3 0x0 0x400000>; + bank-width = <1>; + device-width = <1>; + partition@0 { + reg = <0x0 0x400000>; + label = "NOR"; + }; + }; + }; + +This shows a flash chip attached to chip select 3. diff --git a/Documentation/devicetree/bindings/c6x/interrupt.txt b/Documentation/devicetree/bindings/c6x/interrupt.txt new file mode 100644 index 000000000000..42bb796cc4ad --- /dev/null +++ b/Documentation/devicetree/bindings/c6x/interrupt.txt @@ -0,0 +1,104 @@ +C6X Interrupt Chips +------------------- + +* C64X+ Core Interrupt Controller + + The core interrupt controller provides 16 prioritized interrupts to the + C64X+ core. Priority 0 and 1 are used for reset and NMI respectively. + Priority 2 and 3 are reserved. Priority 4-15 are used for interrupt + sources coming from outside the core. + + Required properties: + -------------------- + - compatible: Should be "ti,c64x+core-pic"; + - #interrupt-cells: <1> + + Interrupt Specifier Definition + ------------------------------ + Single cell specifying the core interrupt priority level (4-15) where + 4 is highest priority and 15 is lowest priority. + + Example + ------- + core_pic: interrupt-controller@0 { + interrupt-controller; + #interrupt-cells = <1>; + compatible = "ti,c64x+core-pic"; + }; + + + +* C64x+ Megamodule Interrupt Controller + + The megamodule PIC consists of four interrupt mupliplexers each of which + combine up to 32 interrupt inputs into a single interrupt output which + may be cascaded into the core interrupt controller. The megamodule PIC + has a total of 12 outputs cascading into the core interrupt controller. + One for each core interrupt priority level. In addition to the combined + interrupt sources, individual megamodule interrupts may be cascaded to + the core interrupt controller. When an individual interrupt is cascaded, + it is no longer handled through a megamodule interrupt combiner and is + considered to have the core interrupt controller as the parent. + + Required properties: + -------------------- + - compatible: "ti,c64x+megamod-pic" + - interrupt-controller + - #interrupt-cells: <1> + - reg: base address and size of register area + - interrupt-parent: must be core interrupt controller + - interrupts: This should have four cells; one for each interrupt combiner. + The cells contain the core priority interrupt to which the + corresponding combiner output is wired. + + Optional properties: + -------------------- + - ti,c64x+megamod-pic-mux: Array of 12 cells correspnding to the 12 core + priority interrupts. The first cell corresponds to + core priority 4 and the last cell corresponds to + core priority 15. The value of each cell is the + megamodule interrupt source which is MUXed to + the core interrupt corresponding to the cell + position. Allowed values are 4 - 127. Mapping for + interrupts 0 - 3 (combined interrupt sources) are + ignored. + + Interrupt Specifier Definition + ------------------------------ + Single cell specifying the megamodule interrupt source (4-127). Note that + interrupts mapped directly to the core with "ti,c64x+megamod-pic-mux" will + use the core interrupt controller as their parent and the specifier will + be the core priority level, not the megamodule interrupt number. + + Examples + -------- + megamod_pic: interrupt-controller@1800000 { + compatible = "ti,c64x+megamod-pic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x1800000 0x1000>; + interrupt-parent = <&core_pic>; + interrupts = < 12 13 14 15 >; + }; + + This is a minimal example where all individual interrupts go through a + combiner. Combiner-0 is mapped to core interrupt 12, combiner-1 is mapped + to interrupt 13, etc. + + + megamod_pic: interrupt-controller@1800000 { + compatible = "ti,c64x+megamod-pic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x1800000 0x1000>; + interrupt-parent = <&core_pic>; + interrupts = < 12 13 14 15 >; + ti,c64x+megamod-pic-mux = < 0 0 0 0 + 32 0 0 0 + 0 0 0 0 >; + }; + + This the same as the first example except that megamodule interrupt 32 is + mapped directly to core priority interrupt 8. The node using this interrupt + must set the core controller as its interrupt parent and use 8 in the + interrupt specifier value. diff --git a/Documentation/devicetree/bindings/c6x/soc.txt b/Documentation/devicetree/bindings/c6x/soc.txt new file mode 100644 index 000000000000..b1e4973b5769 --- /dev/null +++ b/Documentation/devicetree/bindings/c6x/soc.txt @@ -0,0 +1,28 @@ +C6X System-on-Chip +------------------ + +Required properties: + +- compatible: "simple-bus" +- #address-cells: must be 1 +- #size-cells: must be 1 +- ranges + +Optional properties: + +- model: specific SoC model + +- nodes for IP blocks within SoC + + +Example: + + soc { + compatible = "simple-bus"; + model = "tms320c6455"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + ... + }; diff --git a/Documentation/devicetree/bindings/c6x/timer64.txt b/Documentation/devicetree/bindings/c6x/timer64.txt new file mode 100644 index 000000000000..95911fe70224 --- /dev/null +++ b/Documentation/devicetree/bindings/c6x/timer64.txt @@ -0,0 +1,26 @@ +Timer64 +------- + +The timer64 node describes C6X event timers. + +Required properties: + +- compatible: must be "ti,c64x+timer64" +- reg: base address and size of register region +- interrupt-parent: interrupt controller +- interrupts: interrupt id + +Optional properties: + +- ti,dscr-dev-enable: Device ID used to enable timer IP through DSCR interface. + +- ti,core-mask: on multi-core SoCs, bitmask of cores allowed to use this timer. + +Example: + timer0: timer@25e0000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x01 >; + reg = <0x25e0000 0x40>; + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; diff --git a/arch/c6x/boot/dts/dsk6455.dts b/arch/c6x/boot/dts/dsk6455.dts new file mode 100644 index 000000000000..2b71f800618d --- /dev/null +++ b/arch/c6x/boot/dts/dsk6455.dts @@ -0,0 +1,62 @@ +/* + * arch/c6x/boot/dts/dsk6455.dts + * + * DSK6455 Evaluation Platform For TMS320C6455 + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Author: Mark Salter + * + * 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. + * + */ + +/dts-v1/; + +/include/ "tms320c6455.dtsi" + +/ { + model = "Spectrum Digital DSK6455"; + compatible = "spectrum-digital,dsk6455"; + + chosen { + bootargs = "root=/dev/nfs ip=dhcp rw"; + }; + + memory { + device_type = "memory"; + reg = <0xE0000000 0x08000000>; + }; + + soc { + megamod_pic: interrupt-controller@1800000 { + interrupts = < 12 13 14 15 >; + }; + + emifa@70000000 { + flash@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x3 0x0 0x400000>; + bank-width = <1>; + device-width = <1>; + partition@0 { + reg = <0x0 0x400000>; + label = "NOR"; + }; + }; + }; + + timer1: timer@2980000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 69 >; + }; + + clock-controller@029a0000 { + clock-frequency = <50000000>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/evmc6457.dts b/arch/c6x/boot/dts/evmc6457.dts new file mode 100644 index 000000000000..0301eb9a8ff8 --- /dev/null +++ b/arch/c6x/boot/dts/evmc6457.dts @@ -0,0 +1,48 @@ +/* + * arch/c6x/boot/dts/evmc6457.dts + * + * EVMC6457 Evaluation Platform For TMS320C6457 + * + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Author: Mark Salter + * + * 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. + * + */ + +/dts-v1/; + +/include/ "tms320c6457.dtsi" + +/ { + model = "eInfochips EVMC6457"; + compatible = "einfochips,evmc6457"; + + chosen { + bootargs = "console=hvc root=/dev/nfs ip=dhcp rw"; + }; + + memory { + device_type = "memory"; + reg = <0xE0000000 0x10000000>; + }; + + soc { + megamod_pic: interrupt-controller@1800000 { + interrupts = < 12 13 14 15 >; + }; + + timer0: timer@2940000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 67 >; + }; + + clock-controller@29a0000 { + clock-frequency = <60000000>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/evmc6472.dts b/arch/c6x/boot/dts/evmc6472.dts new file mode 100644 index 000000000000..3e207b449a93 --- /dev/null +++ b/arch/c6x/boot/dts/evmc6472.dts @@ -0,0 +1,73 @@ +/* + * arch/c6x/boot/dts/evmc6472.dts + * + * EVMC6472 Evaluation Platform For TMS320C6472 + * + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Author: Mark Salter + * + * 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. + * + */ + +/dts-v1/; + +/include/ "tms320c6472.dtsi" + +/ { + model = "eInfochips EVMC6472"; + compatible = "einfochips,evmc6472"; + + chosen { + bootargs = "console=hvc root=/dev/nfs ip=dhcp rw"; + }; + + memory { + device_type = "memory"; + reg = <0xE0000000 0x10000000>; + }; + + soc { + megamod_pic: interrupt-controller@1800000 { + interrupts = < 12 13 14 15 >; + }; + + timer0: timer@25e0000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; + + timer1: timer@25f0000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; + + timer2: timer@2600000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; + + timer3: timer@2610000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; + + timer4: timer@2620000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; + + timer5: timer@2630000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 16 >; + }; + + clock-controller@29a0000 { + clock-frequency = <25000000>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/evmc6474.dts b/arch/c6x/boot/dts/evmc6474.dts new file mode 100644 index 000000000000..4dc291292bc4 --- /dev/null +++ b/arch/c6x/boot/dts/evmc6474.dts @@ -0,0 +1,58 @@ +/* + * arch/c6x/boot/dts/evmc6474.dts + * + * EVMC6474 Evaluation Platform For TMS320C6474 + * + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Author: Mark Salter + * + * 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. + * + */ + +/dts-v1/; + +/include/ "tms320c6474.dtsi" + +/ { + model = "Spectrum Digital EVMC6474"; + compatible = "spectrum-digital,evmc6474"; + + chosen { + bootargs = "console=hvc root=/dev/nfs ip=dhcp rw"; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x08000000>; + }; + + soc { + megamod_pic: interrupt-controller@1800000 { + interrupts = < 12 13 14 15 >; + }; + + timer3: timer@2940000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 39 >; + }; + + timer4: timer@2950000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 41 >; + }; + + timer5: timer@2960000 { + interrupt-parent = <&megamod_pic>; + interrupts = < 43 >; + }; + + clock-controller@29a0000 { + clock-frequency = <50000000>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/tms320c6455.dtsi b/arch/c6x/boot/dts/tms320c6455.dtsi new file mode 100644 index 000000000000..a804ec1e018b --- /dev/null +++ b/arch/c6x/boot/dts/tms320c6455.dtsi @@ -0,0 +1,96 @@ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "ti,c64x+"; + reg = <0>; + }; + }; + + soc { + compatible = "simple-bus"; + model = "tms320c6455"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + core_pic: interrupt-controller { + interrupt-controller; + #interrupt-cells = <1>; + compatible = "ti,c64x+core-pic"; + }; + + /* + * Megamodule interrupt controller + */ + megamod_pic: interrupt-controller@1800000 { + compatible = "ti,c64x+megamod-pic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x1800000 0x1000>; + interrupt-parent = <&core_pic>; + }; + + cache-controller@1840000 { + compatible = "ti,c64x+cache"; + reg = <0x01840000 0x8400>; + }; + + emifa@70000000 { + compatible = "ti,c64x+emifa", "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + reg = <0x70000000 0x100>; + ranges = <0x2 0x0 0xa0000000 0x00000008 + 0x3 0x0 0xb0000000 0x00400000 + 0x4 0x0 0xc0000000 0x10000000 + 0x5 0x0 0xD0000000 0x10000000>; + + ti,dscr-dev-enable = <13>; + ti,emifa-burst-priority = <255>; + ti,emifa-ce-config = <0x00240120 + 0x00240120 + 0x00240122 + 0x00240122>; + }; + + timer1: timer@2980000 { + compatible = "ti,c64x+timer64"; + reg = <0x2980000 0x40>; + ti,dscr-dev-enable = <4>; + }; + + clock-controller@029a0000 { + compatible = "ti,c6455-pll", "ti,c64x+pll"; + reg = <0x029a0000 0x200>; + ti,c64x+pll-bypass-delay = <1440>; + ti,c64x+pll-reset-delay = <15360>; + ti,c64x+pll-lock-delay = <24000>; + }; + + device-state-config-regs@2a80000 { + compatible = "ti,c64x+dscr"; + reg = <0x02a80000 0x41000>; + + ti,dscr-devstat = <0>; + ti,dscr-silicon-rev = <8 28 0xf>; + ti,dscr-rmii-resets = <0 0x40020 0x00040000>; + + ti,dscr-locked-regs = <0x40008 0x40004 0x0f0a0b00>; + ti,dscr-devstate-ctl-regs = + <0 12 0x40008 1 0 0 2 + 12 1 0x40008 3 0 30 2 + 13 2 0x4002c 1 0xffffffff 0 1>; + ti,dscr-devstate-stat-regs = + <0 10 0x40014 1 0 0 3 + 10 2 0x40018 1 0 0 3>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/tms320c6457.dtsi b/arch/c6x/boot/dts/tms320c6457.dtsi new file mode 100644 index 000000000000..35f40709a719 --- /dev/null +++ b/arch/c6x/boot/dts/tms320c6457.dtsi @@ -0,0 +1,68 @@ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "ti,c64x+"; + reg = <0>; + }; + }; + + soc { + compatible = "simple-bus"; + model = "tms320c6457"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + core_pic: interrupt-controller { + interrupt-controller; + #interrupt-cells = <1>; + compatible = "ti,c64x+core-pic"; + }; + + megamod_pic: interrupt-controller@1800000 { + compatible = "ti,c64x+megamod-pic"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&core_pic>; + reg = <0x1800000 0x1000>; + }; + + cache-controller@1840000 { + compatible = "ti,c64x+cache"; + reg = <0x01840000 0x8400>; + }; + + device-state-controller@2880800 { + compatible = "ti,c64x+dscr"; + reg = <0x02880800 0x400>; + + ti,dscr-devstat = <0x20>; + ti,dscr-silicon-rev = <0x18 28 0xf>; + ti,dscr-mac-fuse-regs = <0x114 3 4 5 6 + 0x118 0 0 1 2>; + ti,dscr-kick-regs = <0x38 0x83E70B13 + 0x3c 0x95A4F1E0>; + }; + + timer0: timer@2940000 { + compatible = "ti,c64x+timer64"; + reg = <0x2940000 0x40>; + }; + + clock-controller@29a0000 { + compatible = "ti,c6457-pll", "ti,c64x+pll"; + reg = <0x029a0000 0x200>; + ti,c64x+pll-bypass-delay = <300>; + ti,c64x+pll-reset-delay = <24000>; + ti,c64x+pll-lock-delay = <50000>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/tms320c6472.dtsi b/arch/c6x/boot/dts/tms320c6472.dtsi new file mode 100644 index 000000000000..b488aaec65c0 --- /dev/null +++ b/arch/c6x/boot/dts/tms320c6472.dtsi @@ -0,0 +1,134 @@ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + reg = <0>; + model = "ti,c64x+"; + }; + cpu@1 { + device_type = "cpu"; + reg = <1>; + model = "ti,c64x+"; + }; + cpu@2 { + device_type = "cpu"; + reg = <2>; + model = "ti,c64x+"; + }; + cpu@3 { + device_type = "cpu"; + reg = <3>; + model = "ti,c64x+"; + }; + cpu@4 { + device_type = "cpu"; + reg = <4>; + model = "ti,c64x+"; + }; + cpu@5 { + device_type = "cpu"; + reg = <5>; + model = "ti,c64x+"; + }; + }; + + soc { + compatible = "simple-bus"; + model = "tms320c6472"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + core_pic: interrupt-controller { + compatible = "ti,c64x+core-pic"; + interrupt-controller; + #interrupt-cells = <1>; + }; + + megamod_pic: interrupt-controller@1800000 { + compatible = "ti,c64x+megamod-pic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x1800000 0x1000>; + interrupt-parent = <&core_pic>; + }; + + cache-controller@1840000 { + compatible = "ti,c64x+cache"; + reg = <0x01840000 0x8400>; + }; + + timer0: timer@25e0000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x01 >; + reg = <0x25e0000 0x40>; + }; + + timer1: timer@25f0000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x02 >; + reg = <0x25f0000 0x40>; + }; + + timer2: timer@2600000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x04 >; + reg = <0x2600000 0x40>; + }; + + timer3: timer@2610000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x08 >; + reg = <0x2610000 0x40>; + }; + + timer4: timer@2620000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x10 >; + reg = <0x2620000 0x40>; + }; + + timer5: timer@2630000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x20 >; + reg = <0x2630000 0x40>; + }; + + clock-controller@29a0000 { + compatible = "ti,c6472-pll", "ti,c64x+pll"; + reg = <0x029a0000 0x200>; + ti,c64x+pll-bypass-delay = <200>; + ti,c64x+pll-reset-delay = <12000>; + ti,c64x+pll-lock-delay = <80000>; + }; + + device-state-controller@2a80000 { + compatible = "ti,c64x+dscr"; + reg = <0x02a80000 0x1000>; + + ti,dscr-devstat = <0>; + ti,dscr-silicon-rev = <0x70c 16 0xff>; + + ti,dscr-mac-fuse-regs = <0x700 1 2 3 4 + 0x704 5 6 0 0>; + + ti,dscr-rmii-resets = <0x208 1 + 0x20c 1>; + + ti,dscr-locked-regs = <0x200 0x204 0x0a1e183a + 0x40c 0x420 0xbea7 + 0x41c 0x420 0xbea7>; + + ti,dscr-privperm = <0x41c 0xaaaaaaaa>; + + ti,dscr-devstate-ctl-regs = <0 13 0x200 1 0 0 1>; + }; + }; +}; diff --git a/arch/c6x/boot/dts/tms320c6474.dtsi b/arch/c6x/boot/dts/tms320c6474.dtsi new file mode 100644 index 000000000000..cc601bf348a1 --- /dev/null +++ b/arch/c6x/boot/dts/tms320c6474.dtsi @@ -0,0 +1,89 @@ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + reg = <0>; + model = "ti,c64x+"; + }; + cpu@1 { + device_type = "cpu"; + reg = <1>; + model = "ti,c64x+"; + }; + cpu@2 { + device_type = "cpu"; + reg = <2>; + model = "ti,c64x+"; + }; + }; + + soc { + compatible = "simple-bus"; + model = "tms320c6474"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + core_pic: interrupt-controller { + interrupt-controller; + #interrupt-cells = <1>; + compatible = "ti,c64x+core-pic"; + }; + + megamod_pic: interrupt-controller@1800000 { + compatible = "ti,c64x+megamod-pic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x1800000 0x1000>; + interrupt-parent = <&core_pic>; + }; + + cache-controller@1840000 { + compatible = "ti,c64x+cache"; + reg = <0x01840000 0x8400>; + }; + + timer3: timer@2940000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x04 >; + reg = <0x2940000 0x40>; + }; + + timer4: timer@2950000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x02 >; + reg = <0x2950000 0x40>; + }; + + timer5: timer@2960000 { + compatible = "ti,c64x+timer64"; + ti,core-mask = < 0x01 >; + reg = <0x2960000 0x40>; + }; + + device-state-controller@2880800 { + compatible = "ti,c64x+dscr"; + reg = <0x02880800 0x400>; + + ti,dscr-devstat = <0x004>; + ti,dscr-silicon-rev = <0x014 28 0xf>; + ti,dscr-mac-fuse-regs = <0x34 3 4 5 6 + 0x38 0 0 1 2>; + }; + + clock-controller@29a0000 { + compatible = "ti,c6474-pll", "ti,c64x+pll"; + reg = <0x029a0000 0x200>; + ti,c64x+pll-bypass-delay = <120>; + ti,c64x+pll-reset-delay = <30000>; + ti,c64x+pll-lock-delay = <60000>; + }; + }; +}; diff --git a/arch/c6x/boot/linked_dtb.S b/arch/c6x/boot/linked_dtb.S new file mode 100644 index 000000000000..57a4454eaec3 --- /dev/null +++ b/arch/c6x/boot/linked_dtb.S @@ -0,0 +1,2 @@ +.section __fdt_blob,"a" +.incbin "arch/c6x/boot/builtin.dtb" diff --git a/arch/c6x/kernel/devicetree.c b/arch/c6x/kernel/devicetree.c new file mode 100644 index 000000000000..bdb56f09d0ac --- /dev/null +++ b/arch/c6x/kernel/devicetree.c @@ -0,0 +1,53 @@ +/* + * Architecture specific OF callbacks. + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 +#include +#include +#include +#include + +void __init early_init_devtree(void *params) +{ + /* Setup flat device-tree pointer */ + initial_boot_params = params; + + /* Retrieve various informations from the /chosen node of the + * device-tree, including the platform type, initrd location and + * size and more ... + */ + of_scan_flat_dt(early_init_dt_scan_chosen, c6x_command_line); + + /* Scan memory nodes and rebuild MEMBLOCKs */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + of_scan_flat_dt(early_init_dt_scan_memory, NULL); +} + + +#ifdef CONFIG_BLK_DEV_INITRD +void __init early_init_dt_setup_initrd_arch(unsigned long start, + unsigned long end) +{ + initrd_start = (unsigned long)__va(start); + initrd_end = (unsigned long)__va(end); + initrd_below_start_ok = 1; +} +#endif + +void __init early_init_dt_add_memory_arch(u64 base, u64 size) +{ + c6x_add_memory(base, size); +} + +void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) +{ + return __va(memblock_alloc(size, align)); +} diff --git a/arch/c6x/platforms/platform.c b/arch/c6x/platforms/platform.c new file mode 100644 index 000000000000..26c1a355d600 --- /dev/null +++ b/arch/c6x/platforms/platform.c @@ -0,0 +1,17 @@ +/* + * Copyright 2011 Texas Instruments Incorporated + * + * 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 +#include + +static int __init c6x_device_probe(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + return 0; +} +core_initcall(c6x_device_probe); -- cgit v1.2.3 From 14aa7e8bf6d84c9a42c48e7f93472d830f694b1e Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 12:17:19 -0400 Subject: C6X: memory management and DMA support Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter The C6X architecture currently lacks an MMU so memory management is relatively simple. There is no bus snooping between L2 and main memory but coherent DMA memory is supported by making regions of main memory uncached. If such a region is desired, it can be specified on the commandline with a "memdma=" argument. Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/dma-mapping.h | 91 ++++++++++++++++++++++ arch/c6x/kernel/dma.c | 153 +++++++++++++++++++++++++++++++++++++ arch/c6x/mm/dma-coherent.c | 143 ++++++++++++++++++++++++++++++++++ arch/c6x/mm/init.c | 113 +++++++++++++++++++++++++++ 4 files changed, 500 insertions(+) create mode 100644 arch/c6x/include/asm/dma-mapping.h create mode 100644 arch/c6x/kernel/dma.c create mode 100644 arch/c6x/mm/dma-coherent.c create mode 100644 arch/c6x/mm/init.c (limited to 'arch') diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h new file mode 100644 index 000000000000..03579fd99dba --- /dev/null +++ b/arch/c6x/include/asm/dma-mapping.h @@ -0,0 +1,91 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot + * + * 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_C6X_DMA_MAPPING_H +#define _ASM_C6X_DMA_MAPPING_H + +#include +#include + +#define dma_supported(d, m) 1 + +static inline int dma_set_mask(struct device *dev, u64 dma_mask) +{ + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + + *dev->dma_mask = dma_mask; + + return 0; +} + +/* + * DMA errors are defined by all-bits-set in the DMA address. + */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr == ~0; +} + +extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, + size_t size, enum dma_data_direction dir); + +extern void dma_unmap_single(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir); + +extern int dma_map_sg(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction direction); + +extern void dma_unmap_sg(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction direction); + +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t handle; + + handle = dma_map_single(dev, page_address(page) + offset, size, dir); + + debug_dma_map_page(dev, page, offset, size, dir, handle, false); + + return handle; +} + +static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + dma_unmap_single(dev, handle, size, dir); + + debug_dma_unmap_page(dev, handle, size, dir, false); +} + +extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir); + +extern void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, + size_t size, + enum dma_data_direction dir); + +extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir); + +extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir); + +extern void coherent_mem_init(u32 start, u32 size); +extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); +extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h)) + +#endif /* _ASM_C6X_DMA_MAPPING_H */ diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c new file mode 100644 index 000000000000..ab7b12de144d --- /dev/null +++ b/arch/c6x/kernel/dma.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 +#include +#include +#include +#include + +#include + +static void c6x_dma_sync(dma_addr_t handle, size_t size, + enum dma_data_direction dir) +{ + unsigned long paddr = handle; + + BUG_ON(!valid_dma_direction(dir)); + + switch (dir) { + case DMA_FROM_DEVICE: + L2_cache_block_invalidate(paddr, paddr + size); + break; + case DMA_TO_DEVICE: + L2_cache_block_writeback(paddr, paddr + size); + break; + case DMA_BIDIRECTIONAL: + L2_cache_block_writeback_invalidate(paddr, paddr + size); + break; + default: + break; + } +} + +dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t addr = virt_to_phys(ptr); + + c6x_dma_sync(addr, size, dir); + + debug_dma_map_page(dev, virt_to_page(ptr), + (unsigned long)ptr & ~PAGE_MASK, size, + dir, addr, true); + return addr; +} +EXPORT_SYMBOL(dma_map_single); + + +void dma_unmap_single(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + c6x_dma_sync(handle, size, dir); + + debug_dma_unmap_page(dev, handle, size, dir, true); +} +EXPORT_SYMBOL(dma_unmap_single); + + +int dma_map_sg(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sglist, sg, nents, i) + sg->dma_address = dma_map_single(dev, sg_virt(sg), sg->length, + dir); + + debug_dma_map_sg(dev, sglist, nents, nents, dir); + + return nents; +} +EXPORT_SYMBOL(dma_map_sg); + + +void dma_unmap_sg(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sglist, sg, nents, i) + dma_unmap_single(dev, sg_dma_address(sg), sg->length, dir); + + debug_dma_unmap_sg(dev, sglist, nents, dir); +} +EXPORT_SYMBOL(dma_unmap_sg); + +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + c6x_dma_sync(handle, size, dir); + + debug_dma_sync_single_for_cpu(dev, handle, size, dir); +} +EXPORT_SYMBOL(dma_sync_single_for_cpu); + + +void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + c6x_dma_sync(handle, size, dir); + + debug_dma_sync_single_for_device(dev, handle, size, dir); +} +EXPORT_SYMBOL(dma_sync_single_for_device); + + +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sglist, sg, nents, i) + dma_sync_single_for_cpu(dev, sg_dma_address(sg), + sg->length, dir); + + debug_dma_sync_sg_for_cpu(dev, sglist, nents, dir); +} +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sglist, sg, nents, i) + dma_sync_single_for_device(dev, sg_dma_address(sg), + sg->length, dir); + + debug_dma_sync_sg_for_device(dev, sglist, nents, dir); +} +EXPORT_SYMBOL(dma_sync_sg_for_device); + + +/* Number of entries preallocated for DMA-API debugging */ +#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) + +static int __init dma_init(void) +{ + dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); + + return 0; +} +fs_initcall(dma_init); diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c new file mode 100644 index 000000000000..4187e5180373 --- /dev/null +++ b/arch/c6x/mm/dma-coherent.c @@ -0,0 +1,143 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot + * + * 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. + * + * DMA uncached mapping support. + * + * Using code pulled from ARM + * Copyright (C) 2000-2004 Russell King + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * DMA coherent memory management, can be redefined using the memdma= + * kernel command line + */ + +/* none by default */ +static phys_addr_t dma_base; +static u32 dma_size; +static u32 dma_pages; + +static unsigned long *dma_bitmap; + +/* bitmap lock */ +static DEFINE_SPINLOCK(dma_lock); + +/* + * Return a DMA coherent and contiguous memory chunk from the DMA memory + */ +static inline u32 __alloc_dma_pages(int order) +{ + unsigned long flags; + u32 pos; + + spin_lock_irqsave(&dma_lock, flags); + pos = bitmap_find_free_region(dma_bitmap, dma_pages, order); + spin_unlock_irqrestore(&dma_lock, flags); + + return dma_base + (pos << PAGE_SHIFT); +} + +static void __free_dma_pages(u32 addr, int order) +{ + unsigned long flags; + u32 pos = (addr - dma_base) >> PAGE_SHIFT; + + if (addr < dma_base || (pos + (1 << order)) >= dma_pages) { + printk(KERN_ERR "%s: freeing outside range.\n", __func__); + BUG(); + } + + spin_lock_irqsave(&dma_lock, flags); + bitmap_release_region(dma_bitmap, pos, order); + spin_unlock_irqrestore(&dma_lock, flags); +} + +/* + * Allocate DMA coherent memory space and return both the kernel + * virtual and DMA address for that space. + */ +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *handle, gfp_t gfp) +{ + u32 paddr; + int order; + + if (!dma_size || !size) + return NULL; + + order = get_count_order(((size - 1) >> PAGE_SHIFT) + 1); + + paddr = __alloc_dma_pages(order); + + if (handle) + *handle = paddr; + + if (!paddr) + return NULL; + + return phys_to_virt(paddr); +} +EXPORT_SYMBOL(dma_alloc_coherent); + +/* + * Free DMA coherent memory as defined by the above mapping. + */ +void dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + int order; + + if (!dma_size || !size) + return; + + order = get_count_order(((size - 1) >> PAGE_SHIFT) + 1); + + __free_dma_pages(virt_to_phys(vaddr), order); +} +EXPORT_SYMBOL(dma_free_coherent); + +/* + * Initialise the coherent DMA memory allocator using the given uncached region. + */ +void __init coherent_mem_init(phys_addr_t start, u32 size) +{ + phys_addr_t bitmap_phys; + + if (!size) + return; + + printk(KERN_INFO + "Coherent memory (DMA) region start=0x%x size=0x%x\n", + start, size); + + dma_base = start; + dma_size = size; + + /* allocate bitmap */ + dma_pages = dma_size >> PAGE_SHIFT; + if (dma_size & (PAGE_SIZE - 1)) + ++dma_pages; + + bitmap_phys = memblock_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long), + sizeof(long)); + + dma_bitmap = phys_to_virt(bitmap_phys); + memset(dma_bitmap, 0, dma_pages * PAGE_SIZE); +} diff --git a/arch/c6x/mm/init.c b/arch/c6x/mm/init.c new file mode 100644 index 000000000000..89395f09648a --- /dev/null +++ b/arch/c6x/mm/init.c @@ -0,0 +1,113 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include +#include +#ifdef CONFIG_BLK_DEV_RAM +#include +#endif +#include + +#include + +/* + * ZERO_PAGE is a special page that is used for zero-initialized + * data and COW. + */ +unsigned long empty_zero_page; +EXPORT_SYMBOL(empty_zero_page); + +/* + * paging_init() continues the virtual memory environment setup which + * was begun by the code in arch/head.S. + * The parameters are pointers to where to stick the starting and ending + * addresses of available kernel virtual memory. + */ +void __init paging_init(void) +{ + struct pglist_data *pgdat = NODE_DATA(0); + unsigned long zones_size[MAX_NR_ZONES] = {0, }; + + empty_zero_page = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); + memset((void *)empty_zero_page, 0, PAGE_SIZE); + + /* + * Set up user data space + */ + set_fs(KERNEL_DS); + + /* + * Define zones + */ + zones_size[ZONE_NORMAL] = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT; + pgdat->node_zones[ZONE_NORMAL].zone_start_pfn = + __pa(PAGE_OFFSET) >> PAGE_SHIFT; + + free_area_init(zones_size); +} + +void __init mem_init(void) +{ + int codek, datak; + unsigned long tmp; + unsigned long len = memory_end - memory_start; + + high_memory = (void *)(memory_end & PAGE_MASK); + + /* this will put all memory onto the freelists */ + totalram_pages = free_all_bootmem(); + + codek = (_etext - _stext) >> 10; + datak = (_end - _sdata) >> 10; + + tmp = nr_free_pages() << PAGE_SHIFT; + printk(KERN_INFO "Memory: %luk/%luk RAM (%dk kernel code, %dk data)\n", + tmp >> 10, len >> 10, codek, datak); +} + +#ifdef CONFIG_BLK_DEV_INITRD +void __init free_initrd_mem(unsigned long start, unsigned long end) +{ + int pages = 0; + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + init_page_count(virt_to_page(start)); + free_page(start); + totalram_pages++; + pages++; + } + printk(KERN_INFO "Freeing initrd memory: %luk freed\n", + (pages * PAGE_SIZE) >> 10); +} +#endif + +void __init free_initmem(void) +{ + unsigned long addr; + + /* + * The following code should be cool even if these sections + * are not page aligned. + */ + addr = PAGE_ALIGN((unsigned long)(__init_begin)); + + /* next to check that the page we free is not a partial page */ + for (; addr + PAGE_SIZE < (unsigned long)(__init_end); + addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + free_page(addr); + totalram_pages++; + } + printk(KERN_INFO "Freeing unused kernel memory: %dK freed\n", + (int) ((addr - PAGE_ALIGN((long) &__init_begin)) >> 10)); +} -- cgit v1.2.3 From 687b12baecae2aa3af9df05c12b90d8e9ef21fa7 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:03:44 -0400 Subject: C6X: process management Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/processor.h | 132 +++++++++++++++++++ arch/c6x/include/asm/thread_info.h | 121 +++++++++++++++++ arch/c6x/kernel/process.c | 263 +++++++++++++++++++++++++++++++++++++ arch/c6x/kernel/switch_to.S | 74 +++++++++++ 4 files changed, 590 insertions(+) create mode 100644 arch/c6x/include/asm/processor.h create mode 100644 arch/c6x/include/asm/thread_info.h create mode 100644 arch/c6x/kernel/process.c create mode 100644 arch/c6x/kernel/switch_to.S (limited to 'arch') diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h new file mode 100644 index 000000000000..8154c4ee8c9c --- /dev/null +++ b/arch/c6x/include/asm/processor.h @@ -0,0 +1,132 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Updated for 2.6.34: Mark Salter + * + * 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_C6X_PROCESSOR_H +#define _ASM_C6X_PROCESSOR_H + +#include +#include +#include + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() \ +({ \ + void *__pc; \ + asm("mvc .S2 pce1,%0\n" : "=b"(__pc)); \ + __pc; \ +}) + +/* + * User space process size. This is mostly meaningless for NOMMU + * but some C6X processors may have RAM addresses up to 0xFFFFFFFF. + * Since calls like mmap() can return an address or an error, we + * have to allow room for error returns when code does something + * like: + * + * addr = do_mmap(...) + * if ((unsigned long)addr >= TASK_SIZE) + * ... its an error code, not an address ... + * + * Here, we allow for 4096 error codes which means we really can't + * use the last 4K page on systems with RAM extending all the way + * to the end of the 32-bit address space. + */ +#define TASK_SIZE 0xFFFFF000 + +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. We won't be using it + */ +#define TASK_UNMAPPED_BASE 0 + +struct thread_struct { + unsigned long long b15_14; + unsigned long long a15_14; + unsigned long long b13_12; + unsigned long long a13_12; + unsigned long long b11_10; + unsigned long long a11_10; + unsigned long long ricl_icl; + unsigned long usp; /* user stack pointer */ + unsigned long pc; /* kernel pc */ + unsigned long wchan; +}; + +#define INIT_THREAD \ +{ \ + .usp = 0, \ + .wchan = 0, \ +} + +#define INIT_MMAP { \ + &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \ + NULL, NULL } + +#define task_pt_regs(task) \ + ((struct pt_regs *)(THREAD_START_SP + task_stack_page(task)) - 1) + +#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + + +/* Forward declaration, a strange C thing */ +struct task_struct; + +extern void start_thread(struct pt_regs *regs, unsigned int pc, + unsigned long usp); + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +#define copy_segments(tsk, mm) do { } while (0) +#define release_segments(mm) do { } while (0) + +/* + * saved PC of a blocked thread. + */ +#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc) + +/* + * saved kernel SP and DP of a blocked thread. + */ +#ifdef _BIG_ENDIAN +#define thread_saved_ksp(tsk) \ + (*(unsigned long *)&(tsk)->thread.b15_14) +#define thread_saved_dp(tsk) \ + (*(((unsigned long *)&(tsk)->thread.b15_14) + 1)) +#else +#define thread_saved_ksp(tsk) \ + (*(((unsigned long *)&(tsk)->thread.b15_14) + 1)) +#define thread_saved_dp(tsk) \ + (*(unsigned long *)&(tsk)->thread.b15_14) +#endif + +extern unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) (task_pt_regs(task)->pc) +#define KSTK_ESP(tsk) (task_pt_regs(task)->sp) + +#define cpu_relax() do { } while (0) + +extern const struct seq_operations cpuinfo_op; + +#endif /* ASM_C6X_PROCESSOR_H */ diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h new file mode 100644 index 000000000000..fd99148cda9d --- /dev/null +++ b/arch/c6x/include/asm/thread_info.h @@ -0,0 +1,121 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Updated for 2.6.3x: Mark Salter + * + * 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_C6X_THREAD_INFO_H +#define _ASM_C6X_THREAD_INFO_H + +#ifdef __KERNEL__ + +#include + +#ifdef CONFIG_4KSTACKS +#define THREAD_SIZE 4096 +#define THREAD_SHIFT 12 +#define THREAD_ORDER 0 +#else +#define THREAD_SIZE 8192 +#define THREAD_SHIFT 13 +#define THREAD_ORDER 1 +#endif + +#define THREAD_START_SP (THREAD_SIZE - 8) + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long seg; +} mm_segment_t; + +/* + * low level task data. + */ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + int cpu; /* cpu we're on */ + int preempt_count; /* 0 = preemptable, <0 = BUG */ + mm_segment_t addr_limit; /* thread address space */ + struct restart_block restart_block; +}; + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = INIT_PREEMPT_COUNT, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* get the thread information struct of current task */ +static inline __attribute__((const)) +struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + asm volatile (" clr .s2 B15,0,%1,%0\n" + : "=b" (ti) + : "Iu5" (THREAD_SHIFT - 1)); + return ti; +} + +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#else +#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK) +#endif + +#define alloc_thread_info_node(tsk, node) \ + ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER)) + +#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) +#endif /* __ASSEMBLY__ */ + +#define PREEMPT_ACTIVE 0x10000000 + +/* + * thread information flag bit numbers + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ + +#define TIF_POLLING_NRFLAG 16 /* true if polling TIF_NEED_RESCHED */ +#define TIF_MEMDIE 17 /* OOM killer killed process */ + +#define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */ +#define TIF_ALLWORK_MASK 0x00007FFF /* work on any return to u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_C6X_THREAD_INFO_H */ diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c new file mode 100644 index 000000000000..aa65c879323b --- /dev/null +++ b/arch/c6x/kernel/process.c @@ -0,0 +1,263 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include +#include +#include +#include +#include +#include + +#include + +/* hooks for board specific support */ +void (*c6x_restart)(void); +void (*c6x_halt)(void); + +extern asmlinkage void ret_from_fork(void); + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + */ +union thread_union init_thread_union __init_task_data = { + INIT_THREAD_INFO(init_task) +}; + +/* + * Initial task structure. + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* + * power off function, if any + */ +void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + +static void c6x_idle(void) +{ + unsigned long tmp; + + /* + * Put local_irq_enable and idle in same execute packet + * to make them atomic and avoid race to idle with + * interrupts enabled. + */ + asm volatile (" mvc .s2 CSR,%0\n" + " or .d2 1,%0,%0\n" + " mvc .s2 %0,CSR\n" + "|| idle\n" + : "=b"(tmp)); +} + +/* + * The idle loop for C64x + */ +void cpu_idle(void) +{ + /* endless idle loop with no priority at all */ + while (1) { + tick_nohz_stop_sched_tick(1); + while (1) { + local_irq_disable(); + if (need_resched()) { + local_irq_enable(); + break; + } + c6x_idle(); /* enables local irqs */ + } + tick_nohz_restart_sched_tick(); + + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +} + +static void halt_loop(void) +{ + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) + asm volatile("idle\n"); +} + +void machine_restart(char *__unused) +{ + if (c6x_restart) + c6x_restart(); + halt_loop(); +} + +void machine_halt(void) +{ + if (c6x_halt) + c6x_halt(); + halt_loop(); +} + +void machine_power_off(void) +{ + if (pm_power_off) + pm_power_off(); + halt_loop(); +} + +static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *)) +{ + do_exit(fn(arg)); +} + +/* + * Create a kernel thread + */ +int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + struct pt_regs regs; + + /* + * copy_thread sets a4 to zero (child return from fork) + * so we can't just set things up to directly return to + * fn. + */ + memset(®s, 0, sizeof(regs)); + regs.b4 = (unsigned long) arg; + regs.a6 = (unsigned long) fn; + regs.pc = (unsigned long) kernel_thread_helper; + local_save_flags(regs.csr); + regs.csr |= 1; + regs.tsr = 5; /* Set GEE and GIE in TSR */ + + /* Ok, create the new process.. */ + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, ®s, + 0, NULL, NULL); +} +EXPORT_SYMBOL(kernel_thread); + +void flush_thread(void) +{ +} + +void exit_thread(void) +{ +} + +SYSCALL_DEFINE1(c6x_clone, struct pt_regs *, regs) +{ + unsigned long clone_flags; + unsigned long newsp; + + /* syscall puts clone_flags in A4 and usp in B4 */ + clone_flags = regs->orig_a4; + if (regs->b4) + newsp = regs->b4; + else + newsp = regs->sp; + + return do_fork(clone_flags, newsp, regs, 0, (int __user *)regs->a6, + (int __user *)regs->b6); +} + +/* + * Do necessary setup to start up a newly executed thread. + */ +void start_thread(struct pt_regs *regs, unsigned int pc, unsigned long usp) +{ + /* + * The binfmt loader will setup a "full" stack, but the C6X + * operates an "empty" stack. So we adjust the usp so that + * argc doesn't get destroyed if an interrupt is taken before + * it is read from the stack. + * + * NB: Library startup code needs to match this. + */ + usp -= 8; + + set_fs(USER_DS); + regs->pc = pc; + regs->sp = usp; + regs->tsr |= 0x40; /* set user mode */ + current->thread.usp = usp; +} + +/* + * Copy a new thread context in its stack. + */ +int copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long ustk_size, + struct task_struct *p, struct pt_regs *regs) +{ + struct pt_regs *childregs; + + childregs = task_pt_regs(p); + + *childregs = *regs; + childregs->a4 = 0; + + if (usp == -1) + /* case of __kernel_thread: we return to supervisor space */ + childregs->sp = (unsigned long)(childregs + 1); + else + /* Otherwise use the given stack */ + childregs->sp = usp; + + /* Set usp/ksp */ + p->thread.usp = childregs->sp; + /* switch_to uses stack to save/restore 14 callee-saved regs */ + thread_saved_ksp(p) = (unsigned long)childregs - 8; + p->thread.pc = (unsigned int) ret_from_fork; + p->thread.wchan = (unsigned long) ret_from_fork; +#ifdef __DSBT__ + { + unsigned long dp; + + asm volatile ("mv .S2 b14,%0\n" : "=b"(dp)); + + thread_saved_dp(p) = dp; + if (usp == -1) + childregs->dp = dp; + } +#endif + return 0; +} + +/* + * c6x_execve() executes a new program. + */ +SYSCALL_DEFINE4(c6x_execve, const char __user *, name, + const char __user *const __user *, argv, + const char __user *const __user *, envp, + struct pt_regs *, regs) +{ + int error; + char *filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + + error = do_execve(filename, argv, envp, regs); + putname(filename); +out: + return error; +} + +unsigned long get_wchan(struct task_struct *p) +{ + return p->thread.wchan; +} diff --git a/arch/c6x/kernel/switch_to.S b/arch/c6x/kernel/switch_to.S new file mode 100644 index 000000000000..09177ed0fa5c --- /dev/null +++ b/arch/c6x/kernel/switch_to.S @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter (msalter@redhat.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 +#include + +#define SP B15 + + /* + * void __switch_to(struct thread_info *prev, + * struct thread_info *next, + * struct task_struct *tsk) ; + */ +ENTRY(__switch_to) + LDDW .D2T2 *+B4(THREAD_B15_14),B7:B6 + || MV .L2X A4,B5 ; prev + || MV .L1X B4,A5 ; next + || MVC .S2 RILC,B1 + + STW .D2T2 B3,*+B5(THREAD_PC) + || STDW .D1T1 A13:A12,*+A4(THREAD_A13_12) + || MVC .S2 ILC,B0 + + LDW .D2T2 *+B4(THREAD_PC),B3 + || LDDW .D1T1 *+A5(THREAD_A13_12),A13:A12 + + STDW .D1T1 A11:A10,*+A4(THREAD_A11_10) + || STDW .D2T2 B1:B0,*+B5(THREAD_RICL_ICL) +#ifndef __DSBT__ + || MVKL .S2 current_ksp,B1 +#endif + + STDW .D2T2 B15:B14,*+B5(THREAD_B15_14) + || STDW .D1T1 A15:A14,*+A4(THREAD_A15_14) +#ifndef __DSBT__ + || MVKH .S2 current_ksp,B1 +#endif + + ;; Switch to next SP + MV .S2 B7,SP +#ifdef __DSBT__ + || STW .D2T2 B7,*+B14(current_ksp) +#else + || STW .D2T2 B7,*B1 + || MV .L2 B6,B14 +#endif + || LDDW .D1T1 *+A5(THREAD_RICL_ICL),A1:A0 + + STDW .D2T2 B11:B10,*+B5(THREAD_B11_10) + || LDDW .D1T1 *+A5(THREAD_A15_14),A15:A14 + + STDW .D2T2 B13:B12,*+B5(THREAD_B13_12) + || LDDW .D1T1 *+A5(THREAD_A11_10),A11:A10 + + B .S2 B3 ; return in next E1 + || LDDW .D2T2 *+B4(THREAD_B13_12),B13:B12 + + LDDW .D2T2 *+B4(THREAD_B11_10),B11:B10 + NOP + + MV .L2X A0,B0 + || MV .S1 A6,A4 + + MVC .S2 B0,ILC + || MV .L2X A1,B1 + + MVC .S2 B1,RILC +ENDPROC(__switch_to) -- cgit v1.2.3 From 03a347558749caaab482f34410ae5d27e893db89 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:04:34 -0400 Subject: C6X: signal management Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/sigcontext.h | 80 ++++++++ arch/c6x/include/asm/signal.h | 17 ++ arch/c6x/kernel/signal.c | 377 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 474 insertions(+) create mode 100644 arch/c6x/include/asm/sigcontext.h create mode 100644 arch/c6x/include/asm/signal.h create mode 100644 arch/c6x/kernel/signal.c (limited to 'arch') diff --git a/arch/c6x/include/asm/sigcontext.h b/arch/c6x/include/asm/sigcontext.h new file mode 100644 index 000000000000..eb702f39cde7 --- /dev/null +++ b/arch/c6x/include/asm/sigcontext.h @@ -0,0 +1,80 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_SIGCONTEXT_H +#define _ASM_C6X_SIGCONTEXT_H + + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_sp; /* old user stack pointer */ + + unsigned long sc_a4; + unsigned long sc_b4; + unsigned long sc_a6; + unsigned long sc_b6; + unsigned long sc_a8; + unsigned long sc_b8; + + unsigned long sc_a0; + unsigned long sc_a1; + unsigned long sc_a2; + unsigned long sc_a3; + unsigned long sc_a5; + unsigned long sc_a7; + unsigned long sc_a9; + + unsigned long sc_b0; + unsigned long sc_b1; + unsigned long sc_b2; + unsigned long sc_b3; + unsigned long sc_b5; + unsigned long sc_b7; + unsigned long sc_b9; + + unsigned long sc_a16; + unsigned long sc_a17; + unsigned long sc_a18; + unsigned long sc_a19; + unsigned long sc_a20; + unsigned long sc_a21; + unsigned long sc_a22; + unsigned long sc_a23; + unsigned long sc_a24; + unsigned long sc_a25; + unsigned long sc_a26; + unsigned long sc_a27; + unsigned long sc_a28; + unsigned long sc_a29; + unsigned long sc_a30; + unsigned long sc_a31; + + unsigned long sc_b16; + unsigned long sc_b17; + unsigned long sc_b18; + unsigned long sc_b19; + unsigned long sc_b20; + unsigned long sc_b21; + unsigned long sc_b22; + unsigned long sc_b23; + unsigned long sc_b24; + unsigned long sc_b25; + unsigned long sc_b26; + unsigned long sc_b27; + unsigned long sc_b28; + unsigned long sc_b29; + unsigned long sc_b30; + unsigned long sc_b31; + + unsigned long sc_csr; + unsigned long sc_pc; +}; + +#endif /* _ASM_C6X_SIGCONTEXT_H */ diff --git a/arch/c6x/include/asm/signal.h b/arch/c6x/include/asm/signal.h new file mode 100644 index 000000000000..f1cd870596a3 --- /dev/null +++ b/arch/c6x/include/asm/signal.h @@ -0,0 +1,17 @@ +#ifndef _ASM_C6X_SIGNAL_H +#define _ASM_C6X_SIGNAL_H + +#include + +#ifndef __ASSEMBLY__ +#include + +struct pt_regs; + +extern asmlinkage int do_rt_sigreturn(struct pt_regs *regs); +extern asmlinkage void do_notify_resume(struct pt_regs *regs, + u32 thread_info_flags, + int syscall); +#endif + +#endif /* _ASM_C6X_SIGNAL_H */ diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c new file mode 100644 index 000000000000..304f675826e9 --- /dev/null +++ b/arch/c6x/kernel/signal.c @@ -0,0 +1,377 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Updated for 2.6.34: Mark Salter + * + * 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 +#include +#include +#include + +#include +#include + + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +/* + * Do a signal return, undo the signal stack. + */ + +#define RETCODE_SIZE (9 << 2) /* 9 instructions = 36 bytes */ + +struct rt_sigframe { + struct siginfo __user *pinfo; + void __user *puc; + struct siginfo info; + struct ucontext uc; + unsigned long retcode[RETCODE_SIZE >> 2]; +}; + +static int restore_sigcontext(struct pt_regs *regs, + struct sigcontext __user *sc) +{ + int err = 0; + + /* The access_ok check was done by caller, so use __get_user here */ +#define COPY(x) (err |= __get_user(regs->x, &sc->sc_##x)) + + COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8); + COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9); + COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9); + + COPY(a16); COPY(a17); COPY(a18); COPY(a19); + COPY(a20); COPY(a21); COPY(a22); COPY(a23); + COPY(a24); COPY(a25); COPY(a26); COPY(a27); + COPY(a28); COPY(a29); COPY(a30); COPY(a31); + COPY(b16); COPY(b17); COPY(b18); COPY(b19); + COPY(b20); COPY(b21); COPY(b22); COPY(b23); + COPY(b24); COPY(b25); COPY(b26); COPY(b27); + COPY(b28); COPY(b29); COPY(b30); COPY(b31); + + COPY(csr); COPY(pc); + +#undef COPY + + return err; +} + +asmlinkage int do_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe __user *frame; + sigset_t set; + + /* + * Since we stacked the signal on a dword boundary, + * 'sp' should be dword aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (regs->sp & 7) + goto badframe; + + frame = (struct rt_sigframe __user *) ((unsigned long) regs->sp + 8); + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) + goto badframe; + + return regs->a4; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, + unsigned long mask) +{ + int err = 0; + + err |= __put_user(mask, &sc->sc_mask); + + /* The access_ok check was done by caller, so use __put_user here */ +#define COPY(x) (err |= __put_user(regs->x, &sc->sc_##x)) + + COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8); + COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9); + COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9); + + COPY(a16); COPY(a17); COPY(a18); COPY(a19); + COPY(a20); COPY(a21); COPY(a22); COPY(a23); + COPY(a24); COPY(a25); COPY(a26); COPY(a27); + COPY(a28); COPY(a29); COPY(a30); COPY(a31); + COPY(b16); COPY(b17); COPY(b18); COPY(b19); + COPY(b20); COPY(b21); COPY(b22); COPY(b23); + COPY(b24); COPY(b25); COPY(b26); COPY(b27); + COPY(b28); COPY(b29); COPY(b30); COPY(b31); + + COPY(csr); COPY(pc); + +#undef COPY + + return err; +} + +static inline void __user *get_sigframe(struct k_sigaction *ka, + struct pt_regs *regs, + unsigned long framesize) +{ + unsigned long sp = regs->sp; + + /* + * This is the X/Open sanctioned signal stack switching. + */ + if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0) + sp = current->sas_ss_sp + current->sas_ss_size; + + /* + * No matter what happens, 'sp' must be dword + * aligned. Otherwise, nasty things will happen + */ + return (void __user *)((sp - framesize) & ~7); +} + +static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe __user *frame; + unsigned long __user *retcode; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto segv_and_exit; + + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + + /* Clear all the bits of the ucontext we don't use. */ + err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); + + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace */ + retcode = (unsigned long __user *) &frame->retcode; + + /* The access_ok check was done above, so use __put_user here */ +#define COPY(x) (err |= __put_user(x, retcode++)) + + COPY(0x0000002AUL | (__NR_rt_sigreturn << 7)); + /* MVK __NR_rt_sigreturn,B0 */ + COPY(0x10000000UL); /* SWE */ + COPY(0x00006000UL); /* NOP 4 */ + COPY(0x00006000UL); /* NOP 4 */ + COPY(0x00006000UL); /* NOP 4 */ + COPY(0x00006000UL); /* NOP 4 */ + COPY(0x00006000UL); /* NOP 4 */ + COPY(0x00006000UL); /* NOP 4 */ + COPY(0x00006000UL); /* NOP 4 */ + +#undef COPY + + if (err) + goto segv_and_exit; + + flush_icache_range((unsigned long) &frame->retcode, + (unsigned long) &frame->retcode + RETCODE_SIZE); + + retcode = (unsigned long __user *) &frame->retcode; + + /* Change user context to branch to signal handler */ + regs->sp = (unsigned long) frame - 8; + regs->b3 = (unsigned long) retcode; + regs->pc = (unsigned long) ka->sa.sa_handler; + + /* Give the signal number to the handler */ + regs->a4 = signr; + + /* + * For realtime signals we must also set the second and third + * arguments for the signal handler. + * -- Peter Maydell 2000-12-06 + */ + regs->b4 = (unsigned long)&frame->info; + regs->a6 = (unsigned long)&frame->uc; + + return 0; + +segv_and_exit: + force_sigsegv(signr, current); + return -EFAULT; +} + +static inline void +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) +{ + switch (regs->a4) { + case -ERESTARTNOHAND: + if (!has_handler) + goto do_restart; + regs->a4 = -EINTR; + break; + + case -ERESTARTSYS: + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { + regs->a4 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: +do_restart: + regs->a4 = regs->orig_a4; + regs->pc -= 4; + break; + } +} + +/* + * handle the actual delivery of a signal to userspace + */ +static int handle_signal(int sig, + siginfo_t *info, struct k_sigaction *ka, + sigset_t *oldset, struct pt_regs *regs, + int syscall) +{ + int ret; + + /* Are we from a system call? */ + if (syscall) { + /* If so, check system call restarting.. */ + switch (regs->a4) { + case -ERESTART_RESTARTBLOCK: + case -ERESTARTNOHAND: + regs->a4 = -EINTR; + break; + + case -ERESTARTSYS: + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->a4 = -EINTR; + break; + } + + /* fallthrough */ + case -ERESTARTNOINTR: + regs->a4 = regs->orig_a4; + regs->pc -= 4; + } + } + + /* Set up the stack frame */ + ret = setup_rt_frame(sig, ka, info, oldset, regs); + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, + &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } + + return ret; +} + +/* + * handle a potential signal + */ +static void do_signal(struct pt_regs *regs, int syscall) +{ + struct k_sigaction ka; + siginfo_t info; + sigset_t *oldset; + int signr; + + /* we want the common case to go fast, which is why we may in certain + * cases get here from kernel mode */ + if (!user_mode(regs)) + return; + + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + if (handle_signal(signr, &info, &ka, oldset, + regs, syscall) == 0) { + /* a signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TIF_RESTORE_SIGMASK flag */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + + tracehook_signal_handler(signr, &info, &ka, regs, 0); + } + + return; + } + + /* did we come from a system call? */ + if (syscall) { + /* restart the system call - no handlers present */ + switch (regs->a4) { + case -ERESTARTNOHAND: + case -ERESTARTSYS: + case -ERESTARTNOINTR: + regs->a4 = regs->orig_a4; + regs->pc -= 4; + break; + + case -ERESTART_RESTARTBLOCK: + regs->a4 = regs->orig_a4; + regs->b0 = __NR_restart_syscall; + regs->pc -= 4; + break; + } + } + + /* if there's no signal to deliver, we just put the saved sigmask + * back */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } +} + +/* + * notification of userspace execution resumption + * - triggered by current->work.notify_resume + */ +asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags, + int syscall) +{ + /* deal with pending signal delivery */ + if (thread_info_flags & ((1 << TIF_SIGPENDING) | + (1 << TIF_RESTORE_SIGMASK))) + do_signal(regs, syscall); + + if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + if (current->replacement_session_keyring) + key_replace_session_keyring(); + } +} -- cgit v1.2.3 From 546a39546c64ad7e73796c5508ef5487af42cae2 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:05:33 -0400 Subject: C6X: time management Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Reviewed-by: Thomas Gleixner Acked-by: Arnd Bergmann --- arch/c6x/include/asm/timer64.h | 6 ++ arch/c6x/include/asm/timex.h | 33 ++++++ arch/c6x/kernel/time.c | 65 ++++++++++++ arch/c6x/platforms/timer64.c | 236 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 arch/c6x/include/asm/timer64.h create mode 100644 arch/c6x/include/asm/timex.h create mode 100644 arch/c6x/kernel/time.c create mode 100644 arch/c6x/platforms/timer64.c (limited to 'arch') diff --git a/arch/c6x/include/asm/timer64.h b/arch/c6x/include/asm/timer64.h new file mode 100644 index 000000000000..bbe27bb9887e --- /dev/null +++ b/arch/c6x/include/asm/timer64.h @@ -0,0 +1,6 @@ +#ifndef _C6X_TIMER64_H +#define _C6X_TIMER64_H + +extern void __init timer64_init(void); + +#endif /* _C6X_TIMER64_H */ diff --git a/arch/c6x/include/asm/timex.h b/arch/c6x/include/asm/timex.h new file mode 100644 index 000000000000..508c3ec971f9 --- /dev/null +++ b/arch/c6x/include/asm/timex.h @@ -0,0 +1,33 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Modified for 2.6.34: Mark Salter + * + * 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_C6X_TIMEX_H +#define _ASM_C6X_TIMEX_H + +#define CLOCK_TICK_RATE ((1000 * 1000000UL) / 6) + +/* 64-bit timestamp */ +typedef unsigned long long cycles_t; + +static inline cycles_t get_cycles(void) +{ + unsigned l, h; + + asm volatile (" dint\n" + " mvc .s2 TSCL,%0\n" + " mvc .s2 TSCH,%1\n" + " rint\n" + : "=b"(l), "=b"(h)); + return ((cycles_t)h << 32) | l; +} + +#endif /* _ASM_C6X_TIMEX_H */ diff --git a/arch/c6x/kernel/time.c b/arch/c6x/kernel/time.c new file mode 100644 index 000000000000..4c9f136165f7 --- /dev/null +++ b/arch/c6x/kernel/time.c @@ -0,0 +1,65 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static u32 sched_clock_multiplier; +#define SCHED_CLOCK_SHIFT 16 + +static cycle_t tsc_read(struct clocksource *cs) +{ + return get_cycles(); +} + +static struct clocksource clocksource_tsc = { + .name = "timestamp", + .rating = 300, + .read = tsc_read, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +/* + * scheduler clock - returns current time in nanoseconds. + */ +u64 sched_clock(void) +{ + u64 tsc = get_cycles(); + + return (tsc * sched_clock_multiplier) >> SCHED_CLOCK_SHIFT; +} + +void time_init(void) +{ + u64 tmp = (u64)NSEC_PER_SEC << SCHED_CLOCK_SHIFT; + + do_div(tmp, c6x_core_freq); + sched_clock_multiplier = tmp; + + clocksource_register_hz(&clocksource_tsc, c6x_core_freq); + + /* write anything into TSCL to enable counting */ + set_creg(TSCL, 0); + + /* probe for timer64 event timer */ + timer64_init(); +} diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c new file mode 100644 index 000000000000..783415861dae --- /dev/null +++ b/arch/c6x/platforms/timer64.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2010, 2011 Texas Instruments Incorporated + * Contributed by: Mark Salter (msalter@redhat.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 +#include +#include +#include +#include +#include +#include +#include +#include + +struct timer_regs { + u32 reserved0; + u32 emumgt; + u32 reserved1; + u32 reserved2; + u32 cntlo; + u32 cnthi; + u32 prdlo; + u32 prdhi; + u32 tcr; + u32 tgcr; + u32 wdtcr; +}; + +static struct timer_regs __iomem *timer; + +#define TCR_TSTATLO 0x001 +#define TCR_INVOUTPLO 0x002 +#define TCR_INVINPLO 0x004 +#define TCR_CPLO 0x008 +#define TCR_ENAMODELO_ONCE 0x040 +#define TCR_ENAMODELO_CONT 0x080 +#define TCR_ENAMODELO_MASK 0x0c0 +#define TCR_PWIDLO_MASK 0x030 +#define TCR_CLKSRCLO 0x100 +#define TCR_TIENLO 0x200 +#define TCR_TSTATHI (0x001 << 16) +#define TCR_INVOUTPHI (0x002 << 16) +#define TCR_CPHI (0x008 << 16) +#define TCR_PWIDHI_MASK (0x030 << 16) +#define TCR_ENAMODEHI_ONCE (0x040 << 16) +#define TCR_ENAMODEHI_CONT (0x080 << 16) +#define TCR_ENAMODEHI_MASK (0x0c0 << 16) + +#define TGCR_TIMLORS 0x001 +#define TGCR_TIMHIRS 0x002 +#define TGCR_TIMMODE_UD32 0x004 +#define TGCR_TIMMODE_WDT64 0x008 +#define TGCR_TIMMODE_CD32 0x00c +#define TGCR_TIMMODE_MASK 0x00c +#define TGCR_PSCHI_MASK (0x00f << 8) +#define TGCR_TDDRHI_MASK (0x00f << 12) + +/* + * Timer clocks are divided down from the CPU clock + * The divisor is in the EMUMGTCLKSPD register + */ +#define TIMER_DIVISOR \ + ((soc_readl(&timer->emumgt) & (0xf << 16)) >> 16) + +#define TIMER64_RATE (c6x_core_freq / TIMER_DIVISOR) + +#define TIMER64_MODE_DISABLED 0 +#define TIMER64_MODE_ONE_SHOT TCR_ENAMODELO_ONCE +#define TIMER64_MODE_PERIODIC TCR_ENAMODELO_CONT + +static int timer64_mode; +static int timer64_devstate_id = -1; + +static void timer64_config(unsigned long period) +{ + u32 tcr = soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK; + + soc_writel(tcr, &timer->tcr); + soc_writel(period - 1, &timer->prdlo); + soc_writel(0, &timer->cntlo); + tcr |= timer64_mode; + soc_writel(tcr, &timer->tcr); +} + +static void timer64_enable(void) +{ + u32 val; + + if (timer64_devstate_id >= 0) + dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED); + + /* disable timer, reset count */ + soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr); + soc_writel(0, &timer->prdlo); + + /* use internal clock and 1 cycle pulse width */ + val = soc_readl(&timer->tcr); + soc_writel(val & ~(TCR_CLKSRCLO | TCR_PWIDLO_MASK), &timer->tcr); + + /* dual 32-bit unchained mode */ + val = soc_readl(&timer->tgcr) & ~TGCR_TIMMODE_MASK; + soc_writel(val, &timer->tgcr); + soc_writel(val | (TGCR_TIMLORS | TGCR_TIMMODE_UD32), &timer->tgcr); +} + +static void timer64_disable(void) +{ + /* disable timer, reset count */ + soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr); + soc_writel(0, &timer->prdlo); + + if (timer64_devstate_id >= 0) + dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_DISABLED); +} + +static int next_event(unsigned long delta, + struct clock_event_device *evt) +{ + timer64_config(delta); + return 0; +} + +static void set_clock_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + timer64_enable(); + timer64_mode = TIMER64_MODE_PERIODIC; + timer64_config(TIMER64_RATE / HZ); + break; + case CLOCK_EVT_MODE_ONESHOT: + timer64_enable(); + timer64_mode = TIMER64_MODE_ONE_SHOT; + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + timer64_mode = TIMER64_MODE_DISABLED; + timer64_disable(); + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device t64_clockevent_device = { + .name = "TIMER64_EVT32_TIMER", + .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, + .rating = 200, + .set_mode = set_clock_mode, + .set_next_event = next_event, +}; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = &t64_clockevent_device; + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction timer_iact = { + .name = "timer", + .flags = IRQF_TIMER, + .handler = timer_interrupt, + .dev_id = &t64_clockevent_device, +}; + +void __init timer64_init(void) +{ + struct clock_event_device *cd = &t64_clockevent_device; + struct device_node *np, *first = NULL; + u32 val; + int err, found = 0; + + for_each_compatible_node(np, NULL, "ti,c64x+timer64") { + err = of_property_read_u32(np, "ti,core-mask", &val); + if (!err) { + if (val & (1 << get_coreid())) { + found = 1; + break; + } + } else if (!first) + first = np; + } + if (!found) { + /* try first one with no core-mask */ + if (first) + np = of_node_get(first); + else { + pr_debug("Cannot find ti,c64x+timer64 timer.\n"); + return; + } + } + + timer = of_iomap(np, 0); + if (!timer) { + pr_debug("%s: Cannot map timer registers.\n", np->full_name); + goto out; + } + pr_debug("%s: Timer registers=%p.\n", np->full_name, timer); + + cd->irq = irq_of_parse_and_map(np, 0); + if (cd->irq == NO_IRQ) { + pr_debug("%s: Cannot find interrupt.\n", np->full_name); + iounmap(timer); + goto out; + } + + /* If there is a device state control, save the ID. */ + err = of_property_read_u32(np, "ti,dscr-dev-enable", &val); + if (!err) + timer64_devstate_id = val; + + pr_debug("%s: Timer irq=%d.\n", np->full_name, cd->irq); + + clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5); + + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(250, cd); + + cd->cpumask = cpumask_of(smp_processor_id()); + + clockevents_register_device(cd); + setup_irq(cd->irq, &timer_iact); + +out: + of_node_put(np); + return; +} -- cgit v1.2.3 From ec500af3059b474df35418c41c684c1cde830c81 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:06:27 -0400 Subject: C6X: interrupt handling Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Reviewed-by: Thomas Gleixner Acked-by: Arnd Bergmann --- arch/c6x/include/asm/hardirq.h | 20 + arch/c6x/include/asm/irq.h | 302 +++++++++++++++ arch/c6x/include/asm/irqflags.h | 72 ++++ arch/c6x/include/asm/megamod-pic.h | 9 + arch/c6x/kernel/irq.c | 728 +++++++++++++++++++++++++++++++++++++ arch/c6x/platforms/megamod-pic.c | 349 ++++++++++++++++++ 6 files changed, 1480 insertions(+) create mode 100644 arch/c6x/include/asm/hardirq.h create mode 100644 arch/c6x/include/asm/irq.h create mode 100644 arch/c6x/include/asm/irqflags.h create mode 100644 arch/c6x/include/asm/megamod-pic.h create mode 100644 arch/c6x/kernel/irq.c create mode 100644 arch/c6x/platforms/megamod-pic.c (limited to 'arch') diff --git a/arch/c6x/include/asm/hardirq.h b/arch/c6x/include/asm/hardirq.h new file mode 100644 index 000000000000..9621954f98f4 --- /dev/null +++ b/arch/c6x/include/asm/hardirq.h @@ -0,0 +1,20 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ + +#ifndef _ASM_C6X_HARDIRQ_H +#define _ASM_C6X_HARDIRQ_H + +extern void ack_bad_irq(int irq); +#define ack_bad_irq ack_bad_irq + +#include + +#endif /* _ASM_C6X_HARDIRQ_H */ diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h new file mode 100644 index 000000000000..a6ae3c9d9c40 --- /dev/null +++ b/arch/c6x/include/asm/irq.h @@ -0,0 +1,302 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Large parts taken directly from powerpc. + * + * 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_C6X_IRQ_H +#define _ASM_C6X_IRQ_H + +#include +#include +#include +#include + +#define irq_canonicalize(irq) (irq) + +/* + * The C64X+ core has 16 IRQ vectors. One each is used by Reset and NMI. Two + * are reserved. The remaining 12 vectors are used to route SoC interrupts. + * These interrupt vectors are prioritized with IRQ 4 having the highest + * priority and IRQ 15 having the lowest. + * + * The C64x+ megamodule provides a PIC which combines SoC IRQ sources into a + * single core IRQ vector. There are four combined sources, each of which + * feed into one of the 12 general interrupt vectors. The remaining 8 vectors + * can each route a single SoC interrupt directly. + */ +#define NR_PRIORITY_IRQS 16 + +#define NR_IRQS_LEGACY NR_PRIORITY_IRQS + +/* Total number of virq in the platform */ +#define NR_IRQS 256 + +/* This number is used when no interrupt has been assigned */ +#define NO_IRQ 0 + +/* This type is the placeholder for a hardware interrupt number. It has to + * be big enough to enclose whatever representation is used by a given + * platform. + */ +typedef unsigned long irq_hw_number_t; + +/* Interrupt controller "host" data structure. This could be defined as a + * irq domain controller. That is, it handles the mapping between hardware + * and virtual interrupt numbers for a given interrupt domain. The host + * structure is generally created by the PIC code for a given PIC instance + * (though a host can cover more than one PIC if they have a flat number + * model). It's the host callbacks that are responsible for setting the + * irq_chip on a given irq_desc after it's been mapped. + * + * The host code and data structures are fairly agnostic to the fact that + * we use an open firmware device-tree. We do have references to struct + * device_node in two places: in irq_find_host() to find the host matching + * a given interrupt controller node, and of course as an argument to its + * counterpart host->ops->match() callback. However, those are treated as + * generic pointers by the core and the fact that it's actually a device-node + * pointer is purely a convention between callers and implementation. This + * code could thus be used on other architectures by replacing those two + * by some sort of arch-specific void * "token" used to identify interrupt + * controllers. + */ +struct irq_host; +struct radix_tree_root; +struct device_node; + +/* Functions below are provided by the host and called whenever a new mapping + * is created or an old mapping is disposed. The host can then proceed to + * whatever internal data structures management is required. It also needs + * to setup the irq_desc when returning from map(). + */ +struct irq_host_ops { + /* Match an interrupt controller device node to a host, returns + * 1 on a match + */ + int (*match)(struct irq_host *h, struct device_node *node); + + /* Create or update a mapping between a virtual irq number and a hw + * irq number. This is called only once for a given mapping. + */ + int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw); + + /* Dispose of such a mapping */ + void (*unmap)(struct irq_host *h, unsigned int virq); + + /* Translate device-tree interrupt specifier from raw format coming + * from the firmware to a irq_hw_number_t (interrupt line number) and + * type (sense) that can be passed to set_irq_type(). In the absence + * of this callback, irq_create_of_mapping() and irq_of_parse_and_map() + * will return the hw number in the first cell and IRQ_TYPE_NONE for + * the type (which amount to keeping whatever default value the + * interrupt controller has for that line) + */ + int (*xlate)(struct irq_host *h, struct device_node *ctrler, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type); +}; + +struct irq_host { + struct list_head link; + + /* type of reverse mapping technique */ + unsigned int revmap_type; +#define IRQ_HOST_MAP_PRIORITY 0 /* core priority irqs, get irqs 1..15 */ +#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */ +#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */ +#define IRQ_HOST_MAP_TREE 3 /* radix tree */ + union { + struct { + unsigned int size; + unsigned int *revmap; + } linear; + struct radix_tree_root tree; + } revmap_data; + struct irq_host_ops *ops; + void *host_data; + irq_hw_number_t inval_irq; + + /* Optional device node pointer */ + struct device_node *of_node; +}; + +struct irq_data; +extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); +extern irq_hw_number_t virq_to_hw(unsigned int virq); +extern bool virq_is_host(unsigned int virq, struct irq_host *host); + +/** + * irq_alloc_host - Allocate a new irq_host data structure + * @of_node: optional device-tree node of the interrupt controller + * @revmap_type: type of reverse mapping to use + * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map + * @ops: map/unmap host callbacks + * @inval_irq: provide a hw number in that host space that is always invalid + * + * Allocates and initialize and irq_host structure. Note that in the case of + * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns + * for all legacy interrupts except 0 (which is always the invalid irq for + * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by + * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated + * later during boot automatically (the reverse mapping will use the slow path + * until that happens). + */ +extern struct irq_host *irq_alloc_host(struct device_node *of_node, + unsigned int revmap_type, + unsigned int revmap_arg, + struct irq_host_ops *ops, + irq_hw_number_t inval_irq); + + +/** + * irq_find_host - Locates a host for a given device node + * @node: device-tree node of the interrupt controller + */ +extern struct irq_host *irq_find_host(struct device_node *node); + + +/** + * irq_set_default_host - Set a "default" host + * @host: default host pointer + * + * For convenience, it's possible to set a "default" host that will be used + * whenever NULL is passed to irq_create_mapping(). It makes life easier for + * platforms that want to manipulate a few hard coded interrupt numbers that + * aren't properly represented in the device-tree. + */ +extern void irq_set_default_host(struct irq_host *host); + + +/** + * irq_set_virq_count - Set the maximum number of virt irqs + * @count: number of linux virtual irqs, capped with NR_IRQS + * + * This is mainly for use by platforms like iSeries who want to program + * the virtual irq number in the controller to avoid the reverse mapping + */ +extern void irq_set_virq_count(unsigned int count); + + +/** + * irq_create_mapping - Map a hardware interrupt into linux virq space + * @host: host owning this hardware interrupt or NULL for default host + * @hwirq: hardware irq number in that host space + * + * Only one mapping per hardware interrupt is permitted. Returns a linux + * virq number. + * If the sense/trigger is to be specified, set_irq_type() should be called + * on the number returned from that call. + */ +extern unsigned int irq_create_mapping(struct irq_host *host, + irq_hw_number_t hwirq); + + +/** + * irq_dispose_mapping - Unmap an interrupt + * @virq: linux virq number of the interrupt to unmap + */ +extern void irq_dispose_mapping(unsigned int virq); + +/** + * irq_find_mapping - Find a linux virq from an hw irq number. + * @host: host owning this hardware interrupt + * @hwirq: hardware irq number in that host space + * + * This is a slow path, for use by generic code. It's expected that an + * irq controller implementation directly calls the appropriate low level + * mapping function. + */ +extern unsigned int irq_find_mapping(struct irq_host *host, + irq_hw_number_t hwirq); + +/** + * irq_create_direct_mapping - Allocate a virq for direct mapping + * @host: host to allocate the virq for or NULL for default host + * + * This routine is used for irq controllers which can choose the hardware + * interrupt numbers they generate. In such a case it's simplest to use + * the linux virq as the hardware interrupt number. + */ +extern unsigned int irq_create_direct_mapping(struct irq_host *host); + +/** + * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping. + * @host: host owning this hardware interrupt + * @virq: linux irq number + * @hwirq: hardware irq number in that host space + * + * This is for use by irq controllers that use a radix tree reverse + * mapping for fast lookup. + */ +extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, + irq_hw_number_t hwirq); + +/** + * irq_radix_revmap_lookup - Find a linux virq from a hw irq number. + * @host: host owning this hardware interrupt + * @hwirq: hardware irq number in that host space + * + * This is a fast path, for use by irq controller code that uses radix tree + * revmaps + */ +extern unsigned int irq_radix_revmap_lookup(struct irq_host *host, + irq_hw_number_t hwirq); + +/** + * irq_linear_revmap - Find a linux virq from a hw irq number. + * @host: host owning this hardware interrupt + * @hwirq: hardware irq number in that host space + * + * This is a fast path, for use by irq controller code that uses linear + * revmaps. It does fallback to the slow path if the revmap doesn't exist + * yet and will create the revmap entry with appropriate locking + */ + +extern unsigned int irq_linear_revmap(struct irq_host *host, + irq_hw_number_t hwirq); + + + +/** + * irq_alloc_virt - Allocate virtual irq numbers + * @host: host owning these new virtual irqs + * @count: number of consecutive numbers to allocate + * @hint: pass a hint number, the allocator will try to use a 1:1 mapping + * + * This is a low level function that is used internally by irq_create_mapping() + * and that can be used by some irq controllers implementations for things + * like allocating ranges of numbers for MSIs. The revmaps are left untouched. + */ +extern unsigned int irq_alloc_virt(struct irq_host *host, + unsigned int count, + unsigned int hint); + +/** + * irq_free_virt - Free virtual irq numbers + * @virq: virtual irq number of the first interrupt to free + * @count: number of interrupts to free + * + * This function is the opposite of irq_alloc_virt. It will not clear reverse + * maps, this should be done previously by unmap'ing the interrupt. In fact, + * all interrupts covered by the range being freed should have been unmapped + * prior to calling this. + */ +extern void irq_free_virt(unsigned int virq, unsigned int count); + +extern void __init init_pic_c64xplus(void); + +extern void init_IRQ(void); + +struct pt_regs; + +extern asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs); + +extern unsigned long irq_err_count; + +#endif /* _ASM_C6X_IRQ_H */ diff --git a/arch/c6x/include/asm/irqflags.h b/arch/c6x/include/asm/irqflags.h new file mode 100644 index 000000000000..cf78e09e18c3 --- /dev/null +++ b/arch/c6x/include/asm/irqflags.h @@ -0,0 +1,72 @@ +/* + * C6X IRQ flag handling + * + * Copyright (C) 2010 Texas Instruments Incorporated + * Written by Mark Salter (msalter@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_IRQFLAGS_H +#define _ASM_IRQFLAGS_H + +#ifndef __ASSEMBLY__ + +/* read interrupt enabled status */ +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + + asm volatile (" mvc .s2 CSR,%0\n" : "=b"(flags)); + return flags; +} + +/* set interrupt enabled status */ +static inline void arch_local_irq_restore(unsigned long flags) +{ + asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags)); +} + +/* unconditionally enable interrupts */ +static inline void arch_local_irq_enable(void) +{ + unsigned long flags = arch_local_save_flags(); + flags |= 1; + arch_local_irq_restore(flags); +} + +/* unconditionally disable interrupts */ +static inline void arch_local_irq_disable(void) +{ + unsigned long flags = arch_local_save_flags(); + flags &= ~1; + arch_local_irq_restore(flags); +} + +/* get status and disable interrupts */ +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + + flags = arch_local_save_flags(); + arch_local_irq_restore(flags & ~1); + return flags; +} + +/* test flags */ +static inline int arch_irqs_disabled_flags(unsigned long flags) +{ + return (flags & 1) == 0; +} + +/* test hardware interrupt enable bit */ +static inline int arch_irqs_disabled(void) +{ + return arch_irqs_disabled_flags(arch_local_save_flags()); +} + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_IRQFLAGS_H */ diff --git a/arch/c6x/include/asm/megamod-pic.h b/arch/c6x/include/asm/megamod-pic.h new file mode 100644 index 000000000000..eca0a8678034 --- /dev/null +++ b/arch/c6x/include/asm/megamod-pic.h @@ -0,0 +1,9 @@ +#ifndef _C6X_MEGAMOD_PIC_H +#define _C6X_MEGAMOD_PIC_H + +#ifdef __KERNEL__ + +extern void __init megamod_pic_init(void); + +#endif /* __KERNEL__ */ +#endif /* _C6X_MEGAMOD_PIC_H */ diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c new file mode 100644 index 000000000000..0929e4b2b244 --- /dev/null +++ b/arch/c6x/kernel/irq.c @@ -0,0 +1,728 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * + * This borrows heavily from powerpc version, which is: + * + * Derived from arch/i386/kernel/irq.c + * Copyright (C) 1992 Linus Torvalds + * Adapted from arch/i386 by Gary Thomas + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Updated and modified by Cort Dougan + * Copyright (C) 1996-2001 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras + * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +unsigned long irq_err_count; + +static DEFINE_RAW_SPINLOCK(core_irq_lock); + +static void mask_core_irq(struct irq_data *data) +{ + unsigned int prio = data->irq; + + BUG_ON(prio < 4 || prio >= NR_PRIORITY_IRQS); + + raw_spin_lock(&core_irq_lock); + and_creg(IER, ~(1 << prio)); + raw_spin_unlock(&core_irq_lock); +} + +static void unmask_core_irq(struct irq_data *data) +{ + unsigned int prio = data->irq; + + raw_spin_lock(&core_irq_lock); + or_creg(IER, 1 << prio); + raw_spin_unlock(&core_irq_lock); +} + +static struct irq_chip core_chip = { + .name = "core", + .irq_mask = mask_core_irq, + .irq_unmask = unmask_core_irq, +}; + +asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + + BUG_ON(prio < 4 || prio >= NR_PRIORITY_IRQS); + + generic_handle_irq(prio); + + irq_exit(); + + set_irq_regs(old_regs); +} + +static struct irq_host *core_host; + +static int core_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + if (hw < 4 || hw >= NR_PRIORITY_IRQS) + return -EINVAL; + + irq_set_status_flags(virq, IRQ_LEVEL); + irq_set_chip_and_handler(virq, &core_chip, handle_level_irq); + return 0; +} + +static struct irq_host_ops core_host_ops = { + .map = core_host_map, +}; + +void __init init_IRQ(void) +{ + struct device_node *np; + + /* Mask all priority IRQs */ + and_creg(IER, ~0xfff0); + + np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic"); + if (np != NULL) { + /* create the core host */ + core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0, + &core_host_ops, 0); + if (core_host) + irq_set_default_host(core_host); + of_node_put(np); + } + + printk(KERN_INFO "Core interrupt controller initialized\n"); + + /* now we're ready for other SoC controllers */ + megamod_pic_init(); + + /* Clear all general IRQ flags */ + set_creg(ICR, 0xfff0); +} + +void ack_bad_irq(int irq) +{ + printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); + irq_err_count++; +} + +int arch_show_interrupts(struct seq_file *p, int prec) +{ + seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); + return 0; +} + +/* + * IRQ controller and virtual interrupts + */ + +/* The main irq map itself is an array of NR_IRQ entries containing the + * associate host and irq number. An entry with a host of NULL is free. + * An entry can be allocated if it's free, the allocator always then sets + * hwirq first to the host's invalid irq number and then fills ops. + */ +struct irq_map_entry { + irq_hw_number_t hwirq; + struct irq_host *host; +}; + +static LIST_HEAD(irq_hosts); +static DEFINE_RAW_SPINLOCK(irq_big_lock); +static DEFINE_MUTEX(revmap_trees_mutex); +static struct irq_map_entry irq_map[NR_IRQS]; +static unsigned int irq_virq_count = NR_IRQS; +static struct irq_host *irq_default_host; + +irq_hw_number_t irqd_to_hwirq(struct irq_data *d) +{ + return irq_map[d->irq].hwirq; +} +EXPORT_SYMBOL_GPL(irqd_to_hwirq); + +irq_hw_number_t virq_to_hw(unsigned int virq) +{ + return irq_map[virq].hwirq; +} +EXPORT_SYMBOL_GPL(virq_to_hw); + +bool virq_is_host(unsigned int virq, struct irq_host *host) +{ + return irq_map[virq].host == host; +} +EXPORT_SYMBOL_GPL(virq_is_host); + +static int default_irq_host_match(struct irq_host *h, struct device_node *np) +{ + return h->of_node != NULL && h->of_node == np; +} + +struct irq_host *irq_alloc_host(struct device_node *of_node, + unsigned int revmap_type, + unsigned int revmap_arg, + struct irq_host_ops *ops, + irq_hw_number_t inval_irq) +{ + struct irq_host *host; + unsigned int size = sizeof(struct irq_host); + unsigned int i; + unsigned int *rmap; + unsigned long flags; + + /* Allocate structure and revmap table if using linear mapping */ + if (revmap_type == IRQ_HOST_MAP_LINEAR) + size += revmap_arg * sizeof(unsigned int); + host = kzalloc(size, GFP_KERNEL); + if (host == NULL) + return NULL; + + /* Fill structure */ + host->revmap_type = revmap_type; + host->inval_irq = inval_irq; + host->ops = ops; + host->of_node = of_node_get(of_node); + + if (host->ops->match == NULL) + host->ops->match = default_irq_host_match; + + raw_spin_lock_irqsave(&irq_big_lock, flags); + + /* Check for the priority controller. */ + if (revmap_type == IRQ_HOST_MAP_PRIORITY) { + if (irq_map[0].host != NULL) { + raw_spin_unlock_irqrestore(&irq_big_lock, flags); + of_node_put(host->of_node); + kfree(host); + return NULL; + } + irq_map[0].host = host; + } + + list_add(&host->link, &irq_hosts); + raw_spin_unlock_irqrestore(&irq_big_lock, flags); + + /* Additional setups per revmap type */ + switch (revmap_type) { + case IRQ_HOST_MAP_PRIORITY: + /* 0 is always the invalid number for priority */ + host->inval_irq = 0; + /* setup us as the host for all priority interrupts */ + for (i = 1; i < NR_PRIORITY_IRQS; i++) { + irq_map[i].hwirq = i; + smp_wmb(); + irq_map[i].host = host; + smp_wmb(); + + ops->map(host, i, i); + } + break; + case IRQ_HOST_MAP_LINEAR: + rmap = (unsigned int *)(host + 1); + for (i = 0; i < revmap_arg; i++) + rmap[i] = NO_IRQ; + host->revmap_data.linear.size = revmap_arg; + smp_wmb(); + host->revmap_data.linear.revmap = rmap; + break; + case IRQ_HOST_MAP_TREE: + INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL); + break; + default: + break; + } + + pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host); + + return host; +} + +struct irq_host *irq_find_host(struct device_node *node) +{ + struct irq_host *h, *found = NULL; + unsigned long flags; + + /* We might want to match the legacy controller last since + * it might potentially be set to match all interrupts in + * the absence of a device node. This isn't a problem so far + * yet though... + */ + raw_spin_lock_irqsave(&irq_big_lock, flags); + list_for_each_entry(h, &irq_hosts, link) + if (h->ops->match(h, node)) { + found = h; + break; + } + raw_spin_unlock_irqrestore(&irq_big_lock, flags); + return found; +} +EXPORT_SYMBOL_GPL(irq_find_host); + +void irq_set_default_host(struct irq_host *host) +{ + pr_debug("irq: Default host set to @0x%p\n", host); + + irq_default_host = host; +} + +void irq_set_virq_count(unsigned int count) +{ + pr_debug("irq: Trying to set virq count to %d\n", count); + + BUG_ON(count < NR_PRIORITY_IRQS); + if (count < NR_IRQS) + irq_virq_count = count; +} + +static int irq_setup_virq(struct irq_host *host, unsigned int virq, + irq_hw_number_t hwirq) +{ + int res; + + res = irq_alloc_desc_at(virq, 0); + if (res != virq) { + pr_debug("irq: -> allocating desc failed\n"); + goto error; + } + + /* map it */ + smp_wmb(); + irq_map[virq].hwirq = hwirq; + smp_mb(); + + if (host->ops->map(host, virq, hwirq)) { + pr_debug("irq: -> mapping failed, freeing\n"); + goto errdesc; + } + + irq_clear_status_flags(virq, IRQ_NOREQUEST); + + return 0; + +errdesc: + irq_free_descs(virq, 1); +error: + irq_free_virt(virq, 1); + return -1; +} + +unsigned int irq_create_direct_mapping(struct irq_host *host) +{ + unsigned int virq; + + if (host == NULL) + host = irq_default_host; + + BUG_ON(host == NULL); + WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP); + + virq = irq_alloc_virt(host, 1, 0); + if (virq == NO_IRQ) { + pr_debug("irq: create_direct virq allocation failed\n"); + return NO_IRQ; + } + + pr_debug("irq: create_direct obtained virq %d\n", virq); + + if (irq_setup_virq(host, virq, virq)) + return NO_IRQ; + + return virq; +} + +unsigned int irq_create_mapping(struct irq_host *host, + irq_hw_number_t hwirq) +{ + unsigned int virq, hint; + + pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq); + + /* Look for default host if nececssary */ + if (host == NULL) + host = irq_default_host; + if (host == NULL) { + printk(KERN_WARNING "irq_create_mapping called for" + " NULL host, hwirq=%lx\n", hwirq); + WARN_ON(1); + return NO_IRQ; + } + pr_debug("irq: -> using host @%p\n", host); + + /* Check if mapping already exists */ + virq = irq_find_mapping(host, hwirq); + if (virq != NO_IRQ) { + pr_debug("irq: -> existing mapping on virq %d\n", virq); + return virq; + } + + /* Allocate a virtual interrupt number */ + hint = hwirq % irq_virq_count; + virq = irq_alloc_virt(host, 1, hint); + if (virq == NO_IRQ) { + pr_debug("irq: -> virq allocation failed\n"); + return NO_IRQ; + } + + if (irq_setup_virq(host, virq, hwirq)) + return NO_IRQ; + + pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n", + hwirq, host->of_node ? host->of_node->full_name : "null", virq); + + return virq; +} +EXPORT_SYMBOL_GPL(irq_create_mapping); + +unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize) +{ + struct irq_host *host; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + unsigned int virq; + + if (controller == NULL) + host = irq_default_host; + else + host = irq_find_host(controller); + if (host == NULL) { + printk(KERN_WARNING "irq: no irq host found for %s !\n", + controller->full_name); + return NO_IRQ; + } + + /* If host has no translation, then we assume interrupt line */ + if (host->ops->xlate == NULL) + hwirq = intspec[0]; + else { + if (host->ops->xlate(host, controller, intspec, intsize, + &hwirq, &type)) + return NO_IRQ; + } + + /* Create mapping */ + virq = irq_create_mapping(host, hwirq); + if (virq == NO_IRQ) + return virq; + + /* Set type if specified and different than the current one */ + if (type != IRQ_TYPE_NONE && + type != (irqd_get_trigger_type(irq_get_irq_data(virq)))) + irq_set_irq_type(virq, type); + return virq; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); + +void irq_dispose_mapping(unsigned int virq) +{ + struct irq_host *host; + irq_hw_number_t hwirq; + + if (virq == NO_IRQ) + return; + + /* Never unmap priority interrupts */ + if (virq < NR_PRIORITY_IRQS) + return; + + host = irq_map[virq].host; + if (WARN_ON(host == NULL)) + return; + + irq_set_status_flags(virq, IRQ_NOREQUEST); + + /* remove chip and handler */ + irq_set_chip_and_handler(virq, NULL, NULL); + + /* Make sure it's completed */ + synchronize_irq(virq); + + /* Tell the PIC about it */ + if (host->ops->unmap) + host->ops->unmap(host, virq); + smp_mb(); + + /* Clear reverse map */ + hwirq = irq_map[virq].hwirq; + switch (host->revmap_type) { + case IRQ_HOST_MAP_LINEAR: + if (hwirq < host->revmap_data.linear.size) + host->revmap_data.linear.revmap[hwirq] = NO_IRQ; + break; + case IRQ_HOST_MAP_TREE: + mutex_lock(&revmap_trees_mutex); + radix_tree_delete(&host->revmap_data.tree, hwirq); + mutex_unlock(&revmap_trees_mutex); + break; + } + + /* Destroy map */ + smp_mb(); + irq_map[virq].hwirq = host->inval_irq; + + irq_free_descs(virq, 1); + /* Free it */ + irq_free_virt(virq, 1); +} +EXPORT_SYMBOL_GPL(irq_dispose_mapping); + +unsigned int irq_find_mapping(struct irq_host *host, + irq_hw_number_t hwirq) +{ + unsigned int i; + unsigned int hint = hwirq % irq_virq_count; + + /* Look for default host if nececssary */ + if (host == NULL) + host = irq_default_host; + if (host == NULL) + return NO_IRQ; + + /* Slow path does a linear search of the map */ + i = hint; + do { + if (irq_map[i].host == host && + irq_map[i].hwirq == hwirq) + return i; + i++; + if (i >= irq_virq_count) + i = 4; + } while (i != hint); + return NO_IRQ; +} +EXPORT_SYMBOL_GPL(irq_find_mapping); + +unsigned int irq_radix_revmap_lookup(struct irq_host *host, + irq_hw_number_t hwirq) +{ + struct irq_map_entry *ptr; + unsigned int virq; + + if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE)) + return irq_find_mapping(host, hwirq); + + /* + * The ptr returned references the static global irq_map. + * but freeing an irq can delete nodes along the path to + * do the lookup via call_rcu. + */ + rcu_read_lock(); + ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq); + rcu_read_unlock(); + + /* + * If found in radix tree, then fine. + * Else fallback to linear lookup - this should not happen in practice + * as it means that we failed to insert the node in the radix tree. + */ + if (ptr) + virq = ptr - irq_map; + else + virq = irq_find_mapping(host, hwirq); + + return virq; +} + +void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, + irq_hw_number_t hwirq) +{ + if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE)) + return; + + if (virq != NO_IRQ) { + mutex_lock(&revmap_trees_mutex); + radix_tree_insert(&host->revmap_data.tree, hwirq, + &irq_map[virq]); + mutex_unlock(&revmap_trees_mutex); + } +} + +unsigned int irq_linear_revmap(struct irq_host *host, + irq_hw_number_t hwirq) +{ + unsigned int *revmap; + + if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR)) + return irq_find_mapping(host, hwirq); + + /* Check revmap bounds */ + if (unlikely(hwirq >= host->revmap_data.linear.size)) + return irq_find_mapping(host, hwirq); + + /* Check if revmap was allocated */ + revmap = host->revmap_data.linear.revmap; + if (unlikely(revmap == NULL)) + return irq_find_mapping(host, hwirq); + + /* Fill up revmap with slow path if no mapping found */ + if (unlikely(revmap[hwirq] == NO_IRQ)) + revmap[hwirq] = irq_find_mapping(host, hwirq); + + return revmap[hwirq]; +} + +unsigned int irq_alloc_virt(struct irq_host *host, + unsigned int count, + unsigned int hint) +{ + unsigned long flags; + unsigned int i, j, found = NO_IRQ; + + if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS)) + return NO_IRQ; + + raw_spin_lock_irqsave(&irq_big_lock, flags); + + /* Use hint for 1 interrupt if any */ + if (count == 1 && hint >= NR_PRIORITY_IRQS && + hint < irq_virq_count && irq_map[hint].host == NULL) { + found = hint; + goto hint_found; + } + + /* Look for count consecutive numbers in the allocatable + * (non-legacy) space + */ + for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) { + if (irq_map[i].host != NULL) + j = 0; + else + j++; + + if (j == count) { + found = i - count + 1; + break; + } + } + if (found == NO_IRQ) { + raw_spin_unlock_irqrestore(&irq_big_lock, flags); + return NO_IRQ; + } + hint_found: + for (i = found; i < (found + count); i++) { + irq_map[i].hwirq = host->inval_irq; + smp_wmb(); + irq_map[i].host = host; + } + raw_spin_unlock_irqrestore(&irq_big_lock, flags); + return found; +} + +void irq_free_virt(unsigned int virq, unsigned int count) +{ + unsigned long flags; + unsigned int i; + + WARN_ON(virq < NR_PRIORITY_IRQS); + WARN_ON(count == 0 || (virq + count) > irq_virq_count); + + if (virq < NR_PRIORITY_IRQS) { + if (virq + count < NR_PRIORITY_IRQS) + return; + count -= NR_PRIORITY_IRQS - virq; + virq = NR_PRIORITY_IRQS; + } + + if (count > irq_virq_count || virq > irq_virq_count - count) { + if (virq > irq_virq_count) + return; + count = irq_virq_count - virq; + } + + raw_spin_lock_irqsave(&irq_big_lock, flags); + for (i = virq; i < (virq + count); i++) { + struct irq_host *host; + + host = irq_map[i].host; + irq_map[i].hwirq = host->inval_irq; + smp_wmb(); + irq_map[i].host = NULL; + } + raw_spin_unlock_irqrestore(&irq_big_lock, flags); +} + +#ifdef CONFIG_VIRQ_DEBUG +static int virq_debug_show(struct seq_file *m, void *private) +{ + unsigned long flags; + struct irq_desc *desc; + const char *p; + static const char none[] = "none"; + void *data; + int i; + + seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", + "chip name", "chip data", "host name"); + + for (i = 1; i < nr_irqs; i++) { + desc = irq_to_desc(i); + if (!desc) + continue; + + raw_spin_lock_irqsave(&desc->lock, flags); + + if (desc->action && desc->action->handler) { + struct irq_chip *chip; + + seq_printf(m, "%5d ", i); + seq_printf(m, "0x%05lx ", irq_map[i].hwirq); + + chip = irq_desc_get_chip(desc); + if (chip && chip->name) + p = chip->name; + else + p = none; + seq_printf(m, "%-15s ", p); + + data = irq_desc_get_chip_data(desc); + seq_printf(m, "0x%16p ", data); + + if (irq_map[i].host && irq_map[i].host->of_node) + p = irq_map[i].host->of_node->full_name; + else + p = none; + seq_printf(m, "%s\n", p); + } + + raw_spin_unlock_irqrestore(&desc->lock, flags); + } + + return 0; +} + +static int virq_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, virq_debug_show, inode->i_private); +} + +static const struct file_operations virq_debug_fops = { + .open = virq_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init irq_debugfs_init(void) +{ + if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root, + NULL, &virq_debug_fops) == NULL) + return -ENOMEM; + + return 0; +} +device_initcall(irq_debugfs_init); +#endif /* CONFIG_VIRQ_DEBUG */ diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c new file mode 100644 index 000000000000..7c37a947fb1c --- /dev/null +++ b/arch/c6x/platforms/megamod-pic.c @@ -0,0 +1,349 @@ +/* + * Support for C64x+ Megamodule Interrupt Controller + * + * Copyright (C) 2010, 2011 Texas Instruments Incorporated + * Contributed by: Mark Salter + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#define NR_COMBINERS 4 +#define NR_MUX_OUTPUTS 12 + +#define IRQ_UNMAPPED 0xffff + +/* + * Megamodule Interrupt Controller register layout + */ +struct megamod_regs { + u32 evtflag[8]; + u32 evtset[8]; + u32 evtclr[8]; + u32 reserved0[8]; + u32 evtmask[8]; + u32 mevtflag[8]; + u32 expmask[8]; + u32 mexpflag[8]; + u32 intmux_unused; + u32 intmux[7]; + u32 reserved1[8]; + u32 aegmux[2]; + u32 reserved2[14]; + u32 intxstat; + u32 intxclr; + u32 intdmask; + u32 reserved3[13]; + u32 evtasrt; +}; + +struct megamod_pic { + struct irq_host *irqhost; + struct megamod_regs __iomem *regs; + raw_spinlock_t lock; + + /* hw mux mapping */ + unsigned int output_to_irq[NR_MUX_OUTPUTS]; +}; + +static struct megamod_pic *mm_pic; + +struct megamod_cascade_data { + struct megamod_pic *pic; + int index; +}; + +static struct megamod_cascade_data cascade_data[NR_COMBINERS]; + +static void mask_megamod(struct irq_data *data) +{ + struct megamod_pic *pic = irq_data_get_irq_chip_data(data); + irq_hw_number_t src = irqd_to_hwirq(data); + u32 __iomem *evtmask = &pic->regs->evtmask[src / 32]; + + raw_spin_lock(&pic->lock); + soc_writel(soc_readl(evtmask) | (1 << (src & 31)), evtmask); + raw_spin_unlock(&pic->lock); +} + +static void unmask_megamod(struct irq_data *data) +{ + struct megamod_pic *pic = irq_data_get_irq_chip_data(data); + irq_hw_number_t src = irqd_to_hwirq(data); + u32 __iomem *evtmask = &pic->regs->evtmask[src / 32]; + + raw_spin_lock(&pic->lock); + soc_writel(soc_readl(evtmask) & ~(1 << (src & 31)), evtmask); + raw_spin_unlock(&pic->lock); +} + +static struct irq_chip megamod_chip = { + .name = "megamod", + .irq_mask = mask_megamod, + .irq_unmask = unmask_megamod, +}; + +static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc) +{ + struct megamod_cascade_data *cascade; + struct megamod_pic *pic; + u32 events; + int n, idx; + + cascade = irq_desc_get_handler_data(desc); + + pic = cascade->pic; + idx = cascade->index; + + while ((events = soc_readl(&pic->regs->mevtflag[idx])) != 0) { + n = __ffs(events); + + irq = irq_linear_revmap(pic->irqhost, idx * 32 + n); + + soc_writel(1 << n, &pic->regs->evtclr[idx]); + + generic_handle_irq(irq); + } +} + +static int megamod_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct megamod_pic *pic = h->host_data; + int i; + + /* We shouldn't see a hwirq which is muxed to core controller */ + for (i = 0; i < NR_MUX_OUTPUTS; i++) + if (pic->output_to_irq[i] == hw) + return -1; + + irq_set_chip_data(virq, pic); + irq_set_chip_and_handler(virq, &megamod_chip, handle_level_irq); + + /* Set default irq type */ + irq_set_irq_type(virq, IRQ_TYPE_NONE); + + return 0; +} + +static int megamod_xlate(struct irq_host *h, struct device_node *ct, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type) + +{ + /* megamod intspecs must have 1 cell */ + BUG_ON(intsize != 1); + *out_hwirq = intspec[0]; + *out_type = IRQ_TYPE_NONE; + return 0; +} + +static struct irq_host_ops megamod_host_ops = { + .map = megamod_map, + .xlate = megamod_xlate, +}; + +static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output) +{ + int index, offset; + u32 val; + + if (src < 0 || src >= (NR_COMBINERS * 32)) { + pic->output_to_irq[output] = IRQ_UNMAPPED; + return; + } + + /* four mappings per mux register */ + index = output / 4; + offset = (output & 3) * 8; + + val = soc_readl(&pic->regs->intmux[index]); + val &= ~(0xff << offset); + val |= src << offset; + soc_writel(val, &pic->regs->intmux[index]); +} + +/* + * Parse the MUX mapping, if one exists. + * + * The MUX map is an array of up to 12 cells; one for each usable core priority + * interrupt. The value of a given cell is the megamodule interrupt source + * which is to me MUXed to the output corresponding to the cell position + * withing the array. The first cell in the array corresponds to priority + * 4 and the last (12th) cell corresponds to priority 15. The allowed + * values are 4 - ((NR_COMBINERS * 32) - 1). Note that the combined interrupt + * sources (0 - 3) are not allowed to be mapped through this property. They + * are handled through the "interrupts" property. This allows us to use a + * value of zero as a "do not map" placeholder. + */ +static void __init parse_priority_map(struct megamod_pic *pic, + int *mapping, int size) +{ + struct device_node *np = pic->irqhost->of_node; + const __be32 *map; + int i, maplen; + u32 val; + + map = of_get_property(np, "ti,c64x+megamod-pic-mux", &maplen); + if (map) { + maplen /= 4; + if (maplen > size) + maplen = size; + + for (i = 0; i < maplen; i++) { + val = be32_to_cpup(map); + if (val && val >= 4) + mapping[i] = val; + ++map; + } + } +} + +static struct megamod_pic * __init init_megamod_pic(struct device_node *np) +{ + struct megamod_pic *pic; + int i, irq; + int mapping[NR_MUX_OUTPUTS]; + + pr_info("Initializing C64x+ Megamodule PIC\n"); + + pic = kzalloc(sizeof(struct megamod_pic), GFP_KERNEL); + if (!pic) { + pr_err("%s: Could not alloc PIC structure.\n", np->full_name); + return NULL; + } + + pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, + NR_COMBINERS * 32, &megamod_host_ops, + IRQ_UNMAPPED); + if (!pic->irqhost) { + pr_err("%s: Could not alloc host.\n", np->full_name); + goto error_free; + } + + pic->irqhost->host_data = pic; + + raw_spin_lock_init(&pic->lock); + + pic->regs = of_iomap(np, 0); + if (!pic->regs) { + pr_err("%s: Could not map registers.\n", np->full_name); + goto error_free; + } + + /* Initialize MUX map */ + for (i = 0; i < ARRAY_SIZE(mapping); i++) + mapping[i] = IRQ_UNMAPPED; + + parse_priority_map(pic, mapping, ARRAY_SIZE(mapping)); + + /* + * We can have up to 12 interrupts cascading to the core controller. + * These cascades can be from the combined interrupt sources or for + * individual interrupt sources. The "interrupts" property only + * deals with the cascaded combined interrupts. The individual + * interrupts muxed to the core controller use the core controller + * as their interrupt parent. + */ + for (i = 0; i < NR_COMBINERS; i++) { + + irq = irq_of_parse_and_map(np, i); + if (irq == NO_IRQ) + continue; + + /* + * We count on the core priority interrupts (4 - 15) being + * direct mapped. Check that device tree provided something + * in that range. + */ + if (irq < 4 || irq >= NR_PRIORITY_IRQS) { + pr_err("%s: combiner-%d virq %d out of range!\n", + np->full_name, i, irq); + continue; + } + + /* record the mapping */ + mapping[irq - 4] = i; + + pr_debug("%s: combiner-%d cascading to virq %d\n", + np->full_name, i, irq); + + cascade_data[i].pic = pic; + cascade_data[i].index = i; + + /* mask and clear all events in combiner */ + soc_writel(~0, &pic->regs->evtmask[i]); + soc_writel(~0, &pic->regs->evtclr[i]); + + irq_set_handler_data(irq, &cascade_data[i]); + irq_set_chained_handler(irq, megamod_irq_cascade); + } + + /* Finally, set up the MUX registers */ + for (i = 0; i < NR_MUX_OUTPUTS; i++) { + if (mapping[i] != IRQ_UNMAPPED) { + pr_debug("%s: setting mux %d to priority %d\n", + np->full_name, mapping[i], i + 4); + set_megamod_mux(pic, mapping[i], i); + } + } + + return pic; + +error_free: + kfree(pic); + + return NULL; +} + +/* + * Return next active event after ACK'ing it. + * Return -1 if no events active. + */ +static int get_exception(void) +{ + int i, bit; + u32 mask; + + for (i = 0; i < NR_COMBINERS; i++) { + mask = soc_readl(&mm_pic->regs->mexpflag[i]); + if (mask) { + bit = __ffs(mask); + soc_writel(1 << bit, &mm_pic->regs->evtclr[i]); + return (i * 32) + bit; + } + } + return -1; +} + +static void assert_event(unsigned int val) +{ + soc_writel(val, &mm_pic->regs->evtasrt); +} + +void __init megamod_pic_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "ti,c64x+megamod-pic"); + if (!np) + return; + + mm_pic = init_megamod_pic(np); + of_node_put(np); + + soc_ops.get_exception = get_exception; + soc_ops.assert_event = assert_event; + + return; +} -- cgit v1.2.3 From 8a0c9e0348479f1b85c640da4795bdd775970bf3 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 12:21:06 -0400 Subject: C6X: syscalls Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann [msalter@redhat.com: add include of linux/module.h to sys_c6x.c] Signed-off-by: Mark Salter --- arch/c6x/include/asm/syscalls.h | 55 ++++++++++++++++++++++++++++++ arch/c6x/include/asm/unistd.h | 26 +++++++++++++++ arch/c6x/kernel/sys_c6x.c | 74 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 arch/c6x/include/asm/syscalls.h create mode 100644 arch/c6x/include/asm/unistd.h create mode 100644 arch/c6x/kernel/sys_c6x.c (limited to 'arch') diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h new file mode 100644 index 000000000000..aed53da703c9 --- /dev/null +++ b/arch/c6x/include/asm/syscalls.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ + +#ifndef __ASM_C6X_SYSCALLS_H +#define __ASM_C6X_SYSCALLS_H + +#include +#include +#include + +/* The array of function pointers for syscalls. */ +extern void *sys_call_table[]; + +/* The following are trampolines in entry.S to handle 64-bit arguments */ +extern long sys_pread_c6x(unsigned int fd, char __user *buf, + size_t count, off_t pos_low, off_t pos_high); +extern long sys_pwrite_c6x(unsigned int fd, const char __user *buf, + size_t count, off_t pos_low, off_t pos_high); +extern long sys_truncate64_c6x(const char __user *path, + off_t length_low, off_t length_high); +extern long sys_ftruncate64_c6x(unsigned int fd, + off_t length_low, off_t length_high); +extern long sys_fadvise64_c6x(int fd, u32 offset_lo, u32 offset_hi, + u32 len, int advice); +extern long sys_fadvise64_64_c6x(int fd, u32 offset_lo, u32 offset_hi, + u32 len_lo, u32 len_hi, int advice); +extern long sys_fallocate_c6x(int fd, int mode, + u32 offset_lo, u32 offset_hi, + u32 len_lo, u32 len_hi); +extern int sys_cache_sync(unsigned long s, unsigned long e); + +struct pt_regs; + +extern asmlinkage long sys_c6x_clone(struct pt_regs *regs); +extern asmlinkage long sys_c6x_execve(const char __user *name, + const char __user *const __user *argv, + const char __user *const __user *envp, + struct pt_regs *regs); + + +#include + +#endif /* __ASM_C6X_SYSCALLS_H */ diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/asm/unistd.h new file mode 100644 index 000000000000..6d54ea4262eb --- /dev/null +++ b/arch/c6x/include/asm/unistd.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Based on arch/tile version. + * + * 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 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ +#if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL) +#define _ASM_C6X_UNISTD_H + +/* Use the standard ABI for syscalls. */ +#include + +/* C6X-specific syscalls. */ +#define __NR_cache_sync (__NR_arch_specific_syscall + 0) +__SYSCALL(__NR_cache_sync, sys_cache_sync) + +#endif /* _ASM_C6X_UNISTD_H */ diff --git a/arch/c6x/kernel/sys_c6x.c b/arch/c6x/kernel/sys_c6x.c new file mode 100644 index 000000000000..3e9bdfbee8ad --- /dev/null +++ b/arch/c6x/kernel/sys_c6x.c @@ -0,0 +1,74 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include + +#include + +#ifdef CONFIG_ACCESS_CHECK +int _access_ok(unsigned long addr, unsigned long size) +{ + if (!size) + return 1; + + if (!addr || addr > (0xffffffffUL - (size - 1))) + goto _bad_access; + + if (segment_eq(get_fs(), KERNEL_DS)) + return 1; + + if (memory_start <= addr && (addr + size - 1) < memory_end) + return 1; + +_bad_access: + pr_debug("Bad access attempt: pid[%d] addr[%08lx] size[0x%lx]\n", + current->pid, addr, size); + return 0; +} +EXPORT_SYMBOL(_access_ok); +#endif + +/* sys_cache_sync -- sync caches over given range */ +asmlinkage int sys_cache_sync(unsigned long s, unsigned long e) +{ + L1D_cache_block_writeback_invalidate(s, e); + L1P_cache_block_invalidate(s, e); + + return 0; +} + +/* Provide the actual syscall number to call mapping. */ +#undef __SYSCALL +#define __SYSCALL(nr, call) [nr] = (call), + +/* + * Use trampolines + */ +#define sys_pread64 sys_pread_c6x +#define sys_pwrite64 sys_pwrite_c6x +#define sys_truncate64 sys_truncate64_c6x +#define sys_ftruncate64 sys_ftruncate64_c6x +#define sys_fadvise64 sys_fadvise64_c6x +#define sys_fadvise64_64 sys_fadvise64_64_c6x +#define sys_fallocate sys_fallocate_c6x + +/* Use sys_mmap_pgoff directly */ +#define sys_mmap2 sys_mmap_pgoff + +/* + * Note that we can't include here since the header + * guard will defeat us; checks for __SYSCALL as well. + */ +void *sys_call_table[__NR_syscalls] = { + [0 ... __NR_syscalls-1] = sys_ni_syscall, +#include +}; -- cgit v1.2.3 From e94e668251ab31b17ef6dcd16ba7fe05ffc1917a Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:10:02 -0400 Subject: C6X: build infrastructure Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/traps.h | 36 ++ arch/c6x/kernel/asm-offsets.c | 123 +++++++ arch/c6x/kernel/entry.S | 803 ++++++++++++++++++++++++++++++++++++++++++ arch/c6x/kernel/traps.c | 423 ++++++++++++++++++++++ 4 files changed, 1385 insertions(+) create mode 100644 arch/c6x/include/asm/traps.h create mode 100644 arch/c6x/kernel/asm-offsets.c create mode 100644 arch/c6x/kernel/entry.S create mode 100644 arch/c6x/kernel/traps.c (limited to 'arch') diff --git a/arch/c6x/include/asm/traps.h b/arch/c6x/include/asm/traps.h new file mode 100644 index 000000000000..62124d7b1b5f --- /dev/null +++ b/arch/c6x/include/asm/traps.h @@ -0,0 +1,36 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_TRAPS_H +#define _ASM_C6X_TRAPS_H + +#define EXCEPT_TYPE_NXF 31 /* NMI */ +#define EXCEPT_TYPE_EXC 30 /* external exception */ +#define EXCEPT_TYPE_IXF 1 /* internal exception */ +#define EXCEPT_TYPE_SXF 0 /* software exception */ + +#define EXCEPT_CAUSE_LBX (1 << 7) /* loop buffer exception */ +#define EXCEPT_CAUSE_PRX (1 << 6) /* privilege exception */ +#define EXCEPT_CAUSE_RAX (1 << 5) /* resource access exception */ +#define EXCEPT_CAUSE_RCX (1 << 4) /* resource conflict exception */ +#define EXCEPT_CAUSE_OPX (1 << 3) /* opcode exception */ +#define EXCEPT_CAUSE_EPX (1 << 2) /* execute packet exception */ +#define EXCEPT_CAUSE_FPX (1 << 1) /* fetch packet exception */ +#define EXCEPT_CAUSE_IFX (1 << 0) /* instruction fetch exception */ + +struct exception_info { + char *kernel_str; + int signo; + int code; +}; + +extern int (*c6x_nmi_handler)(struct pt_regs *regs); + +#endif /* _ASM_C6X_TRAPS_H */ diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c new file mode 100644 index 000000000000..759ad6d207b6 --- /dev/null +++ b/arch/c6x/kernel/asm-offsets.c @@ -0,0 +1,123 @@ +/* + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed + * to extract and format the required data. + */ + +#include +#include +#include +#include +#include + +void foo(void) +{ + OFFSET(REGS_A16, pt_regs, a16); + OFFSET(REGS_A17, pt_regs, a17); + OFFSET(REGS_A18, pt_regs, a18); + OFFSET(REGS_A19, pt_regs, a19); + OFFSET(REGS_A20, pt_regs, a20); + OFFSET(REGS_A21, pt_regs, a21); + OFFSET(REGS_A22, pt_regs, a22); + OFFSET(REGS_A23, pt_regs, a23); + OFFSET(REGS_A24, pt_regs, a24); + OFFSET(REGS_A25, pt_regs, a25); + OFFSET(REGS_A26, pt_regs, a26); + OFFSET(REGS_A27, pt_regs, a27); + OFFSET(REGS_A28, pt_regs, a28); + OFFSET(REGS_A29, pt_regs, a29); + OFFSET(REGS_A30, pt_regs, a30); + OFFSET(REGS_A31, pt_regs, a31); + + OFFSET(REGS_B16, pt_regs, b16); + OFFSET(REGS_B17, pt_regs, b17); + OFFSET(REGS_B18, pt_regs, b18); + OFFSET(REGS_B19, pt_regs, b19); + OFFSET(REGS_B20, pt_regs, b20); + OFFSET(REGS_B21, pt_regs, b21); + OFFSET(REGS_B22, pt_regs, b22); + OFFSET(REGS_B23, pt_regs, b23); + OFFSET(REGS_B24, pt_regs, b24); + OFFSET(REGS_B25, pt_regs, b25); + OFFSET(REGS_B26, pt_regs, b26); + OFFSET(REGS_B27, pt_regs, b27); + OFFSET(REGS_B28, pt_regs, b28); + OFFSET(REGS_B29, pt_regs, b29); + OFFSET(REGS_B30, pt_regs, b30); + OFFSET(REGS_B31, pt_regs, b31); + + OFFSET(REGS_A0, pt_regs, a0); + OFFSET(REGS_A1, pt_regs, a1); + OFFSET(REGS_A2, pt_regs, a2); + OFFSET(REGS_A3, pt_regs, a3); + OFFSET(REGS_A4, pt_regs, a4); + OFFSET(REGS_A5, pt_regs, a5); + OFFSET(REGS_A6, pt_regs, a6); + OFFSET(REGS_A7, pt_regs, a7); + OFFSET(REGS_A8, pt_regs, a8); + OFFSET(REGS_A9, pt_regs, a9); + OFFSET(REGS_A10, pt_regs, a10); + OFFSET(REGS_A11, pt_regs, a11); + OFFSET(REGS_A12, pt_regs, a12); + OFFSET(REGS_A13, pt_regs, a13); + OFFSET(REGS_A14, pt_regs, a14); + OFFSET(REGS_A15, pt_regs, a15); + + OFFSET(REGS_B0, pt_regs, b0); + OFFSET(REGS_B1, pt_regs, b1); + OFFSET(REGS_B2, pt_regs, b2); + OFFSET(REGS_B3, pt_regs, b3); + OFFSET(REGS_B4, pt_regs, b4); + OFFSET(REGS_B5, pt_regs, b5); + OFFSET(REGS_B6, pt_regs, b6); + OFFSET(REGS_B7, pt_regs, b7); + OFFSET(REGS_B8, pt_regs, b8); + OFFSET(REGS_B9, pt_regs, b9); + OFFSET(REGS_B10, pt_regs, b10); + OFFSET(REGS_B11, pt_regs, b11); + OFFSET(REGS_B12, pt_regs, b12); + OFFSET(REGS_B13, pt_regs, b13); + OFFSET(REGS_DP, pt_regs, dp); + OFFSET(REGS_SP, pt_regs, sp); + + OFFSET(REGS_TSR, pt_regs, tsr); + OFFSET(REGS_ORIG_A4, pt_regs, orig_a4); + + DEFINE(REGS__END, sizeof(struct pt_regs)); + BLANK(); + + OFFSET(THREAD_PC, thread_struct, pc); + OFFSET(THREAD_B15_14, thread_struct, b15_14); + OFFSET(THREAD_A15_14, thread_struct, a15_14); + OFFSET(THREAD_B13_12, thread_struct, b13_12); + OFFSET(THREAD_A13_12, thread_struct, a13_12); + OFFSET(THREAD_B11_10, thread_struct, b11_10); + OFFSET(THREAD_A11_10, thread_struct, a11_10); + OFFSET(THREAD_RICL_ICL, thread_struct, ricl_icl); + BLANK(); + + OFFSET(TASK_STATE, task_struct, state); + BLANK(); + + OFFSET(THREAD_INFO_FLAGS, thread_info, flags); + OFFSET(THREAD_INFO_PREEMPT_COUNT, thread_info, preempt_count); + BLANK(); + + /* These would be unneccessary if we ran asm files + * through the preprocessor. + */ + DEFINE(KTHREAD_SIZE, THREAD_SIZE); + DEFINE(KTHREAD_SHIFT, THREAD_SHIFT); + DEFINE(KTHREAD_START_SP, THREAD_START_SP); + DEFINE(ENOSYS_, ENOSYS); + DEFINE(NR_SYSCALLS_, __NR_syscalls); + + DEFINE(_TIF_SYSCALL_TRACE, (1< +; +; 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 +#include +#include +#include +#include +#include + +; Registers naming +#define DP B14 +#define SP B15 + +#ifndef CONFIG_PREEMPT +#define resume_kernel restore_all +#endif + + .altmacro + + .macro MASK_INT reg + MVC .S2 CSR,reg + CLR .S2 reg,0,0,reg + MVC .S2 reg,CSR + .endm + + .macro UNMASK_INT reg + MVC .S2 CSR,reg + SET .S2 reg,0,0,reg + MVC .S2 reg,CSR + .endm + + .macro GET_THREAD_INFO reg + SHR .S1X SP,THREAD_SHIFT,reg + SHL .S1 reg,THREAD_SHIFT,reg + .endm + + ;; + ;; This defines the normal kernel pt_regs layout. + ;; + .macro SAVE_ALL __rp __tsr + STW .D2T2 B0,*SP--[2] ; save original B0 + MVKL .S2 current_ksp,B0 + MVKH .S2 current_ksp,B0 + LDW .D2T2 *B0,B1 ; KSP + + NOP 3 + STW .D2T2 B1,*+SP[1] ; save original B1 + XOR .D2 SP,B1,B0 ; (SP ^ KSP) + LDW .D2T2 *+SP[1],B1 ; restore B0/B1 + LDW .D2T2 *++SP[2],B0 + SHR .S2 B0,THREAD_SHIFT,B0 ; 0 if already using kstack + [B0] STDW .D2T2 SP:DP,*--B1[1] ; user: save user sp/dp kstack + [B0] MV .S2 B1,SP ; and switch to kstack +||[!B0] STDW .D2T2 SP:DP,*--SP[1] ; kernel: save on current stack + + SUBAW .D2 SP,2,SP + + ADD .D1X SP,-8,A15 + || STDW .D2T1 A15:A14,*SP--[16] ; save A15:A14 + + STDW .D2T2 B13:B12,*SP--[1] + || STDW .D1T1 A13:A12,*A15--[1] + || MVC .S2 __rp,B13 + + STDW .D2T2 B11:B10,*SP--[1] + || STDW .D1T1 A11:A10,*A15--[1] + || MVC .S2 CSR,B12 + + STDW .D2T2 B9:B8,*SP--[1] + || STDW .D1T1 A9:A8,*A15--[1] + || MVC .S2 RILC,B11 + STDW .D2T2 B7:B6,*SP--[1] + || STDW .D1T1 A7:A6,*A15--[1] + || MVC .S2 ILC,B10 + + STDW .D2T2 B5:B4,*SP--[1] + || STDW .D1T1 A5:A4,*A15--[1] + + STDW .D2T2 B3:B2,*SP--[1] + || STDW .D1T1 A3:A2,*A15--[1] + || MVC .S2 __tsr,B5 + + STDW .D2T2 B1:B0,*SP--[1] + || STDW .D1T1 A1:A0,*A15--[1] + || MV .S1X B5,A5 + + STDW .D2T2 B31:B30,*SP--[1] + || STDW .D1T1 A31:A30,*A15--[1] + STDW .D2T2 B29:B28,*SP--[1] + || STDW .D1T1 A29:A28,*A15--[1] + STDW .D2T2 B27:B26,*SP--[1] + || STDW .D1T1 A27:A26,*A15--[1] + STDW .D2T2 B25:B24,*SP--[1] + || STDW .D1T1 A25:A24,*A15--[1] + STDW .D2T2 B23:B22,*SP--[1] + || STDW .D1T1 A23:A22,*A15--[1] + STDW .D2T2 B21:B20,*SP--[1] + || STDW .D1T1 A21:A20,*A15--[1] + STDW .D2T2 B19:B18,*SP--[1] + || STDW .D1T1 A19:A18,*A15--[1] + STDW .D2T2 B17:B16,*SP--[1] + || STDW .D1T1 A17:A16,*A15--[1] + + STDW .D2T2 B13:B12,*SP--[1] ; save PC and CSR + + STDW .D2T2 B11:B10,*SP--[1] ; save RILC and ILC + STDW .D2T1 A5:A4,*SP--[1] ; save TSR and orig A4 + + ;; We left an unused word on the stack just above pt_regs. + ;; It is used to save whether or not this frame is due to + ;; a syscall. It is cleared here, but the syscall handler + ;; sets it to a non-zero value. + MVK .L2 0,B1 + STW .D2T2 B1,*+SP(REGS__END+8) ; clear syscall flag + .endm + + .macro RESTORE_ALL __rp __tsr + LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9) + LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10) + LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12) + + ADDAW .D1X SP,30,A15 + + LDDW .D1T1 *++A15[1],A17:A16 + || LDDW .D2T2 *++SP[1],B17:B16 + LDDW .D1T1 *++A15[1],A19:A18 + || LDDW .D2T2 *++SP[1],B19:B18 + LDDW .D1T1 *++A15[1],A21:A20 + || LDDW .D2T2 *++SP[1],B21:B20 + LDDW .D1T1 *++A15[1],A23:A22 + || LDDW .D2T2 *++SP[1],B23:B22 + LDDW .D1T1 *++A15[1],A25:A24 + || LDDW .D2T2 *++SP[1],B25:B24 + LDDW .D1T1 *++A15[1],A27:A26 + || LDDW .D2T2 *++SP[1],B27:B26 + LDDW .D1T1 *++A15[1],A29:A28 + || LDDW .D2T2 *++SP[1],B29:B28 + LDDW .D1T1 *++A15[1],A31:A30 + || LDDW .D2T2 *++SP[1],B31:B30 + + LDDW .D1T1 *++A15[1],A1:A0 + || LDDW .D2T2 *++SP[1],B1:B0 + + LDDW .D1T1 *++A15[1],A3:A2 + || LDDW .D2T2 *++SP[1],B3:B2 + || MVC .S2 B9,__tsr + LDDW .D1T1 *++A15[1],A5:A4 + || LDDW .D2T2 *++SP[1],B5:B4 + || MVC .S2 B11,RILC + LDDW .D1T1 *++A15[1],A7:A6 + || LDDW .D2T2 *++SP[1],B7:B6 + || MVC .S2 B10,ILC + + LDDW .D1T1 *++A15[1],A9:A8 + || LDDW .D2T2 *++SP[1],B9:B8 + || MVC .S2 B13,__rp + + LDDW .D1T1 *++A15[1],A11:A10 + || LDDW .D2T2 *++SP[1],B11:B10 + || MVC .S2 B12,CSR + + LDDW .D1T1 *++A15[1],A13:A12 + || LDDW .D2T2 *++SP[1],B13:B12 + + MV .D2X A15,SP + || MVKL .S1 current_ksp,A15 + MVKH .S1 current_ksp,A15 + || ADDAW .D1X SP,6,A14 + STW .D1T1 A14,*A15 ; save kernel stack pointer + + LDDW .D2T1 *++SP[1],A15:A14 + + B .S2 __rp ; return from interruption + LDDW .D2T2 *+SP[1],SP:DP + NOP 4 + .endm + + .section .text + + ;; + ;; Jump to schedule() then return to ret_from_exception + ;; +_reschedule: +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 schedule,A0 + MVKH .S1 schedule,A0 + B .S2X A0 +#else + B .S1 schedule +#endif + ADDKPC .S2 ret_from_exception,B3,4 + + ;; + ;; Called before syscall handler when process is being debugged + ;; +tracesys_on: +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 syscall_trace_entry,A0 + MVKH .S1 syscall_trace_entry,A0 + B .S2X A0 +#else + B .S1 syscall_trace_entry +#endif + ADDKPC .S2 ret_from_syscall_trace,B3,3 + ADD .S1X 8,SP,A4 + +ret_from_syscall_trace: + ;; tracing returns (possibly new) syscall number + MV .D2X A4,B0 + || MVK .S2 __NR_syscalls,B1 + CMPLTU .L2 B0,B1,B1 + + [!B1] BNOP .S2 ret_from_syscall_function,5 + || MVK .S1 -ENOSYS,A4 + + ;; reload syscall args from (possibly modified) stack frame + ;; and get syscall handler addr from sys_call_table: + LDW .D2T2 *+SP(REGS_B4+8),B4 + || MVKL .S2 sys_call_table,B1 + LDW .D2T1 *+SP(REGS_A6+8),A6 + || MVKH .S2 sys_call_table,B1 + LDW .D2T2 *+B1[B0],B0 + || MVKL .S2 ret_from_syscall_function,B3 + LDW .D2T2 *+SP(REGS_B6+8),B6 + || MVKH .S2 ret_from_syscall_function,B3 + LDW .D2T1 *+SP(REGS_A8+8),A8 + LDW .D2T2 *+SP(REGS_B8+8),B8 + NOP + ; B0 = sys_call_table[__NR_*] + BNOP .S2 B0,5 ; branch to syscall handler + || LDW .D2T1 *+SP(REGS_ORIG_A4+8),A4 + +syscall_exit_work: + AND .D1 _TIF_SYSCALL_TRACE,A2,A0 + [!A0] BNOP .S1 work_pending,5 + [A0] B .S2 syscall_trace_exit + ADDKPC .S2 resume_userspace,B3,1 + MVC .S2 CSR,B1 + SET .S2 B1,0,0,B1 + MVC .S2 B1,CSR ; enable ints + +work_pending: + AND .D1 _TIF_NEED_RESCHED,A2,A0 + [!A0] BNOP .S1 work_notifysig,5 + +work_resched: +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 schedule,A1 + MVKH .S1 schedule,A1 + B .S2X A1 +#else + B .S2 schedule +#endif + ADDKPC .S2 work_rescheduled,B3,4 +work_rescheduled: + ;; make sure we don't miss an interrupt setting need_resched or + ;; sigpending between sampling and the rti + MASK_INT B2 + GET_THREAD_INFO A12 + LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 + MVK .S1 _TIF_WORK_MASK,A1 + MVK .S1 _TIF_NEED_RESCHED,A3 + NOP 2 + AND .D1 A1,A2,A0 + || AND .S1 A3,A2,A1 + [!A0] BNOP .S1 restore_all,5 + [A1] BNOP .S1 work_resched,5 + +work_notifysig: + B .S2 do_notify_resume + LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag + ADDKPC .S2 resume_userspace,B3,1 + ADD .S1X 8,SP,A4 ; pt_regs pointer is first arg + MV .D2X A2,B4 ; thread_info flags is second arg + + ;; + ;; On C64x+, the return way from exception and interrupt + ;; is a little bit different + ;; +ENTRY(ret_from_exception) +#ifdef CONFIG_PREEMPT + MASK_INT B2 +#endif + +ENTRY(ret_from_interrupt) + ;; + ;; Check if we are comming from user mode. + ;; + LDW .D2T2 *+SP(REGS_TSR+8),B0 + MVK .S2 0x40,B1 + NOP 3 + AND .D2 B0,B1,B0 + [!B0] BNOP .S2 resume_kernel,5 + +resume_userspace: + ;; make sure we don't miss an interrupt setting need_resched or + ;; sigpending between sampling and the rti + MASK_INT B2 + GET_THREAD_INFO A12 + LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 + MVK .S1 _TIF_WORK_MASK,A1 + MVK .S1 _TIF_NEED_RESCHED,A3 + NOP 2 + AND .D1 A1,A2,A0 + [A0] BNOP .S1 work_pending,5 + BNOP .S1 restore_all,5 + + ;; + ;; System call handling + ;; B0 = syscall number (in sys_call_table) + ;; A4,B4,A6,B6,A8,B8 = arguments of the syscall function + ;; A4 is the return value register + ;; +system_call_saved: + MVK .L2 1,B2 + STW .D2T2 B2,*+SP(REGS__END+8) ; set syscall flag + MVC .S2 B2,ECR ; ack the software exception + + UNMASK_INT B2 ; re-enable global IT + +system_call_saved_noack: + ;; Check system call number + MVK .S2 __NR_syscalls,B1 +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_ni_syscall,A0 +#endif + CMPLTU .L2 B0,B1,B1 +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKH .S1 sys_ni_syscall,A0 +#endif + + ;; Check for ptrace + GET_THREAD_INFO A12 + +#ifdef CONFIG_C6X_BIG_KERNEL + [!B1] B .S2X A0 +#else + [!B1] B .S2 sys_ni_syscall +#endif + [!B1] ADDKPC .S2 ret_from_syscall_function,B3,4 + + ;; Get syscall handler addr from sys_call_table + ;; call tracesys_on or call syscall handler + LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 + || MVKL .S2 sys_call_table,B1 + MVKH .S2 sys_call_table,B1 + LDW .D2T2 *+B1[B0],B0 + NOP 2 + ; A2 = thread_info flags + AND .D1 _TIF_SYSCALL_TRACE,A2,A2 + [A2] BNOP .S1 tracesys_on,5 + ;; B0 = _sys_call_table[__NR_*] + B .S2 B0 + ADDKPC .S2 ret_from_syscall_function,B3,4 + +ret_from_syscall_function: + STW .D2T1 A4,*+SP(REGS_A4+8) ; save return value in A4 + ; original A4 is in orig_A4 +syscall_exit: + ;; make sure we don't miss an interrupt setting need_resched or + ;; sigpending between sampling and the rti + MASK_INT B2 + LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 + MVK .S1 _TIF_ALLWORK_MASK,A1 + NOP 3 + AND .D1 A1,A2,A2 ; check for work to do + [A2] BNOP .S1 syscall_exit_work,5 + +restore_all: + RESTORE_ALL NRP,NTSR + + ;; + ;; After a fork we jump here directly from resume, + ;; so that A4 contains the previous task structure. + ;; +ENTRY(ret_from_fork) +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 schedule_tail,A0 + MVKH .S1 schedule_tail,A0 + B .S2X A0 +#else + B .S2 schedule_tail +#endif + ADDKPC .S2 ret_from_fork_2,B3,4 +ret_from_fork_2: + ;; return 0 in A4 for child process + GET_THREAD_INFO A12 + BNOP .S2 syscall_exit,3 + MVK .L2 0,B0 + STW .D2T2 B0,*+SP(REGS_A4+8) +ENDPROC(ret_from_fork) + + ;; + ;; These are the interrupt handlers, responsible for calling __do_IRQ() + ;; int6 is used for syscalls (see _system_call entry) + ;; + .macro SAVE_ALL_INT + SAVE_ALL IRP,ITSR + .endm + + .macro CALL_INT int +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 c6x_do_IRQ,A0 + MVKH .S1 c6x_do_IRQ,A0 + BNOP .S2X A0,1 + MVK .S1 int,A4 + ADDAW .D2 SP,2,B4 + MVKL .S2 ret_from_interrupt,B3 + MVKH .S2 ret_from_interrupt,B3 +#else + CALLP .S2 c6x_do_IRQ,B3 + || MVK .S1 int,A4 + || ADDAW .D2 SP,2,B4 + B .S1 ret_from_interrupt + NOP 5 +#endif + .endm + +ENTRY(_int4_handler) + SAVE_ALL_INT + CALL_INT 4 +ENDPROC(_int4_handler) + +ENTRY(_int5_handler) + SAVE_ALL_INT + CALL_INT 5 +ENDPROC(_int5_handler) + +ENTRY(_int6_handler) + SAVE_ALL_INT + CALL_INT 6 +ENDPROC(_int6_handler) + +ENTRY(_int7_handler) + SAVE_ALL_INT + CALL_INT 7 +ENDPROC(_int7_handler) + +ENTRY(_int8_handler) + SAVE_ALL_INT + CALL_INT 8 +ENDPROC(_int8_handler) + +ENTRY(_int9_handler) + SAVE_ALL_INT + CALL_INT 9 +ENDPROC(_int9_handler) + +ENTRY(_int10_handler) + SAVE_ALL_INT + CALL_INT 10 +ENDPROC(_int10_handler) + +ENTRY(_int11_handler) + SAVE_ALL_INT + CALL_INT 11 +ENDPROC(_int11_handler) + +ENTRY(_int12_handler) + SAVE_ALL_INT + CALL_INT 12 +ENDPROC(_int12_handler) + +ENTRY(_int13_handler) + SAVE_ALL_INT + CALL_INT 13 +ENDPROC(_int13_handler) + +ENTRY(_int14_handler) + SAVE_ALL_INT + CALL_INT 14 +ENDPROC(_int14_handler) + +ENTRY(_int15_handler) + SAVE_ALL_INT + CALL_INT 15 +ENDPROC(_int15_handler) + + ;; + ;; Handler for uninitialized and spurious interrupts + ;; +ENTRY(_bad_interrupt) + B .S2 IRP + NOP 5 +ENDPROC(_bad_interrupt) + + ;; + ;; Entry for NMI/exceptions/syscall + ;; +ENTRY(_nmi_handler) + SAVE_ALL NRP,NTSR + + MVC .S2 EFR,B2 + CMPEQ .L2 1,B2,B2 + || MVC .S2 TSR,B1 + CLR .S2 B1,10,10,B1 + MVC .S2 B1,TSR +#ifdef CONFIG_C6X_BIG_KERNEL + [!B2] MVKL .S1 process_exception,A0 + [!B2] MVKH .S1 process_exception,A0 + [!B2] B .S2X A0 +#else + [!B2] B .S2 process_exception +#endif + [B2] B .S2 system_call_saved + [!B2] ADDAW .D2 SP,2,B1 + [!B2] MV .D1X B1,A4 + ADDKPC .S2 ret_from_trap,B3,2 + +ret_from_trap: + MV .D2X A4,B0 + [!B0] BNOP .S2 ret_from_exception,5 + +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S2 system_call_saved_noack,B3 + MVKH .S2 system_call_saved_noack,B3 +#endif + LDW .D2T2 *+SP(REGS_B0+8),B0 + LDW .D2T1 *+SP(REGS_A4+8),A4 + LDW .D2T2 *+SP(REGS_B4+8),B4 + LDW .D2T1 *+SP(REGS_A6+8),A6 + LDW .D2T2 *+SP(REGS_B6+8),B6 + LDW .D2T1 *+SP(REGS_A8+8),A8 +#ifdef CONFIG_C6X_BIG_KERNEL + || B .S2 B3 +#else + || B .S2 system_call_saved_noack +#endif + LDW .D2T2 *+SP(REGS_B8+8),B8 + NOP 4 +ENDPROC(_nmi_handler) + + ;; + ;; Jump to schedule() then return to ret_from_isr + ;; +#ifdef CONFIG_PREEMPT +resume_kernel: + GET_THREAD_INFO A12 + LDW .D1T1 *+A12(THREAD_INFO_PREEMPT_COUNT),A1 + NOP 4 + [A1] BNOP .S2 restore_all,5 + +preempt_schedule: + GET_THREAD_INFO A2 + LDW .D1T1 *+A2(THREAD_INFO_FLAGS),A1 +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S2 preempt_schedule_irq,B0 + MVKH .S2 preempt_schedule_irq,B0 + NOP 2 +#else + NOP 4 +#endif + AND .D1 _TIF_NEED_RESCHED,A1,A1 + [!A1] BNOP .S2 restore_all,5 +#ifdef CONFIG_C6X_BIG_KERNEL + B .S2 B0 +#else + B .S2 preempt_schedule_irq +#endif + ADDKPC .S2 preempt_schedule,B3,4 +#endif /* CONFIG_PREEMPT */ + +ENTRY(enable_exception) + DINT + MVC .S2 TSR,B0 + MVC .S2 B3,NRP + MVK .L2 0xc,B1 + OR .D2 B0,B1,B0 + MVC .S2 B0,TSR ; Set GEE and XEN in TSR + B .S2 NRP + NOP 5 +ENDPROC(enable_exception) + +ENTRY(sys_sigaltstack) +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 do_sigaltstack,A0 ; branch to do_sigaltstack + MVKH .S1 do_sigaltstack,A0 + B .S2X A0 +#else + B .S2 do_sigaltstack +#endif + LDW .D2T1 *+SP(REGS_SP+8),A6 + NOP 4 +ENDPROC(sys_sigaltstack) + + ;; kernel_execve +ENTRY(kernel_execve) + MVK .S2 __NR_execve,B0 + SWE + BNOP .S2 B3,5 +ENDPROC(kernel_execve) + + ;; + ;; Special system calls + ;; return address is in B3 + ;; +ENTRY(sys_clone) + ADD .D1X SP,8,A4 +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_c6x_clone,A0 + MVKH .S1 sys_c6x_clone,A0 + BNOP .S2X A0,5 +#else + || B .S2 sys_c6x_clone + NOP 5 +#endif +ENDPROC(sys_clone) + +ENTRY(sys_rt_sigreturn) + ADD .D1X SP,8,A4 +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 do_rt_sigreturn,A0 + MVKH .S1 do_rt_sigreturn,A0 + BNOP .S2X A0,5 +#else + || B .S2 do_rt_sigreturn + NOP 5 +#endif +ENDPROC(sys_rt_sigreturn) + +ENTRY(sys_execve) + ADDAW .D2 SP,2,B6 ; put regs addr in 4th parameter + ; & adjust regs stack addr + LDW .D2T2 *+SP(REGS_B4+8),B4 + + ;; c6x_execve(char *name, char **argv, + ;; char **envp, struct pt_regs *regs) +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_c6x_execve,A0 + MVKH .S1 sys_c6x_execve,A0 + B .S2X A0 +#else + || B .S2 sys_c6x_execve +#endif + STW .D2T2 B3,*SP--[2] + ADDKPC .S2 ret_from_c6x_execve,B3,3 + +ret_from_c6x_execve: + LDW .D2T2 *++SP[2],B3 + NOP 4 + BNOP .S2 B3,5 +ENDPROC(sys_execve) + +ENTRY(sys_pread_c6x) + MV .D2X A8,B7 +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_pread64,A0 + MVKH .S1 sys_pread64,A0 + BNOP .S2X A0,5 +#else + || B .S2 sys_pread64 + NOP 5 +#endif +ENDPROC(sys_pread_c6x) + +ENTRY(sys_pwrite_c6x) + MV .D2X A8,B7 +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_pwrite64,A0 + MVKH .S1 sys_pwrite64,A0 + BNOP .S2X A0,5 +#else + || B .S2 sys_pwrite64 + NOP 5 +#endif +ENDPROC(sys_pwrite_c6x) + +;; On Entry +;; A4 - path +;; B4 - offset_lo (LE), offset_hi (BE) +;; A6 - offset_lo (BE), offset_hi (LE) +ENTRY(sys_truncate64_c6x) +#ifdef CONFIG_CPU_BIG_ENDIAN + MV .S2 B4,B5 + MV .D2X A6,B4 +#else + MV .D2X A6,B5 +#endif +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_truncate64,A0 + MVKH .S1 sys_truncate64,A0 + BNOP .S2X A0,5 +#else + || B .S2 sys_truncate64 + NOP 5 +#endif +ENDPROC(sys_truncate64_c6x) + +;; On Entry +;; A4 - fd +;; B4 - offset_lo (LE), offset_hi (BE) +;; A6 - offset_lo (BE), offset_hi (LE) +ENTRY(sys_ftruncate64_c6x) +#ifdef CONFIG_CPU_BIG_ENDIAN + MV .S2 B4,B5 + MV .D2X A6,B4 +#else + MV .D2X A6,B5 +#endif +#ifdef CONFIG_C6X_BIG_KERNEL + || MVKL .S1 sys_ftruncate64,A0 + MVKH .S1 sys_ftruncate64,A0 + BNOP .S2X A0,5 +#else + || B .S2 sys_ftruncate64 + NOP 5 +#endif +ENDPROC(sys_ftruncate64_c6x) + +#ifdef __ARCH_WANT_SYSCALL_OFF_T +;; On Entry +;; A4 - fd +;; B4 - offset_lo (LE), offset_hi (BE) +;; A6 - offset_lo (BE), offset_hi (LE) +;; B6 - len +;; A8 - advice +ENTRY(sys_fadvise64_c6x) +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 sys_fadvise64,A0 + MVKH .S1 sys_fadvise64,A0 + BNOP .S2X A0,2 +#else + B .S2 sys_fadvise64 + NOP 2 +#endif +#ifdef CONFIG_CPU_BIG_ENDIAN + MV .L2 B4,B5 + || MV .D2X A6,B4 +#else + MV .D2X A6,B5 +#endif + MV .D1X B6,A6 + MV .D2X A8,B6 +#endif +ENDPROC(sys_fadvise64_c6x) + +;; On Entry +;; A4 - fd +;; B4 - offset_lo (LE), offset_hi (BE) +;; A6 - offset_lo (BE), offset_hi (LE) +;; B6 - len_lo (LE), len_hi (BE) +;; A8 - len_lo (BE), len_hi (LE) +;; B8 - advice +ENTRY(sys_fadvise64_64_c6x) +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 sys_fadvise64_64,A0 + MVKH .S1 sys_fadvise64_64,A0 + BNOP .S2X A0,2 +#else + B .S2 sys_fadvise64_64 + NOP 2 +#endif +#ifdef CONFIG_CPU_BIG_ENDIAN + MV .L2 B4,B5 + || MV .D2X A6,B4 + MV .L1 A8,A6 + || MV .D1X B6,A7 +#else + MV .D2X A6,B5 + MV .L1 A8,A7 + || MV .D1X B6,A6 +#endif + MV .L2 B8,B6 +ENDPROC(sys_fadvise64_64_c6x) + +;; On Entry +;; A4 - fd +;; B4 - mode +;; A6 - offset_hi +;; B6 - offset_lo +;; A8 - len_hi +;; B8 - len_lo +ENTRY(sys_fallocate_c6x) +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 sys_fallocate,A0 + MVKH .S1 sys_fallocate,A0 + BNOP .S2X A0,1 +#else + B .S2 sys_fallocate + NOP +#endif + MV .D1 A6,A7 + MV .D1X B6,A6 + MV .D2X A8,B7 + MV .D2 B8,B6 +ENDPROC(sys_fallocate_c6x) + + ;; put this in .neardata for faster access when using DSBT mode + .section .neardata,"aw",@progbits + .global current_ksp + .hidden current_ksp +current_ksp: + .word init_thread_union + THREAD_START_SP diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c new file mode 100644 index 000000000000..f50e3edd6dad --- /dev/null +++ b/arch/c6x/kernel/traps.c @@ -0,0 +1,423 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include +#include + +#include +#include + +int (*c6x_nmi_handler)(struct pt_regs *regs); + +void __init trap_init(void) +{ + ack_exception(EXCEPT_TYPE_NXF); + ack_exception(EXCEPT_TYPE_EXC); + ack_exception(EXCEPT_TYPE_IXF); + ack_exception(EXCEPT_TYPE_SXF); + enable_exception(); +} + +void show_regs(struct pt_regs *regs) +{ + pr_err("\n"); + pr_err("PC: %08lx SP: %08lx\n", regs->pc, regs->sp); + pr_err("Status: %08lx ORIG_A4: %08lx\n", regs->csr, regs->orig_a4); + pr_err("A0: %08lx B0: %08lx\n", regs->a0, regs->b0); + pr_err("A1: %08lx B1: %08lx\n", regs->a1, regs->b1); + pr_err("A2: %08lx B2: %08lx\n", regs->a2, regs->b2); + pr_err("A3: %08lx B3: %08lx\n", regs->a3, regs->b3); + pr_err("A4: %08lx B4: %08lx\n", regs->a4, regs->b4); + pr_err("A5: %08lx B5: %08lx\n", regs->a5, regs->b5); + pr_err("A6: %08lx B6: %08lx\n", regs->a6, regs->b6); + pr_err("A7: %08lx B7: %08lx\n", regs->a7, regs->b7); + pr_err("A8: %08lx B8: %08lx\n", regs->a8, regs->b8); + pr_err("A9: %08lx B9: %08lx\n", regs->a9, regs->b9); + pr_err("A10: %08lx B10: %08lx\n", regs->a10, regs->b10); + pr_err("A11: %08lx B11: %08lx\n", regs->a11, regs->b11); + pr_err("A12: %08lx B12: %08lx\n", regs->a12, regs->b12); + pr_err("A13: %08lx B13: %08lx\n", regs->a13, regs->b13); + pr_err("A14: %08lx B14: %08lx\n", regs->a14, regs->dp); + pr_err("A15: %08lx B15: %08lx\n", regs->a15, regs->sp); + pr_err("A16: %08lx B16: %08lx\n", regs->a16, regs->b16); + pr_err("A17: %08lx B17: %08lx\n", regs->a17, regs->b17); + pr_err("A18: %08lx B18: %08lx\n", regs->a18, regs->b18); + pr_err("A19: %08lx B19: %08lx\n", regs->a19, regs->b19); + pr_err("A20: %08lx B20: %08lx\n", regs->a20, regs->b20); + pr_err("A21: %08lx B21: %08lx\n", regs->a21, regs->b21); + pr_err("A22: %08lx B22: %08lx\n", regs->a22, regs->b22); + pr_err("A23: %08lx B23: %08lx\n", regs->a23, regs->b23); + pr_err("A24: %08lx B24: %08lx\n", regs->a24, regs->b24); + pr_err("A25: %08lx B25: %08lx\n", regs->a25, regs->b25); + pr_err("A26: %08lx B26: %08lx\n", regs->a26, regs->b26); + pr_err("A27: %08lx B27: %08lx\n", regs->a27, regs->b27); + pr_err("A28: %08lx B28: %08lx\n", regs->a28, regs->b28); + pr_err("A29: %08lx B29: %08lx\n", regs->a29, regs->b29); + pr_err("A30: %08lx B30: %08lx\n", regs->a30, regs->b30); + pr_err("A31: %08lx B31: %08lx\n", regs->a31, regs->b31); +} + +void dump_stack(void) +{ + unsigned long stack; + + show_stack(current, &stack); +} +EXPORT_SYMBOL(dump_stack); + + +void die(char *str, struct pt_regs *fp, int nr) +{ + console_verbose(); + pr_err("%s: %08x\n", str, nr); + show_regs(fp); + + pr_err("Process %s (pid: %d, stackpage=%08lx)\n", + current->comm, current->pid, (PAGE_SIZE + + (unsigned long) current)); + + dump_stack(); + while (1) + ; +} + +static void die_if_kernel(char *str, struct pt_regs *fp, int nr) +{ + if (user_mode(fp)) + return; + + die(str, fp, nr); +} + + +/* Internal exceptions */ +static struct exception_info iexcept_table[10] = { + { "Oops - instruction fetch", SIGBUS, BUS_ADRERR }, + { "Oops - fetch packet", SIGBUS, BUS_ADRERR }, + { "Oops - execute packet", SIGILL, ILL_ILLOPC }, + { "Oops - undefined instruction", SIGILL, ILL_ILLOPC }, + { "Oops - resource conflict", SIGILL, ILL_ILLOPC }, + { "Oops - resource access", SIGILL, ILL_PRVREG }, + { "Oops - privilege", SIGILL, ILL_PRVOPC }, + { "Oops - loops buffer", SIGILL, ILL_ILLOPC }, + { "Oops - software exception", SIGILL, ILL_ILLTRP }, + { "Oops - unknown exception", SIGILL, ILL_ILLOPC } +}; + +/* External exceptions */ +static struct exception_info eexcept_table[128] = { + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - external exception", SIGBUS, BUS_ADRERR }, + { "Oops - CPU memory protection fault", SIGSEGV, SEGV_ACCERR }, + { "Oops - CPU memory protection fault in L1P", SIGSEGV, SEGV_ACCERR }, + { "Oops - DMA memory protection fault in L1P", SIGSEGV, SEGV_ACCERR }, + { "Oops - CPU memory protection fault in L1D", SIGSEGV, SEGV_ACCERR }, + { "Oops - DMA memory protection fault in L1D", SIGSEGV, SEGV_ACCERR }, + { "Oops - CPU memory protection fault in L2", SIGSEGV, SEGV_ACCERR }, + { "Oops - DMA memory protection fault in L2", SIGSEGV, SEGV_ACCERR }, + { "Oops - EMC CPU memory protection fault", SIGSEGV, SEGV_ACCERR }, + { "Oops - EMC bus error", SIGBUS, BUS_ADRERR } +}; + +static void do_trap(struct exception_info *except_info, struct pt_regs *regs) +{ + unsigned long addr = instruction_pointer(regs); + siginfo_t info; + + if (except_info->code != TRAP_BRKPT) + pr_err("TRAP: %s PC[0x%lx] signo[%d] code[%d]\n", + except_info->kernel_str, regs->pc, + except_info->signo, except_info->code); + + die_if_kernel(except_info->kernel_str, regs, addr); + + info.si_signo = except_info->signo; + info.si_errno = 0; + info.si_code = except_info->code; + info.si_addr = (void __user *)addr; + + force_sig_info(except_info->signo, &info, current); +} + +/* + * Process an internal exception (non maskable) + */ +static int process_iexcept(struct pt_regs *regs) +{ + unsigned int iexcept_report = get_iexcept(); + unsigned int iexcept_num; + + ack_exception(EXCEPT_TYPE_IXF); + + pr_err("IEXCEPT: PC[0x%lx]\n", regs->pc); + + while (iexcept_report) { + iexcept_num = __ffs(iexcept_report); + iexcept_report &= ~(1 << iexcept_num); + set_iexcept(iexcept_report); + if (*(unsigned int *)regs->pc == BKPT_OPCODE) { + /* This is a breakpoint */ + struct exception_info bkpt_exception = { + "Oops - undefined instruction", + SIGTRAP, TRAP_BRKPT + }; + do_trap(&bkpt_exception, regs); + iexcept_report &= ~(0xFF); + set_iexcept(iexcept_report); + continue; + } + + do_trap(&iexcept_table[iexcept_num], regs); + } + return 0; +} + +/* + * Process an external exception (maskable) + */ +static void process_eexcept(struct pt_regs *regs) +{ + int evt; + + pr_err("EEXCEPT: PC[0x%lx]\n", regs->pc); + + while ((evt = soc_get_exception()) >= 0) + do_trap(&eexcept_table[evt], regs); + + ack_exception(EXCEPT_TYPE_EXC); +} + +/* + * Main exception processing + */ +asmlinkage int process_exception(struct pt_regs *regs) +{ + unsigned int type; + unsigned int type_num; + unsigned int ie_num = 9; /* default is unknown exception */ + + while ((type = get_except_type()) != 0) { + type_num = fls(type) - 1; + + switch (type_num) { + case EXCEPT_TYPE_NXF: + ack_exception(EXCEPT_TYPE_NXF); + if (c6x_nmi_handler) + (c6x_nmi_handler)(regs); + else + pr_alert("NMI interrupt!\n"); + break; + + case EXCEPT_TYPE_IXF: + if (process_iexcept(regs)) + return 1; + break; + + case EXCEPT_TYPE_EXC: + process_eexcept(regs); + break; + + case EXCEPT_TYPE_SXF: + ie_num = 8; + default: + ack_exception(type_num); + do_trap(&iexcept_table[ie_num], regs); + break; + } + } + return 0; +} + +static int kstack_depth_to_print = 48; + +static void show_trace(unsigned long *stack, unsigned long *endstack) +{ + unsigned long addr; + int i; + + pr_debug("Call trace:"); + i = 0; + while (stack + 1 <= endstack) { + addr = *stack++; + /* + * If the address is either in the text segment of the + * kernel, or in the region which contains vmalloc'ed + * memory, it *may* be the address of a calling + * routine; if so, print it so that someone tracing + * down the cause of the crash will be able to figure + * out the call path that was taken. + */ + if (__kernel_text_address(addr)) { +#ifndef CONFIG_KALLSYMS + if (i % 5 == 0) + pr_debug("\n "); +#endif + pr_debug(" [<%08lx>]", addr); + print_symbol(" %s\n", addr); + i++; + } + } + pr_debug("\n"); +} + +void show_stack(struct task_struct *task, unsigned long *stack) +{ + unsigned long *p, *endstack; + int i; + + if (!stack) { + if (task && task != current) + /* We know this is a kernel stack, + so this is the start/end */ + stack = (unsigned long *)thread_saved_ksp(task); + else + stack = (unsigned long *)&stack; + } + endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) + & -THREAD_SIZE); + + pr_debug("Stack from %08lx:", (unsigned long)stack); + for (i = 0, p = stack; i < kstack_depth_to_print; i++) { + if (p + 1 > endstack) + break; + if (i % 8 == 0) + pr_cont("\n "); + pr_cont(" %08lx", *p++); + } + pr_cont("\n"); + show_trace(stack, endstack); +} + +int is_valid_bugaddr(unsigned long addr) +{ + return __kernel_text_address(addr); +} -- cgit v1.2.3 From 81ec98898188639ac53413605681b3e3bb0a2ff1 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Tue, 4 Oct 2011 11:10:50 -0400 Subject: C6X: clocks The C6X SoCs contain several PLL controllers each with up to 16 clock outputs feeding into the cores or peripheral clock domains. The hardware is very similar to arm/mach-davinci clocks. This is still a work in progress which needs to be updated once device tree clock binding changes shake out. Signed-off-by: Mark Salter Signed-off-by: Aurelien Jacquiot Acked-by: Arnd Bergmann --- arch/c6x/include/asm/clkdev.h | 22 +++ arch/c6x/include/asm/clock.h | 148 ++++++++++++++ arch/c6x/platforms/pll.c | 444 ++++++++++++++++++++++++++++++++++++++++++ arch/c6x/platforms/plldata.c | 404 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 1018 insertions(+) create mode 100644 arch/c6x/include/asm/clkdev.h create mode 100644 arch/c6x/include/asm/clock.h create mode 100644 arch/c6x/platforms/pll.c create mode 100644 arch/c6x/platforms/plldata.c (limited to 'arch') diff --git a/arch/c6x/include/asm/clkdev.h b/arch/c6x/include/asm/clkdev.h new file mode 100644 index 000000000000..76a070b1c2e5 --- /dev/null +++ b/arch/c6x/include/asm/clkdev.h @@ -0,0 +1,22 @@ +#ifndef _ASM_CLKDEV_H +#define _ASM_CLKDEV_H + +#include + +struct clk; + +static inline int __clk_get(struct clk *clk) +{ + return 1; +} + +static inline void __clk_put(struct clk *clk) +{ +} + +static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) +{ + return kzalloc(size, GFP_KERNEL); +} + +#endif /* _ASM_CLKDEV_H */ diff --git a/arch/c6x/include/asm/clock.h b/arch/c6x/include/asm/clock.h new file mode 100644 index 000000000000..bcf42b2b4b1e --- /dev/null +++ b/arch/c6x/include/asm/clock.h @@ -0,0 +1,148 @@ +/* + * TI C64X clock definitions + * + * Copyright (C) 2010, 2011 Texas Instruments. + * Contributed by: Mark Salter + * + * Copied heavily from arm/mach-davinci/clock.h, so: + * + * Copyright (C) 2006-2007 Texas Instruments. + * Copyright (C) 2008-2009 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 version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _ASM_C6X_CLOCK_H +#define _ASM_C6X_CLOCK_H + +#ifndef __ASSEMBLER__ + +#include + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLM 0x110 +#define PLLPRE 0x114 +#define PLLDIV1 0x118 +#define PLLDIV2 0x11c +#define PLLDIV3 0x120 +#define PLLPOST 0x128 +#define PLLCMD 0x138 +#define PLLSTAT 0x13c +#define PLLALNCTL 0x140 +#define PLLDCHANGE 0x144 +#define PLLCKEN 0x148 +#define PLLCKSTAT 0x14c +#define PLLSYSTAT 0x150 +#define PLLDIV4 0x160 +#define PLLDIV5 0x164 +#define PLLDIV6 0x168 +#define PLLDIV7 0x16c +#define PLLDIV8 0x170 +#define PLLDIV9 0x174 +#define PLLDIV10 0x178 +#define PLLDIV11 0x17c +#define PLLDIV12 0x180 +#define PLLDIV13 0x184 +#define PLLDIV14 0x188 +#define PLLDIV15 0x18c +#define PLLDIV16 0x190 + +/* PLLM register bits */ +#define PLLM_PLLM_MASK 0xff +#define PLLM_VAL(x) ((x) - 1) + +/* PREDIV register bits */ +#define PLLPREDIV_EN BIT(15) +#define PLLPREDIV_VAL(x) ((x) - 1) + +/* PLLCTL register bits */ +#define PLLCTL_PLLEN BIT(0) +#define PLLCTL_PLLPWRDN BIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRC BIT(5) +#define PLLCTL_CLKMODE BIT(8) + +/* PLLCMD register bits */ +#define PLLCMD_GOSTAT BIT(0) + +/* PLLSTAT register bits */ +#define PLLSTAT_GOSTAT BIT(0) + +/* PLLDIV register bits */ +#define PLLDIV_EN BIT(15) +#define PLLDIV_RATIO_MASK 0x1f +#define PLLDIV_RATIO(x) ((x) - 1) + +struct pll_data; + +struct clk { + struct list_head node; + struct module *owner; + const char *name; + unsigned long rate; + int usecount; + u32 flags; + struct clk *parent; + struct list_head children; /* list of children */ + struct list_head childnode; /* parent's child list node */ + struct pll_data *pll_data; + u32 div; + unsigned long (*recalc) (struct clk *); + int (*set_rate) (struct clk *clk, unsigned long rate); + int (*round_rate) (struct clk *clk, unsigned long rate); +}; + +/* Clock flags: SoC-specific flags start at BIT(16) */ +#define ALWAYS_ENABLED BIT(1) +#define CLK_PLL BIT(2) /* PLL-derived clock */ +#define PRE_PLL BIT(3) /* source is before PLL mult/div */ +#define FIXED_DIV_PLL BIT(4) /* fixed divisor from PLL */ +#define FIXED_RATE_PLL BIT(5) /* fixed ouput rate PLL */ + +#define MAX_PLL_SYSCLKS 16 + +struct pll_data { + void __iomem *base; + u32 num; + u32 flags; + u32 input_rate; + u32 bypass_delay; /* in loops */ + u32 reset_delay; /* in loops */ + u32 lock_delay; /* in loops */ + struct clk sysclks[MAX_PLL_SYSCLKS + 1]; +}; + +/* pll_data flag bit */ +#define PLL_HAS_PRE BIT(0) +#define PLL_HAS_MUL BIT(1) +#define PLL_HAS_POST BIT(2) + +#define CLK(dev, con, ck) \ + { \ + .dev_id = dev, \ + .con_id = con, \ + .clk = ck, \ + } \ + +extern void c6x_clks_init(struct clk_lookup *clocks); +extern int clk_register(struct clk *clk); +extern void clk_unregister(struct clk *clk); +extern void c64x_setup_clocks(void); + +extern struct pll_data c6x_soc_pll1; + +extern struct clk clkin1; +extern struct clk c6x_core_clk; +extern struct clk c6x_i2c_clk; +extern struct clk c6x_watchdog_clk; +extern struct clk c6x_mcbsp1_clk; +extern struct clk c6x_mcbsp2_clk; +extern struct clk c6x_mdio_clk; + +#endif + +#endif /* _ASM_C6X_CLOCK_H */ diff --git a/arch/c6x/platforms/pll.c b/arch/c6x/platforms/pll.c new file mode 100644 index 000000000000..3aa898f7ce4d --- /dev/null +++ b/arch/c6x/platforms/pll.c @@ -0,0 +1,444 @@ +/* + * Clock and PLL control for C64x+ devices + * + * Copyright (C) 2010, 2011 Texas Instruments. + * Contributed by: Mark Salter + * + * Copied heavily from arm/mach-davinci/clock.c, so: + * + * Copyright (C) 2006-2007 Texas Instruments. + * Copyright (C) 2008-2009 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; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); +static DEFINE_SPINLOCK(clockfw_lock); + +static void __clk_enable(struct clk *clk) +{ + if (clk->parent) + __clk_enable(clk->parent); + clk->usecount++; +} + +static void __clk_disable(struct clk *clk) +{ + if (WARN_ON(clk->usecount == 0)) + return; + --clk->usecount; + + if (clk->parent) + __clk_disable(clk->parent); +} + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + spin_lock_irqsave(&clockfw_lock, flags); + __clk_enable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return; + + spin_lock_irqsave(&clockfw_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + if (clk->round_rate) + return clk->round_rate(clk, rate); + + return clk->rate; +} +EXPORT_SYMBOL(clk_round_rate); + +/* Propagate rate to children */ +static void propagate_rate(struct clk *root) +{ + struct clk *clk; + + list_for_each_entry(clk, &root->children, childnode) { + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + } +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + int ret = -EINVAL; + + if (clk == NULL || IS_ERR(clk)) + return ret; + + if (clk->set_rate) + ret = clk->set_rate(clk, rate); + + spin_lock_irqsave(&clockfw_lock, flags); + if (ret == 0) { + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + } + spin_unlock_irqrestore(&clockfw_lock, flags); + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + /* Cannot change parent on enabled clock */ + if (WARN_ON(clk->usecount)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + clk->parent = parent; + list_del_init(&clk->childnode); + list_add(&clk->childnode, &clk->parent->children); + mutex_unlock(&clocks_mutex); + + spin_lock_irqsave(&clockfw_lock, flags); + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +int clk_register(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + if (WARN(clk->parent && !clk->parent->rate, + "CLK: %s parent %s has no rate!\n", + clk->name, clk->parent->name)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + list_add_tail(&clk->node, &clocks); + if (clk->parent) + list_add_tail(&clk->childnode, &clk->parent->children); + mutex_unlock(&clocks_mutex); + + /* If rate is already set, use it */ + if (clk->rate) + return 0; + + /* Else, see if there is a way to calculate it */ + if (clk->recalc) + clk->rate = clk->recalc(clk); + + /* Otherwise, default to parent rate */ + else if (clk->parent) + clk->rate = clk->parent->rate; + + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + mutex_lock(&clocks_mutex); + list_del(&clk->node); + list_del(&clk->childnode); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clk_unregister); + + +static u32 pll_read(struct pll_data *pll, int reg) +{ + return soc_readl(pll->base + reg); +} + +static unsigned long clk_sysclk_recalc(struct clk *clk) +{ + u32 v, plldiv = 0; + struct pll_data *pll; + unsigned long rate = clk->rate; + + if (WARN_ON(!clk->parent)) + return rate; + + rate = clk->parent->rate; + + /* the parent must be a PLL */ + if (WARN_ON(!clk->parent->pll_data)) + return rate; + + pll = clk->parent->pll_data; + + /* If pre-PLL, source clock is before the multiplier and divider(s) */ + if (clk->flags & PRE_PLL) + rate = pll->input_rate; + + if (!clk->div) { + pr_debug("%s: (no divider) rate = %lu KHz\n", + clk->name, rate / 1000); + return rate; + } + + if (clk->flags & FIXED_DIV_PLL) { + rate /= clk->div; + pr_debug("%s: (fixed divide by %d) rate = %lu KHz\n", + clk->name, clk->div, rate / 1000); + return rate; + } + + v = pll_read(pll, clk->div); + if (v & PLLDIV_EN) + plldiv = (v & PLLDIV_RATIO_MASK) + 1; + + if (plldiv == 0) + plldiv = 1; + + rate /= plldiv; + + pr_debug("%s: (divide by %d) rate = %lu KHz\n", + clk->name, plldiv, rate / 1000); + + return rate; +} + +static unsigned long clk_leafclk_recalc(struct clk *clk) +{ + if (WARN_ON(!clk->parent)) + return clk->rate; + + pr_debug("%s: (parent %s) rate = %lu KHz\n", + clk->name, clk->parent->name, clk->parent->rate / 1000); + + return clk->parent->rate; +} + +static unsigned long clk_pllclk_recalc(struct clk *clk) +{ + u32 ctrl, mult = 0, prediv = 0, postdiv = 0; + u8 bypass; + struct pll_data *pll = clk->pll_data; + unsigned long rate = clk->rate; + + if (clk->flags & FIXED_RATE_PLL) + return rate; + + ctrl = pll_read(pll, PLLCTL); + rate = pll->input_rate = clk->parent->rate; + + if (ctrl & PLLCTL_PLLEN) + bypass = 0; + else + bypass = 1; + + if (pll->flags & PLL_HAS_MUL) { + mult = pll_read(pll, PLLM); + mult = (mult & PLLM_PLLM_MASK) + 1; + } + if (pll->flags & PLL_HAS_PRE) { + prediv = pll_read(pll, PLLPRE); + if (prediv & PLLDIV_EN) + prediv = (prediv & PLLDIV_RATIO_MASK) + 1; + else + prediv = 0; + } + if (pll->flags & PLL_HAS_POST) { + postdiv = pll_read(pll, PLLPOST); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1; + else + postdiv = 1; + } + + if (!bypass) { + if (prediv) + rate /= prediv; + if (mult) + rate *= mult; + if (postdiv) + rate /= postdiv; + + pr_debug("PLL%d: input = %luMHz, pre[%d] mul[%d] post[%d] " + "--> %luMHz output.\n", + pll->num, clk->parent->rate / 1000000, + prediv, mult, postdiv, rate / 1000000); + } else + pr_debug("PLL%d: input = %luMHz, bypass mode.\n", + pll->num, clk->parent->rate / 1000000); + + return rate; +} + + +static void __init __init_clk(struct clk *clk) +{ + INIT_LIST_HEAD(&clk->node); + INIT_LIST_HEAD(&clk->children); + INIT_LIST_HEAD(&clk->childnode); + + if (!clk->recalc) { + + /* Check if clock is a PLL */ + if (clk->pll_data) + clk->recalc = clk_pllclk_recalc; + + /* Else, if it is a PLL-derived clock */ + else if (clk->flags & CLK_PLL) + clk->recalc = clk_sysclk_recalc; + + /* Otherwise, it is a leaf clock (PSC clock) */ + else if (clk->parent) + clk->recalc = clk_leafclk_recalc; + } +} + +void __init c6x_clks_init(struct clk_lookup *clocks) +{ + struct clk_lookup *c; + struct clk *clk; + size_t num_clocks = 0; + + for (c = clocks; c->clk; c++) { + clk = c->clk; + + __init_clk(clk); + clk_register(clk); + num_clocks++; + + /* Turn on clocks that Linux doesn't otherwise manage */ + if (clk->flags & ALWAYS_ENABLED) + clk_enable(clk); + } + + clkdev_add_table(clocks, num_clocks); +} + +#ifdef CONFIG_DEBUG_FS + +#include +#include + +#define CLKNAME_MAX 10 /* longest clock name */ +#define NEST_DELTA 2 +#define NEST_MAX 4 + +static void +dump_clock(struct seq_file *s, unsigned nest, struct clk *parent) +{ + char *state; + char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX]; + struct clk *clk; + unsigned i; + + if (parent->flags & CLK_PLL) + state = "pll"; + else + state = ""; + + /* name */ + memset(buf, ' ', sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + i = strlen(parent->name); + memcpy(buf + nest, parent->name, + min(i, (unsigned)(sizeof(buf) - 1 - nest))); + + seq_printf(s, "%s users=%2d %-3s %9ld Hz\n", + buf, parent->usecount, state, clk_get_rate(parent)); + /* REVISIT show device associations too */ + + /* cost is now small, but not linear... */ + list_for_each_entry(clk, &parent->children, childnode) { + dump_clock(s, nest + NEST_DELTA, clk); + } +} + +static int c6x_ck_show(struct seq_file *m, void *v) +{ + struct clk *clk; + + /* + * Show clock tree; We trust nonzero usecounts equate to PSC enables... + */ + mutex_lock(&clocks_mutex); + list_for_each_entry(clk, &clocks, node) + if (!clk->parent) + dump_clock(m, 0, clk); + mutex_unlock(&clocks_mutex); + + return 0; +} + +static int c6x_ck_open(struct inode *inode, struct file *file) +{ + return single_open(file, c6x_ck_show, NULL); +} + +static const struct file_operations c6x_ck_operations = { + .open = c6x_ck_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init c6x_clk_debugfs_init(void) +{ + debugfs_create_file("c6x_clocks", S_IFREG | S_IRUGO, NULL, NULL, + &c6x_ck_operations); + + return 0; +} +device_initcall(c6x_clk_debugfs_init); +#endif /* CONFIG_DEBUG_FS */ diff --git a/arch/c6x/platforms/plldata.c b/arch/c6x/platforms/plldata.c new file mode 100644 index 000000000000..2cfd6f42968f --- /dev/null +++ b/arch/c6x/platforms/plldata.c @@ -0,0 +1,404 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Common SoC clock support. + */ + +/* Default input for PLL1 */ +struct clk clkin1 = { + .name = "clkin1", + .node = LIST_HEAD_INIT(clkin1.node), + .children = LIST_HEAD_INIT(clkin1.children), + .childnode = LIST_HEAD_INIT(clkin1.childnode), +}; + +struct pll_data c6x_soc_pll1 = { + .num = 1, + .sysclks = { + { + .name = "pll1", + .parent = &clkin1, + .pll_data = &c6x_soc_pll1, + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk1", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk2", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk3", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk4", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk5", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk6", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk7", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk8", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk9", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk10", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk11", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk12", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk13", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk14", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk15", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + { + .name = "pll1_sysclk16", + .parent = &c6x_soc_pll1.sysclks[0], + .flags = CLK_PLL, + }, + }, +}; + +/* CPU core clock */ +struct clk c6x_core_clk = { + .name = "core", +}; + +/* miscellaneous IO clocks */ +struct clk c6x_i2c_clk = { + .name = "i2c", +}; + +struct clk c6x_watchdog_clk = { + .name = "watchdog", +}; + +struct clk c6x_mcbsp1_clk = { + .name = "mcbsp1", +}; + +struct clk c6x_mcbsp2_clk = { + .name = "mcbsp2", +}; + +struct clk c6x_mdio_clk = { + .name = "mdio", +}; + + +#ifdef CONFIG_SOC_TMS320C6455 +static struct clk_lookup c6455_clks[] = { + CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), + CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), + CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), + CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), + CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), + CLK(NULL, "core", &c6x_core_clk), + CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), + CLK("watchdog", NULL, &c6x_watchdog_clk), + CLK("2c81800.mdio", NULL, &c6x_mdio_clk), + CLK("", NULL, NULL) +}; + + +static void __init c6455_setup_clocks(struct device_node *node) +{ + struct pll_data *pll = &c6x_soc_pll1; + struct clk *sysclks = pll->sysclks; + + pll->flags = PLL_HAS_PRE | PLL_HAS_MUL; + + sysclks[2].flags |= FIXED_DIV_PLL; + sysclks[2].div = 3; + sysclks[3].flags |= FIXED_DIV_PLL; + sysclks[3].div = 6; + sysclks[4].div = PLLDIV4; + sysclks[5].div = PLLDIV5; + + c6x_core_clk.parent = &sysclks[0]; + c6x_i2c_clk.parent = &sysclks[3]; + c6x_watchdog_clk.parent = &sysclks[3]; + c6x_mdio_clk.parent = &sysclks[3]; + + c6x_clks_init(c6455_clks); +} +#endif /* CONFIG_SOC_TMS320C6455 */ + +#ifdef CONFIG_SOC_TMS320C6457 +static struct clk_lookup c6457_clks[] = { + CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), + CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]), + CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), + CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), + CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), + CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), + CLK(NULL, "core", &c6x_core_clk), + CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), + CLK("watchdog", NULL, &c6x_watchdog_clk), + CLK("2c81800.mdio", NULL, &c6x_mdio_clk), + CLK("", NULL, NULL) +}; + +static void __init c6457_setup_clocks(struct device_node *node) +{ + struct pll_data *pll = &c6x_soc_pll1; + struct clk *sysclks = pll->sysclks; + + pll->flags = PLL_HAS_MUL | PLL_HAS_POST; + + sysclks[1].flags |= FIXED_DIV_PLL; + sysclks[1].div = 1; + sysclks[2].flags |= FIXED_DIV_PLL; + sysclks[2].div = 3; + sysclks[3].flags |= FIXED_DIV_PLL; + sysclks[3].div = 6; + sysclks[4].div = PLLDIV4; + sysclks[5].div = PLLDIV5; + + c6x_core_clk.parent = &sysclks[1]; + c6x_i2c_clk.parent = &sysclks[3]; + c6x_watchdog_clk.parent = &sysclks[5]; + c6x_mdio_clk.parent = &sysclks[5]; + + c6x_clks_init(c6457_clks); +} +#endif /* CONFIG_SOC_TMS320C6455 */ + +#ifdef CONFIG_SOC_TMS320C6472 +static struct clk_lookup c6472_clks[] = { + CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), + CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]), + CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), + CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), + CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), + CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), + CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]), + CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]), + CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]), + CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]), + CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]), + CLK(NULL, "core", &c6x_core_clk), + CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), + CLK("watchdog", NULL, &c6x_watchdog_clk), + CLK("2c81800.mdio", NULL, &c6x_mdio_clk), + CLK("", NULL, NULL) +}; + +/* assumptions used for delay loop calculations */ +#define MIN_CLKIN1_KHz 15625 +#define MAX_CORE_KHz 700000 +#define MIN_PLLOUT_KHz MIN_CLKIN1_KHz + +static void __init c6472_setup_clocks(struct device_node *node) +{ + struct pll_data *pll = &c6x_soc_pll1; + struct clk *sysclks = pll->sysclks; + int i; + + pll->flags = PLL_HAS_MUL; + + for (i = 1; i <= 6; i++) { + sysclks[i].flags |= FIXED_DIV_PLL; + sysclks[i].div = 1; + } + + sysclks[7].flags |= FIXED_DIV_PLL; + sysclks[7].div = 3; + sysclks[8].flags |= FIXED_DIV_PLL; + sysclks[8].div = 6; + sysclks[9].flags |= FIXED_DIV_PLL; + sysclks[9].div = 2; + sysclks[10].div = PLLDIV10; + + c6x_core_clk.parent = &sysclks[get_coreid() + 1]; + c6x_i2c_clk.parent = &sysclks[8]; + c6x_watchdog_clk.parent = &sysclks[8]; + c6x_mdio_clk.parent = &sysclks[5]; + + c6x_clks_init(c6472_clks); +} +#endif /* CONFIG_SOC_TMS320C6472 */ + + +#ifdef CONFIG_SOC_TMS320C6474 +static struct clk_lookup c6474_clks[] = { + CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), + CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]), + CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]), + CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]), + CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]), + CLK(NULL, "pll1_sysclk12", &c6x_soc_pll1.sysclks[12]), + CLK(NULL, "pll1_sysclk13", &c6x_soc_pll1.sysclks[13]), + CLK(NULL, "core", &c6x_core_clk), + CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), + CLK("mcbsp.1", NULL, &c6x_mcbsp1_clk), + CLK("mcbsp.2", NULL, &c6x_mcbsp2_clk), + CLK("watchdog", NULL, &c6x_watchdog_clk), + CLK("2c81800.mdio", NULL, &c6x_mdio_clk), + CLK("", NULL, NULL) +}; + +static void __init c6474_setup_clocks(struct device_node *node) +{ + struct pll_data *pll = &c6x_soc_pll1; + struct clk *sysclks = pll->sysclks; + + pll->flags = PLL_HAS_MUL; + + sysclks[7].flags |= FIXED_DIV_PLL; + sysclks[7].div = 1; + sysclks[9].flags |= FIXED_DIV_PLL; + sysclks[9].div = 3; + sysclks[10].flags |= FIXED_DIV_PLL; + sysclks[10].div = 6; + + sysclks[11].div = PLLDIV11; + + sysclks[12].flags |= FIXED_DIV_PLL; + sysclks[12].div = 2; + + sysclks[13].div = PLLDIV13; + + c6x_core_clk.parent = &sysclks[7]; + c6x_i2c_clk.parent = &sysclks[10]; + c6x_watchdog_clk.parent = &sysclks[10]; + c6x_mcbsp1_clk.parent = &sysclks[10]; + c6x_mcbsp2_clk.parent = &sysclks[10]; + + c6x_clks_init(c6474_clks); +} +#endif /* CONFIG_SOC_TMS320C6474 */ + +static struct of_device_id c6x_clkc_match[] __initdata = { +#ifdef CONFIG_SOC_TMS320C6455 + { .compatible = "ti,c6455-pll", .data = c6455_setup_clocks }, +#endif +#ifdef CONFIG_SOC_TMS320C6457 + { .compatible = "ti,c6457-pll", .data = c6457_setup_clocks }, +#endif +#ifdef CONFIG_SOC_TMS320C6472 + { .compatible = "ti,c6472-pll", .data = c6472_setup_clocks }, +#endif +#ifdef CONFIG_SOC_TMS320C6474 + { .compatible = "ti,c6474-pll", .data = c6474_setup_clocks }, +#endif + { .compatible = "ti,c64x+pll" }, + {} +}; + +void __init c64x_setup_clocks(void) +{ + void (*__setup_clocks)(struct device_node *np); + struct pll_data *pll = &c6x_soc_pll1; + struct device_node *node; + const struct of_device_id *id; + int err; + u32 val; + + node = of_find_matching_node(NULL, c6x_clkc_match); + if (!node) + return; + + pll->base = of_iomap(node, 0); + if (!pll->base) + goto out; + + err = of_property_read_u32(node, "clock-frequency", &val); + if (err || val == 0) { + pr_err("%s: no clock-frequency found! Using %dMHz\n", + node->full_name, (int)val / 1000000); + val = 25000000; + } + clkin1.rate = val; + + err = of_property_read_u32(node, "ti,c64x+pll-bypass-delay", &val); + if (err) + val = 5000; + pll->bypass_delay = val; + + err = of_property_read_u32(node, "ti,c64x+pll-reset-delay", &val); + if (err) + val = 30000; + pll->reset_delay = val; + + err = of_property_read_u32(node, "ti,c64x+pll-lock-delay", &val); + if (err) + val = 30000; + pll->lock_delay = val; + + /* id->data is a pointer to SoC-specific setup */ + id = of_match_node(c6x_clkc_match, node); + if (id && id->data) { + __setup_clocks = id->data; + __setup_clocks(node); + } + +out: + of_node_put(node); +} -- cgit v1.2.3 From 784bdcd0aa1d8ce38025bcfaa321146762738fe0 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:11:35 -0400 Subject: C6X: cache control Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/cache.h | 90 ++++++++ arch/c6x/include/asm/cacheflush.h | 65 ++++++ arch/c6x/platforms/cache.c | 445 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 600 insertions(+) create mode 100644 arch/c6x/include/asm/cache.h create mode 100644 arch/c6x/include/asm/cacheflush.h create mode 100644 arch/c6x/platforms/cache.c (limited to 'arch') diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h new file mode 100644 index 000000000000..6d521d96d941 --- /dev/null +++ b/arch/c6x/include/asm/cache.h @@ -0,0 +1,90 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_CACHE_H +#define _ASM_C6X_CACHE_H + +#include + +/* + * Cache line size + */ +#define L1D_CACHE_BYTES 64 +#define L1P_CACHE_BYTES 32 +#define L2_CACHE_BYTES 128 + +/* + * L2 used as cache + */ +#define L2MODE_SIZE L2MODE_256K_CACHE + +/* + * For practical reasons the L1_CACHE_BYTES defines should not be smaller than + * the L2 line size + */ +#define L1_CACHE_BYTES L2_CACHE_BYTES + +#define L2_CACHE_ALIGN_LOW(x) \ + (((x) & ~(L2_CACHE_BYTES - 1))) +#define L2_CACHE_ALIGN_UP(x) \ + (((x) + (L2_CACHE_BYTES - 1)) & ~(L2_CACHE_BYTES - 1)) +#define L2_CACHE_ALIGN_CNT(x) \ + (((x) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) + +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES +#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES + +/* + * This is the granularity of hardware cacheability control. + */ +#define CACHEABILITY_ALIGN 0x01000000 + +/* + * Align a physical address to MAR regions + */ +#define CACHE_REGION_START(v) \ + (((u32) (v)) & ~(CACHEABILITY_ALIGN - 1)) +#define CACHE_REGION_END(v) \ + (((u32) (v) + (CACHEABILITY_ALIGN - 1)) & ~(CACHEABILITY_ALIGN - 1)) + +extern void __init c6x_cache_init(void); + +extern void enable_caching(unsigned long start, unsigned long end); +extern void disable_caching(unsigned long start, unsigned long end); + +extern void L1_cache_off(void); +extern void L1_cache_on(void); + +extern void L1P_cache_global_invalidate(void); +extern void L1D_cache_global_invalidate(void); +extern void L1D_cache_global_writeback(void); +extern void L1D_cache_global_writeback_invalidate(void); +extern void L2_cache_set_mode(unsigned int mode); +extern void L2_cache_global_writeback_invalidate(void); +extern void L2_cache_global_writeback(void); + +extern void L1P_cache_block_invalidate(unsigned int start, unsigned int end); +extern void L1D_cache_block_invalidate(unsigned int start, unsigned int end); +extern void L1D_cache_block_writeback_invalidate(unsigned int start, + unsigned int end); +extern void L1D_cache_block_writeback(unsigned int start, unsigned int end); +extern void L2_cache_block_invalidate(unsigned int start, unsigned int end); +extern void L2_cache_block_writeback(unsigned int start, unsigned int end); +extern void L2_cache_block_writeback_invalidate(unsigned int start, + unsigned int end); +extern void L2_cache_block_invalidate_nowait(unsigned int start, + unsigned int end); +extern void L2_cache_block_writeback_nowait(unsigned int start, + unsigned int end); + +extern void L2_cache_block_writeback_invalidate_nowait(unsigned int start, + unsigned int end); + +#endif /* _ASM_C6X_CACHE_H */ diff --git a/arch/c6x/include/asm/cacheflush.h b/arch/c6x/include/asm/cacheflush.h new file mode 100644 index 000000000000..df5db90dbe56 --- /dev/null +++ b/arch/c6x/include/asm/cacheflush.h @@ -0,0 +1,65 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_CACHEFLUSH_H +#define _ASM_C6X_CACHEFLUSH_H + +#include + +#include +#include +#include +#include +#include + +/* + * virtually-indexed cache management (our cache is physically indexed) + */ +#define flush_cache_all() do {} while (0) +#define flush_cache_mm(mm) do {} while (0) +#define flush_cache_dup_mm(mm) do {} while (0) +#define flush_cache_range(mm, start, end) do {} while (0) +#define flush_cache_page(vma, vmaddr, pfn) do {} while (0) +#define flush_cache_vmap(start, end) do {} while (0) +#define flush_cache_vunmap(start, end) do {} while (0) +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 +#define flush_dcache_page(page) do {} while (0) +#define flush_dcache_mmap_lock(mapping) do {} while (0) +#define flush_dcache_mmap_unlock(mapping) do {} while (0) + +/* + * physically-indexed cache management + */ +#define flush_icache_range(s, e) \ +do { \ + L1D_cache_block_writeback((s), (e)); \ + L1P_cache_block_invalidate((s), (e)); \ +} while (0) + +#define flush_icache_page(vma, page) \ +do { \ + if ((vma)->vm_flags & PROT_EXEC) \ + L1D_cache_block_writeback_invalidate(page_address(page), \ + (unsigned long) page_address(page) + PAGE_SIZE)); \ + L1P_cache_block_invalidate(page_address(page), \ + (unsigned long) page_address(page) + PAGE_SIZE)); \ +} while (0) + + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ +do { \ + memcpy(dst, src, len); \ + flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \ +} while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) + +#endif /* _ASM_C6X_CACHEFLUSH_H */ diff --git a/arch/c6x/platforms/cache.c b/arch/c6x/platforms/cache.c new file mode 100644 index 000000000000..86318a16a252 --- /dev/null +++ b/arch/c6x/platforms/cache.c @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 +#include +#include + +#include +#include + +/* + * Internal Memory Control Registers for caches + */ +#define IMCR_CCFG 0x0000 +#define IMCR_L1PCFG 0x0020 +#define IMCR_L1PCC 0x0024 +#define IMCR_L1DCFG 0x0040 +#define IMCR_L1DCC 0x0044 +#define IMCR_L2ALLOC0 0x2000 +#define IMCR_L2ALLOC1 0x2004 +#define IMCR_L2ALLOC2 0x2008 +#define IMCR_L2ALLOC3 0x200c +#define IMCR_L2WBAR 0x4000 +#define IMCR_L2WWC 0x4004 +#define IMCR_L2WIBAR 0x4010 +#define IMCR_L2WIWC 0x4014 +#define IMCR_L2IBAR 0x4018 +#define IMCR_L2IWC 0x401c +#define IMCR_L1PIBAR 0x4020 +#define IMCR_L1PIWC 0x4024 +#define IMCR_L1DWIBAR 0x4030 +#define IMCR_L1DWIWC 0x4034 +#define IMCR_L1DWBAR 0x4040 +#define IMCR_L1DWWC 0x4044 +#define IMCR_L1DIBAR 0x4048 +#define IMCR_L1DIWC 0x404c +#define IMCR_L2WB 0x5000 +#define IMCR_L2WBINV 0x5004 +#define IMCR_L2INV 0x5008 +#define IMCR_L1PINV 0x5028 +#define IMCR_L1DWB 0x5040 +#define IMCR_L1DWBINV 0x5044 +#define IMCR_L1DINV 0x5048 +#define IMCR_MAR_BASE 0x8000 +#define IMCR_MAR96_111 0x8180 +#define IMCR_MAR128_191 0x8200 +#define IMCR_MAR224_239 0x8380 +#define IMCR_L2MPFAR 0xa000 +#define IMCR_L2MPFSR 0xa004 +#define IMCR_L2MPFCR 0xa008 +#define IMCR_L2MPLK0 0xa100 +#define IMCR_L2MPLK1 0xa104 +#define IMCR_L2MPLK2 0xa108 +#define IMCR_L2MPLK3 0xa10c +#define IMCR_L2MPLKCMD 0xa110 +#define IMCR_L2MPLKSTAT 0xa114 +#define IMCR_L2MPPA_BASE 0xa200 +#define IMCR_L1PMPFAR 0xa400 +#define IMCR_L1PMPFSR 0xa404 +#define IMCR_L1PMPFCR 0xa408 +#define IMCR_L1PMPLK0 0xa500 +#define IMCR_L1PMPLK1 0xa504 +#define IMCR_L1PMPLK2 0xa508 +#define IMCR_L1PMPLK3 0xa50c +#define IMCR_L1PMPLKCMD 0xa510 +#define IMCR_L1PMPLKSTAT 0xa514 +#define IMCR_L1PMPPA_BASE 0xa600 +#define IMCR_L1DMPFAR 0xac00 +#define IMCR_L1DMPFSR 0xac04 +#define IMCR_L1DMPFCR 0xac08 +#define IMCR_L1DMPLK0 0xad00 +#define IMCR_L1DMPLK1 0xad04 +#define IMCR_L1DMPLK2 0xad08 +#define IMCR_L1DMPLK3 0xad0c +#define IMCR_L1DMPLKCMD 0xad10 +#define IMCR_L1DMPLKSTAT 0xad14 +#define IMCR_L1DMPPA_BASE 0xae00 +#define IMCR_L2PDWAKE0 0xc040 +#define IMCR_L2PDWAKE1 0xc044 +#define IMCR_L2PDSLEEP0 0xc050 +#define IMCR_L2PDSLEEP1 0xc054 +#define IMCR_L2PDSTAT0 0xc060 +#define IMCR_L2PDSTAT1 0xc064 + +/* + * CCFG register values and bits + */ +#define L2MODE_0K_CACHE 0x0 +#define L2MODE_32K_CACHE 0x1 +#define L2MODE_64K_CACHE 0x2 +#define L2MODE_128K_CACHE 0x3 +#define L2MODE_256K_CACHE 0x7 + +#define L2PRIO_URGENT 0x0 +#define L2PRIO_HIGH 0x1 +#define L2PRIO_MEDIUM 0x2 +#define L2PRIO_LOW 0x3 + +#define CCFG_ID 0x100 /* Invalidate L1P bit */ +#define CCFG_IP 0x200 /* Invalidate L1D bit */ + +static void __iomem *cache_base; + +/* + * L1 & L2 caches generic functions + */ +#define imcr_get(reg) soc_readl(cache_base + (reg)) +#define imcr_set(reg, value) \ +do { \ + soc_writel((value), cache_base + (reg)); \ + soc_readl(cache_base + (reg)); \ +} while (0) + +static void cache_block_operation_wait(unsigned int wc_reg) +{ + /* Wait for completion */ + while (imcr_get(wc_reg)) + cpu_relax(); +} + +static DEFINE_SPINLOCK(cache_lock); + +/* + * Generic function to perform a block cache operation as + * invalidate or writeback/invalidate + */ +static void cache_block_operation(unsigned int *start, + unsigned int *end, + unsigned int bar_reg, + unsigned int wc_reg) +{ + unsigned long flags; + unsigned int wcnt = + (L2_CACHE_ALIGN_CNT((unsigned int) end) + - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2; + unsigned int wc = 0; + + for (; wcnt; wcnt -= wc, start += wc) { +loop: + spin_lock_irqsave(&cache_lock, flags); + + /* + * If another cache operation is occuring + */ + if (unlikely(imcr_get(wc_reg))) { + spin_unlock_irqrestore(&cache_lock, flags); + + /* Wait for previous operation completion */ + cache_block_operation_wait(wc_reg); + + /* Try again */ + goto loop; + } + + imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start)); + + if (wcnt > 0xffff) + wc = 0xffff; + else + wc = wcnt; + + /* Set word count value in the WC register */ + imcr_set(wc_reg, wc & 0xffff); + + spin_unlock_irqrestore(&cache_lock, flags); + + /* Wait for completion */ + cache_block_operation_wait(wc_reg); + } +} + +static void cache_block_operation_nowait(unsigned int *start, + unsigned int *end, + unsigned int bar_reg, + unsigned int wc_reg) +{ + unsigned long flags; + unsigned int wcnt = + (L2_CACHE_ALIGN_CNT((unsigned int) end) + - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2; + unsigned int wc = 0; + + for (; wcnt; wcnt -= wc, start += wc) { + + spin_lock_irqsave(&cache_lock, flags); + + imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start)); + + if (wcnt > 0xffff) + wc = 0xffff; + else + wc = wcnt; + + /* Set word count value in the WC register */ + imcr_set(wc_reg, wc & 0xffff); + + spin_unlock_irqrestore(&cache_lock, flags); + + /* Don't wait for completion on last cache operation */ + if (wcnt > 0xffff) + cache_block_operation_wait(wc_reg); + } +} + +/* + * L1 caches management + */ + +/* + * Disable L1 caches + */ +void L1_cache_off(void) +{ + unsigned int dummy; + + imcr_set(IMCR_L1PCFG, 0); + dummy = imcr_get(IMCR_L1PCFG); + + imcr_set(IMCR_L1DCFG, 0); + dummy = imcr_get(IMCR_L1DCFG); +} + +/* + * Enable L1 caches + */ +void L1_cache_on(void) +{ + unsigned int dummy; + + imcr_set(IMCR_L1PCFG, 7); + dummy = imcr_get(IMCR_L1PCFG); + + imcr_set(IMCR_L1DCFG, 7); + dummy = imcr_get(IMCR_L1DCFG); +} + +/* + * L1P global-invalidate all + */ +void L1P_cache_global_invalidate(void) +{ + unsigned int set = 1; + imcr_set(IMCR_L1PINV, set); + while (imcr_get(IMCR_L1PINV) & 1) + cpu_relax(); +} + +/* + * L1D global-invalidate all + * + * Warning: this operation causes all updated data in L1D to + * be discarded rather than written back to the lower levels of + * memory + */ +void L1D_cache_global_invalidate(void) +{ + unsigned int set = 1; + imcr_set(IMCR_L1DINV, set); + while (imcr_get(IMCR_L1DINV) & 1) + cpu_relax(); +} + +void L1D_cache_global_writeback(void) +{ + unsigned int set = 1; + imcr_set(IMCR_L1DWB, set); + while (imcr_get(IMCR_L1DWB) & 1) + cpu_relax(); +} + +void L1D_cache_global_writeback_invalidate(void) +{ + unsigned int set = 1; + imcr_set(IMCR_L1DWBINV, set); + while (imcr_get(IMCR_L1DWBINV) & 1) + cpu_relax(); +} + +/* + * L2 caches management + */ + +/* + * Set L2 operation mode + */ +void L2_cache_set_mode(unsigned int mode) +{ + unsigned int ccfg = imcr_get(IMCR_CCFG); + + /* Clear and set the L2MODE bits in CCFG */ + ccfg &= ~7; + ccfg |= (mode & 7); + imcr_set(IMCR_CCFG, ccfg); + ccfg = imcr_get(IMCR_CCFG); +} + +/* + * L2 global-writeback and global-invalidate all + */ +void L2_cache_global_writeback_invalidate(void) +{ + imcr_set(IMCR_L2WBINV, 1); + while (imcr_get(IMCR_L2WBINV)) + cpu_relax(); +} + +/* + * L2 global-writeback all + */ +void L2_cache_global_writeback(void) +{ + imcr_set(IMCR_L2WB, 1); + while (imcr_get(IMCR_L2WB)) + cpu_relax(); +} + +/* + * Cacheability controls + */ +void enable_caching(unsigned long start, unsigned long end) +{ + unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2); + unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2); + + for (; mar <= mar_e; mar += 4) + imcr_set(mar, imcr_get(mar) | 1); +} + +void disable_caching(unsigned long start, unsigned long end) +{ + unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2); + unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2); + + for (; mar <= mar_e; mar += 4) + imcr_set(mar, imcr_get(mar) & ~1); +} + + +/* + * L1 block operations + */ +void L1P_cache_block_invalidate(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L1PIBAR, IMCR_L1PIWC); +} + +void L1D_cache_block_invalidate(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L1DIBAR, IMCR_L1DIWC); +} + +void L1D_cache_block_writeback_invalidate(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L1DWIBAR, IMCR_L1DWIWC); +} + +void L1D_cache_block_writeback(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L1DWBAR, IMCR_L1DWWC); +} + +/* + * L2 block operations + */ +void L2_cache_block_invalidate(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L2IBAR, IMCR_L2IWC); +} + +void L2_cache_block_writeback(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L2WBAR, IMCR_L2WWC); +} + +void L2_cache_block_writeback_invalidate(unsigned int start, unsigned int end) +{ + cache_block_operation((unsigned int *) start, + (unsigned int *) end, + IMCR_L2WIBAR, IMCR_L2WIWC); +} + +void L2_cache_block_invalidate_nowait(unsigned int start, unsigned int end) +{ + cache_block_operation_nowait((unsigned int *) start, + (unsigned int *) end, + IMCR_L2IBAR, IMCR_L2IWC); +} + +void L2_cache_block_writeback_nowait(unsigned int start, unsigned int end) +{ + cache_block_operation_nowait((unsigned int *) start, + (unsigned int *) end, + IMCR_L2WBAR, IMCR_L2WWC); +} + +void L2_cache_block_writeback_invalidate_nowait(unsigned int start, + unsigned int end) +{ + cache_block_operation_nowait((unsigned int *) start, + (unsigned int *) end, + IMCR_L2WIBAR, IMCR_L2WIWC); +} + + +/* + * L1 and L2 caches configuration + */ +void __init c6x_cache_init(void) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "ti,c64x+cache"); + if (!node) + return; + + cache_base = of_iomap(node, 0); + + of_node_put(node); + + if (!cache_base) + return; + + /* Set L2 caches on the the whole L2 SRAM memory */ + L2_cache_set_mode(L2MODE_SIZE); + + /* Enable L1 */ + L1_cache_on(); +} -- cgit v1.2.3 From 64236ac1444eecca4b7b51270879d58bd291c8c2 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:12:27 -0400 Subject: C6X: loadable module support Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/module.h | 33 ++++++++++++ arch/c6x/kernel/c6x_ksyms.c | 66 +++++++++++++++++++++++ arch/c6x/kernel/module.c | 123 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 arch/c6x/include/asm/module.h create mode 100644 arch/c6x/kernel/c6x_ksyms.c create mode 100644 arch/c6x/kernel/module.c (limited to 'arch') diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h new file mode 100644 index 000000000000..a453f9744f42 --- /dev/null +++ b/arch/c6x/include/asm/module.h @@ -0,0 +1,33 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Updated for 2.6.34 by: Mark Salter (msalter@redhat.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. + */ +#ifndef _ASM_C6X_MODULE_H +#define _ASM_C6X_MODULE_H + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Addr Elf32_Addr +#define Elf_Word Elf32_Word + +/* + * This file contains the C6x architecture specific module code. + */ +struct mod_arch_specific { +}; + +struct loaded_sections { + unsigned int new_vaddr; + unsigned int loaded; +}; + +#endif /* _ASM_C6X_MODULE_H */ diff --git a/arch/c6x/kernel/c6x_ksyms.c b/arch/c6x/kernel/c6x_ksyms.c new file mode 100644 index 000000000000..0ba3e0bba3e1 --- /dev/null +++ b/arch/c6x/kernel/c6x_ksyms.c @@ -0,0 +1,66 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 +#include +#include + +/* + * libgcc functions - used internally by the compiler... + */ +extern int __c6xabi_divi(int dividend, int divisor); +EXPORT_SYMBOL(__c6xabi_divi); + +extern unsigned __c6xabi_divu(unsigned dividend, unsigned divisor); +EXPORT_SYMBOL(__c6xabi_divu); + +extern int __c6xabi_remi(int dividend, int divisor); +EXPORT_SYMBOL(__c6xabi_remi); + +extern unsigned __c6xabi_remu(unsigned dividend, unsigned divisor); +EXPORT_SYMBOL(__c6xabi_remu); + +extern int __c6xabi_divremi(int dividend, int divisor); +EXPORT_SYMBOL(__c6xabi_divremi); + +extern unsigned __c6xabi_divremu(unsigned dividend, unsigned divisor); +EXPORT_SYMBOL(__c6xabi_divremu); + +extern unsigned long long __c6xabi_mpyll(unsigned long long src1, + unsigned long long src2); +EXPORT_SYMBOL(__c6xabi_mpyll); + +extern long long __c6xabi_negll(long long src); +EXPORT_SYMBOL(__c6xabi_negll); + +extern unsigned long long __c6xabi_llshl(unsigned long long src1, uint src2); +EXPORT_SYMBOL(__c6xabi_llshl); + +extern long long __c6xabi_llshr(long long src1, uint src2); +EXPORT_SYMBOL(__c6xabi_llshr); + +extern unsigned long long __c6xabi_llshru(unsigned long long src1, uint src2); +EXPORT_SYMBOL(__c6xabi_llshru); + +extern void __c6xabi_strasgi(int *dst, const int *src, unsigned cnt); +EXPORT_SYMBOL(__c6xabi_strasgi); + +extern void __c6xabi_push_rts(void); +EXPORT_SYMBOL(__c6xabi_push_rts); + +extern void __c6xabi_pop_rts(void); +EXPORT_SYMBOL(__c6xabi_pop_rts); + +extern void __c6xabi_strasgi_64plus(int *dst, const int *src, unsigned cnt); +EXPORT_SYMBOL(__c6xabi_strasgi_64plus); + +/* lib functions */ +EXPORT_SYMBOL(memcpy); diff --git a/arch/c6x/kernel/module.c b/arch/c6x/kernel/module.c new file mode 100644 index 000000000000..5fc03f18f56c --- /dev/null +++ b/arch/c6x/kernel/module.c @@ -0,0 +1,123 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2005, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Thomas Charleux (thomas.charleux@jaluna.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 +#include +#include +#include + +static inline int fixup_pcr(u32 *ip, Elf32_Addr dest, u32 maskbits, int shift) +{ + u32 opcode; + long ep = (long)ip & ~31; + long delta = ((long)dest - ep) >> 2; + long mask = (1 << maskbits) - 1; + + if ((delta >> (maskbits - 1)) == 0 || + (delta >> (maskbits - 1)) == -1) { + opcode = *ip; + opcode &= ~(mask << shift); + opcode |= ((delta & mask) << shift); + *ip = opcode; + + pr_debug("REL PCR_S%d[%p] dest[%p] opcode[%08x]\n", + maskbits, ip, (void *)dest, opcode); + + return 0; + } + pr_err("PCR_S%d reloc %p -> %p out of range!\n", + maskbits, ip, (void *)dest); + + return -1; +} + +/* + * apply a RELA relocation + */ +int apply_relocate_add(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + Elf32_Rela *rel = (void *) sechdrs[relsec].sh_addr; + Elf_Sym *sym; + u32 *location, opcode; + unsigned int i; + Elf32_Addr v; + Elf_Addr offset = 0; + + pr_debug("Applying relocate section %u to %u with offset 0x%x\n", + relsec, sechdrs[relsec].sh_info, offset); + + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { + /* This is where to make the change */ + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + + rel[i].r_offset - offset; + + /* This is the symbol it is referring to. Note that all + undefined symbols have been resolved. */ + sym = (Elf_Sym *)sechdrs[symindex].sh_addr + + ELF32_R_SYM(rel[i].r_info); + + /* this is the adjustment to be made */ + v = sym->st_value + rel[i].r_addend; + + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_C6000_ABS32: + pr_debug("RELA ABS32: [%p] = 0x%x\n", location, v); + *location = v; + break; + case R_C6000_ABS16: + pr_debug("RELA ABS16: [%p] = 0x%x\n", location, v); + *(u16 *)location = v; + break; + case R_C6000_ABS8: + pr_debug("RELA ABS8: [%p] = 0x%x\n", location, v); + *(u8 *)location = v; + break; + case R_C6000_ABS_L16: + opcode = *location; + opcode &= ~0x7fff80; + opcode |= ((v & 0xffff) << 7); + pr_debug("RELA ABS_L16[%p] v[0x%x] opcode[0x%x]\n", + location, v, opcode); + *location = opcode; + break; + case R_C6000_ABS_H16: + opcode = *location; + opcode &= ~0x7fff80; + opcode |= ((v >> 9) & 0x7fff80); + pr_debug("RELA ABS_H16[%p] v[0x%x] opcode[0x%x]\n", + location, v, opcode); + *location = opcode; + break; + case R_C6000_PCR_S21: + if (fixup_pcr(location, v, 21, 7)) + return -ENOEXEC; + break; + case R_C6000_PCR_S12: + if (fixup_pcr(location, v, 12, 16)) + return -ENOEXEC; + break; + case R_C6000_PCR_S10: + if (fixup_pcr(location, v, 10, 13)) + return -ENOEXEC; + break; + default: + pr_err("module %s: Unknown RELA relocation: %u\n", + me->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } + } + + return 0; +} -- cgit v1.2.3 From 52679b2d735492bce02503bafb333da87fae22c2 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:13:21 -0400 Subject: C6X: ptrace support Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/ptrace.h | 174 +++++++++++++++++++++++++++++++++++++++ arch/c6x/kernel/ptrace.c | 187 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 361 insertions(+) create mode 100644 arch/c6x/include/asm/ptrace.h create mode 100644 arch/c6x/kernel/ptrace.c (limited to 'arch') diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h new file mode 100644 index 000000000000..21e8d7931fe7 --- /dev/null +++ b/arch/c6x/include/asm/ptrace.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Updated for 2.6.34: Mark Salter + * + * 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_C6X_PTRACE_H +#define _ASM_C6X_PTRACE_H + +#define BKPT_OPCODE 0x56454314 /* illegal opcode */ + +#ifdef _BIG_ENDIAN +#define PT_LO(odd, even) odd +#define PT_HI(odd, even) even +#else +#define PT_LO(odd, even) even +#define PT_HI(odd, even) odd +#endif + +#define PT_A4_ORG PT_LO(1, 0) +#define PT_TSR PT_HI(1, 0) +#define PT_ILC PT_LO(3, 2) +#define PT_RILC PT_HI(3, 2) +#define PT_CSR PT_LO(5, 4) +#define PT_PC PT_HI(5, 4) +#define PT_B16 PT_LO(7, 6) +#define PT_B17 PT_HI(7, 6) +#define PT_B18 PT_LO(9, 8) +#define PT_B19 PT_HI(9, 8) +#define PT_B20 PT_LO(11, 10) +#define PT_B21 PT_HI(11, 10) +#define PT_B22 PT_LO(13, 12) +#define PT_B23 PT_HI(13, 12) +#define PT_B24 PT_LO(15, 14) +#define PT_B25 PT_HI(15, 14) +#define PT_B26 PT_LO(17, 16) +#define PT_B27 PT_HI(17, 16) +#define PT_B28 PT_LO(19, 18) +#define PT_B29 PT_HI(19, 18) +#define PT_B30 PT_LO(21, 20) +#define PT_B31 PT_HI(21, 20) +#define PT_B0 PT_LO(23, 22) +#define PT_B1 PT_HI(23, 22) +#define PT_B2 PT_LO(25, 24) +#define PT_B3 PT_HI(25, 24) +#define PT_B4 PT_LO(27, 26) +#define PT_B5 PT_HI(27, 26) +#define PT_B6 PT_LO(29, 28) +#define PT_B7 PT_HI(29, 28) +#define PT_B8 PT_LO(31, 30) +#define PT_B9 PT_HI(31, 30) +#define PT_B10 PT_LO(33, 32) +#define PT_B11 PT_HI(33, 32) +#define PT_B12 PT_LO(35, 34) +#define PT_B13 PT_HI(35, 34) +#define PT_A16 PT_LO(37, 36) +#define PT_A17 PT_HI(37, 36) +#define PT_A18 PT_LO(39, 38) +#define PT_A19 PT_HI(39, 38) +#define PT_A20 PT_LO(41, 40) +#define PT_A21 PT_HI(41, 40) +#define PT_A22 PT_LO(43, 42) +#define PT_A23 PT_HI(43, 42) +#define PT_A24 PT_LO(45, 44) +#define PT_A25 PT_HI(45, 44) +#define PT_A26 PT_LO(47, 46) +#define PT_A27 PT_HI(47, 46) +#define PT_A28 PT_LO(49, 48) +#define PT_A29 PT_HI(49, 48) +#define PT_A30 PT_LO(51, 50) +#define PT_A31 PT_HI(51, 50) +#define PT_A0 PT_LO(53, 52) +#define PT_A1 PT_HI(53, 52) +#define PT_A2 PT_LO(55, 54) +#define PT_A3 PT_HI(55, 54) +#define PT_A4 PT_LO(57, 56) +#define PT_A5 PT_HI(57, 56) +#define PT_A6 PT_LO(59, 58) +#define PT_A7 PT_HI(59, 58) +#define PT_A8 PT_LO(61, 60) +#define PT_A9 PT_HI(61, 60) +#define PT_A10 PT_LO(63, 62) +#define PT_A11 PT_HI(63, 62) +#define PT_A12 PT_LO(65, 64) +#define PT_A13 PT_HI(65, 64) +#define PT_A14 PT_LO(67, 66) +#define PT_A15 PT_HI(67, 66) +#define PT_B14 PT_LO(69, 68) +#define PT_B15 PT_HI(69, 68) + +#define NR_PTREGS 70 + +#define PT_DP PT_B14 /* Data Segment Pointer (B14) */ +#define PT_SP PT_B15 /* Stack Pointer (B15) */ + +#ifndef __ASSEMBLY__ + +#ifdef _BIG_ENDIAN +#define REG_PAIR(odd, even) unsigned long odd; unsigned long even +#else +#define REG_PAIR(odd, even) unsigned long even; unsigned long odd +#endif + +/* + * this struct defines the way the registers are stored on the + * stack during a system call. fields defined with REG_PAIR + * are saved and restored using double-word memory operations + * which means the word ordering of the pair depends on endianess. + */ +struct pt_regs { + REG_PAIR(tsr, orig_a4); + REG_PAIR(rilc, ilc); + REG_PAIR(pc, csr); + + REG_PAIR(b17, b16); + REG_PAIR(b19, b18); + REG_PAIR(b21, b20); + REG_PAIR(b23, b22); + REG_PAIR(b25, b24); + REG_PAIR(b27, b26); + REG_PAIR(b29, b28); + REG_PAIR(b31, b30); + + REG_PAIR(b1, b0); + REG_PAIR(b3, b2); + REG_PAIR(b5, b4); + REG_PAIR(b7, b6); + REG_PAIR(b9, b8); + REG_PAIR(b11, b10); + REG_PAIR(b13, b12); + + REG_PAIR(a17, a16); + REG_PAIR(a19, a18); + REG_PAIR(a21, a20); + REG_PAIR(a23, a22); + REG_PAIR(a25, a24); + REG_PAIR(a27, a26); + REG_PAIR(a29, a28); + REG_PAIR(a31, a30); + + REG_PAIR(a1, a0); + REG_PAIR(a3, a2); + REG_PAIR(a5, a4); + REG_PAIR(a7, a6); + REG_PAIR(a9, a8); + REG_PAIR(a11, a10); + REG_PAIR(a13, a12); + + REG_PAIR(a15, a14); + REG_PAIR(sp, dp); +}; + +#ifdef __KERNEL__ + +#include + +#define user_mode(regs) ((((regs)->tsr) & 0x40) != 0) + +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +#define user_stack_pointer(regs) ((regs)->sp) + +extern void show_regs(struct pt_regs *); + +extern asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs); +extern asmlinkage void syscall_trace_exit(struct pt_regs *regs); + +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_C6X_PTRACE_H */ diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c new file mode 100644 index 000000000000..3c494e84444d --- /dev/null +++ b/arch/c6x/kernel/ptrace.c @@ -0,0 +1,187 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * Updated for 2.6.34: Mark Salter + * + * 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 +#include +#include +#include + +#include + +#define PT_REG_SIZE (sizeof(struct pt_regs)) + +/* + * Called by kernel/ptrace.c when detaching. + */ +void ptrace_disable(struct task_struct *child) +{ + /* nothing to do */ +} + +/* + * Get a register number from live pt_regs for the specified task. + */ +static inline long get_reg(struct task_struct *task, int regno) +{ + long *addr = (long *)task_pt_regs(task); + + if (regno == PT_TSR || regno == PT_CSR) + return 0; + + return addr[regno]; +} + +/* + * Write contents of register REGNO in task TASK. + */ +static inline int put_reg(struct task_struct *task, + int regno, + unsigned long data) +{ + unsigned long *addr = (unsigned long *)task_pt_regs(task); + + if (regno != PT_TSR && regno != PT_CSR) + addr[regno] = data; + + return 0; +} + +/* regset get/set implementations */ + +static int gpr_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + struct pt_regs *regs = task_pt_regs(target); + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + regs, + 0, sizeof(*regs)); +} + +static int gpr_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + struct pt_regs *regs = task_pt_regs(target); + + /* Don't copyin TSR or CSR */ + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s, + 0, PT_TSR * sizeof(long)); + if (ret) + return ret; + + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + PT_TSR * sizeof(long), + (PT_TSR + 1) * sizeof(long)); + if (ret) + return ret; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s, + (PT_TSR + 1) * sizeof(long), + PT_CSR * sizeof(long)); + if (ret) + return ret; + + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + PT_CSR * sizeof(long), + (PT_CSR + 1) * sizeof(long)); + if (ret) + return ret; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s, + (PT_CSR + 1) * sizeof(long), -1); + return ret; +} + +enum c6x_regset { + REGSET_GPR, +}; + +static const struct user_regset c6x_regsets[] = { + [REGSET_GPR] = { + .core_note_type = NT_PRSTATUS, + .n = ELF_NGREG, + .size = sizeof(u32), + .align = sizeof(u32), + .get = gpr_get, + .set = gpr_set + }, +}; + +static const struct user_regset_view user_c6x_native_view = { + .name = "tic6x", + .e_machine = EM_TI_C6000, + .regsets = c6x_regsets, + .n = ARRAY_SIZE(c6x_regsets), +}; + +const struct user_regset_view *task_user_regset_view(struct task_struct *task) +{ + return &user_c6x_native_view; +} + +/* + * Perform ptrace request + */ +long arch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) +{ + int ret = 0; + + switch (request) { + /* + * write the word at location addr. + */ + case PTRACE_POKETEXT: + ret = generic_ptrace_pokedata(child, addr, data); + if (ret == 0 && request == PTRACE_POKETEXT) + flush_icache_range(addr, addr + 4); + break; + default: + ret = ptrace_request(child, request, addr, data); + break; + } + + return ret; +} + +/* + * handle tracing of system call entry + * - return the revised system call number or ULONG_MAX to cause ENOSYS + */ +asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs) +{ + if (tracehook_report_syscall_entry(regs)) + /* tracing decided this syscall should not happen, so + * We'll return a bogus call number to get an ENOSYS + * error, but leave the original number in + * regs->orig_a4 + */ + return ULONG_MAX; + + return regs->b0; +} + +/* + * handle tracing of system call exit + */ +asmlinkage void syscall_trace_exit(struct pt_regs *regs) +{ + tracehook_report_syscall_exit(regs, 0); +} -- cgit v1.2.3 From a7f626c1948ab6178d2338831c5ffea7385e9f7f Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:14:47 -0400 Subject: C6X: headers Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/asm-offsets.h | 1 + arch/c6x/include/asm/bitops.h | 105 +++++++++++++++++++++++ arch/c6x/include/asm/byteorder.h | 12 +++ arch/c6x/include/asm/delay.h | 67 +++++++++++++++ arch/c6x/include/asm/elf.h | 113 ++++++++++++++++++++++++ arch/c6x/include/asm/ftrace.h | 6 ++ arch/c6x/include/asm/linkage.h | 30 +++++++ arch/c6x/include/asm/memblock.h | 4 + arch/c6x/include/asm/mmu.h | 18 ++++ arch/c6x/include/asm/mutex.h | 6 ++ arch/c6x/include/asm/page.h | 11 +++ arch/c6x/include/asm/pgtable.h | 81 ++++++++++++++++++ arch/c6x/include/asm/procinfo.h | 28 ++++++ arch/c6x/include/asm/prom.h | 1 + arch/c6x/include/asm/sections.h | 12 +++ arch/c6x/include/asm/setup.h | 32 +++++++ arch/c6x/include/asm/string.h | 21 +++++ arch/c6x/include/asm/swab.h | 54 ++++++++++++ arch/c6x/include/asm/syscall.h | 123 +++++++++++++++++++++++++++ arch/c6x/include/asm/system.h | 168 ++++++++++++++++++++++++++++++++++++ arch/c6x/include/asm/tlb.h | 8 ++ arch/c6x/include/asm/uaccess.h | 107 +++++++++++++++++++++++ arch/c6x/include/asm/unaligned.h | 170 +++++++++++++++++++++++++++++++++++++ 23 files changed, 1178 insertions(+) create mode 100644 arch/c6x/include/asm/asm-offsets.h create mode 100644 arch/c6x/include/asm/bitops.h create mode 100644 arch/c6x/include/asm/byteorder.h create mode 100644 arch/c6x/include/asm/delay.h create mode 100644 arch/c6x/include/asm/elf.h create mode 100644 arch/c6x/include/asm/ftrace.h create mode 100644 arch/c6x/include/asm/linkage.h create mode 100644 arch/c6x/include/asm/memblock.h create mode 100644 arch/c6x/include/asm/mmu.h create mode 100644 arch/c6x/include/asm/mutex.h create mode 100644 arch/c6x/include/asm/page.h create mode 100644 arch/c6x/include/asm/pgtable.h create mode 100644 arch/c6x/include/asm/procinfo.h create mode 100644 arch/c6x/include/asm/prom.h create mode 100644 arch/c6x/include/asm/sections.h create mode 100644 arch/c6x/include/asm/setup.h create mode 100644 arch/c6x/include/asm/string.h create mode 100644 arch/c6x/include/asm/swab.h create mode 100644 arch/c6x/include/asm/syscall.h create mode 100644 arch/c6x/include/asm/system.h create mode 100644 arch/c6x/include/asm/tlb.h create mode 100644 arch/c6x/include/asm/uaccess.h create mode 100644 arch/c6x/include/asm/unaligned.h (limited to 'arch') diff --git a/arch/c6x/include/asm/asm-offsets.h b/arch/c6x/include/asm/asm-offsets.h new file mode 100644 index 000000000000..d370ee36a182 --- /dev/null +++ b/arch/c6x/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h new file mode 100644 index 000000000000..39ab7e874d96 --- /dev/null +++ b/arch/c6x/include/asm/bitops.h @@ -0,0 +1,105 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_BITOPS_H +#define _ASM_C6X_BITOPS_H + +#ifdef __KERNEL__ + +#include + +#include +#include + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/* + * We are lucky, DSP is perfect for bitops: do it in 3 cycles + */ + +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + * Note __ffs(0) = undef, __ffs(1) = 0, __ffs(0x80000000) = 31. + * + */ +static inline unsigned long __ffs(unsigned long x) +{ + asm (" bitr .M1 %0,%0\n" + " nop\n" + " lmbd .L1 1,%0,%0\n" + : "+a"(x)); + + return x; +} + +/* + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +#define ffz(x) __ffs(~(x)) + +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ +static inline int fls(int x) +{ + if (!x) + return 0; + + asm (" lmbd .L1 1,%0,%0\n" : "+a"(x)); + + return 32 - x; +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32. + */ +static inline int ffs(int x) +{ + if (!x) + return 0; + + return __ffs(x) + 1; +} + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#endif /* __KERNEL__ */ +#endif /* _ASM_C6X_BITOPS_H */ diff --git a/arch/c6x/include/asm/byteorder.h b/arch/c6x/include/asm/byteorder.h new file mode 100644 index 000000000000..166038db342b --- /dev/null +++ b/arch/c6x/include/asm/byteorder.h @@ -0,0 +1,12 @@ +#ifndef _ASM_C6X_BYTEORDER_H +#define _ASM_C6X_BYTEORDER_H + +#include + +#ifdef _BIG_ENDIAN +#include +#else /* _BIG_ENDIAN */ +#include +#endif /* _BIG_ENDIAN */ + +#endif /* _ASM_BYTEORDER_H */ diff --git a/arch/c6x/include/asm/delay.h b/arch/c6x/include/asm/delay.h new file mode 100644 index 000000000000..f314c2e9eb54 --- /dev/null +++ b/arch/c6x/include/asm/delay.h @@ -0,0 +1,67 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_DELAY_H +#define _ASM_C6X_DELAY_H + +#include + +extern unsigned int ticks_per_ns_scaled; + +static inline void __delay(unsigned long loops) +{ + uint32_t tmp; + + /* 6 cycles per loop */ + asm volatile (" mv .s1 %0,%1\n" + "0: [%1] b .s1 0b\n" + " add .l1 -6,%0,%0\n" + " cmplt .l1 1,%0,%1\n" + " nop 3\n" + : "+a"(loops), "=A"(tmp)); +} + +static inline void _c6x_tickdelay(unsigned int x) +{ + uint32_t cnt, endcnt; + + asm volatile (" mvc .s2 TSCL,%0\n" + " add .s2x %0,%1,%2\n" + " || mvk .l2 1,B0\n" + "0: [B0] b .s2 0b\n" + " mvc .s2 TSCL,%0\n" + " sub .s2 %0,%2,%0\n" + " cmpgt .l2 0,%0,B0\n" + " nop 2\n" + : "=b"(cnt), "+a"(x), "=b"(endcnt) : : "B0"); +} + +/* use scaled math to avoid slow division */ +#define C6X_NDELAY_SCALE 10 + +static inline void _ndelay(unsigned int n) +{ + _c6x_tickdelay((ticks_per_ns_scaled * n) >> C6X_NDELAY_SCALE); +} + +static inline void _udelay(unsigned int n) +{ + while (n >= 10) { + _ndelay(10000); + n -= 10; + } + while (n-- > 0) + _ndelay(1000); +} + +#define udelay(x) _udelay((unsigned int)(x)) +#define ndelay(x) _ndelay((unsigned int)(x)) + +#endif /* _ASM_C6X_DELAY_H */ diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h new file mode 100644 index 000000000000..d57865ba2c44 --- /dev/null +++ b/arch/c6x/include/asm/elf.h @@ -0,0 +1,113 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_ELF_H +#define _ASM_C6X_ELF_H + +/* + * ELF register definitions.. + */ +#include + +typedef unsigned long elf_greg_t; +typedef unsigned long elf_fpreg_t; + +#define ELF_NGREG 58 +#define ELF_NFPREG 1 + +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000) + +#define elf_check_const_displacement(x) (1) + +/* + * These are used to set parameters in the core dumps. + */ +#ifdef __LITTLE_ENDIAN__ +#define ELF_DATA ELFDATA2LSB +#else +#define ELF_DATA ELFDATA2MSB +#endif + +#define ELF_CLASS ELFCLASS32 +#define ELF_ARCH EM_TI_C6000 + +/* Nothing for now. Need to setup DP... */ +#define ELF_PLAT_INIT(_r) + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_CORE_COPY_REGS(_dest, _regs) \ + memcpy((char *) &_dest, (char *) _regs, \ + sizeof(struct pt_regs)); + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#define SET_PERSONALITY(ex) set_personality(PER_LINUX) + +/* C6X specific section types */ +#define SHT_C6000_UNWIND 0x70000001 +#define SHT_C6000_PREEMPTMAP 0x70000002 +#define SHT_C6000_ATTRIBUTES 0x70000003 + +/* C6X specific DT_ tags */ +#define DT_C6000_DSBT_BASE 0x70000000 +#define DT_C6000_DSBT_SIZE 0x70000001 +#define DT_C6000_PREEMPTMAP 0x70000002 +#define DT_C6000_DSBT_INDEX 0x70000003 + +/* C6X specific relocs */ +#define R_C6000_NONE 0 +#define R_C6000_ABS32 1 +#define R_C6000_ABS16 2 +#define R_C6000_ABS8 3 +#define R_C6000_PCR_S21 4 +#define R_C6000_PCR_S12 5 +#define R_C6000_PCR_S10 6 +#define R_C6000_PCR_S7 7 +#define R_C6000_ABS_S16 8 +#define R_C6000_ABS_L16 9 +#define R_C6000_ABS_H16 10 +#define R_C6000_SBR_U15_B 11 +#define R_C6000_SBR_U15_H 12 +#define R_C6000_SBR_U15_W 13 +#define R_C6000_SBR_S16 14 +#define R_C6000_SBR_L16_B 15 +#define R_C6000_SBR_L16_H 16 +#define R_C6000_SBR_L16_W 17 +#define R_C6000_SBR_H16_B 18 +#define R_C6000_SBR_H16_H 19 +#define R_C6000_SBR_H16_W 20 +#define R_C6000_SBR_GOT_U15_W 21 +#define R_C6000_SBR_GOT_L16_W 22 +#define R_C6000_SBR_GOT_H16_W 23 +#define R_C6000_DSBT_INDEX 24 +#define R_C6000_PREL31 25 +#define R_C6000_COPY 26 +#define R_C6000_ALIGN 253 +#define R_C6000_FPHEAD 254 +#define R_C6000_NOCMP 255 + +#endif /*_ASM_C6X_ELF_H */ diff --git a/arch/c6x/include/asm/ftrace.h b/arch/c6x/include/asm/ftrace.h new file mode 100644 index 000000000000..3701958d3d1c --- /dev/null +++ b/arch/c6x/include/asm/ftrace.h @@ -0,0 +1,6 @@ +#ifndef _ASM_C6X_FTRACE_H +#define _ASM_C6X_FTRACE_H + +/* empty */ + +#endif /* _ASM_C6X_FTRACE_H */ diff --git a/arch/c6x/include/asm/linkage.h b/arch/c6x/include/asm/linkage.h new file mode 100644 index 000000000000..376925c47d57 --- /dev/null +++ b/arch/c6x/include/asm/linkage.h @@ -0,0 +1,30 @@ +#ifndef _ASM_C6X_LINKAGE_H +#define _ASM_C6X_LINKAGE_H + +#ifdef __ASSEMBLER__ + +#define __ALIGN .align 2 +#define __ALIGN_STR ".align 2" + +#ifndef __DSBT__ +#define ENTRY(name) \ + .global name @ \ + __ALIGN @ \ +name: +#else +#define ENTRY(name) \ + .global name @ \ + .hidden name @ \ + __ALIGN @ \ +name: +#endif + +#define ENDPROC(name) \ + .type name, @function @ \ + .size name, . - name + +#endif + +#include + +#endif /* _ASM_C6X_LINKAGE_H */ diff --git a/arch/c6x/include/asm/memblock.h b/arch/c6x/include/asm/memblock.h new file mode 100644 index 000000000000..1181a979a823 --- /dev/null +++ b/arch/c6x/include/asm/memblock.h @@ -0,0 +1,4 @@ +#ifndef _ASM_C6X_MEMBLOCK_H +#define _ASM_C6X_MEMBLOCK_H + +#endif /* _ASM_C6X_MEMBLOCK_H */ diff --git a/arch/c6x/include/asm/mmu.h b/arch/c6x/include/asm/mmu.h new file mode 100644 index 000000000000..41592bf16067 --- /dev/null +++ b/arch/c6x/include/asm/mmu.h @@ -0,0 +1,18 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_MMU_H +#define _ASM_C6X_MMU_H + +typedef struct { + unsigned long end_brk; +} mm_context_t; + +#endif /* _ASM_C6X_MMU_H */ diff --git a/arch/c6x/include/asm/mutex.h b/arch/c6x/include/asm/mutex.h new file mode 100644 index 000000000000..7a7248e0462d --- /dev/null +++ b/arch/c6x/include/asm/mutex.h @@ -0,0 +1,6 @@ +#ifndef _ASM_C6X_MUTEX_H +#define _ASM_C6X_MUTEX_H + +#include + +#endif /* _ASM_C6X_MUTEX_H */ diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h new file mode 100644 index 000000000000..d18e2b0c7aea --- /dev/null +++ b/arch/c6x/include/asm/page.h @@ -0,0 +1,11 @@ +#ifndef _ASM_C6X_PAGE_H +#define _ASM_C6X_PAGE_H + +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#include + +#endif /* _ASM_C6X_PAGE_H */ diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h new file mode 100644 index 000000000000..68c8af4f1f97 --- /dev/null +++ b/arch/c6x/include/asm/pgtable.h @@ -0,0 +1,81 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_PGTABLE_H +#define _ASM_C6X_PGTABLE_H + +#include + +#include +#include + +/* + * All 32bit addresses are effectively valid for vmalloc... + * Sort of meaningless for non-VM targets. + */ +#define VMALLOC_START 0 +#define VMALLOC_END 0xffffffff + +#define pgd_present(pgd) (1) +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) + +#define pmd_offset(a, b) ((void *)0) +#define pmd_none(x) (!pmd_val(x)) +#define pmd_present(x) (pmd_val(x)) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) + +#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ +#define pgprot_noncached(prot) (prot) + +extern void paging_init(void); + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +static inline int pte_file(pte_t pte) +{ + return 0; +} + +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) +extern unsigned long empty_zero_page; + +#define swapper_pg_dir ((pgd_t *) 0) + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) +#define io_remap_pfn_range remap_pfn_range + +#define io_remap_page_range(vma, vaddr, paddr, size, prot) \ + remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + +#include + +#endif /* _ASM_C6X_PGTABLE_H */ diff --git a/arch/c6x/include/asm/procinfo.h b/arch/c6x/include/asm/procinfo.h new file mode 100644 index 000000000000..c139d1e71f87 --- /dev/null +++ b/arch/c6x/include/asm/procinfo.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2010 Texas Instruments Incorporated + * Author: Mark Salter (msalter@redhat.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. + */ +#ifndef _ASM_C6X_PROCINFO_H +#define _ASM_C6X_PROCINFO_H + +#ifdef __KERNEL__ + +struct proc_info_list { + unsigned int cpu_val; + unsigned int cpu_mask; + const char *arch_name; + const char *elf_name; + unsigned int elf_hwcap; +}; + +#else /* __KERNEL__ */ +#include +#warning "Please include asm/elf.h instead" +#endif /* __KERNEL__ */ + +#endif /* _ASM_C6X_PROCINFO_H */ diff --git a/arch/c6x/include/asm/prom.h b/arch/c6x/include/asm/prom.h new file mode 100644 index 000000000000..b4ec95f07518 --- /dev/null +++ b/arch/c6x/include/asm/prom.h @@ -0,0 +1 @@ +/* dummy prom.h; here to make linux/of.h's #includes happy */ diff --git a/arch/c6x/include/asm/sections.h b/arch/c6x/include/asm/sections.h new file mode 100644 index 000000000000..f703989d837a --- /dev/null +++ b/arch/c6x/include/asm/sections.h @@ -0,0 +1,12 @@ +#ifndef _ASM_C6X_SECTIONS_H +#define _ASM_C6X_SECTIONS_H + +#include + +extern char _vectors_start[]; +extern char _vectors_end[]; + +extern char _data_lma[]; +extern char _fdt_start[], _fdt_end[]; + +#endif /* _ASM_C6X_SECTIONS_H */ diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h new file mode 100644 index 000000000000..1808f279f82e --- /dev/null +++ b/arch/c6x/include/asm/setup.h @@ -0,0 +1,32 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_SETUP_H +#define _ASM_C6X_SETUP_H + +#define COMMAND_LINE_SIZE 1024 + +#ifndef __ASSEMBLY__ +extern char c6x_command_line[COMMAND_LINE_SIZE]; + +extern int c6x_add_memory(phys_addr_t start, unsigned long size); + +extern unsigned long ram_start; +extern unsigned long ram_end; + +extern int c6x_num_cores; +extern unsigned int c6x_silicon_rev; +extern unsigned int c6x_devstat; +extern unsigned char c6x_fuse_mac[6]; + +extern void machine_init(unsigned long dt_ptr); + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_C6X_SETUP_H */ diff --git a/arch/c6x/include/asm/string.h b/arch/c6x/include/asm/string.h new file mode 100644 index 000000000000..b21517c80a17 --- /dev/null +++ b/arch/c6x/include/asm/string.h @@ -0,0 +1,21 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_STRING_H +#define _ASM_C6X_STRING_H + +#include +#include + +asmlinkage extern void *memcpy(void *to, const void *from, size_t n); + +#define __HAVE_ARCH_MEMCPY + +#endif /* _ASM_C6X_STRING_H */ diff --git a/arch/c6x/include/asm/swab.h b/arch/c6x/include/asm/swab.h new file mode 100644 index 000000000000..fd4bb0520e5e --- /dev/null +++ b/arch/c6x/include/asm/swab.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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_C6X_SWAB_H +#define _ASM_C6X_SWAB_H + +static inline __attribute_const__ __u16 __c6x_swab16(__u16 val) +{ + asm("swap4 .l1 %0,%0\n" : "+a"(val)); + return val; +} + +static inline __attribute_const__ __u32 __c6x_swab32(__u32 val) +{ + asm("swap4 .l1 %0,%0\n" + "swap2 .l1 %0,%0\n" + : "+a"(val)); + return val; +} + +static inline __attribute_const__ __u64 __c6x_swab64(__u64 val) +{ + asm(" swap2 .s1 %p0,%P0\n" + "|| swap2 .l1 %P0,%p0\n" + " swap4 .l1 %p0,%p0\n" + " swap4 .l1 %P0,%P0\n" + : "+a"(val)); + return val; +} + +static inline __attribute_const__ __u32 __c6x_swahw32(__u32 val) +{ + asm("swap2 .l1 %0,%0\n" : "+a"(val)); + return val; +} + +static inline __attribute_const__ __u32 __c6x_swahb32(__u32 val) +{ + asm("swap4 .l1 %0,%0\n" : "+a"(val)); + return val; +} + +#define __arch_swab16 __c6x_swab16 +#define __arch_swab32 __c6x_swab32 +#define __arch_swab64 __c6x_swab64 +#define __arch_swahw32 __c6x_swahw32 +#define __arch_swahb32 __c6x_swahb32 + +#endif /* _ASM_C6X_SWAB_H */ diff --git a/arch/c6x/include/asm/syscall.h b/arch/c6x/include/asm/syscall.h new file mode 100644 index 000000000000..ae2be315ee9c --- /dev/null +++ b/arch/c6x/include/asm/syscall.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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_C6X_SYSCALL_H +#define __ASM_C6X_SYSCALL_H + +#include +#include + +static inline int syscall_get_nr(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->b0; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + /* do nothing */ +} + +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ + return IS_ERR_VALUE(regs->a4) ? regs->a4 : 0; +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->a4; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->a4 = error ?: val; +} + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, unsigned int i, + unsigned int n, unsigned long *args) +{ + switch (i) { + case 0: + if (!n--) + break; + *args++ = regs->a4; + case 1: + if (!n--) + break; + *args++ = regs->b4; + case 2: + if (!n--) + break; + *args++ = regs->a6; + case 3: + if (!n--) + break; + *args++ = regs->b6; + case 4: + if (!n--) + break; + *args++ = regs->a8; + case 5: + if (!n--) + break; + *args++ = regs->b8; + case 6: + if (!n--) + break; + default: + BUG(); + } +} + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + const unsigned long *args) +{ + switch (i) { + case 0: + if (!n--) + break; + regs->a4 = *args++; + case 1: + if (!n--) + break; + regs->b4 = *args++; + case 2: + if (!n--) + break; + regs->a6 = *args++; + case 3: + if (!n--) + break; + regs->b6 = *args++; + case 4: + if (!n--) + break; + regs->a8 = *args++; + case 5: + if (!n--) + break; + regs->a9 = *args++; + case 6: + if (!n) + break; + default: + BUG(); + } +} + +#endif /* __ASM_C6X_SYSCALLS_H */ diff --git a/arch/c6x/include/asm/system.h b/arch/c6x/include/asm/system.h new file mode 100644 index 000000000000..e076dc0eacc8 --- /dev/null +++ b/arch/c6x/include/asm/system.h @@ -0,0 +1,168 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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. + */ +#ifndef _ASM_C6X_SYSTEM_H +#define _ASM_C6X_SYSTEM_H + +#include +#include + +#define prepare_to_switch() do { } while (0) + +struct task_struct; +struct thread_struct; +asmlinkage void *__switch_to(struct thread_struct *prev, + struct thread_struct *next, + struct task_struct *tsk); + +#define switch_to(prev, next, last) \ + do { \ + current->thread.wchan = (u_long) __builtin_return_address(0); \ + (last) = __switch_to(&(prev)->thread, \ + &(next)->thread, (prev)); \ + mb(); \ + current->thread.wchan = 0; \ + } while (0) + +/* Reset the board */ +#define HARD_RESET_NOW() + +#define get_creg(reg) \ + ({ unsigned int __x; \ + asm volatile ("mvc .s2 " #reg ",%0\n" : "=b"(__x)); __x; }) + +#define set_creg(reg, v) \ + do { unsigned int __x = (unsigned int)(v); \ + asm volatile ("mvc .s2 %0," #reg "\n" : : "b"(__x)); \ + } while (0) + +#define or_creg(reg, n) \ + do { unsigned __x, __n = (unsigned)(n); \ + asm volatile ("mvc .s2 " #reg ",%0\n" \ + "or .l2 %1,%0,%0\n" \ + "mvc .s2 %0," #reg "\n" \ + "nop\n" \ + : "=&b"(__x) : "b"(__n)); \ + } while (0) + +#define and_creg(reg, n) \ + do { unsigned __x, __n = (unsigned)(n); \ + asm volatile ("mvc .s2 " #reg ",%0\n" \ + "and .l2 %1,%0,%0\n" \ + "mvc .s2 %0," #reg "\n" \ + "nop\n" \ + : "=&b"(__x) : "b"(__n)); \ + } while (0) + +#define get_coreid() (get_creg(DNUM) & 0xff) + +/* Set/get IST */ +#define set_ist(x) set_creg(ISTP, x) +#define get_ist() get_creg(ISTP) + +/* + * Exception management + */ +asmlinkage void enable_exception(void); +#define disable_exception() +#define get_except_type() get_creg(EFR) +#define ack_exception(type) set_creg(ECR, 1 << (type)) +#define get_iexcept() get_creg(IERR) +#define set_iexcept(mask) set_creg(IERR, (mask)) + +/* + * Misc. functions + */ +#define nop() asm("NOP\n"); +#define mb() barrier() +#define rmb() barrier() +#define wmb() barrier() +#define set_mb(var, value) do { var = value; mb(); } while (0) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) + +#define xchg(ptr, x) \ + ((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \ + sizeof(*(ptr)))) +#define tas(ptr) xchg((ptr), 1) + +unsigned int _lmbd(unsigned int, unsigned int); +unsigned int _bitr(unsigned int); + +struct __xchg_dummy { unsigned int a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size) +{ + unsigned int tmp; + unsigned long flags; + + local_irq_save(flags); + + switch (size) { + case 1: + tmp = 0; + tmp = *((unsigned char *) ptr); + *((unsigned char *) ptr) = (unsigned char) x; + break; + case 2: + tmp = 0; + tmp = *((unsigned short *) ptr); + *((unsigned short *) ptr) = x; + break; + case 4: + tmp = 0; + tmp = *((unsigned int *) ptr); + *((unsigned int *) ptr) = x; + break; + } + local_irq_restore(flags); + return tmp; +} + +#include + +/* + * 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)) + +#include + +#define _extu(x, s, e) \ + ({ unsigned int __x; \ + asm volatile ("extu .S2 %3,%1,%2,%0\n" : \ + "=b"(__x) : "n"(s), "n"(e), "b"(x)); \ + __x; }) + + +extern unsigned int c6x_core_freq; + +struct pt_regs; + +extern void die(char *str, struct pt_regs *fp, int nr); +extern asmlinkage int process_exception(struct pt_regs *regs); +extern void time_init(void); +extern void free_initmem(void); + +extern void (*c6x_restart)(void); +extern void (*c6x_halt)(void); + +#endif /* _ASM_C6X_SYSTEM_H */ diff --git a/arch/c6x/include/asm/tlb.h b/arch/c6x/include/asm/tlb.h new file mode 100644 index 000000000000..8709e5e29d2d --- /dev/null +++ b/arch/c6x/include/asm/tlb.h @@ -0,0 +1,8 @@ +#ifndef _ASM_C6X_TLB_H +#define _ASM_C6X_TLB_H + +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +#include + +#endif /* _ASM_C6X_TLB_H */ diff --git a/arch/c6x/include/asm/uaccess.h b/arch/c6x/include/asm/uaccess.h new file mode 100644 index 000000000000..453dd263bee3 --- /dev/null +++ b/arch/c6x/include/asm/uaccess.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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_C6X_UACCESS_H +#define _ASM_C6X_UACCESS_H + +#include +#include +#include + +#ifdef CONFIG_ACCESS_CHECK +#define __access_ok _access_ok +#endif + +/* + * __copy_from_user/copy_to_user are based on ones in asm-generic/uaccess.h + * + * C6X supports unaligned 32 and 64 bit loads and stores. + */ +static inline __must_check long __copy_from_user(void *to, + const void __user *from, unsigned long n) +{ + u32 tmp32; + u64 tmp64; + + if (__builtin_constant_p(n)) { + switch (n) { + case 1: + *(u8 *)to = *(u8 __force *)from; + return 0; + case 4: + asm volatile ("ldnw .d1t1 *%2,%0\n" + "nop 4\n" + "stnw .d1t1 %0,*%1\n" + : "=&a"(tmp32) + : "A"(to), "a"(from) + : "memory"); + return 0; + case 8: + asm volatile ("ldndw .d1t1 *%2,%0\n" + "nop 4\n" + "stndw .d1t1 %0,*%1\n" + : "=&a"(tmp64) + : "a"(to), "a"(from) + : "memory"); + return 0; + default: + break; + } + } + + memcpy(to, (const void __force *)from, n); + return 0; +} + +static inline __must_check long __copy_to_user(void __user *to, + const void *from, unsigned long n) +{ + u32 tmp32; + u64 tmp64; + + if (__builtin_constant_p(n)) { + switch (n) { + case 1: + *(u8 __force *)to = *(u8 *)from; + return 0; + case 4: + asm volatile ("ldnw .d1t1 *%2,%0\n" + "nop 4\n" + "stnw .d1t1 %0,*%1\n" + : "=&a"(tmp32) + : "a"(to), "a"(from) + : "memory"); + return 0; + case 8: + asm volatile ("ldndw .d1t1 *%2,%0\n" + "nop 4\n" + "stndw .d1t1 %0,*%1\n" + : "=&a"(tmp64) + : "a"(to), "a"(from) + : "memory"); + return 0; + default: + break; + } + } + + memcpy((void __force *)to, from, n); + return 0; +} + +#define __copy_to_user __copy_to_user +#define __copy_from_user __copy_from_user + +extern int _access_ok(unsigned long addr, unsigned long size); +#ifdef CONFIG_ACCESS_CHECK +#define __access_ok _access_ok +#endif + +#include + +#endif /* _ASM_C6X_UACCESS_H */ diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h new file mode 100644 index 000000000000..b976cb740eaa --- /dev/null +++ b/arch/c6x/include/asm/unaligned.h @@ -0,0 +1,170 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * Rewritten for 2.6.3x: Mark Salter + * + * 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_C6X_UNALIGNED_H +#define _ASM_C6X_UNALIGNED_H + +#include + +/* + * The C64x+ can do unaligned word and dword accesses in hardware + * using special load/store instructions. + */ + +static inline u16 get_unaligned_le16(const void *p) +{ + const u8 *_p = p; + return _p[0] | _p[1] << 8; +} + +static inline u16 get_unaligned_be16(const void *p) +{ + const u8 *_p = p; + return _p[0] << 8 | _p[1]; +} + +static inline void put_unaligned_le16(u16 val, void *p) +{ + u8 *_p = p; + _p[0] = val; + _p[1] = val >> 8; +} + +static inline void put_unaligned_be16(u16 val, void *p) +{ + u8 *_p = p; + _p[0] = val >> 8; + _p[1] = val; +} + +static inline u32 get_unaligned32(const void *p) +{ + u32 val = (u32) p; + asm (" ldnw .d1t1 *%0,%0\n" + " nop 4\n" + : "+a"(val)); + return val; +} + +static inline void put_unaligned32(u32 val, void *p) +{ + asm volatile (" stnw .d2t1 %0,*%1\n" + : : "a"(val), "b"(p) : "memory"); +} + +static inline u64 get_unaligned64(const void *p) +{ + u64 val; + asm volatile (" ldndw .d1t1 *%1,%0\n" + " nop 4\n" + : "=a"(val) : "a"(p)); + return val; +} + +static inline void put_unaligned64(u64 val, const void *p) +{ + asm volatile (" stndw .d2t1 %0,*%1\n" + : : "a"(val), "b"(p) : "memory"); +} + +#ifdef CONFIG_CPU_BIG_ENDIAN + +#define get_unaligned_le32(p) __swab32(get_unaligned32(p)) +#define get_unaligned_le64(p) __swab64(get_unaligned64(p)) +#define get_unaligned_be32(p) get_unaligned32(p) +#define get_unaligned_be64(p) get_unaligned64(p) +#define put_unaligned_le32(v, p) put_unaligned32(__swab32(v), (p)) +#define put_unaligned_le64(v, p) put_unaligned64(__swab64(v), (p)) +#define put_unaligned_be32(v, p) put_unaligned32((v), (p)) +#define put_unaligned_be64(v, p) put_unaligned64((v), (p)) +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be + +#else + +#define get_unaligned_le32(p) get_unaligned32(p) +#define get_unaligned_le64(p) get_unaligned64(p) +#define get_unaligned_be32(p) __swab32(get_unaligned32(p)) +#define get_unaligned_be64(p) __swab64(get_unaligned64(p)) +#define put_unaligned_le32(v, p) put_unaligned32((v), (p)) +#define put_unaligned_le64(v, p) put_unaligned64((v), (p)) +#define put_unaligned_be32(v, p) put_unaligned32(__swab32(v), (p)) +#define put_unaligned_be64(v, p) put_unaligned64(__swab64(v), (p)) +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le + +#endif + +/* + * Cause a link-time error if we try an unaligned access other than + * 1,2,4 or 8 bytes long + */ +extern int __bad_unaligned_access_size(void); + +#define __get_unaligned_le(ptr) (typeof(*(ptr)))({ \ + sizeof(*(ptr)) == 1 ? *(ptr) : \ + (sizeof(*(ptr)) == 2 ? get_unaligned_le16((ptr)) : \ + (sizeof(*(ptr)) == 4 ? get_unaligned_le32((ptr)) : \ + (sizeof(*(ptr)) == 8 ? get_unaligned_le64((ptr)) : \ + __bad_unaligned_access_size()))); \ + }) + +#define __get_unaligned_be(ptr) (__force typeof(*(ptr)))({ \ + sizeof(*(ptr)) == 1 ? *(ptr) : \ + (sizeof(*(ptr)) == 2 ? get_unaligned_be16((ptr)) : \ + (sizeof(*(ptr)) == 4 ? get_unaligned_be32((ptr)) : \ + (sizeof(*(ptr)) == 8 ? get_unaligned_be64((ptr)) : \ + __bad_unaligned_access_size()))); \ + }) + +#define __put_unaligned_le(val, ptr) ({ \ + void *__gu_p = (ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + *(u8 *)__gu_p = (__force u8)(val); \ + break; \ + case 2: \ + put_unaligned_le16((__force u16)(val), __gu_p); \ + break; \ + case 4: \ + put_unaligned_le32((__force u32)(val), __gu_p); \ + break; \ + case 8: \ + put_unaligned_le64((__force u64)(val), __gu_p); \ + break; \ + default: \ + __bad_unaligned_access_size(); \ + break; \ + } \ + (void)0; }) + +#define __put_unaligned_be(val, ptr) ({ \ + void *__gu_p = (ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + *(u8 *)__gu_p = (__force u8)(val); \ + break; \ + case 2: \ + put_unaligned_be16((__force u16)(val), __gu_p); \ + break; \ + case 4: \ + put_unaligned_be32((__force u32)(val), __gu_p); \ + break; \ + case 8: \ + put_unaligned_be64((__force u64)(val), __gu_p); \ + break; \ + default: \ + __bad_unaligned_access_size(); \ + break; \ + } \ + (void)0; }) + +#endif /* _ASM_C6X_UNALIGNED_H */ -- cgit v1.2.3 From 09831ca73443bd819ad7993db5409b19c899ba33 Mon Sep 17 00:00:00 2001 From: Aurelien Jacquiot Date: Tue, 4 Oct 2011 11:15:51 -0400 Subject: C6X: library code Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter Signed-off-by: Aurelien Jacquiot Signed-off-by: Mark Salter Acked-by: Arnd Bergmann --- arch/c6x/include/asm/checksum.h | 34 ++++ arch/c6x/lib/checksum.c | 36 ++++ arch/c6x/lib/csum_64plus.S | 419 ++++++++++++++++++++++++++++++++++++++++ arch/c6x/lib/divi.S | 53 +++++ arch/c6x/lib/divremi.S | 46 +++++ arch/c6x/lib/divremu.S | 87 +++++++++ arch/c6x/lib/divu.S | 98 ++++++++++ arch/c6x/lib/llshl.S | 37 ++++ arch/c6x/lib/llshr.S | 38 ++++ arch/c6x/lib/llshru.S | 38 ++++ arch/c6x/lib/memcpy_64plus.S | 46 +++++ arch/c6x/lib/mpyll.S | 49 +++++ arch/c6x/lib/negll.S | 31 +++ arch/c6x/lib/pop_rts.S | 32 +++ arch/c6x/lib/push_rts.S | 31 +++ arch/c6x/lib/remi.S | 64 ++++++ arch/c6x/lib/remu.S | 82 ++++++++ arch/c6x/lib/strasgi.S | 89 +++++++++ arch/c6x/lib/strasgi_64plus.S | 39 ++++ 19 files changed, 1349 insertions(+) create mode 100644 arch/c6x/include/asm/checksum.h create mode 100644 arch/c6x/lib/checksum.c create mode 100644 arch/c6x/lib/csum_64plus.S create mode 100644 arch/c6x/lib/divi.S create mode 100644 arch/c6x/lib/divremi.S create mode 100644 arch/c6x/lib/divremu.S create mode 100644 arch/c6x/lib/divu.S create mode 100644 arch/c6x/lib/llshl.S create mode 100644 arch/c6x/lib/llshr.S create mode 100644 arch/c6x/lib/llshru.S create mode 100644 arch/c6x/lib/memcpy_64plus.S create mode 100644 arch/c6x/lib/mpyll.S create mode 100644 arch/c6x/lib/negll.S create mode 100644 arch/c6x/lib/pop_rts.S create mode 100644 arch/c6x/lib/push_rts.S create mode 100644 arch/c6x/lib/remi.S create mode 100644 arch/c6x/lib/remu.S create mode 100644 arch/c6x/lib/strasgi.S create mode 100644 arch/c6x/lib/strasgi_64plus.S (limited to 'arch') diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h new file mode 100644 index 000000000000..7246816d6e4d --- /dev/null +++ b/arch/c6x/include/asm/checksum.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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_C6X_CHECKSUM_H +#define _ASM_C6X_CHECKSUM_H + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + unsigned long long tmp; + + asm ("add .d1 %1,%5,%1\n" + "|| addu .l1 %3,%4,%0\n" + "addu .l1 %2,%0,%0\n" +#ifndef CONFIG_CPU_BIG_ENDIAN + "|| shl .s1 %1,8,%1\n" +#endif + "addu .l1 %1,%0,%0\n" + "add .l1 %P0,%p0,%2\n" + : "=&a"(tmp), "+a"(len), "+a"(sum) + : "a" (saddr), "a" (daddr), "a" (proto)); + return sum; +} +#define csum_tcpudp_nofold csum_tcpudp_nofold + +#include + +#endif /* _ASM_C6X_CHECKSUM_H */ diff --git a/arch/c6x/lib/checksum.c b/arch/c6x/lib/checksum.c new file mode 100644 index 000000000000..67cc93b0b932 --- /dev/null +++ b/arch/c6x/lib/checksum.c @@ -0,0 +1,36 @@ +/* + * 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 +#include + +#include + +/* + * copy from fs while checksumming, otherwise like csum_partial + */ +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, int len, + __wsum sum, int *csum_err) +{ + int missing; + + missing = __copy_from_user(dst, src, len); + if (missing) { + memset(dst + len - missing, 0, missing); + *csum_err = -EFAULT; + } else + *csum_err = 0; + + return csum_partial(dst, len, sum); +} +EXPORT_SYMBOL(csum_partial_copy_from_user); + +/* These are from csum_64plus.S */ +EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(csum_partial_copy); +EXPORT_SYMBOL(ip_compute_csum); +EXPORT_SYMBOL(ip_fast_csum); diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S new file mode 100644 index 000000000000..6d2589647227 --- /dev/null +++ b/arch/c6x/lib/csum_64plus.S @@ -0,0 +1,419 @@ +; +; linux/arch/c6x/lib/csum_64plus.s +; +; Port on Texas Instruments TMS320C6x architecture +; +; Copyright (C) 2006, 2009, 2010, 2011 Texas Instruments Incorporated +; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 + +; +;unsigned int csum_partial_copy(const char *src, char * dst, +; int len, int sum) +; +; A4: src +; B4: dst +; A6: len +; B6: sum +; return csum in A4 +; + + .text +ENTRY(csum_partial_copy) + MVC .S2 ILC,B30 + + MV .D1X B6,A31 ; given csum + ZERO .D1 A9 ; csum (a side) +|| ZERO .D2 B9 ; csum (b side) +|| SHRU .S2X A6,2,B5 ; len / 4 + + ;; Check alignment and size + AND .S1 3,A4,A1 +|| AND .S2 3,B4,B0 + OR .L2X B0,A1,B0 ; non aligned condition +|| MVC .S2 B5,ILC +|| MVK .D2 1,B2 +|| MV .D1X B5,A1 ; words condition + [!A1] B .S1 L8 + [B0] BNOP .S1 L6,5 + + SPLOOP 1 + + ;; Main loop for aligned words + LDW .D1T1 *A4++,A7 + NOP 4 + MV .S2X A7,B7 +|| EXTU .S1 A7,0,16,A16 + STW .D2T2 B7,*B4++ +|| MPYU .M2 B7,B2,B8 +|| ADD .L1 A16,A9,A9 + NOP + SPKERNEL 8,0 +|| ADD .L2 B8,B9,B9 + + ZERO .D1 A1 +|| ADD .L1X A9,B9,A9 ; add csum from a and b sides + +L6: + [!A1] BNOP .S1 L8,5 + + ;; Main loop for non-aligned words + SPLOOP 2 + || MVK .L1 1,A2 + + LDNW .D1T1 *A4++,A7 + NOP 3 + + NOP + MV .S2X A7,B7 + || EXTU .S1 A7,0,16,A16 + || MPYU .M1 A7,A2,A8 + + ADD .L1 A16,A9,A9 + SPKERNEL 6,0 + || STNW .D2T2 B7,*B4++ + || ADD .L1 A8,A9,A9 + +L8: AND .S2X 2,A6,B5 + CMPGT .L2 B5,0,B0 + [!B0] BNOP .S1 L82,4 + + ;; Manage half-word + ZERO .L1 A7 +|| ZERO .D1 A8 + +#ifdef CONFIG_CPU_BIG_ENDIAN + + LDBU .D1T1 *A4++,A7 + LDBU .D1T1 *A4++,A8 + NOP 3 + SHL .S1 A7,8,A0 + ADD .S1 A8,A9,A9 + STB .D2T1 A7,*B4++ +|| ADD .S1 A0,A9,A9 + STB .D2T1 A8,*B4++ + +#else + + LDBU .D1T1 *A4++,A7 + LDBU .D1T1 *A4++,A8 + NOP 3 + ADD .S1 A7,A9,A9 + SHL .S1 A8,8,A0 + + STB .D2T1 A7,*B4++ +|| ADD .S1 A0,A9,A9 + STB .D2T1 A8,*B4++ + +#endif + + ;; Manage eventually the last byte +L82: AND .S2X 1,A6,B0 + [!B0] BNOP .S1 L9,5 + +|| ZERO .L1 A7 + +L83: LDBU .D1T1 *A4++,A7 + NOP 4 + + MV .L2X A7,B7 + +#ifdef CONFIG_CPU_BIG_ENDIAN + + STB .D2T2 B7,*B4++ +|| SHL .S1 A7,8,A7 + ADD .S1 A7,A9,A9 + +#else + + STB .D2T2 B7,*B4++ +|| ADD .S1 A7,A9,A9 + +#endif + + ;; Fold the csum +L9: SHRU .S2X A9,16,B0 + [!B0] BNOP .S1 L10,5 + +L91: SHRU .S2X A9,16,B4 +|| EXTU .S1 A9,16,16,A3 + ADD .D1X A3,B4,A9 + + SHRU .S1 A9,16,A0 + [A0] BNOP .S1 L91,5 + +L10: ADD .D1 A31,A9,A9 + MV .D1 A9,A4 + + BNOP .S2 B3,4 + MVC .S2 B30,ILC +ENDPROC(csum_partial_copy) + +; +;unsigned short +;ip_fast_csum(unsigned char *iph, unsigned int ihl) +;{ +; unsigned int checksum = 0; +; unsigned short *tosum = (unsigned short *) iph; +; int len; +; +; len = ihl*4; +; +; if (len <= 0) +; return 0; +; +; while(len) { +; len -= 2; +; checksum += *tosum++; +; } +; if (len & 1) +; checksum += *(unsigned char*) tosum; +; +; while(checksum >> 16) +; checksum = (checksum & 0xffff) + (checksum >> 16); +; +; return ~checksum; +;} +; +; A4: iph +; B4: ihl +; return checksum in A4 +; + .text + +ENTRY(ip_fast_csum) + ZERO .D1 A5 + || MVC .S2 ILC,B30 + SHL .S2 B4,2,B0 + CMPGT .L2 B0,0,B1 + [!B1] BNOP .S1 L15,4 + [!B1] ZERO .D1 A3 + + [!B0] B .S1 L12 + SHRU .S2 B0,1,B0 + MVC .S2 B0,ILC + NOP 3 + + SPLOOP 1 + LDHU .D1T1 *A4++,A3 + NOP 3 + NOP + SPKERNEL 5,0 + || ADD .L1 A3,A5,A5 + +L12: SHRU .S1 A5,16,A0 + [!A0] BNOP .S1 L14,5 + +L13: SHRU .S2X A5,16,B4 + EXTU .S1 A5,16,16,A3 + ADD .D1X A3,B4,A5 + SHRU .S1 A5,16,A0 + [A0] BNOP .S1 L13,5 + +L14: NOT .D1 A5,A3 + EXTU .S1 A3,16,16,A3 + +L15: BNOP .S2 B3,3 + MVC .S2 B30,ILC + MV .D1 A3,A4 +ENDPROC(ip_fast_csum) + +; +;unsigned short +;do_csum(unsigned char *buff, unsigned int len) +;{ +; int odd, count; +; unsigned int result = 0; +; +; if (len <= 0) +; goto out; +; odd = 1 & (unsigned long) buff; +; if (odd) { +;#ifdef __LITTLE_ENDIAN +; result += (*buff << 8); +;#else +; result = *buff; +;#endif +; len--; +; buff++; +; } +; count = len >> 1; /* nr of 16-bit words.. */ +; if (count) { +; if (2 & (unsigned long) buff) { +; result += *(unsigned short *) buff; +; count--; +; len -= 2; +; buff += 2; +; } +; count >>= 1; /* nr of 32-bit words.. */ +; if (count) { +; unsigned int carry = 0; +; do { +; unsigned int w = *(unsigned int *) buff; +; count--; +; buff += 4; +; result += carry; +; result += w; +; carry = (w > result); +; } while (count); +; result += carry; +; result = (result & 0xffff) + (result >> 16); +; } +; if (len & 2) { +; result += *(unsigned short *) buff; +; buff += 2; +; } +; } +; if (len & 1) +;#ifdef __LITTLE_ENDIAN +; result += *buff; +;#else +; result += (*buff << 8); +;#endif +; result = (result & 0xffff) + (result >> 16); +; /* add up carry.. */ +; result = (result & 0xffff) + (result >> 16); +; if (odd) +; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); +;out: +; return result; +;} +; +; A4: buff +; B4: len +; return checksum in A4 +; + +ENTRY(do_csum) + CMPGT .L2 B4,0,B0 + [!B0] BNOP .S1 L26,3 + EXTU .S1 A4,31,31,A0 + + MV .L1 A0,A3 +|| MV .S1X B3,A5 +|| MV .L2 B4,B3 +|| ZERO .D1 A1 + +#ifdef CONFIG_CPU_BIG_ENDIAN + [A0] SUB .L2 B3,1,B3 +|| [A0] LDBU .D1T1 *A4++,A1 +#else + [!A0] BNOP .S1 L21,5 +|| [A0] LDBU .D1T1 *A4++,A0 + SUB .L2 B3,1,B3 +|| SHL .S1 A0,8,A1 +L21: +#endif + SHR .S2 B3,1,B0 + [!B0] BNOP .S1 L24,3 + MVK .L1 2,A0 + AND .L1 A4,A0,A0 + + [!A0] BNOP .S1 L22,5 +|| [A0] LDHU .D1T1 *A4++,A0 + SUB .L2 B0,1,B0 +|| SUB .S2 B3,2,B3 +|| ADD .L1 A0,A1,A1 +L22: + SHR .S2 B0,1,B0 +|| ZERO .L1 A0 + + [!B0] BNOP .S1 L23,5 +|| [B0] MVC .S2 B0,ILC + + SPLOOP 3 + SPMASK L1 +|| MV .L1 A1,A2 +|| LDW .D1T1 *A4++,A1 + + NOP 4 + ADD .L1 A0,A1,A0 + ADD .L1 A2,A0,A2 + + SPKERNEL 1,2 +|| CMPGTU .L1 A1,A2,A0 + + ADD .L1 A0,A2,A6 + EXTU .S1 A6,16,16,A7 + SHRU .S2X A6,16,B0 + NOP 1 + ADD .L1X A7,B0,A1 +L23: + MVK .L2 2,B0 + AND .L2 B3,B0,B0 + [B0] LDHU .D1T1 *A4++,A0 + NOP 4 + [B0] ADD .L1 A0,A1,A1 +L24: + EXTU .S2 B3,31,31,B0 +#ifdef CONFIG_CPU_BIG_ENDIAN + [!B0] BNOP .S1 L25,4 +|| [B0] LDBU .D1T1 *A4,A0 + SHL .S1 A0,8,A0 + ADD .L1 A0,A1,A1 +L25: +#else + [B0] LDBU .D1T1 *A4,A0 + NOP 4 + [B0] ADD .L1 A0,A1,A1 +#endif + EXTU .S1 A1,16,16,A0 + SHRU .S2X A1,16,B0 + NOP 1 + ADD .L1X A0,B0,A0 + SHRU .S1 A0,16,A1 + ADD .L1 A0,A1,A0 + EXTU .S1 A0,16,16,A1 + EXTU .S1 A1,16,24,A2 + + EXTU .S1 A1,24,16,A0 +|| MV .L2X A3,B0 + + [B0] OR .L1 A0,A2,A1 +L26: + NOP 1 + BNOP .S2X A5,4 + MV .L1 A1,A4 +ENDPROC(do_csum) + +;__wsum csum_partial(const void *buff, int len, __wsum wsum) +;{ +; unsigned int sum = (__force unsigned int)wsum; +; unsigned int result = do_csum(buff, len); +; +; /* add in old sum, and carry.. */ +; result += sum; +; if (sum > result) +; result += 1; +; return (__force __wsum)result; +;} +; +ENTRY(csum_partial) + MV .L1X B3,A9 +|| CALLP .S2 do_csum,B3 +|| MV .S1 A6,A8 + BNOP .S2X A9,2 + ADD .L1 A8,A4,A1 + CMPGTU .L1 A8,A1,A0 + ADD .L1 A1,A0,A4 +ENDPROC(csum_partial) + +;unsigned short +;ip_compute_csum(unsigned char *buff, unsigned int len) +; +; A4: buff +; B4: len +; return checksum in A4 + +ENTRY(ip_compute_csum) + MV .L1X B3,A9 +|| CALLP .S2 do_csum,B3 + BNOP .S2X A9,3 + NOT .S1 A4,A4 + CLR .S1 A4,16,31,A4 +ENDPROC(ip_compute_csum) diff --git a/arch/c6x/lib/divi.S b/arch/c6x/lib/divi.S new file mode 100644 index 000000000000..4bde924f2a98 --- /dev/null +++ b/arch/c6x/lib/divi.S @@ -0,0 +1,53 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + ;; ABI considerations for the divide functions + ;; The following registers are call-used: + ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 + ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 + ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 + ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 + ;; + ;; In our implementation, divu and remu are leaf functions, + ;; while both divi and remi call into divu. + ;; A0 is not clobbered by any of the functions. + ;; divu does not clobber B2 either, which is taken advantage of + ;; in remi. + ;; divi uses B5 to hold the original return address during + ;; the call to divu. + ;; remi uses B2 and A5 to hold the input values during the + ;; call to divu. It stores B3 in on the stack. + + .text +ENTRY(__c6xabi_divi) + call .s2 __c6xabi_divu +|| mv .d2 B3, B5 +|| cmpgt .l1 0, A4, A1 +|| cmpgt .l2 0, B4, B1 + + [A1] neg .l1 A4, A4 +|| [B1] neg .l2 B4, B4 +|| xor .s1x A1, B1, A1 + [A1] addkpc .s2 _divu_ret, B3, 4 +_divu_ret: + neg .l1 A4, A4 +|| mv .l2 B3,B5 +|| ret .s2 B5 + nop 5 +ENDPROC(__c6xabi_divi) diff --git a/arch/c6x/lib/divremi.S b/arch/c6x/lib/divremi.S new file mode 100644 index 000000000000..64bc5aa95ad3 --- /dev/null +++ b/arch/c6x/lib/divremi.S @@ -0,0 +1,46 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + .text +ENTRY(__c6xabi_divremi) + stw .d2t2 B3, *B15--[2] +|| cmpgt .l1 0, A4, A1 +|| cmpgt .l2 0, B4, B2 +|| mv .s1 A4, A5 +|| call .s2 __c6xabi_divu + + [A1] neg .l1 A4, A4 +|| [B2] neg .l2 B4, B4 +|| xor .s2x B2, A1, B0 +|| mv .d2 B4, B2 + + [B0] addkpc .s2 _divu_ret_1, B3, 1 + [!B0] addkpc .s2 _divu_ret_2, B3, 1 + nop 2 +_divu_ret_1: + neg .l1 A4, A4 +_divu_ret_2: + ldw .d2t2 *++B15[2], B3 + + mpy32 .m1x A4, B2, A6 + nop 3 + ret .s2 B3 + sub .l1 A5, A6, A5 + nop 4 +ENDPROC(__c6xabi_divremi) diff --git a/arch/c6x/lib/divremu.S b/arch/c6x/lib/divremu.S new file mode 100644 index 000000000000..caa9f23ee167 --- /dev/null +++ b/arch/c6x/lib/divremu.S @@ -0,0 +1,87 @@ +;; Copyright 2011 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + .text +ENTRY(__c6xabi_divremu) + ;; We use a series of up to 31 subc instructions. First, we find + ;; out how many leading zero bits there are in the divisor. This + ;; gives us both a shift count for aligning (shifting) the divisor + ;; to the, and the number of times we have to execute subc. + + ;; At the end, we have both the remainder and most of the quotient + ;; in A4. The top bit of the quotient is computed first and is + ;; placed in A2. + + ;; Return immediately if the dividend is zero. Setting B4 to 1 + ;; is a trick to allow us to leave the following insns in the jump + ;; delay slot without affecting the result. + mv .s2x A4, B1 + + [b1] lmbd .l2 1, B4, B1 +||[!b1] b .s2 B3 ; RETURN A +||[!b1] mvk .d2 1, B4 + +||[!b1] zero .s1 A5 + mv .l1x B1, A6 +|| shl .s2 B4, B1, B4 + + ;; The loop performs a maximum of 28 steps, so we do the + ;; first 3 here. + cmpltu .l1x A4, B4, A2 + [!A2] sub .l1x A4, B4, A4 +|| shru .s2 B4, 1, B4 +|| xor .s1 1, A2, A2 + + shl .s1 A2, 31, A2 +|| [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + + ;; RETURN A may happen here (note: must happen before the next branch) +__divremu0: + cmpgt .l2 B1, 7, B0 +|| [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 +|| [b0] b .s1 __divremu0 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + [b1] subc .l1x A4,B4,A4 +|| [b1] add .s2 -1, B1, B1 + ;; loop backwards branch happens here + + ret .s2 B3 +|| mvk .s1 32, A1 + sub .l1 A1, A6, A6 +|| extu .s1 A4, A6, A5 + shl .s1 A4, A6, A4 + shru .s1 A4, 1, A4 +|| sub .l1 A6, 1, A6 + or .l1 A2, A4, A4 + shru .s1 A4, A6, A4 + nop +ENDPROC(__c6xabi_divremu) diff --git a/arch/c6x/lib/divu.S b/arch/c6x/lib/divu.S new file mode 100644 index 000000000000..64af3c006dd3 --- /dev/null +++ b/arch/c6x/lib/divu.S @@ -0,0 +1,98 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + ;; ABI considerations for the divide functions + ;; The following registers are call-used: + ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 + ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 + ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 + ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 + ;; + ;; In our implementation, divu and remu are leaf functions, + ;; while both divi and remi call into divu. + ;; A0 is not clobbered by any of the functions. + ;; divu does not clobber B2 either, which is taken advantage of + ;; in remi. + ;; divi uses B5 to hold the original return address during + ;; the call to divu. + ;; remi uses B2 and A5 to hold the input values during the + ;; call to divu. It stores B3 in on the stack. + + .text +ENTRY(__c6xabi_divu) + ;; We use a series of up to 31 subc instructions. First, we find + ;; out how many leading zero bits there are in the divisor. This + ;; gives us both a shift count for aligning (shifting) the divisor + ;; to the, and the number of times we have to execute subc. + + ;; At the end, we have both the remainder and most of the quotient + ;; in A4. The top bit of the quotient is computed first and is + ;; placed in A2. + + ;; Return immediately if the dividend is zero. + mv .s2x A4, B1 + [B1] lmbd .l2 1, B4, B1 +|| [!B1] b .s2 B3 ; RETURN A +|| [!B1] mvk .d2 1, B4 + mv .l1x B1, A6 +|| shl .s2 B4, B1, B4 + + ;; The loop performs a maximum of 28 steps, so we do the + ;; first 3 here. + cmpltu .l1x A4, B4, A2 + [!A2] sub .l1x A4, B4, A4 +|| shru .s2 B4, 1, B4 +|| xor .s1 1, A2, A2 + + shl .s1 A2, 31, A2 +|| [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + + ;; RETURN A may happen here (note: must happen before the next branch) +_divu_loop: + cmpgt .l2 B1, 7, B0 +|| [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 +|| [B0] b .s1 _divu_loop + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + ;; loop backwards branch happens here + + ret .s2 B3 +|| mvk .s1 32, A1 + sub .l1 A1, A6, A6 + shl .s1 A4, A6, A4 + shru .s1 A4, 1, A4 +|| sub .l1 A6, 1, A6 + or .l1 A2, A4, A4 + shru .s1 A4, A6, A4 + nop +ENDPROC(__c6xabi_divu) diff --git a/arch/c6x/lib/llshl.S b/arch/c6x/lib/llshl.S new file mode 100644 index 000000000000..7b105e2d1b78 --- /dev/null +++ b/arch/c6x/lib/llshl.S @@ -0,0 +1,37 @@ +;; Copyright (C) 2010 Texas Instruments Incorporated +;; Contributed by Mark Salter . +;; +;; 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. + +;; uint64_t __c6xabi_llshl(uint64_t val, uint shift) + +#include + + .text +ENTRY(__c6xabi_llshl) + mv .l1x B4,A1 + [!A1] b .s2 B3 ; just return if zero shift + mvk .s1 32,A0 + sub .d1 A0,A1,A0 + cmplt .l1 0,A0,A2 + [A2] shru .s1 A4,A0,A0 + [!A2] neg .l1 A0,A5 +|| [A2] shl .s1 A5,A1,A5 + [!A2] shl .s1 A4,A5,A5 +|| [A2] or .d1 A5,A0,A5 +|| [!A2] mvk .l1 0,A4 + [A2] shl .s1 A4,A1,A4 + bnop .s2 B3,5 +ENDPROC(__c6xabi_llshl) diff --git a/arch/c6x/lib/llshr.S b/arch/c6x/lib/llshr.S new file mode 100644 index 000000000000..fde1bec7cf5a --- /dev/null +++ b/arch/c6x/lib/llshr.S @@ -0,0 +1,38 @@ +;; Copyright (C) 2010 Texas Instruments Incorporated +;; Contributed by Mark Salter . +;; +;; 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. + +;; uint64_t __c6xabi_llshr(uint64_t val, uint shift) + +#include + + .text +ENTRY(__c6xabi_llshr) + mv .l1x B4,A1 + [!A1] b .s2 B3 ; return if zero shift count + mvk .s1 32,A0 + sub .d1 A0,A1,A0 + cmplt .l1 0,A0,A2 + [A2] shl .s1 A5,A0,A0 + nop + [!A2] neg .l1 A0,A4 +|| [A2] shru .s1 A4,A1,A4 + [!A2] shr .s1 A5,A4,A4 +|| [A2] or .d1 A4,A0,A4 + [!A2] shr .s1 A5,0x1f,A5 + [A2] shr .s1 A5,A1,A5 + bnop .s2 B3,5 +ENDPROC(__c6xabi_llshr) diff --git a/arch/c6x/lib/llshru.S b/arch/c6x/lib/llshru.S new file mode 100644 index 000000000000..596ae3ff5c0f --- /dev/null +++ b/arch/c6x/lib/llshru.S @@ -0,0 +1,38 @@ +;; Copyright (C) 2010 Texas Instruments Incorporated +;; Contributed by Mark Salter . +;; +;; 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. + +;; uint64_t __c6xabi_llshru(uint64_t val, uint shift) + +#include + + .text +ENTRY(__c6xabi_llshru) + mv .l1x B4,A1 + [!A1] b .s2 B3 ; return if zero shift count + mvk .s1 32,A0 + sub .d1 A0,A1,A0 + cmplt .l1 0,A0,A2 + [A2] shl .s1 A5,A0,A0 + nop + [!A2] neg .l1 A0,A4 +|| [A2] shru .s1 A4,A1,A4 + [!A2] shru .s1 A5,A4,A4 +|| [A2] or .d1 A4,A0,A4 +|| [!A2] mvk .l1 0,A5 + [A2] shru .s1 A5,A1,A5 + bnop .s2 B3,5 +ENDPROC(__c6xabi_llshru) diff --git a/arch/c6x/lib/memcpy_64plus.S b/arch/c6x/lib/memcpy_64plus.S new file mode 100644 index 000000000000..0bbc2cbf9318 --- /dev/null +++ b/arch/c6x/lib/memcpy_64plus.S @@ -0,0 +1,46 @@ +; Port on Texas Instruments TMS320C6x architecture +; +; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated +; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 + + .text + +ENTRY(memcpy) + AND .L1 0x1,A6,A0 + || AND .S1 0x2,A6,A1 + || AND .L2X 0x4,A6,B0 + || MV .D1 A4,A3 + || MVC .S2 ILC,B2 + + [A0] LDB .D2T1 *B4++,A5 + [A1] LDB .D2T1 *B4++,A7 + [A1] LDB .D2T1 *B4++,A8 + [B0] LDNW .D2T1 *B4++,A9 + || SHRU .S2X A6,0x3,B1 + [!B1] BNOP .S2 B3,1 + + [A0] STB .D1T1 A5,*A3++ + ||[B1] MVC .S2 B1,ILC + [A1] STB .D1T1 A7,*A3++ + [A1] STB .D1T1 A8,*A3++ + [B0] STNW .D1T1 A9,*A3++ ; return when len < 8 + + SPLOOP 2 + + LDNDW .D2T1 *B4++,A9:A8 + NOP 3 + + NOP + SPKERNEL 0,0 + || STNDW .D1T1 A9:A8,*A3++ + + BNOP .S2 B3,4 + MVC .S2 B2,ILC +ENDPROC(memcpy) diff --git a/arch/c6x/lib/mpyll.S b/arch/c6x/lib/mpyll.S new file mode 100644 index 000000000000..f1034418b4db --- /dev/null +++ b/arch/c6x/lib/mpyll.S @@ -0,0 +1,49 @@ +;; Copyright (C) 2010 Texas Instruments Incorporated +;; Contributed by Mark Salter . +;; +;; 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 + + ;; uint64_t __c6xabi_mpyll(uint64_t x, uint64_t y) + ;; + ;; 64x64 multiply + ;; First compute partial results using 32-bit parts of x and y: + ;; + ;; b63 b32 b31 b0 + ;; ----------------------------- + ;; | 1 | 0 | + ;; ----------------------------- + ;; + ;; P0 = X0*Y0 + ;; P1 = X0*Y1 + X1*Y0 + ;; P2 = X1*Y1 + ;; + ;; result = (P2 << 64) + (P1 << 32) + P0 + ;; + ;; Since the result is also 64-bit, we can skip the P2 term. + + .text +ENTRY(__c6xabi_mpyll) + mpy32u .m1x A4,B4,A1:A0 ; X0*Y0 + b .s2 B3 + || mpy32u .m2x B5,A4,B1:B0 ; X0*Y1 (don't need upper 32-bits) + || mpy32u .m1x A5,B4,A3:A2 ; X1*Y0 (don't need upper 32-bits) + nop + nop + mv .s1 A0,A4 + add .l1x A2,B0,A5 + add .s1 A1,A5,A5 +ENDPROC(__c6xabi_mpyll) diff --git a/arch/c6x/lib/negll.S b/arch/c6x/lib/negll.S new file mode 100644 index 000000000000..82f4bcec9afb --- /dev/null +++ b/arch/c6x/lib/negll.S @@ -0,0 +1,31 @@ +;; Copyright (C) 2010 Texas Instruments Incorporated +;; Contributed by Mark Salter . +;; +;; 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. + +;; int64_t __c6xabi_negll(int64_t val) + +#include + + .text +ENTRY(__c6xabi_negll) + b .s2 B3 + mvk .l1 0,A0 + subu .l1 A0,A4,A3:A2 + sub .l1 A0,A5,A0 +|| ext .s1 A3,24,24,A5 + add .l1 A5,A0,A5 + mv .s1 A2,A4 +ENDPROC(__c6xabi_negll) diff --git a/arch/c6x/lib/pop_rts.S b/arch/c6x/lib/pop_rts.S new file mode 100644 index 000000000000..d7d96c70e9e7 --- /dev/null +++ b/arch/c6x/lib/pop_rts.S @@ -0,0 +1,32 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + .text + +ENTRY(__c6xabi_pop_rts) + lddw .d2t2 *++B15, B3:B2 + lddw .d2t1 *++B15, A11:A10 + lddw .d2t2 *++B15, B11:B10 + lddw .d2t1 *++B15, A13:A12 + lddw .d2t2 *++B15, B13:B12 + lddw .d2t1 *++B15, A15:A14 +|| b .s2 B3 + ldw .d2t2 *++B15[2], B14 + nop 4 +ENDPROC(__c6xabi_pop_rts) diff --git a/arch/c6x/lib/push_rts.S b/arch/c6x/lib/push_rts.S new file mode 100644 index 000000000000..f6e3db3b6065 --- /dev/null +++ b/arch/c6x/lib/push_rts.S @@ -0,0 +1,31 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + .text + +ENTRY(__c6xabi_push_rts) + stw .d2t2 B14, *B15--[2] + stdw .d2t1 A15:A14, *B15-- +|| b .s2x A3 + stdw .d2t2 B13:B12, *B15-- + stdw .d2t1 A13:A12, *B15-- + stdw .d2t2 B11:B10, *B15-- + stdw .d2t1 A11:A10, *B15-- + stdw .d2t2 B3:B2, *B15-- +ENDPROC(__c6xabi_push_rts) diff --git a/arch/c6x/lib/remi.S b/arch/c6x/lib/remi.S new file mode 100644 index 000000000000..6f2ca18c3f98 --- /dev/null +++ b/arch/c6x/lib/remi.S @@ -0,0 +1,64 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + ;; ABI considerations for the divide functions + ;; The following registers are call-used: + ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 + ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 + ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 + ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 + ;; + ;; In our implementation, divu and remu are leaf functions, + ;; while both divi and remi call into divu. + ;; A0 is not clobbered by any of the functions. + ;; divu does not clobber B2 either, which is taken advantage of + ;; in remi. + ;; divi uses B5 to hold the original return address during + ;; the call to divu. + ;; remi uses B2 and A5 to hold the input values during the + ;; call to divu. It stores B3 in on the stack. + + .text + +ENTRY(__c6xabi_remi) + stw .d2t2 B3, *B15--[2] +|| cmpgt .l1 0, A4, A1 +|| cmpgt .l2 0, B4, B2 +|| mv .s1 A4, A5 +|| call .s2 __c6xabi_divu + + [A1] neg .l1 A4, A4 +|| [B2] neg .l2 B4, B4 +|| xor .s2x B2, A1, B0 +|| mv .d2 B4, B2 + + [B0] addkpc .s2 _divu_ret_1, B3, 1 + [!B0] addkpc .s2 _divu_ret_2, B3, 1 + nop 2 +_divu_ret_1: + neg .l1 A4, A4 +_divu_ret_2: + ldw .d2t2 *++B15[2], B3 + + mpy32 .m1x A4, B2, A6 + nop 3 + ret .s2 B3 + sub .l1 A5, A6, A4 + nop 4 +ENDPROC(__c6xabi_remi) diff --git a/arch/c6x/lib/remu.S b/arch/c6x/lib/remu.S new file mode 100644 index 000000000000..3fae719185ab --- /dev/null +++ b/arch/c6x/lib/remu.S @@ -0,0 +1,82 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + ;; ABI considerations for the divide functions + ;; The following registers are call-used: + ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 + ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 + ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 + ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 + ;; + ;; In our implementation, divu and remu are leaf functions, + ;; while both divi and remi call into divu. + ;; A0 is not clobbered by any of the functions. + ;; divu does not clobber B2 either, which is taken advantage of + ;; in remi. + ;; divi uses B5 to hold the original return address during + ;; the call to divu. + ;; remi uses B2 and A5 to hold the input values during the + ;; call to divu. It stores B3 in on the stack. + + + .text + +ENTRY(__c6xabi_remu) + ;; The ABI seems designed to prevent these functions calling each other, + ;; so we duplicate most of the divsi3 code here. + mv .s2x A4, B1 + lmbd .l2 1, B4, B1 +|| [!B1] b .s2 B3 ; RETURN A +|| [!B1] mvk .d2 1, B4 + + mv .l1x B1, A7 +|| shl .s2 B4, B1, B4 + + cmpltu .l1x A4, B4, A1 + [!A1] sub .l1x A4, B4, A4 + shru .s2 B4, 1, B4 + +_remu_loop: + cmpgt .l2 B1, 7, B0 +|| [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + ;; RETURN A may happen here (note: must happen before the next branch) + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 +|| [B0] b .s1 _remu_loop + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + ;; loop backwards branch happens here + + ret .s2 B3 + [B1] subc .l1x A4,B4,A4 +|| [B1] add .s2 -1, B1, B1 + [B1] subc .l1x A4,B4,A4 + + extu .s1 A4, A7, A4 + nop 2 +ENDPROC(__c6xabi_remu) diff --git a/arch/c6x/lib/strasgi.S b/arch/c6x/lib/strasgi.S new file mode 100644 index 000000000000..de2740765536 --- /dev/null +++ b/arch/c6x/lib/strasgi.S @@ -0,0 +1,89 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + .text + +ENTRY(__c6xabi_strasgi) + ;; This is essentially memcpy, with alignment known to be at least + ;; 4, and the size a multiple of 4 greater than or equal to 28. + ldw .d2t1 *B4++, A0 +|| mvk .s2 16, B1 + ldw .d2t1 *B4++, A1 +|| mvk .s2 20, B2 +|| sub .d1 A6, 24, A6 + ldw .d2t1 *B4++, A5 + ldw .d2t1 *B4++, A7 +|| mv .l2x A6, B7 + ldw .d2t1 *B4++, A8 + ldw .d2t1 *B4++, A9 +|| mv .s2x A0, B5 +|| cmpltu .l2 B2, B7, B0 + +_strasgi_loop: + stw .d1t2 B5, *A4++ +|| [B0] ldw .d2t1 *B4++, A0 +|| mv .s2x A1, B5 +|| mv .l2 B7, B6 + + [B0] sub .d2 B6, 24, B7 +|| [B0] b .s2 _strasgi_loop +|| cmpltu .l2 B1, B6, B0 + + [B0] ldw .d2t1 *B4++, A1 +|| stw .d1t2 B5, *A4++ +|| mv .s2x A5, B5 +|| cmpltu .l2 12, B6, B0 + + [B0] ldw .d2t1 *B4++, A5 +|| stw .d1t2 B5, *A4++ +|| mv .s2x A7, B5 +|| cmpltu .l2 8, B6, B0 + + [B0] ldw .d2t1 *B4++, A7 +|| stw .d1t2 B5, *A4++ +|| mv .s2x A8, B5 +|| cmpltu .l2 4, B6, B0 + + [B0] ldw .d2t1 *B4++, A8 +|| stw .d1t2 B5, *A4++ +|| mv .s2x A9, B5 +|| cmpltu .l2 0, B6, B0 + + [B0] ldw .d2t1 *B4++, A9 +|| stw .d1t2 B5, *A4++ +|| mv .s2x A0, B5 +|| cmpltu .l2 B2, B7, B0 + + ;; loop back branch happens here + + cmpltu .l2 B1, B6, B0 +|| ret .s2 b3 + + [B0] stw .d1t1 A1, *A4++ +|| cmpltu .l2 12, B6, B0 + [B0] stw .d1t1 A5, *A4++ +|| cmpltu .l2 8, B6, B0 + [B0] stw .d1t1 A7, *A4++ +|| cmpltu .l2 4, B6, B0 + [B0] stw .d1t1 A8, *A4++ +|| cmpltu .l2 0, B6, B0 + [B0] stw .d1t1 A9, *A4++ + + ;; return happens here +ENDPROC(__c6xabi_strasgi) diff --git a/arch/c6x/lib/strasgi_64plus.S b/arch/c6x/lib/strasgi_64plus.S new file mode 100644 index 000000000000..c9fd159b5fa2 --- /dev/null +++ b/arch/c6x/lib/strasgi_64plus.S @@ -0,0 +1,39 @@ +;; Copyright 2010 Free Software Foundation, Inc. +;; Contributed by Bernd Schmidt . +;; +;; 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 + + .text + +ENTRY(__c6xabi_strasgi_64plus) + shru .s2x a6, 2, b31 +|| mv .s1 a4, a30 +|| mv .d2 b4, b30 + + add .s2 -4, b31, b31 + + sploopd 1 +|| mvc .s2 b31, ilc + ldw .d2t2 *b30++, b31 + nop 4 + mv .s1x b31,a31 + spkernel 6, 0 +|| stw .d1t1 a31, *a30++ + + ret .s2 b3 + nop 5 +ENDPROC(__c6xabi_strasgi_64plus) -- cgit v1.2.3 From 69910a284cee7864c9bf96e13505a4ab35ab8dce Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Tue, 4 Oct 2011 11:17:47 -0400 Subject: C6X: general SoC support This patch provides a soc_ops struct which provides hooks for SoC functionality which doesn't fit well into other places. Signed-off-by: Mark Salter Signed-off-by: Aurelien Jacquiot Acked-by: Arnd Bergmann --- arch/c6x/include/asm/soc.h | 35 ++++++++++++++++++ arch/c6x/kernel/soc.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 arch/c6x/include/asm/soc.h create mode 100644 arch/c6x/kernel/soc.c (limited to 'arch') diff --git a/arch/c6x/include/asm/soc.h b/arch/c6x/include/asm/soc.h new file mode 100644 index 000000000000..43f50159e59b --- /dev/null +++ b/arch/c6x/include/asm/soc.h @@ -0,0 +1,35 @@ +/* + * Miscellaneous SoC-specific hooks. + * + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Author: Mark Salter + * + * 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_C6X_SOC_H +#define _ASM_C6X_SOC_H + +struct soc_ops { + /* Return active exception event or -1 if none */ + int (*get_exception)(void); + + /* Assert an event */ + void (*assert_event)(unsigned int evt); +}; + +extern struct soc_ops soc_ops; + +extern int soc_get_exception(void); +extern void soc_assert_event(unsigned int event); +extern int soc_mac_addr(unsigned int index, u8 *addr); + +/* + * for mmio on SoC devices. regs are always same byte order as cpu. + */ +#define soc_readl(addr) __raw_readl(addr) +#define soc_writel(b, addr) __raw_writel((b), (addr)) + +#endif /* _ASM_C6X_SOC_H */ diff --git a/arch/c6x/kernel/soc.c b/arch/c6x/kernel/soc.c new file mode 100644 index 000000000000..dd45bc39af0e --- /dev/null +++ b/arch/c6x/kernel/soc.c @@ -0,0 +1,91 @@ +/* + * Miscellaneous SoC-specific hooks. + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 +#include +#include +#include +#include +#include + +struct soc_ops soc_ops; + +int soc_get_exception(void) +{ + if (!soc_ops.get_exception) + return -1; + return soc_ops.get_exception(); +} + +void soc_assert_event(unsigned int evt) +{ + if (soc_ops.assert_event) + soc_ops.assert_event(evt); +} + +static u8 cmdline_mac[6]; + +static int __init get_mac_addr_from_cmdline(char *str) +{ + int count, i, val; + + for (count = 0; count < 6 && *str; count++, str += 3) { + if (!isxdigit(str[0]) || !isxdigit(str[1])) + return 0; + if (str[2] != ((count < 5) ? ':' : '\0')) + return 0; + + for (i = 0, val = 0; i < 2; i++) { + val = val << 4; + val |= isdigit(str[i]) ? + str[i] - '0' : toupper(str[i]) - 'A' + 10; + } + cmdline_mac[count] = val; + } + return 1; +} +__setup("emac_addr=", get_mac_addr_from_cmdline); + +/* + * Setup the MAC address for SoC ethernet devices. + * + * Before calling this function, the ethernet driver will have + * initialized the addr with local-mac-address from the device + * tree (if found). Allow command line to override, but not + * the fused address. + */ +int soc_mac_addr(unsigned int index, u8 *addr) +{ + int i, have_dt_mac = 0, have_cmdline_mac = 0, have_fuse_mac = 0; + + for (i = 0; i < 6; i++) { + if (cmdline_mac[i]) + have_cmdline_mac = 1; + if (c6x_fuse_mac[i]) + have_fuse_mac = 1; + if (addr[i]) + have_dt_mac = 1; + } + + /* cmdline overrides all */ + if (have_cmdline_mac) + memcpy(addr, cmdline_mac, 6); + else if (!have_dt_mac) { + if (have_fuse_mac) + memcpy(addr, c6x_fuse_mac, 6); + else + random_ether_addr(addr); + } + + /* adjust for specific EMAC device */ + addr[5] += index * c6x_num_cores; + return 1; +} +EXPORT_SYMBOL_GPL(soc_mac_addr); -- cgit v1.2.3 From 6bbfd8975cf3b78aadd1513a25bf7b5c04866a6f Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Tue, 4 Oct 2011 11:18:46 -0400 Subject: C6X: EMIF - External Memory Interface Several SoC parts provide a simple bridge to support external memory mapped devices. This code probes the device tree for an EMIF node and sets up the bridge registers if such a node is found. Beyond initial set up, there is no further need to access the bridge control registers. External devices on the bus are accessed through their MMIO registers using suitable drivers. The bridge hardware does provide for timeout and other error interrupts, but these are not yet supported. Signed-off-by: Mark Salter Signed-off-by: Aurelien Jacquiot Acked-by: Arnd Bergmann --- arch/c6x/platforms/emif.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 arch/c6x/platforms/emif.c (limited to 'arch') diff --git a/arch/c6x/platforms/emif.c b/arch/c6x/platforms/emif.c new file mode 100644 index 000000000000..6a0d4ff972ed --- /dev/null +++ b/arch/c6x/platforms/emif.c @@ -0,0 +1,88 @@ +/* + * External Memory Interface + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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 +#include +#include +#include +#include + +#define NUM_EMIFA_CHIP_ENABLES 4 + +struct emifa_regs { + u32 midr; + u32 stat; + u32 reserved1[6]; + u32 bprio; + u32 reserved2[23]; + u32 ce_config; + u32 cecfg[NUM_EMIFA_CHIP_ENABLES]; + u32 reserved3[4]; + u32 awcc; + u32 reserved4[7]; + u32 intraw; + u32 intmsk; + u32 intmskset; + u32 intmskclr; +}; + +static struct of_device_id emifa_match[] __initdata = { + { .compatible = "ti,c64x+emifa" }, + {} +}; + +/* + * Parse device tree for existence of an EMIF (External Memory Interface) + * and initialize it if found. + */ +static int __init c6x_emifa_init(void) +{ + struct emifa_regs __iomem *regs; + struct device_node *node; + const __be32 *p; + u32 val; + int i, len, err; + + node = of_find_matching_node(NULL, emifa_match); + if (!node) + return 0; + + regs = of_iomap(node, 0); + if (!regs) + return 0; + + /* look for a dscr-based enable for emifa pin buffers */ + err = of_property_read_u32_array(node, "ti,dscr-dev-enable", &val, 1); + if (!err) + dscr_set_devstate(val, DSCR_DEVSTATE_ENABLED); + + /* set up the chip enables */ + p = of_get_property(node, "ti,emifa-ce-config", &len); + if (p) { + len /= sizeof(u32); + if (len > NUM_EMIFA_CHIP_ENABLES) + len = NUM_EMIFA_CHIP_ENABLES; + for (i = 0; i <= len; i++) + soc_writel(be32_to_cpup(&p[i]), ®s->cecfg[i]); + } + + err = of_property_read_u32_array(node, "ti,emifa-burst-priority", &val, 1); + if (!err) + soc_writel(val, ®s->bprio); + + err = of_property_read_u32_array(node, "ti,emifa-async-wait-control", &val, 1); + if (!err) + soc_writel(val, ®s->awcc); + + iounmap(regs); + of_node_put(node); + return 0; +} +pure_initcall(c6x_emifa_init); -- cgit v1.2.3 From 9de98fb4ec4c91597feedc521120c16fca54a5b6 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Tue, 4 Oct 2011 11:20:28 -0400 Subject: C6X: DSCR - Device State Configuration Registers All SoCs provide an area of device configuration registers called the DSCR. The location of specific registers as well as their use varies considerably from implementation to implementation. Rather than having to rely on additional SoC-specific DSCR code for each new supported SoC, this code generalize things as much as possible using device tree properties. Initialization must take place early on (setup_arch time) in case the event timer device needs to be enable via the DSCR. Signed-off-by: Mark Salter Signed-off-by: Aurelien Jacquiot Acked-by: Arnd Bergmann --- arch/c6x/include/asm/dscr.h | 34 +++ arch/c6x/platforms/dscr.c | 598 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 632 insertions(+) create mode 100644 arch/c6x/include/asm/dscr.h create mode 100644 arch/c6x/platforms/dscr.c (limited to 'arch') diff --git a/arch/c6x/include/asm/dscr.h b/arch/c6x/include/asm/dscr.h new file mode 100644 index 000000000000..561ba8332042 --- /dev/null +++ b/arch/c6x/include/asm/dscr.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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_C6X_DSCR_H +#define _ASM_C6X_DSCR_H + +enum dscr_devstate_t { + DSCR_DEVSTATE_ENABLED, + DSCR_DEVSTATE_DISABLED, +}; + +/* + * Set the device state of the device with the given ID. + * + * Individual drivers should use this to enable or disable the + * hardware device. The devid used to identify the device being + * controlled should be a property in the device's tree node. + */ +extern void dscr_set_devstate(int devid, enum dscr_devstate_t state); + +/* + * Assert or de-assert an RMII reset. + */ +extern void dscr_rmii_reset(int id, int assert); + +extern void dscr_probe(void); + +#endif /* _ASM_C6X_DSCR_H */ diff --git a/arch/c6x/platforms/dscr.c b/arch/c6x/platforms/dscr.c new file mode 100644 index 000000000000..f848a65ee646 --- /dev/null +++ b/arch/c6x/platforms/dscr.c @@ -0,0 +1,598 @@ +/* + * Device State Control Registers driver + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter + * + * 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. + */ + +/* + * The Device State Control Registers (DSCR) provide SoC level control over + * a number of peripherals. Details vary considerably among the various SoC + * parts. In general, the DSCR block will provide one or more configuration + * registers often protected by a lock register. One or more key values must + * be written to a lock register in order to unlock the configuration register. + * The configuration register may be used to enable (and disable in some + * cases) SoC pin drivers, peripheral clock sources (internal or pin), etc. + * In some cases, a configuration register is write once or the individual + * bits are write once. That is, you may be able to enable a device, but + * will not be able to disable it. + * + * In addition to device configuration, the DSCR block may provide registers + * which are used to reset SoC peripherals, provide device ID information, + * provide MAC addresses, and other miscellaneous functions. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_DEVSTATE_IDS 32 +#define MAX_DEVCTL_REGS 8 +#define MAX_DEVSTAT_REGS 8 +#define MAX_LOCKED_REGS 4 +#define MAX_SOC_EMACS 2 + +struct rmii_reset_reg { + u32 reg; + u32 mask; +}; + +/* + * Some registerd may be locked. In order to write to these + * registers, the key value must first be written to the lockreg. + */ +struct locked_reg { + u32 reg; /* offset from base */ + u32 lockreg; /* offset from base */ + u32 key; /* unlock key */ +}; + +/* + * This describes a contiguous area of like control bits used to enable/disable + * SoC devices. Each controllable device is given an ID which is used by the + * individual device drivers to control the device state. These IDs start at + * zero and are assigned sequentially to the control bitfield ranges described + * by this structure. + */ +struct devstate_ctl_reg { + u32 reg; /* register holding the control bits */ + u8 start_id; /* start id of this range */ + u8 num_ids; /* number of devices in this range */ + u8 enable_only; /* bits are write-once to enable only */ + u8 enable; /* value used to enable device */ + u8 disable; /* value used to disable device */ + u8 shift; /* starting (rightmost) bit in range */ + u8 nbits; /* number of bits per device */ +}; + + +/* + * This describes a region of status bits indicating the state of + * various devices. This is used internally to wait for status + * change completion when enabling/disabling a device. Status is + * optional and not all device controls will have a corresponding + * status. + */ +struct devstate_stat_reg { + u32 reg; /* register holding the status bits */ + u8 start_id; /* start id of this range */ + u8 num_ids; /* number of devices in this range */ + u8 enable; /* value indicating enabled state */ + u8 disable; /* value indicating disabled state */ + u8 shift; /* starting (rightmost) bit in range */ + u8 nbits; /* number of bits per device */ +}; + +struct devstate_info { + struct devstate_ctl_reg *ctl; + struct devstate_stat_reg *stat; +}; + +/* These are callbacks to SOC-specific code. */ +struct dscr_ops { + void (*init)(struct device_node *node); +}; + +struct dscr_regs { + spinlock_t lock; + void __iomem *base; + u32 kick_reg[2]; + u32 kick_key[2]; + struct locked_reg locked[MAX_LOCKED_REGS]; + struct devstate_info devstate_info[MAX_DEVSTATE_IDS]; + struct rmii_reset_reg rmii_resets[MAX_SOC_EMACS]; + struct devstate_ctl_reg devctl[MAX_DEVCTL_REGS]; + struct devstate_stat_reg devstat[MAX_DEVSTAT_REGS]; +}; + +static struct dscr_regs dscr; + +static struct locked_reg *find_locked_reg(u32 reg) +{ + int i; + + for (i = 0; i < MAX_LOCKED_REGS; i++) + if (dscr.locked[i].key && reg == dscr.locked[i].reg) + return &dscr.locked[i]; + return NULL; +} + +/* + * Write to a register with one lock + */ +static void dscr_write_locked1(u32 reg, u32 val, + u32 lock, u32 key) +{ + void __iomem *reg_addr = dscr.base + reg; + void __iomem *lock_addr = dscr.base + lock; + + /* + * For some registers, the lock is relocked after a short number + * of cycles. We have to put the lock write and register write in + * the same fetch packet to meet this timing. The .align ensures + * the two stw instructions are in the same fetch packet. + */ + asm volatile ("b .s2 0f\n" + "nop 5\n" + " .align 5\n" + "0:\n" + "stw .D1T2 %3,*%2\n" + "stw .D1T2 %1,*%0\n" + : + : "a"(reg_addr), "b"(val), "a"(lock_addr), "b"(key) + ); + + /* in case the hw doesn't reset the lock */ + soc_writel(0, lock_addr); +} + +/* + * Write to a register protected by two lock registers + */ +static void dscr_write_locked2(u32 reg, u32 val, + u32 lock0, u32 key0, + u32 lock1, u32 key1) +{ + soc_writel(key0, dscr.base + lock0); + soc_writel(key1, dscr.base + lock1); + soc_writel(val, dscr.base + reg); + soc_writel(0, dscr.base + lock0); + soc_writel(0, dscr.base + lock1); +} + +static void dscr_write(u32 reg, u32 val) +{ + struct locked_reg *lock; + + lock = find_locked_reg(reg); + if (lock) + dscr_write_locked1(reg, val, lock->lockreg, lock->key); + else if (dscr.kick_key[0]) + dscr_write_locked2(reg, val, dscr.kick_reg[0], dscr.kick_key[0], + dscr.kick_reg[1], dscr.kick_key[1]); + else + soc_writel(val, dscr.base + reg); +} + + +/* + * Drivers can use this interface to enable/disable SoC IP blocks. + */ +void dscr_set_devstate(int id, enum dscr_devstate_t state) +{ + struct devstate_ctl_reg *ctl; + struct devstate_stat_reg *stat; + struct devstate_info *info; + u32 ctl_val, val; + int ctl_shift, ctl_mask; + unsigned long flags; + + if (!dscr.base) + return; + + if (id < 0 || id >= MAX_DEVSTATE_IDS) + return; + + info = &dscr.devstate_info[id]; + ctl = info->ctl; + stat = info->stat; + + if (ctl == NULL) + return; + + ctl_shift = ctl->shift + ctl->nbits * (id - ctl->start_id); + ctl_mask = ((1 << ctl->nbits) - 1) << ctl_shift; + + switch (state) { + case DSCR_DEVSTATE_ENABLED: + ctl_val = ctl->enable << ctl_shift; + break; + case DSCR_DEVSTATE_DISABLED: + if (ctl->enable_only) + return; + ctl_val = ctl->disable << ctl_shift; + break; + default: + return; + } + + spin_lock_irqsave(&dscr.lock, flags); + + val = soc_readl(dscr.base + ctl->reg); + val &= ~ctl_mask; + val |= ctl_val; + + dscr_write(ctl->reg, val); + + spin_unlock_irqrestore(&dscr.lock, flags); + + if (!stat) + return; + + ctl_shift = stat->shift + stat->nbits * (id - stat->start_id); + + if (state == DSCR_DEVSTATE_ENABLED) + ctl_val = stat->enable; + else + ctl_val = stat->disable; + + do { + val = soc_readl(dscr.base + stat->reg); + val >>= ctl_shift; + val &= ((1 << stat->nbits) - 1); + } while (val != ctl_val); +} +EXPORT_SYMBOL(dscr_set_devstate); + +/* + * Drivers can use this to reset RMII module. + */ +void dscr_rmii_reset(int id, int assert) +{ + struct rmii_reset_reg *r; + unsigned long flags; + u32 val; + + if (id < 0 || id >= MAX_SOC_EMACS) + return; + + r = &dscr.rmii_resets[id]; + if (r->mask == 0) + return; + + spin_lock_irqsave(&dscr.lock, flags); + + val = soc_readl(dscr.base + r->reg); + if (assert) + dscr_write(r->reg, val | r->mask); + else + dscr_write(r->reg, val & ~(r->mask)); + + spin_unlock_irqrestore(&dscr.lock, flags); +} +EXPORT_SYMBOL(dscr_rmii_reset); + +static void __init dscr_parse_devstat(struct device_node *node, + void __iomem *base) +{ + u32 val; + int err; + + err = of_property_read_u32_array(node, "ti,dscr-devstat", &val, 1); + if (!err) + c6x_devstat = soc_readl(base + val); + printk(KERN_INFO "DEVSTAT: %08x\n", c6x_devstat); +} + +static void __init dscr_parse_silicon_rev(struct device_node *node, + void __iomem *base) +{ + u32 vals[3]; + int err; + + err = of_property_read_u32_array(node, "ti,dscr-silicon-rev", vals, 3); + if (!err) { + c6x_silicon_rev = soc_readl(base + vals[0]); + c6x_silicon_rev >>= vals[1]; + c6x_silicon_rev &= vals[2]; + } +} + +/* + * Some SoCs will have a pair of fuse registers which hold + * an ethernet MAC address. The "ti,dscr-mac-fuse-regs" + * property is a mapping from fuse register bytes to MAC + * address bytes. The expected format is: + * + * ti,dscr-mac-fuse-regs = + * + * reg0 and reg1 are the offsets of the two fuse registers. + * b3-b0 positionally represent bytes within the fuse register. + * b3 is the most significant byte and b0 is the least. + * Allowable values for b3-b0 are: + * + * 0 = fuse register byte not used in MAC address + * 1-6 = index+1 into c6x_fuse_mac[] + */ +static void __init dscr_parse_mac_fuse(struct device_node *node, + void __iomem *base) +{ + u32 vals[10], fuse; + int f, i, j, err; + + err = of_property_read_u32_array(node, "ti,dscr-mac-fuse-regs", + vals, 10); + if (err) + return; + + for (f = 0; f < 2; f++) { + fuse = soc_readl(base + vals[f * 5]); + for (j = (f * 5) + 1, i = 24; i >= 0; i -= 8, j++) + if (vals[j] && vals[j] <= 6) + c6x_fuse_mac[vals[j] - 1] = fuse >> i; + } +} + +static void __init dscr_parse_rmii_resets(struct device_node *node, + void __iomem *base) +{ + const __be32 *p; + int i, size; + + /* look for RMII reset registers */ + p = of_get_property(node, "ti,dscr-rmii-resets", &size); + if (p) { + /* parse all the reg/mask pairs we can handle */ + size /= (sizeof(*p) * 2); + if (size > MAX_SOC_EMACS) + size = MAX_SOC_EMACS; + + for (i = 0; i < size; i++) { + dscr.rmii_resets[i].reg = be32_to_cpup(p++); + dscr.rmii_resets[i].mask = be32_to_cpup(p++); + } + } +} + + +static void __init dscr_parse_privperm(struct device_node *node, + void __iomem *base) +{ + u32 vals[2]; + int err; + + err = of_property_read_u32_array(node, "ti,dscr-privperm", vals, 2); + if (err) + return; + dscr_write(vals[0], vals[1]); +} + +/* + * SoCs may have "locked" DSCR registers which can only be written + * to only after writing a key value to a lock registers. These + * regisers can be described with the "ti,dscr-locked-regs" property. + * This property provides a list of register descriptions with each + * description consisting of three values. + * + * ti,dscr-locked-regs = ; + * + * reg is the offset of the locked register + * lockreg is the offset of the lock register + * key is the unlock key written to lockreg + * + */ +static void __init dscr_parse_locked_regs(struct device_node *node, + void __iomem *base) +{ + struct locked_reg *r; + const __be32 *p; + int i, size; + + p = of_get_property(node, "ti,dscr-locked-regs", &size); + if (p) { + /* parse all the register descriptions we can handle */ + size /= (sizeof(*p) * 3); + if (size > MAX_LOCKED_REGS) + size = MAX_LOCKED_REGS; + + for (i = 0; i < size; i++) { + r = &dscr.locked[i]; + + r->reg = be32_to_cpup(p++); + r->lockreg = be32_to_cpup(p++); + r->key = be32_to_cpup(p++); + } + } +} + +/* + * SoCs may have DSCR registers which are only write enabled after + * writing specific key values to two registers. The two key registers + * and the key values can be parsed from a "ti,dscr-kick-regs" + * propety with the following layout: + * + * ti,dscr-kick-regs = + * + * kickreg is the offset of the "kick" register + * key is the value which unlocks writing for protected regs + */ +static void __init dscr_parse_kick_regs(struct device_node *node, + void __iomem *base) +{ + u32 vals[4]; + int err; + + err = of_property_read_u32_array(node, "ti,dscr-kick-regs", vals, 4); + if (!err) { + dscr.kick_reg[0] = vals[0]; + dscr.kick_key[0] = vals[1]; + dscr.kick_reg[1] = vals[2]; + dscr.kick_key[1] = vals[3]; + } +} + + +/* + * SoCs may provide controls to enable/disable individual IP blocks. These + * controls in the DSCR usually control pin drivers but also may control + * clocking and or resets. The device tree is used to describe the bitfields + * in registers used to control device state. The number of bits and their + * values may vary even within the same register. + * + * The layout of these bitfields is described by the ti,dscr-devstate-ctl-regs + * property. This property is a list where each element describes a contiguous + * range of control fields with like properties. Each element of the list + * consists of 7 cells with the following values: + * + * start_id num_ids reg enable disable start_bit nbits + * + * start_id is device id for the first device control in the range + * num_ids is the number of device controls in the range + * reg is the offset of the register holding the control bits + * enable is the value to enable a device + * disable is the value to disable a device (0xffffffff if cannot disable) + * start_bit is the bit number of the first bit in the range + * nbits is the number of bits per device control + */ +static void __init dscr_parse_devstate_ctl_regs(struct device_node *node, + void __iomem *base) +{ + struct devstate_ctl_reg *r; + const __be32 *p; + int i, j, size; + + p = of_get_property(node, "ti,dscr-devstate-ctl-regs", &size); + if (p) { + /* parse all the ranges we can handle */ + size /= (sizeof(*p) * 7); + if (size > MAX_DEVCTL_REGS) + size = MAX_DEVCTL_REGS; + + for (i = 0; i < size; i++) { + r = &dscr.devctl[i]; + + r->start_id = be32_to_cpup(p++); + r->num_ids = be32_to_cpup(p++); + r->reg = be32_to_cpup(p++); + r->enable = be32_to_cpup(p++); + r->disable = be32_to_cpup(p++); + if (r->disable == 0xffffffff) + r->enable_only = 1; + r->shift = be32_to_cpup(p++); + r->nbits = be32_to_cpup(p++); + + for (j = r->start_id; + j < (r->start_id + r->num_ids); + j++) + dscr.devstate_info[j].ctl = r; + } + } +} + +/* + * SoCs may provide status registers indicating the state (enabled/disabled) of + * devices on the SoC. The device tree is used to describe the bitfields in + * registers used to provide device status. The number of bits and their + * values used to provide status may vary even within the same register. + * + * The layout of these bitfields is described by the ti,dscr-devstate-stat-regs + * property. This property is a list where each element describes a contiguous + * range of status fields with like properties. Each element of the list + * consists of 7 cells with the following values: + * + * start_id num_ids reg enable disable start_bit nbits + * + * start_id is device id for the first device status in the range + * num_ids is the number of devices covered by the range + * reg is the offset of the register holding the status bits + * enable is the value indicating device is enabled + * disable is the value indicating device is disabled + * start_bit is the bit number of the first bit in the range + * nbits is the number of bits per device status + */ +static void __init dscr_parse_devstate_stat_regs(struct device_node *node, + void __iomem *base) +{ + struct devstate_stat_reg *r; + const __be32 *p; + int i, j, size; + + p = of_get_property(node, "ti,dscr-devstate-stat-regs", &size); + if (p) { + /* parse all the ranges we can handle */ + size /= (sizeof(*p) * 7); + if (size > MAX_DEVSTAT_REGS) + size = MAX_DEVSTAT_REGS; + + for (i = 0; i < size; i++) { + r = &dscr.devstat[i]; + + r->start_id = be32_to_cpup(p++); + r->num_ids = be32_to_cpup(p++); + r->reg = be32_to_cpup(p++); + r->enable = be32_to_cpup(p++); + r->disable = be32_to_cpup(p++); + r->shift = be32_to_cpup(p++); + r->nbits = be32_to_cpup(p++); + + for (j = r->start_id; + j < (r->start_id + r->num_ids); + j++) + dscr.devstate_info[j].stat = r; + } + } +} + +static struct of_device_id dscr_ids[] __initdata = { + { .compatible = "ti,c64x+dscr" }, + {} +}; + +/* + * Probe for DSCR area. + * + * This has to be done early on in case timer or interrupt controller + * needs something. e.g. On C6455 SoC, timer must be enabled through + * DSCR before it is functional. + */ +void __init dscr_probe(void) +{ + struct device_node *node; + void __iomem *base; + + spin_lock_init(&dscr.lock); + + node = of_find_matching_node(NULL, dscr_ids); + if (!node) + return; + + base = of_iomap(node, 0); + if (!base) { + of_node_put(node); + return; + } + + dscr.base = base; + + dscr_parse_devstat(node, base); + dscr_parse_silicon_rev(node, base); + dscr_parse_mac_fuse(node, base); + dscr_parse_rmii_resets(node, base); + dscr_parse_locked_regs(node, base); + dscr_parse_kick_regs(node, base); + dscr_parse_devstate_ctl_regs(node, base); + dscr_parse_devstate_stat_regs(node, base); + dscr_parse_privperm(node, base); +} -- cgit v1.2.3 From b462c20e2915e6eca2fb812b4f63c94e7e042b9a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 Nov 2011 16:15:37 +0900 Subject: ARM: S3C64XX: Update for conversion to SAMSUNG_GPIO_EXTRA The conversion of the S3C64XX GPIOs to the generic Samsung GPIOs mean that rather than using the previous S3C24XX_GPIO_EXTRA configuration the driver now uses SAMSUNG_GPIO_EXTRA. Since SAMSUNG_GPIO_EXTRA requires the arch to include the extra space in ARCH_NR_GPIOs add it on to BOARD_NR_GPIOs (in case boards are relying on the existing reservation). Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/include/mach/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio.h b/arch/arm/mach-s3c64xx/include/mach/gpio.h index 6e34c2f6e670..8b540c42d5dd 100644 --- a/arch/arm/mach-s3c64xx/include/mach/gpio.h +++ b/arch/arm/mach-s3c64xx/include/mach/gpio.h @@ -88,6 +88,6 @@ enum s3c_gpio_number { /* define the number of gpios we need to the one after the GPQ() range */ #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) -#define BOARD_NR_GPIOS 16 +#define BOARD_NR_GPIOS (16 + CONFIG_SAMSUNG_GPIO_EXTRA) #define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS) -- cgit v1.2.3 From 4ff13995b512cfadef44e0bf5cb15298d6094519 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 Nov 2011 16:15:38 +0900 Subject: ARM: SAMSUNG: Fix GPIO space reservation for S3C64xx platforms The conversion to use SAMSUNG_GPIO_EXTRA rather than S3C24XX_GPIO_EXTRA broke a number of S3C64xx boards which had been using the symbols provided to reserve a range of GPIOs for board specific use. Fix this by adding equivalent symbols for the new shared driver and updating the relevant boards to use the new symbols. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/Kconfig | 6 +++--- arch/arm/plat-samsung/Kconfig | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 5552e048c2be..4d8c489edc04 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -188,7 +188,7 @@ config SMDK6410_WM1190_EV1 depends on MACH_SMDK6410 select REGULATOR select REGULATOR_WM8350 - select S3C24XX_GPIO_EXTRA64 + select SAMSUNG_GPIO_EXTRA64 select MFD_WM8350_I2C select MFD_WM8350_CONFIG_MODE_0 select MFD_WM8350_CONFIG_MODE_3 @@ -206,7 +206,7 @@ config SMDK6410_WM1192_EV1 depends on MACH_SMDK6410 select REGULATOR select REGULATOR_WM831X - select S3C24XX_GPIO_EXTRA64 + select SAMSUNG_GPIO_EXTRA64 select MFD_WM831X select MFD_WM831X_I2C help @@ -287,7 +287,7 @@ config MACH_WLF_CRAGG_6410 select S3C_DEV_WDT select S3C_DEV_RTC select S3C64XX_DEV_SPI - select S3C24XX_GPIO_EXTRA128 + select SAMSUNG_GPIO_EXTRA128 select I2C help Machine support for the Wolfson Cragganmore S3C6410 variant. diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 313eb26cfa62..bb0af66bb487 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -88,12 +88,20 @@ config S5P_GPIO_DRVSTR config SAMSUNG_GPIO_EXTRA int "Number of additional GPIO pins" + default 128 if SAMSUNG_GPIO_EXTRA128 + default 64 if SAMSUNG_GPIO_EXTRA64 default 0 help Use additional GPIO space in addition to the GPIO's the SOC provides. This allows expanding the GPIO space for use with GPIO expanders. +config SAMSUNG_GPIO_EXTRA64 + bool + +config SAMSUNG_GPIO_EXTRA128 + bool + config S3C_GPIO_SPACE int "Space between gpio banks" default 0 -- cgit v1.2.3 From aaed44e1672c61b28dcae6e3d7bd5d15aef362f3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 Nov 2011 16:28:15 +0900 Subject: ARM: S3C64XX: Correct reservation of GPIOs for CPU module on Cragganmore The gpio_base for the PMIC on the CPU module was being incorrectly set to be the same as that for the CODEC causing the two GPIO drivers to collide. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/include/mach/crag6410.h | 3 ++- arch/arm/mach-s3c64xx/mach-crag6410.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h index be9074e17dfd..1cc1cc82e754 100644 --- a/arch/arm/mach-s3c64xx/include/mach/crag6410.h +++ b/arch/arm/mach-s3c64xx/include/mach/crag6410.h @@ -17,7 +17,8 @@ #define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) #define PCA935X_GPIO_BASE GPIO_BOARD_START -#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) +#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) #define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 16) +#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 32) #endif diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index d04b65448510..8b04a46e9f6d 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -500,7 +500,7 @@ static struct wm831x_touch_pdata touch_pdata __initdata = { static struct wm831x_pdata crag_pmic_pdata __initdata = { .wm831x_num = 1, .irq_base = BANFF_PMIC_IRQ_BASE, - .gpio_base = GPIO_BOARD_START + 8, + .gpio_base = BANFF_PMIC_GPIO_BASE, .backup = &banff_backup_pdata, -- cgit v1.2.3 From 650e3f0d66ade2a614d854765dae3bbc9a87f58d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:33:03 -0800 Subject: ARM: msm: Consolidate and move DEBUG_LL to DEBUG_LL choice Now that DEBUG_LL is a choice we can move MSM's homegrown choice menu to DEBUG_LL. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/Kconfig.debug | 21 ++++++++++++++++ arch/arm/mach-msm/Kconfig | 32 ------------------------- arch/arm/mach-msm/include/mach/debug-macro.S | 19 +++------------ arch/arm/mach-msm/include/mach/msm_iomap-7x00.h | 12 ---------- arch/arm/mach-msm/include/mach/msm_iomap-7x30.h | 12 ---------- arch/arm/mach-msm/include/mach/msm_iomap-8x50.h | 12 ---------- arch/arm/mach-msm/include/mach/msm_iomap.h | 12 ++++++++++ arch/arm/mach-msm/io.c | 9 ++++--- 8 files changed, 42 insertions(+), 87 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c5213e78606b..333b6a416d2f 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -247,6 +247,27 @@ 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 + help + Say Y here if you want the debug print routines to direct + their output to the first serial port on MSM devices. + + 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 the second serial port on MSM devices. + + 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. + endchoice config EARLY_PRINTK diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index ebde97f5d5f0..5b07b6104e5d 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -13,7 +13,6 @@ config ARCH_MSM7X00A select CPU_V6 select GPIO_MSM_V1 select MSM_PROC_COMM - select HAS_MSM_DEBUG_UART_PHYS config ARCH_MSM7X30 bool "MSM7x30" @@ -25,7 +24,6 @@ config ARCH_MSM7X30 select MSM_GPIOMUX select GPIO_MSM_V1 select MSM_PROC_COMM - select HAS_MSM_DEBUG_UART_PHYS config ARCH_QSD8X50 bool "QSD8X50" @@ -37,7 +35,6 @@ config ARCH_QSD8X50 select MSM_GPIOMUX select GPIO_MSM_V1 select MSM_PROC_COMM - select HAS_MSM_DEBUG_UART_PHYS config ARCH_MSM8X60 bool "MSM8X60" @@ -73,9 +70,6 @@ config ARCH_MSM_ARM11 config ARCH_MSM_SCORPION bool -config HAS_MSM_DEBUG_UART_PHYS - bool - config MSM_VIC bool @@ -152,32 +146,6 @@ config MACH_MSM8960_RUMI3 endmenu -config MSM_DEBUG_UART - int - default 1 if MSM_DEBUG_UART1 - default 2 if MSM_DEBUG_UART2 - default 3 if MSM_DEBUG_UART3 - -if HAS_MSM_DEBUG_UART_PHYS -choice - prompt "Debug UART" - - default MSM_DEBUG_UART_NONE - - config MSM_DEBUG_UART_NONE - bool "None" - - config MSM_DEBUG_UART1 - bool "UART1" - - config MSM_DEBUG_UART2 - bool "UART2" - - config MSM_DEBUG_UART3 - bool "UART3" -endchoice -endif - config MSM_SMD_PKG3 bool diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index 2dc73ccddb11..db1f22830d64 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -1,4 +1,4 @@ -/* arch/arm/mach-msm7200/include/mach/debug-macro.S +/* * * Copyright (C) 2007 Google, Inc. * Author: Brian Swetland @@ -14,15 +14,14 @@ * */ - - #include #include -#if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE) .macro addruart, rp, rv, tmp +#ifdef MSM_DEBUG_UART_PHYS ldr \rp, =MSM_DEBUG_UART_PHYS ldr \rv, =MSM_DEBUG_UART_BASE +#endif .endm .macro senduart,rd,rx @@ -36,18 +35,6 @@ tst \rd, #0x04 beq 1001b .endm -#else - .macro addruart, rp, rv, tmp - mov \rv, #0xff000000 - orr \rv, \rv, #0x00f00000 - .endm - - .macro senduart,rd,rx - .endm - - .macro waituart,rd,rx - .endm -#endif .macro busyuart,rd,rx .endm 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 94fe9fe6feb3..8af46123dab6 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h @@ -78,18 +78,6 @@ #define MSM_UART3_PHYS 0xA9C00000 #define MSM_UART3_SIZE SZ_4K -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - #define MSM_SDC1_PHYS 0xA0400000 #define MSM_SDC1_SIZE SZ_4K 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 37694442d1bd..198202c267c8 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h @@ -89,18 +89,6 @@ #define MSM_UART3_PHYS 0xACC00000 #define MSM_UART3_SIZE SZ_4K -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - #define MSM_MDC_BASE IOMEM(0xE0200000) #define MSM_MDC_PHYS 0xAA500000 #define MSM_MDC_SIZE SZ_1M 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 d67cd73316f4..0faa894729b7 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h @@ -83,18 +83,6 @@ #define MSM_UART3_PHYS 0xA9C00000 #define MSM_UART3_SIZE SZ_4K -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - #define MSM_MDC_BASE IOMEM(0xE0200000) #define MSM_MDC_PHYS 0xAA500000 #define MSM_MDC_SIZE SZ_1M diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 4ded15238b60..90682f4599d3 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -55,6 +55,18 @@ #include "msm_iomap-8960.h" +#define MSM_DEBUG_UART_SIZE SZ_4K +#if defined(CONFIG_DEBUG_MSM_UART1) +#define MSM_DEBUG_UART_BASE 0xE1000000 +#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS +#elif defined(CONFIG_DEBUG_MSM_UART2) +#define MSM_DEBUG_UART_BASE 0xE1000000 +#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS +#elif defined(CONFIG_DEBUG_MSM_UART3) +#define MSM_DEBUG_UART_BASE 0xE1000000 +#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS +#endif + /* Virtual addresses shared across all MSM targets. */ #define MSM_CSR_BASE IOMEM(0xE0001000) #define MSM_QGIC_DIST_BASE IOMEM(0xF0000000) diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 8759ecf7454f..03036afe6266 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -47,7 +47,8 @@ static struct map_desc msm_io_desc[] __initdata = { MSM_CHIP_DEVICE(GPIO1, MSM7X00), MSM_CHIP_DEVICE(GPIO2, MSM7X00), MSM_DEVICE(CLK_CTL), -#ifdef CONFIG_MSM_DEBUG_UART +#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \ + defined(CONFIG_DEBUG_MSM_UART3) MSM_DEVICE(DEBUG_UART), #endif #ifdef CONFIG_ARCH_MSM7X30 @@ -84,7 +85,8 @@ static struct map_desc qsd8x50_io_desc[] __initdata = { MSM_DEVICE(SCPLL), MSM_DEVICE(AD5), MSM_DEVICE(MDC), -#ifdef CONFIG_MSM_DEBUG_UART +#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \ + defined(CONFIG_DEBUG_MSM_UART3) MSM_DEVICE(DEBUG_UART), #endif { @@ -146,7 +148,8 @@ static struct map_desc msm7x30_io_desc[] __initdata = { MSM_DEVICE(SAW), MSM_DEVICE(GCC), MSM_DEVICE(TCSR), -#ifdef CONFIG_MSM_DEBUG_UART +#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \ + defined(CONFIG_DEBUG_MSM_UART3) MSM_DEVICE(DEBUG_UART), #endif { -- cgit v1.2.3 From a3d3ef9d4fd57cfd407c8d2d0a7daec000468ebf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:33:04 -0800 Subject: msm: Support DEBUG_LL on MSM8660 and MSM8960 Add support for DEBUG_LL on the 8660 and 8960 development boards. While we're here cleanup the uncompress.h code a bit. Avoid the use of readl/writel as those are Linux specific APIs that aren't guaranteed to work in the decompressor. Cc: Nicolas Pitre Signed-off-by: Stephen Boyd Acked-by: Nicolas Pitre Signed-off-by: David Brown --- arch/arm/Kconfig.debug | 16 ++++++++++ arch/arm/mach-msm/Kconfig | 3 ++ arch/arm/mach-msm/include/mach/debug-macro.S | 32 ++++++++++++++++++-- arch/arm/mach-msm/include/mach/msm_iomap-8960.h | 5 ++++ arch/arm/mach-msm/include/mach/msm_iomap-8x60.h | 5 ++++ arch/arm/mach-msm/include/mach/uncompress.h | 39 ++++++++++++++++++++----- arch/arm/mach-msm/io.c | 6 ++++ 7 files changed, 95 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 333b6a416d2f..4c1eb7dd2a7e 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -268,6 +268,22 @@ choice Say Y here if you want the debug print routines to direct their output to the third serial port on MSM devices. + 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 the serial port on MSM 8660 devices. + + 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. + endchoice config EARLY_PRINTK diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 5b07b6104e5d..000ddf0a4f33 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -60,6 +60,9 @@ config ARCH_MSM8960 endchoice +config MSM_HAS_DEBUG_UART_HS + bool + config MSM_SOC_REV_A bool config ARCH_MSM_SCORPIONMP diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index db1f22830d64..3ffd8668c9a5 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -1,6 +1,7 @@ /* * * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -24,17 +25,42 @@ #endif .endm - .macro senduart,rd,rx + .macro senduart, rd, rx +#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS + @ Write the 1 character to UARTDM_TF + str \rd, [\rx, #0x70] +#else teq \rx, #0 strne \rd, [\rx, #0x0C] +#endif .endm - .macro waituart,rd,rx + .macro waituart, rd, rx +#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS + @ check for TX_EMT in UARTDM_SR + ldr \rd, [\rx, #0x08] + tst \rd, #0x08 + bne 1002f + @ wait for TXREADY in UARTDM_ISR +1001: ldr \rd, [\rx, #0x14] + tst \rd, #0x80 + beq 1001b +1002: + @ Clear TX_READY by writing to the UARTDM_CR register + mov \rd, #0x300 + str \rd, [\rx, #0x10] + @ Write 0x1 to NCF register + mov \rd, #0x1 + str \rd, [\rx, #0x40] + @ UARTDM reg. Read to induce delay + ldr \rd, [\rx, #0x08] +#else @ wait for TX_READY 1001: ldr \rd, [\rx, #0x08] tst \rd, #0x04 beq 1001b +#endif .endm - .macro busyuart,rd,rx + .macro busyuart, rd, rx .endm 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 3c9d9602a318..800b55767e6b 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h @@ -45,4 +45,9 @@ #define MSM8960_TMR0_PHYS 0x0208A000 #define MSM8960_TMR0_SIZE SZ_4K +#ifdef CONFIG_DEBUG_MSM8960_UART +#define MSM_DEBUG_UART_BASE 0xE1040000 +#define MSM_DEBUG_UART_PHYS 0x16440000 +#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 3b19b8f244b8..54e12caa8d86 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h @@ -62,4 +62,9 @@ #define MSM8X60_TMR0_PHYS 0x02040000 #define MSM8X60_TMR0_SIZE SZ_4K +#ifdef CONFIG_DEBUG_MSM8660_UART +#define MSM_DEBUG_UART_BASE 0xE1040000 +#define MSM_DEBUG_UART_PHYS 0x19C40000 +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h index d94292c29d8e..169a84007456 100644 --- a/arch/arm/mach-msm/include/mach/uncompress.h +++ b/arch/arm/mach-msm/include/mach/uncompress.h @@ -1,6 +1,6 @@ -/* arch/arm/mach-msm/include/mach/uncompress.h - * +/* * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2011, Code Aurora Forum. 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 @@ -14,17 +14,40 @@ */ #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H +#define __ASM_ARCH_MSM_UNCOMPRESS_H + +#include +#include + +#define UART_CSR (*(volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x08)) +#define UART_TF (*(volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x0c)) -#include "hardware.h" -#include "linux/io.h" -#include "mach/msm_iomap.h" +#define UART_DM_SR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x08))) +#define UART_DM_CR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x10))) +#define UART_DM_ISR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x14))) +#define UART_DM_NCHAR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x40))) +#define UART_DM_TF (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x70))) static void putc(int c) { #if defined(MSM_DEBUG_UART_PHYS) - unsigned base = MSM_DEBUG_UART_PHYS; - while (!(readl(base + 0x08) & 0x04)) ; - writel(c, base + 0x0c); +#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS + /* + * Wait for TX_READY to be set; but skip it if we have a + * TX underrun. + */ + if (UART_DM_SR & 0x08) + while (!(UART_DM_ISR & 0x80)) + cpu_relax(); + + UART_DM_CR = 0x300; + UART_DM_NCHAR = 0x1; + UART_DM_TF = c; +#else + while (!(UART_CSR & 0x04)) + cpu_relax(); + UART_TF = c; +#endif #endif } diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 03036afe6266..578b04e42deb 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -111,6 +111,9 @@ static struct map_desc msm8x60_io_desc[] __initdata = { MSM_CHIP_DEVICE(TMR0, MSM8X60), MSM_DEVICE(ACC), MSM_DEVICE(GCC), +#ifdef CONFIG_DEBUG_MSM8660_UART + MSM_DEVICE(DEBUG_UART), +#endif }; void __init msm_map_msm8x60_io(void) @@ -125,6 +128,9 @@ static struct map_desc msm8960_io_desc[] __initdata = { MSM_CHIP_DEVICE(QGIC_CPU, MSM8960), MSM_CHIP_DEVICE(TMR, MSM8960), MSM_CHIP_DEVICE(TMR0, MSM8960), +#ifdef CONFIG_DEBUG_MSM8960_UART + MSM_DEVICE(DEBUG_UART), +#endif }; void __init msm_map_msm8960_io(void) -- cgit v1.2.3 From 2852ccaed4461365e6627fadb9e214a52fa3c600 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:03 -0800 Subject: msm: timer: Tighten #ifdef for local timer support It is more correct to only define the local timer support code when CONFIG_LOCAL_TIMERS=y. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index afeeca52fc66..1cab55983d52 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -279,7 +279,7 @@ static void __init msm_timer_init(void) } } -#ifdef CONFIG_SMP +#ifdef CONFIG_LOCAL_TIMERS int __cpuinit local_timer_setup(struct clock_event_device *evt) { static bool local_timer_inited; @@ -321,8 +321,7 @@ void local_timer_stop(struct clock_event_device *evt) evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); disable_percpu_irq(evt->irq); } - -#endif +#endif /* CONFIG_LOCAL_TIMERS */ struct sys_timer msm_timer = { .init = msm_timer_init -- cgit v1.2.3 From 4a1840755294b2a14236ee7b9c74ede261156b09 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:04 -0800 Subject: msm: timer: Cleanup #includes and #defines Remove unused/unnecessary #defines, #includes, and use the BIT macro appropriately. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 1cab55983d52..ce389ca4950f 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -13,44 +13,32 @@ * */ +#include +#include #include -#include #include #include -#include -#include -#include #include #include #include +#include #include #include +#include #define TIMER_MATCH_VAL 0x0000 #define TIMER_COUNT_VAL 0x0004 #define TIMER_ENABLE 0x0008 -#define TIMER_ENABLE_CLR_ON_MATCH_EN 2 -#define TIMER_ENABLE_EN 1 +#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) +#define TIMER_ENABLE_EN BIT(0) #define TIMER_CLEAR 0x000C #define DGT_CLK_CTL 0x0034 -enum { - DGT_CLK_CTL_DIV_1 = 0, - DGT_CLK_CTL_DIV_2 = 1, - DGT_CLK_CTL_DIV_3 = 2, - DGT_CLK_CTL_DIV_4 = 3, -}; -#define CSR_PROTECTION 0x0020 -#define CSR_PROTECTION_EN 1 +#define DGT_CLK_CTL_DIV_4 0x3 #define GPT_HZ 32768 -enum timer_location { - LOCAL_TIMER = 0, - GLOBAL_TIMER = 1, -}; - #define MSM_GLOBAL_TIMER MSM_CLOCK_DGT /* TODO: Remove these ifdefs */ -- cgit v1.2.3 From dd15ab814149df65187943c32ca09e4eeaac0047 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:05 -0800 Subject: msm: timer: Use GPT for clockevents and DGT for clocksource The clocksource shouldn't stop ticking when the clockevent stops. This is exactly what happens today with MSM timers. The same hardware is used for both the clockevent and the clocksource because the ratings of the two are the same. Fix this by registering a clockevent based on the GPT and a clocksource based on the DGT. This removes any other possible configuration (e.g. a GPT clocksource and a DGT clockevent) but that shouldn't be a big issue since we want higher precision timing than high precision scheduling interrupts. Signed-off-by: Stephen Boyd Cc: Thomas Gleixner Cc: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 121 ++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 69 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index ce389ca4950f..405e8a925202 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -1,6 +1,7 @@ -/* linux/arch/arm/mach-msm/timer.c +/* * * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2009-2011, Code Aurora Forum. 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 @@ -39,7 +40,7 @@ #define GPT_HZ 32768 -#define MSM_GLOBAL_TIMER MSM_CLOCK_DGT +#define MSM_GLOBAL_TIMER MSM_CLOCK_GPT /* TODO: Remove these ifdefs */ #if defined(CONFIG_ARCH_QSD8X50) @@ -153,25 +154,10 @@ static struct msm_clock msm_clocks[] = { .set_next_event = msm_timer_set_next_event, .set_mode = msm_timer_set_mode, }, - .clocksource = { - .name = "gp_timer", - .rating = 200, - .read = msm_read_timer_count, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - }, .irq = INT_GP_TIMER_EXP, .freq = GPT_HZ, }, [MSM_CLOCK_DGT] = { - .clockevent = { - .name = "dg_timer", - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32 + MSM_DGT_SHIFT, - .rating = 300, - .set_next_event = msm_timer_set_next_event, - .set_mode = msm_timer_set_mode, - }, .clocksource = { .name = "dg_timer", .rating = 300, @@ -179,7 +165,6 @@ static struct msm_clock msm_clocks[] = { .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }, - .irq = INT_DEBUG_TIMER_EXP, .freq = DGT_HZ >> MSM_DGT_SHIFT, .shift = MSM_DGT_SHIFT, } @@ -187,10 +172,13 @@ static struct msm_clock msm_clocks[] = { static void __init msm_timer_init(void) { - int i; + struct msm_clock *clock; + struct clock_event_device *ce = &msm_clocks[MSM_CLOCK_GPT].clockevent; + struct clocksource *cs = &msm_clocks[MSM_CLOCK_DGT].clocksource; int res; int global_offset = 0; + if (cpu_is_msm7x01()) { msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE; msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10; @@ -213,58 +201,55 @@ static void __init msm_timer_init(void) writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); #endif - for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) { - struct msm_clock *clock = &msm_clocks[i]; - struct clock_event_device *ce = &clock->clockevent; - struct clocksource *cs = &clock->clocksource; - - clock->local_counter = clock->regbase + TIMER_COUNT_VAL; - clock->global_counter = clock->local_counter + global_offset; - - writel(0, clock->regbase + TIMER_ENABLE); - writel(0, clock->regbase + TIMER_CLEAR); - writel(~0, clock->regbase + TIMER_MATCH_VAL); + clock = &msm_clocks[MSM_CLOCK_GPT]; + clock->local_counter = clock->regbase + TIMER_COUNT_VAL; - ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift); - /* allow at least 10 seconds to notice that the timer wrapped */ - ce->max_delta_ns = - clockevent_delta2ns(0xf0000000 >> clock->shift, ce); - /* 4 gets rounded down to 3 */ - ce->min_delta_ns = clockevent_delta2ns(4, ce); - ce->cpumask = cpumask_of(0); - - res = clocksource_register_hz(cs, clock->freq); - if (res) - printk(KERN_ERR "msm_timer_init: clocksource_register " - "failed for %s\n", cs->name); - - ce->irq = clock->irq; - if (cpu_is_msm8x60() || cpu_is_msm8960()) { - clock->percpu_evt = alloc_percpu(struct clock_event_device *); - if (!clock->percpu_evt) { - pr_err("msm_timer_init: memory allocation " - "failed for %s\n", ce->name); - continue; - } - - *__this_cpu_ptr(clock->percpu_evt) = ce; - res = request_percpu_irq(ce->irq, msm_timer_interrupt, - ce->name, clock->percpu_evt); - if (!res) - enable_percpu_irq(ce->irq, 0); - } else { - clock->evt = ce; - res = request_irq(ce->irq, msm_timer_interrupt, - IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING, - ce->name, &clock->evt); + writel_relaxed(0, clock->regbase + TIMER_ENABLE); + writel_relaxed(0, clock->regbase + TIMER_CLEAR); + writel_relaxed(~0, clock->regbase + TIMER_MATCH_VAL); + ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift); + /* + * allow at least 10 seconds to notice that the timer + * wrapped + */ + ce->max_delta_ns = + clockevent_delta2ns(0xf0000000 >> clock->shift, ce); + /* 4 gets rounded down to 3 */ + ce->min_delta_ns = clockevent_delta2ns(4, ce); + ce->cpumask = cpumask_of(0); + + ce->irq = clock->irq; + if (cpu_is_msm8x60() || cpu_is_msm8960()) { + clock->percpu_evt = alloc_percpu(struct clock_event_device *); + if (!clock->percpu_evt) { + pr_err("memory allocation failed for %s\n", ce->name); + goto err; } - if (res) - pr_err("msm_timer_init: request_irq failed for %s\n", - ce->name); - - clockevents_register_device(ce); + *__this_cpu_ptr(clock->percpu_evt) = ce; + res = request_percpu_irq(ce->irq, msm_timer_interrupt, + ce->name, clock->percpu_evt); + if (!res) + enable_percpu_irq(ce->irq, 0); + } else { + clock->evt = ce; + res = request_irq(ce->irq, msm_timer_interrupt, + IRQF_TIMER | IRQF_NOBALANCING | + IRQF_TRIGGER_RISING, ce->name, &clock->evt); } + + if (res) + pr_err("request_irq failed for %s\n", ce->name); + + clockevents_register_device(ce); +err: + clock = &msm_clocks[MSM_CLOCK_DGT]; + clock->local_counter = clock->regbase + TIMER_COUNT_VAL; + clock->global_counter = clock->local_counter + global_offset; + writel_relaxed(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); + res = clocksource_register_hz(cs, clock->freq); + if (res) + pr_err("clocksource_register failed for %s\n", cs->name); } #ifdef CONFIG_LOCAL_TIMERS @@ -277,8 +262,6 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt) if (!smp_processor_id()) return 0; - writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); - if (!local_timer_inited) { writel(0, clock->regbase + TIMER_ENABLE); writel(0, clock->regbase + TIMER_CLEAR); -- cgit v1.2.3 From a850c3f6446d30b47c984d3f9e45c935385fd592 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:06 -0800 Subject: msm: timer: Fix ONESHOT mode interrupts MSM timers don't support an interrupt enable/disable bit. Therefore, when the timer is free running it's possible for the count to wrap and the match value to match again even though a set_next_event() call hasn't been made since the last match. Workaround the lack of an interrupt enable bit by explicitly stopping the timer in the interrupt handler when the clockevent is in ONESHOT mode. This should prevent any possibility of the timer wrapping and matching more than once per set_next_event(). Signed-off-by: Stephen Boyd Cc: Thomas Gleixner Cc: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 405e8a925202..9f3671a43314 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -81,11 +81,20 @@ enum { static struct msm_clock msm_clocks[]; +static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt); + static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = *(struct clock_event_device **)dev_id; if (evt->event_handler == NULL) return IRQ_HANDLED; + /* Stop the timer tick */ + if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { + struct msm_clock *clock = clockevent_to_clock(evt); + u32 ctrl = readl_relaxed(clock->regbase + TIMER_ENABLE); + ctrl &= ~TIMER_ENABLE_EN; + writel_relaxed(ctrl, clock->regbase + TIMER_ENABLE); + } evt->event_handler(evt); return IRQ_HANDLED; } @@ -118,10 +127,12 @@ static int msm_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { struct msm_clock *clock = clockevent_to_clock(evt); - uint32_t now = readl(clock->local_counter); - uint32_t alarm = now + (cycles << clock->shift); + u32 match = cycles << clock->shift; + u32 ctrl = readl_relaxed(clock->regbase + TIMER_ENABLE); - writel(alarm, clock->regbase + TIMER_MATCH_VAL); + writel_relaxed(0, clock->regbase + TIMER_CLEAR); + writel_relaxed(match, clock->regbase + TIMER_MATCH_VAL); + writel_relaxed(ctrl | TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); return 0; } @@ -129,19 +140,23 @@ static void msm_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { struct msm_clock *clock = clockevent_to_clock(evt); + u32 ctrl; + + ctrl = readl_relaxed(clock->regbase + TIMER_ENABLE); + ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); switch (mode) { case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_PERIODIC: break; case CLOCK_EVT_MODE_ONESHOT: - writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); + /* Timer is enabled in set_next_event */ break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: - writel(0, clock->regbase + TIMER_ENABLE); break; } + writel_relaxed(ctrl, clock->regbase + TIMER_ENABLE); } static struct msm_clock msm_clocks[] = { -- cgit v1.2.3 From 2a00c1068b2c1ae451e230ef8bd010d7b2f56f54 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:07 -0800 Subject: msm: timer: Remove msm_clocks[] and simplify code We can simplify the timer code now that we only use the DGT for the clocksource and the GPT for the clockevent. Get rid of the msm_clocks[] array and propagate the changes throughout the code. This reduces the lines of code in this file and improves readability. Signed-off-by: Stephen Boyd Cc: Thomas Gleixner Cc: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 221 ++++++++++++++++------------------------------ 1 file changed, 76 insertions(+), 145 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 9f3671a43314..fc0646442e09 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -40,8 +40,6 @@ #define GPT_HZ 32768 -#define MSM_GLOBAL_TIMER MSM_CLOCK_GPT - /* TODO: Remove these ifdefs */ #if defined(CONFIG_ARCH_QSD8X50) #define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */ @@ -57,31 +55,7 @@ #define MSM_DGT_SHIFT (5) #endif -struct msm_clock { - struct clock_event_device clockevent; - struct clocksource clocksource; - unsigned int irq; - void __iomem *regbase; - uint32_t freq; - uint32_t shift; - void __iomem *global_counter; - void __iomem *local_counter; - union { - struct clock_event_device *evt; - struct clock_event_device __percpu **percpu_evt; - }; -}; - -enum { - MSM_CLOCK_GPT, - MSM_CLOCK_DGT, - NR_TIMERS, -}; - - -static struct msm_clock msm_clocks[]; - -static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt); +static void __iomem *event_base; static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) { @@ -90,59 +64,31 @@ static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; /* Stop the timer tick */ if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { - struct msm_clock *clock = clockevent_to_clock(evt); - u32 ctrl = readl_relaxed(clock->regbase + TIMER_ENABLE); + u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); ctrl &= ~TIMER_ENABLE_EN; - writel_relaxed(ctrl, clock->regbase + TIMER_ENABLE); + writel_relaxed(ctrl, event_base + TIMER_ENABLE); } evt->event_handler(evt); return IRQ_HANDLED; } -static cycle_t msm_read_timer_count(struct clocksource *cs) -{ - struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource); - - /* - * Shift timer count down by a constant due to unreliable lower bits - * on some targets. - */ - return readl(clk->global_counter) >> clk->shift; -} - -static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt) -{ -#ifdef CONFIG_SMP - int i; - for (i = 0; i < NR_TIMERS; i++) - if (evt == &(msm_clocks[i].clockevent)) - return &msm_clocks[i]; - return &msm_clocks[MSM_GLOBAL_TIMER]; -#else - return container_of(evt, struct msm_clock, clockevent); -#endif -} - static int msm_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - struct msm_clock *clock = clockevent_to_clock(evt); - u32 match = cycles << clock->shift; - u32 ctrl = readl_relaxed(clock->regbase + TIMER_ENABLE); + u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); - writel_relaxed(0, clock->regbase + TIMER_CLEAR); - writel_relaxed(match, clock->regbase + TIMER_MATCH_VAL); - writel_relaxed(ctrl | TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); + writel_relaxed(0, event_base + TIMER_CLEAR); + writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); + writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); return 0; } static void msm_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - struct msm_clock *clock = clockevent_to_clock(evt); u32 ctrl; - ctrl = readl_relaxed(clock->regbase + TIMER_ENABLE); + ctrl = readl_relaxed(event_base + TIMER_ENABLE); ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); switch (mode) { @@ -156,59 +102,61 @@ static void msm_timer_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_SHUTDOWN: break; } - writel_relaxed(ctrl, clock->regbase + TIMER_ENABLE); + writel_relaxed(ctrl, event_base + TIMER_ENABLE); } -static struct msm_clock msm_clocks[] = { - [MSM_CLOCK_GPT] = { - .clockevent = { - .name = "gp_timer", - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .rating = 200, - .set_next_event = msm_timer_set_next_event, - .set_mode = msm_timer_set_mode, - }, - .irq = INT_GP_TIMER_EXP, - .freq = GPT_HZ, - }, - [MSM_CLOCK_DGT] = { - .clocksource = { - .name = "dg_timer", - .rating = 300, - .read = msm_read_timer_count, - .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - }, - .freq = DGT_HZ >> MSM_DGT_SHIFT, - .shift = MSM_DGT_SHIFT, - } +static struct clock_event_device msm_clockevent = { + .name = "gp_timer", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .rating = 200, + .set_next_event = msm_timer_set_next_event, + .set_mode = msm_timer_set_mode, +}; + +static union { + struct clock_event_device *evt; + struct clock_event_device __percpu **percpu_evt; +} msm_evt; + +static void __iomem *source_base; + +static cycle_t msm_read_timer_count(struct clocksource *cs) +{ + /* + * Shift timer count down by a constant due to unreliable lower bits + * on some targets. + */ + return readl_relaxed(source_base + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT; +} + +static struct clocksource msm_clocksource = { + .name = "dg_timer", + .rating = 300, + .read = msm_read_timer_count, + .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static void __init msm_timer_init(void) { - struct msm_clock *clock; - struct clock_event_device *ce = &msm_clocks[MSM_CLOCK_GPT].clockevent; - struct clocksource *cs = &msm_clocks[MSM_CLOCK_DGT].clocksource; + struct clock_event_device *ce = &msm_clockevent; + struct clocksource *cs = &msm_clocksource; int res; - int global_offset = 0; - if (cpu_is_msm7x01()) { - msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE; - msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10; + event_base = MSM_CSR_BASE; + source_base = MSM_CSR_BASE + 0x10; } else if (cpu_is_msm7x30()) { - msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE + 0x04; - msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x24; + event_base = MSM_CSR_BASE + 0x04; + source_base = MSM_CSR_BASE + 0x24; } else if (cpu_is_qsd8x50()) { - msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE; - msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10; + event_base = MSM_CSR_BASE; + source_base = MSM_CSR_BASE + 0x10; } else if (cpu_is_msm8x60() || cpu_is_msm8960()) { - msm_clocks[MSM_CLOCK_GPT].regbase = MSM_TMR_BASE + 0x04; - msm_clocks[MSM_CLOCK_DGT].regbase = MSM_TMR_BASE + 0x24; - - /* Use CPU0's timer as the global timer. */ - global_offset = MSM_TMR0_BASE - MSM_TMR_BASE; + event_base = MSM_TMR_BASE + 0x04; + /* Use CPU0's timer as the global clock source. */ + source_base = MSM_TMR0_BASE + 0x24; } else BUG(); @@ -216,88 +164,71 @@ static void __init msm_timer_init(void) writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); #endif - clock = &msm_clocks[MSM_CLOCK_GPT]; - clock->local_counter = clock->regbase + TIMER_COUNT_VAL; - - writel_relaxed(0, clock->regbase + TIMER_ENABLE); - writel_relaxed(0, clock->regbase + TIMER_CLEAR); - writel_relaxed(~0, clock->regbase + TIMER_MATCH_VAL); - ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift); + writel_relaxed(0, event_base + TIMER_ENABLE); + writel_relaxed(0, event_base + TIMER_CLEAR); + writel_relaxed(~0, event_base + TIMER_MATCH_VAL); + ce->mult = div_sc(GPT_HZ, NSEC_PER_SEC, ce->shift); /* * allow at least 10 seconds to notice that the timer * wrapped */ - ce->max_delta_ns = - clockevent_delta2ns(0xf0000000 >> clock->shift, ce); + ce->max_delta_ns = clockevent_delta2ns(0xf0000000, ce); /* 4 gets rounded down to 3 */ ce->min_delta_ns = clockevent_delta2ns(4, ce); ce->cpumask = cpumask_of(0); - ce->irq = clock->irq; + ce->irq = INT_GP_TIMER_EXP; if (cpu_is_msm8x60() || cpu_is_msm8960()) { - clock->percpu_evt = alloc_percpu(struct clock_event_device *); - if (!clock->percpu_evt) { + msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); + if (!msm_evt.percpu_evt) { pr_err("memory allocation failed for %s\n", ce->name); goto err; } - - *__this_cpu_ptr(clock->percpu_evt) = ce; + *__this_cpu_ptr(msm_evt.percpu_evt) = ce; res = request_percpu_irq(ce->irq, msm_timer_interrupt, - ce->name, clock->percpu_evt); + ce->name, msm_evt.percpu_evt); if (!res) enable_percpu_irq(ce->irq, 0); } else { - clock->evt = ce; + msm_evt.evt = ce; res = request_irq(ce->irq, msm_timer_interrupt, IRQF_TIMER | IRQF_NOBALANCING | - IRQF_TRIGGER_RISING, ce->name, &clock->evt); + IRQF_TRIGGER_RISING, ce->name, &msm_evt.evt); } if (res) pr_err("request_irq failed for %s\n", ce->name); - clockevents_register_device(ce); err: - clock = &msm_clocks[MSM_CLOCK_DGT]; - clock->local_counter = clock->regbase + TIMER_COUNT_VAL; - clock->global_counter = clock->local_counter + global_offset; - writel_relaxed(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); - res = clocksource_register_hz(cs, clock->freq); + writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); + res = clocksource_register_hz(cs, DGT_HZ >> MSM_DGT_SHIFT); if (res) - pr_err("clocksource_register failed for %s\n", cs->name); + pr_err("clocksource_register failed\n"); } #ifdef CONFIG_LOCAL_TIMERS int __cpuinit local_timer_setup(struct clock_event_device *evt) { - static bool local_timer_inited; - struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER]; - /* Use existing clock_event for cpu 0 */ if (!smp_processor_id()) return 0; - if (!local_timer_inited) { - writel(0, clock->regbase + TIMER_ENABLE); - writel(0, clock->regbase + TIMER_CLEAR); - writel(~0, clock->regbase + TIMER_MATCH_VAL); - local_timer_inited = true; - } - evt->irq = clock->irq; + 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 = CLOCK_EVT_FEAT_ONESHOT; - evt->rating = clock->clockevent.rating; + 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 = clock->clockevent.shift; - evt->mult = div_sc(clock->freq, NSEC_PER_SEC, evt->shift); - evt->max_delta_ns = - clockevent_delta2ns(0xf0000000 >> clock->shift, evt); + 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(clock->percpu_evt) = evt; + *__this_cpu_ptr(msm_evt.percpu_evt) = evt; enable_percpu_irq(evt->irq, 0); - clockevents_register_device(evt); return 0; } -- cgit v1.2.3 From 2081a6b57fba2717fa4b04fe978abad238e1f9e4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:08 -0800 Subject: msm: timer: Remove SoC specific #ifdefs The timer frequency is currently ifdefed in addition to setting the DGT clock's divider value on SCORPIONMP targets. Setup the frequency dynamically using the existing cpu_is_*() branches and assign a custom clocksource read function for 7x01a to get the shift out of the generic path. Signed-off-by: Stephen Boyd Cc: Thomas Gleixner Cc: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index fc0646442e09..ca0a957d8626 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -40,20 +40,7 @@ #define GPT_HZ 32768 -/* TODO: Remove these ifdefs */ -#if defined(CONFIG_ARCH_QSD8X50) -#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */ -#define MSM_DGT_SHIFT (0) -#elif defined(CONFIG_ARCH_MSM7X30) -#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */ -#define MSM_DGT_SHIFT (0) -#elif defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960) -#define DGT_HZ (27000000 / 4) /* 27 MHz (PXO) / 4 by default */ -#define MSM_DGT_SHIFT (0) -#else -#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */ -#define MSM_DGT_SHIFT (5) -#endif +#define MSM_DGT_SHIFT 5 static void __iomem *event_base; @@ -122,19 +109,24 @@ static union { static void __iomem *source_base; static 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) { /* * Shift timer count down by a constant due to unreliable lower bits * on some targets. */ - return readl_relaxed(source_base + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT; + return msm_read_timer_count(cs) >> MSM_DGT_SHIFT; } static struct clocksource msm_clocksource = { .name = "dg_timer", .rating = 300, .read = msm_read_timer_count, - .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), + .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -143,27 +135,31 @@ static void __init msm_timer_init(void) struct clock_event_device *ce = &msm_clockevent; struct clocksource *cs = &msm_clocksource; int res; + u32 dgt_hz; if (cpu_is_msm7x01()) { event_base = MSM_CSR_BASE; source_base = MSM_CSR_BASE + 0x10; + dgt_hz = 19200000 >> MSM_DGT_SHIFT; /* 600 KHz */ + cs->read = msm_read_timer_count_shift; + cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)); } else if (cpu_is_msm7x30()) { event_base = MSM_CSR_BASE + 0x04; source_base = MSM_CSR_BASE + 0x24; + dgt_hz = 24576000 / 4; } else if (cpu_is_qsd8x50()) { event_base = MSM_CSR_BASE; source_base = MSM_CSR_BASE + 0x10; + dgt_hz = 19200000 / 4; } else if (cpu_is_msm8x60() || cpu_is_msm8960()) { event_base = MSM_TMR_BASE + 0x04; /* Use CPU0's timer as the global clock source. */ source_base = MSM_TMR0_BASE + 0x24; + dgt_hz = 27000000 / 4; + writel_relaxed(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); } else BUG(); -#ifdef CONFIG_ARCH_MSM_SCORPIONMP - writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); -#endif - writel_relaxed(0, event_base + TIMER_ENABLE); writel_relaxed(0, event_base + TIMER_CLEAR); writel_relaxed(~0, event_base + TIMER_MATCH_VAL); @@ -201,7 +197,7 @@ static void __init msm_timer_init(void) clockevents_register_device(ce); err: writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); - res = clocksource_register_hz(cs, DGT_HZ >> MSM_DGT_SHIFT); + res = clocksource_register_hz(cs, dgt_hz); if (res) pr_err("clocksource_register failed\n"); } -- cgit v1.2.3 From dde7d61e7f9bf0e844df375412ec5d51650db486 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:09 -0800 Subject: msm: timer: Setup interrupt after registering clockevent Some bootloaders may leave a pending interrupt for the timer and thus msm_timer_interrupt() has a check for a NULL event handler. Unmask and register for the interrupt after registering the clockevent so that we can get the NULL pointer check out of the fast path. Signed-off-by: Stephen Boyd Cc: Thomas Gleixner Cc: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index ca0a957d8626..3d80fbf34165 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -47,8 +47,6 @@ static void __iomem *event_base; static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = *(struct clock_event_device **)dev_id; - if (evt->event_handler == NULL) - return IRQ_HANDLED; /* Stop the timer tick */ if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); @@ -174,6 +172,7 @@ static void __init msm_timer_init(void) ce->cpumask = cpumask_of(0); ce->irq = INT_GP_TIMER_EXP; + clockevents_register_device(ce); if (cpu_is_msm8x60() || cpu_is_msm8960()) { msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); if (!msm_evt.percpu_evt) { @@ -194,7 +193,6 @@ static void __init msm_timer_init(void) if (res) pr_err("request_irq failed for %s\n", ce->name); - clockevents_register_device(ce); err: writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); res = clocksource_register_hz(cs, dgt_hz); @@ -224,8 +222,8 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt) evt->min_delta_ns = clockevent_delta2ns(4, evt); *__this_cpu_ptr(msm_evt.percpu_evt) = evt; - enable_percpu_irq(evt->irq, 0); clockevents_register_device(evt); + enable_percpu_irq(evt->irq, 0); return 0; } -- cgit v1.2.3 From 27fdb577435e336e4b00b9e51626f9002b88a86c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:34:10 -0800 Subject: msm: timer: Use clockevents_config_and_register() Don't open code the min/max delta logic. Use the generic version instead. Also expand the number of bits we can handle because there isn't anything that says we can't handle all 32 bits. Before: max_delta_ns: 122880426391799 min_delta_ns: 122070 mult: 140737 shift: 32 After: max_delta_ns: 131071523464981 min_delta_ns: 122069 mult: 70369 shift: 31 Signed-off-by: Stephen Boyd Cc: Thomas Gleixner Cc: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 3d80fbf34165..11d0d8f2656c 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -93,7 +93,6 @@ static void msm_timer_set_mode(enum clock_event_mode mode, static struct clock_event_device msm_clockevent = { .name = "gp_timer", .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, .rating = 200, .set_next_event = msm_timer_set_next_event, .set_mode = msm_timer_set_mode, @@ -161,18 +160,10 @@ static void __init msm_timer_init(void) writel_relaxed(0, event_base + TIMER_ENABLE); writel_relaxed(0, event_base + TIMER_CLEAR); writel_relaxed(~0, event_base + TIMER_MATCH_VAL); - ce->mult = div_sc(GPT_HZ, NSEC_PER_SEC, ce->shift); - /* - * allow at least 10 seconds to notice that the timer - * wrapped - */ - ce->max_delta_ns = clockevent_delta2ns(0xf0000000, ce); - /* 4 gets rounded down to 3 */ - ce->min_delta_ns = clockevent_delta2ns(4, ce); ce->cpumask = cpumask_of(0); ce->irq = INT_GP_TIMER_EXP; - clockevents_register_device(ce); + clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff); if (cpu_is_msm8x60() || cpu_is_msm8960()) { msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); if (!msm_evt.percpu_evt) { -- cgit v1.2.3 From 2b222a2971e4d73fc25c09aeb203c16c0c3c142e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 19 Sep 2011 10:54:04 -0700 Subject: msm: platsmp: Mark ioremapped memory as __iomem Fixes a handful of sparse warnings. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index fdec58aaa35c..0b3e357c4c8c 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -79,7 +79,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu) ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup), SCM_FLAG_COLDBOOT_CPU1); if (ret == 0) { - void *sc1_base_ptr; + void __iomem *sc1_base_ptr; sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); if (sc1_base_ptr) { writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); -- cgit v1.2.3 From 6384fdadb48a875bcc1c0f58933275f15f409b76 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 10 Oct 2011 14:21:08 +0800 Subject: ARM: pxa: rename IRQ_GPIO to PXA_GPIO_TO_IRQ Avoid potential naming confliction since multiple architecture will be built in a single kernel. Signed-off-by: Haojian Zhuang Acked-by: Grant Likely --- arch/arm/mach-pxa/am200epd.c | 4 +- arch/arm/mach-pxa/am300epd.c | 4 +- arch/arm/mach-pxa/balloon3.c | 2 +- arch/arm/mach-pxa/cm-x270.c | 2 +- arch/arm/mach-pxa/cm-x2xx.c | 4 +- arch/arm/mach-pxa/cm-x300.c | 6 +-- arch/arm/mach-pxa/em-x270.c | 6 +-- arch/arm/mach-pxa/eseries.c | 4 +- arch/arm/mach-pxa/idp.c | 4 +- arch/arm/mach-pxa/include/mach/balloon3.h | 6 +-- arch/arm/mach-pxa/include/mach/corgi.h | 24 ++++++------ arch/arm/mach-pxa/include/mach/gpio.h | 2 +- arch/arm/mach-pxa/include/mach/gumstix.h | 20 +++++----- arch/arm/mach-pxa/include/mach/idp.h | 14 +++---- arch/arm/mach-pxa/include/mach/irqs.h | 2 +- arch/arm/mach-pxa/include/mach/palmld.h | 8 ++-- arch/arm/mach-pxa/include/mach/palmt5.h | 8 ++-- arch/arm/mach-pxa/include/mach/palmtc.h | 4 +- arch/arm/mach-pxa/include/mach/palmtx.h | 8 ++-- arch/arm/mach-pxa/include/mach/pcm027.h | 8 ++-- arch/arm/mach-pxa/include/mach/pcm990_baseboard.h | 14 +++---- arch/arm/mach-pxa/include/mach/poodle.h | 24 ++++++------ arch/arm/mach-pxa/include/mach/spitz.h | 34 ++++++++-------- arch/arm/mach-pxa/include/mach/tosa.h | 48 +++++++++++------------ arch/arm/mach-pxa/include/mach/trizeps4.h | 16 ++++---- arch/arm/mach-pxa/littleton.c | 4 +- arch/arm/mach-pxa/lpd270.c | 4 +- arch/arm/mach-pxa/lubbock.c | 4 +- arch/arm/mach-pxa/mainstone.c | 4 +- arch/arm/mach-pxa/poodle.c | 4 +- arch/arm/mach-pxa/sharpsl_pm.c | 24 ++++++------ arch/arm/mach-pxa/stargate2.c | 22 +++++------ arch/arm/mach-pxa/vpac270.c | 6 +-- arch/arm/mach-pxa/zylonite_pxa300.c | 4 +- 34 files changed, 176 insertions(+), 176 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c index 4cb069fd9af2..ccdac4b6a469 100644 --- a/arch/arm/mach-pxa/am200epd.c +++ b/arch/arm/mach-pxa/am200epd.c @@ -138,7 +138,7 @@ static void am200_cleanup(struct metronomefb_par *par) { int i; - free_irq(IRQ_GPIO(RDY_GPIO_PIN), par); + free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par); for (i = 0; i < ARRAY_SIZE(gpios); i++) gpio_free(gpios[i]); @@ -292,7 +292,7 @@ static int am200_setup_irq(struct fb_info *info) { int ret; - ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq, + ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am200_handle_irq, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "AM200", info->par); if (ret) diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c index fa8bad235d9f..76c4b9494031 100644 --- a/arch/arm/mach-pxa/am300epd.c +++ b/arch/arm/mach-pxa/am300epd.c @@ -176,7 +176,7 @@ static void am300_cleanup(struct broadsheetfb_par *par) { int i; - free_irq(IRQ_GPIO(RDY_GPIO_PIN), par); + free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par); for (i = 0; i < ARRAY_SIZE(gpios); i++) gpio_free(gpios[i]); @@ -240,7 +240,7 @@ static int am300_setup_irq(struct fb_info *info) int ret; struct broadsheetfb_par *par = info->par; - ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am300_handle_irq, + ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am300_handle_irq, IRQF_DISABLED|IRQF_TRIGGER_RISING, "AM300", par); if (ret) diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index fc0b8544e174..1c7890cdb0c9 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -179,7 +179,7 @@ static unsigned long balloon3_ac97_pin_config[] __initdata = { }; static struct ucb1400_pdata vpac270_ucb1400_pdata = { - .irq = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ), + .irq = PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ), }; diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 13518a705399..4ebcee5756b1 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -33,7 +33,7 @@ /* GPIO IRQ usage */ #define GPIO83_MMC_IRQ (83) -#define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) +#define CMX270_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO83_MMC_IRQ) /* MMC power enable */ #define GPIO105_MMC_POWER (105) diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index f2e4190080cb..9344a0e3ba8a 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -58,8 +58,8 @@ extern void cmx270_init(void); #define CMX255_GPIO_IT8152_IRQ (0) #define CMX270_GPIO_IT8152_IRQ (22) -#define CMX255_ETHIRQ IRQ_GPIO(GPIO22_ETHIRQ) -#define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ) +#define CMX255_ETHIRQ PXA_GPIO_TO_IRQ(GPIO22_ETHIRQ) +#define CMX270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO10_ETHIRQ) #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) static struct resource cmx255_dm9000_resource[] = { diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 3a7387f93c38..21ac8e3e2f7a 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -64,7 +64,7 @@ #define GPIO82_MMC_IRQ (82) #define GPIO85_MMC_WP (85) -#define CM_X300_MMC_IRQ IRQ_GPIO(GPIO82_MMC_IRQ) +#define CM_X300_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO82_MMC_IRQ) #define GPIO95_RTC_CS (95) #define GPIO96_RTC_WR (96) @@ -229,8 +229,8 @@ static struct resource dm9000_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)), - .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 94acc0b01dd6..3358f4da2ec9 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -70,7 +70,7 @@ /* common GPIOs */ #define GPIO11_NAND_CS (11) #define GPIO41_ETHIRQ (41) -#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) +#define EM_X270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO41_ETHIRQ) #define GPIO115_WLAN_PWEN (115) #define GPIO19_WLAN_STRAP (19) #define GPIO9_USB_VBUS_EN (9) @@ -805,7 +805,7 @@ static struct spi_board_info em_x270_spi_devices[] __initdata = { .modalias = "libertas_spi", .max_speed_hz = 13000000, .bus_num = 2, - .irq = IRQ_GPIO(116), + .irq = PXA_GPIO_TO_IRQ(116), .chip_select = 0, .controller_data = &em_x270_libertas_chip, .platform_data = &em_x270_libertas_pdata, @@ -1203,7 +1203,7 @@ static struct da903x_platform_data em_x270_da9030_info = { static struct i2c_board_info em_x270_i2c_pmic_info = { I2C_BOARD_INFO("da9030", 0x49), - .irq = IRQ_GPIO(0), + .irq = PXA_GPIO_TO_IRQ(0), .platform_data = &em_x270_da9030_info, }; diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index d82b7aa3c096..e556a1e3ff0f 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -119,8 +119,8 @@ struct resource eseries_tmio_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ), - .end = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ), .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index ddf20e5c376e..bb98ff57b71f 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -75,8 +75,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(4), - .end = IRQ_GPIO(4), + .start = PXA_GPIO_TO_IRQ(4), + .end = PXA_GPIO_TO_IRQ(4), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index 6d7eab3d0867..f02fa1e6ba86 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -172,9 +172,9 @@ enum balloon3_features { /* Balloon3 Interrupts */ #define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x)) -#define BALLOON3_AUX_NIRQ IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ) -#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ) -#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD) +#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/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h index 5dfd1195a5a7..c9f86172520e 100644 --- a/arch/arm/mach-pxa/include/mach/corgi.h +++ b/arch/arm/mach-pxa/include/mach/corgi.h @@ -66,18 +66,18 @@ /* * Corgi Interrupts */ -#define CORGI_IRQ_GPIO_KEY_INT IRQ_GPIO(0) -#define CORGI_IRQ_GPIO_AC_IN IRQ_GPIO(1) -#define CORGI_IRQ_GPIO_WAKEUP IRQ_GPIO(3) -#define CORGI_IRQ_GPIO_AK_INT IRQ_GPIO(4) -#define CORGI_IRQ_GPIO_TP_INT IRQ_GPIO(5) -#define CORGI_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9) -#define CORGI_IRQ_GPIO_nSD_INT IRQ_GPIO(10) -#define CORGI_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(11) -#define CORGI_IRQ_GPIO_CF_CD IRQ_GPIO(14) -#define CORGI_IRQ_GPIO_CHRG_FULL IRQ_GPIO(16) /* Battery fully charged */ -#define CORGI_IRQ_GPIO_CF_IRQ IRQ_GPIO(17) -#define CORGI_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(58+(a)) /* Keyboard Sense lines */ +#define CORGI_IRQ_GPIO_KEY_INT PXA_GPIO_TO_IRQ(0) +#define CORGI_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1) +#define CORGI_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(3) +#define CORGI_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(4) +#define CORGI_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5) +#define CORGI_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9) +#define CORGI_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(10) +#define CORGI_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(11) +#define CORGI_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14) +#define CORGI_IRQ_GPIO_CHRG_FULL PXA_GPIO_TO_IRQ(16) /* Battery fully charged */ +#define CORGI_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17) +#define CORGI_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(58+(a)) /* Keyboard Sense lines */ /* diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h index 004cade7bb13..07fa3ba7a818 100644 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -28,7 +28,7 @@ /* The defines for the driver are needed for the accelerated accessors */ #include "gpio-pxa.h" -#define gpio_to_irq(gpio) IRQ_GPIO(gpio) +#define gpio_to_irq(gpio) PXA_GPIO_TO_IRQ(gpio) static inline int irq_to_gpio(unsigned int irq) { diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h index 9b898680b206..dba14b6503ad 100644 --- a/arch/arm/mach-pxa/include/mach/gumstix.h +++ b/arch/arm/mach-pxa/include/mach/gumstix.h @@ -24,7 +24,7 @@ has detected a cable insertion; driven low otherwise. */ #define GPIO_GUMSTIX_USB_GPIOx 41 /* usb state change */ -#define GUMSTIX_USB_INTR_IRQ IRQ_GPIO(GPIO_GUMSTIX_USB_GPIOn) +#define GUMSTIX_USB_INTR_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_USB_GPIOn) #define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN) #define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT) @@ -35,7 +35,7 @@ has detected a cable insertion; driven low otherwise. */ */ #define GUMSTIX_GPIO_nSD_WP 22 /* SD Write Protect */ #define GUMSTIX_GPIO_nSD_DETECT 11 /* MMC/SD Card Detect */ -#define GUMSTIX_IRQ_GPIO_nSD_DETECT IRQ_GPIO(GUMSTIX_GPIO_nSD_DETECT) +#define GUMSTIX_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT) /* * SMC Ethernet definitions @@ -49,10 +49,10 @@ has detected a cable insertion; driven low otherwise. */ #define GPIO_GUMSTIX_ETH0 36 #define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN) -#define GUMSTIX_ETH0_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH0) +#define GUMSTIX_ETH0_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0) #define GPIO_GUMSTIX_ETH1 27 #define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN) -#define GUMSTIX_ETH1_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH1) +#define GUMSTIX_ETH1_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1) /* CF reset line */ @@ -63,18 +63,18 @@ has detected a cable insertion; driven low otherwise. */ #define GPIO4_nSTSCHG GPIO4_nBVD1 #define GPIO11_nCD 11 #define GPIO26_PRDY_nBSY 26 -#define GUMSTIX_S0_nSTSCHG_IRQ IRQ_GPIO(GPIO4_nSTSCHG) -#define GUMSTIX_S0_nCD_IRQ IRQ_GPIO(GPIO11_nCD) -#define GUMSTIX_S0_PRDY_nBSY_IRQ IRQ_GPIO(GPIO26_PRDY_nBSY) +#define GUMSTIX_S0_nSTSCHG_IRQ PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG) +#define GUMSTIX_S0_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO11_nCD) +#define GUMSTIX_S0_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(GPIO26_PRDY_nBSY) /* CF slot 1 */ #define GPIO18_nBVD1 18 #define GPIO18_nSTSCHG GPIO18_nBVD1 #define GPIO36_nCD 36 #define GPIO27_PRDY_nBSY 27 -#define GUMSTIX_S1_nSTSCHG_IRQ IRQ_GPIO(GPIO18_nSTSCHG) -#define GUMSTIX_S1_nCD_IRQ IRQ_GPIO(GPIO36_nCD) -#define GUMSTIX_S1_PRDY_nBSY_IRQ IRQ_GPIO(GPIO27_PRDY_nBSY) +#define GUMSTIX_S1_nSTSCHG_IRQ PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG) +#define GUMSTIX_S1_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO36_nCD) +#define GUMSTIX_S1_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(GPIO27_PRDY_nBSY) /* CF GPIO line modes */ #define GPIO4_nSTSCHG_MD (GPIO4_nSTSCHG | GPIO_IN) diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h index 5eff96fcc944..a7f912f5ea2f 100644 --- a/arch/arm/mach-pxa/include/mach/idp.h +++ b/arch/arm/mach-pxa/include/mach/idp.h @@ -135,24 +135,24 @@ /* A listing of interrupts used by external hardware devices */ -#define TOUCH_PANEL_IRQ IRQ_GPIO(5) -#define IDE_IRQ IRQ_GPIO(21) +#define TOUCH_PANEL_IRQ PXA_GPIO_TO_IRQ(5) +#define IDE_IRQ PXA_GPIO_TO_IRQ(21) #define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING -#define ETHERNET_IRQ IRQ_GPIO(4) +#define ETHERNET_IRQ PXA_GPIO_TO_IRQ(4) #define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING -#define PCMCIA_S0_CD_VALID IRQ_GPIO(7) +#define PCMCIA_S0_CD_VALID PXA_GPIO_TO_IRQ(7) #define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH -#define PCMCIA_S1_CD_VALID IRQ_GPIO(8) +#define PCMCIA_S1_CD_VALID PXA_GPIO_TO_IRQ(8) #define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH -#define PCMCIA_S0_RDYINT IRQ_GPIO(19) -#define PCMCIA_S1_RDYINT IRQ_GPIO(22) +#define PCMCIA_S0_RDYINT PXA_GPIO_TO_IRQ(19) +#define PCMCIA_S1_RDYINT PXA_GPIO_TO_IRQ(22) /* diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 7cc5a781e99e..1f996643b9de 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -91,7 +91,7 @@ #define PXA_GPIO_IRQ_NUM (192) #define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x)) -#define IRQ_GPIO(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x)) +#define PXA_GPIO_TO_IRQ(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x)) /* * The following interrupts are for board specific purposes. Since diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h index ae536e86d8e8..2c4471336570 100644 --- a/arch/arm/mach-pxa/include/mach/palmld.h +++ b/arch/arm/mach-pxa/include/mach/palmld.h @@ -68,10 +68,10 @@ /* 20, 53 and 86 are usb related too */ /* INTERRUPTS */ -#define IRQ_GPIO_PALMLD_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMLD_GPIO_RESET) -#define IRQ_GPIO_PALMLD_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMLD_SD_DETECT_N) -#define IRQ_GPIO_PALMLD_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMLD_WM9712_IRQ) -#define IRQ_GPIO_PALMLD_IDE_IRQ IRQ_GPIO(GPIO_NR_PALMLD_IDE_IRQ) +#define IRQ_GPIO_PALMLD_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_GPIO_RESET) +#define IRQ_GPIO_PALMLD_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_SD_DETECT_N) +#define IRQ_GPIO_PALMLD_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_WM9712_IRQ) +#define IRQ_GPIO_PALMLD_IDE_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_IDE_IRQ) /** HERE ARE INIT VALUES **/ diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h index 6baf7469d4ec..0bd4f036c72f 100644 --- a/arch/arm/mach-pxa/include/mach/palmt5.h +++ b/arch/arm/mach-pxa/include/mach/palmt5.h @@ -48,10 +48,10 @@ #define GPIO_NR_PALMT5_BT_RESET 83 /* INTERRUPTS */ -#define IRQ_GPIO_PALMT5_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMT5_SD_DETECT_N) -#define IRQ_GPIO_PALMT5_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMT5_WM9712_IRQ) -#define IRQ_GPIO_PALMT5_USB_DETECT IRQ_GPIO(GPIO_NR_PALMT5_USB_DETECT) -#define IRQ_GPIO_PALMT5_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMT5_GPIO_RESET) +#define IRQ_GPIO_PALMT5_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N) +#define IRQ_GPIO_PALMT5_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ) +#define IRQ_GPIO_PALMT5_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT) +#define IRQ_GPIO_PALMT5_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_GPIO_RESET) /** HERE ARE INIT VALUES **/ diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h index 3f9dd3fd4638..c383a21680b6 100644 --- a/arch/arm/mach-pxa/include/mach/palmtc.h +++ b/arch/arm/mach-pxa/include/mach/palmtc.h @@ -52,8 +52,8 @@ #define GPIO_NR_PALMTC_IR_DISABLE 45 /* IRQs */ -#define IRQ_GPIO_PALMTC_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTC_SD_DETECT_N) -#define IRQ_GPIO_PALMTC_WLAN_READY IRQ_GPIO(GPIO_NR_PALMTC_WLAN_READY) +#define IRQ_GPIO_PALMTC_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_SD_DETECT_N) +#define IRQ_GPIO_PALMTC_WLAN_READY PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_WLAN_READY) /* UCB1400 GPIOs */ #define GPIO_NR_PALMTC_POWER_DETECT (0x80 | 0x00) diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h index 7074a6ed46c6..f2e530380253 100644 --- a/arch/arm/mach-pxa/include/mach/palmtx.h +++ b/arch/arm/mach-pxa/include/mach/palmtx.h @@ -62,10 +62,10 @@ #define GPIO_NR_PALMTX_NAND_BUFFER_DIR 79 /* INTERRUPTS */ -#define IRQ_GPIO_PALMTX_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTX_SD_DETECT_N) -#define IRQ_GPIO_PALMTX_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMTX_WM9712_IRQ) -#define IRQ_GPIO_PALMTX_USB_DETECT IRQ_GPIO(GPIO_NR_PALMTX_USB_DETECT) -#define IRQ_GPIO_PALMTX_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMTX_GPIO_RESET) +#define IRQ_GPIO_PALMTX_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_SD_DETECT_N) +#define IRQ_GPIO_PALMTX_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_WM9712_IRQ) +#define IRQ_GPIO_PALMTX_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_USB_DETECT) +#define IRQ_GPIO_PALMTX_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_GPIO_RESET) /** HERE ARE INIT VALUES **/ diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h index 4bac588478a8..6bf28de228bd 100644 --- a/arch/arm/mach-pxa/include/mach/pcm027.h +++ b/arch/arm/mach-pxa/include/mach/pcm027.h @@ -34,7 +34,7 @@ /* I2C RTC */ #define PCM027_RTC_IRQ_GPIO 0 -#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO) +#define PCM027_RTC_IRQ PXA_GPIO_TO_IRQ(PCM027_RTC_IRQ_GPIO) #define PCM027_RTC_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define ADR_PCM027_RTC 0x51 /* I2C address */ @@ -43,21 +43,21 @@ /* Ethernet chip (SMSC91C111) */ #define PCM027_ETH_IRQ_GPIO 52 -#define PCM027_ETH_IRQ IRQ_GPIO(PCM027_ETH_IRQ_GPIO) +#define PCM027_ETH_IRQ PXA_GPIO_TO_IRQ(PCM027_ETH_IRQ_GPIO) #define PCM027_ETH_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM027_ETH_PHYS PXA_CS5_PHYS #define PCM027_ETH_SIZE (1*1024*1024) /* CAN controller SJA1000 (unsupported yet) */ #define PCM027_CAN_IRQ_GPIO 114 -#define PCM027_CAN_IRQ IRQ_GPIO(PCM027_CAN_IRQ_GPIO) +#define PCM027_CAN_IRQ PXA_GPIO_TO_IRQ(PCM027_CAN_IRQ_GPIO) #define PCM027_CAN_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define PCM027_CAN_PHYS 0x22000000 #define PCM027_CAN_SIZE 0x100 /* SPI GPIO expander (unsupported yet) */ #define PCM027_EGPIO_IRQ_GPIO 27 -#define PCM027_EGPIO_IRQ IRQ_GPIO(PCM027_EGPIO_IRQ_GPIO) +#define PCM027_EGPIO_IRQ PXA_GPIO_TO_IRQ(PCM027_EGPIO_IRQ_GPIO) #define PCM027_EGPIO_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define PCM027_EGPIO_CS 24 /* diff --git a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h index 8a4383b776d7..d72791695b26 100644 --- a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h +++ b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h @@ -28,14 +28,14 @@ /* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */ #define PCM990_CTRL_INT_IRQ_GPIO 9 -#define PCM990_CTRL_INT_IRQ IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO) +#define PCM990_CTRL_INT_IRQ PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO) #define PCM990_CTRL_INT_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CTRL_PHYS PXA_CS1_PHYS /* 16-Bit */ #define PCM990_CTRL_BASE 0xea000000 #define PCM990_CTRL_SIZE (1*1024*1024) #define PCM990_CTRL_PWR_IRQ_GPIO 14 -#define PCM990_CTRL_PWR_IRQ IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO) +#define PCM990_CTRL_PWR_IRQ PXA_GPIO_TO_IRQ(PCM990_CTRL_PWR_IRQ_GPIO) #define PCM990_CTRL_PWR_IRQ_EDGE IRQ_TYPE_EDGE_RISING /* visible CPLD (U7) registers */ @@ -132,7 +132,7 @@ * IDE */ #define PCM990_IDE_IRQ_GPIO 13 -#define PCM990_IDE_IRQ IRQ_GPIO(PCM990_IDE_IRQ_GPIO) +#define PCM990_IDE_IRQ PXA_GPIO_TO_IRQ(PCM990_IDE_IRQ_GPIO) #define PCM990_IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_IDE_PLD_PHYS 0x20000000 /* 16 bit wide */ #define PCM990_IDE_PLD_BASE 0xee000000 @@ -188,11 +188,11 @@ * Compact Flash */ #define PCM990_CF_IRQ_GPIO 11 -#define PCM990_CF_IRQ IRQ_GPIO(PCM990_CF_IRQ_GPIO) +#define PCM990_CF_IRQ PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO) #define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CF_CD_GPIO 12 -#define PCM990_CF_CD IRQ_GPIO(PCM990_CF_CD_GPIO) +#define PCM990_CF_CD PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO) #define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */ @@ -258,14 +258,14 @@ * Wolfson AC97 Touch */ #define PCM990_AC97_IRQ_GPIO 10 -#define PCM990_AC97_IRQ IRQ_GPIO(PCM990_AC97_IRQ_GPIO) +#define PCM990_AC97_IRQ PXA_GPIO_TO_IRQ(PCM990_AC97_IRQ_GPIO) #define PCM990_AC97_IRQ_EDGE IRQ_TYPE_EDGE_RISING /* * MMC phyCORE */ #define PCM990_MMC0_IRQ_GPIO 9 -#define PCM990_MMC0_IRQ IRQ_GPIO(PCM990_MMC0_IRQ_GPIO) +#define PCM990_MMC0_IRQ PXA_GPIO_TO_IRQ(PCM990_MMC0_IRQ_GPIO) #define PCM990_MMC0_IRQ_EDGE IRQ_TYPE_EDGE_FALLING /* diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h index 83d1cfd00fc9..763fdc4f2b4b 100644 --- a/arch/arm/mach-pxa/include/mach/poodle.h +++ b/arch/arm/mach-pxa/include/mach/poodle.h @@ -47,18 +47,18 @@ #define POODLE_GPIO_DISCHARGE_ON (42) /* Enable battery discharge */ /* PXA GPIOs */ -#define POODLE_IRQ_GPIO_ON_KEY IRQ_GPIO(0) -#define POODLE_IRQ_GPIO_AC_IN IRQ_GPIO(1) -#define POODLE_IRQ_GPIO_HP_IN IRQ_GPIO(4) -#define POODLE_IRQ_GPIO_CO IRQ_GPIO(16) -#define POODLE_IRQ_GPIO_TP_INT IRQ_GPIO(5) -#define POODLE_IRQ_GPIO_WAKEUP IRQ_GPIO(11) -#define POODLE_IRQ_GPIO_GA_INT IRQ_GPIO(10) -#define POODLE_IRQ_GPIO_CF_IRQ IRQ_GPIO(17) -#define POODLE_IRQ_GPIO_CF_CD IRQ_GPIO(14) -#define POODLE_IRQ_GPIO_nSD_INT IRQ_GPIO(8) -#define POODLE_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9) -#define POODLE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(13) +#define POODLE_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(0) +#define POODLE_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1) +#define POODLE_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(4) +#define POODLE_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(16) +#define POODLE_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5) +#define POODLE_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(11) +#define POODLE_IRQ_GPIO_GA_INT PXA_GPIO_TO_IRQ(10) +#define POODLE_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17) +#define POODLE_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14) +#define POODLE_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(8) +#define POODLE_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9) +#define POODLE_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(13) /* SCOOP GPIOs */ #define POODLE_SCOOP_CHARGE_ON SCOOP_GPCR_PA11 diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h index 685749a51c42..273381a5c497 100644 --- a/arch/arm/mach-pxa/include/mach/spitz.h +++ b/arch/arm/mach-pxa/include/mach/spitz.h @@ -164,23 +164,23 @@ /* Spitz IRQ Definitions */ -#define SPITZ_IRQ_GPIO_KEY_INT IRQ_GPIO(SPITZ_GPIO_KEY_INT) -#define SPITZ_IRQ_GPIO_AC_IN IRQ_GPIO(SPITZ_GPIO_AC_IN) -#define SPITZ_IRQ_GPIO_AK_INT IRQ_GPIO(SPITZ_GPIO_AK_INT) -#define SPITZ_IRQ_GPIO_HP_IN IRQ_GPIO(SPITZ_GPIO_HP_IN) -#define SPITZ_IRQ_GPIO_TP_INT IRQ_GPIO(SPITZ_GPIO_TP_INT) -#define SPITZ_IRQ_GPIO_SYNC IRQ_GPIO(SPITZ_GPIO_SYNC) -#define SPITZ_IRQ_GPIO_ON_KEY IRQ_GPIO(SPITZ_GPIO_ON_KEY) -#define SPITZ_IRQ_GPIO_SWA IRQ_GPIO(SPITZ_GPIO_SWA) -#define SPITZ_IRQ_GPIO_SWB IRQ_GPIO(SPITZ_GPIO_SWB) -#define SPITZ_IRQ_GPIO_BAT_COVER IRQ_GPIO(SPITZ_GPIO_BAT_COVER) -#define SPITZ_IRQ_GPIO_FATAL_BAT IRQ_GPIO(SPITZ_GPIO_FATAL_BAT) -#define SPITZ_IRQ_GPIO_CO IRQ_GPIO(SPITZ_GPIO_CO) -#define SPITZ_IRQ_GPIO_CF_IRQ IRQ_GPIO(SPITZ_GPIO_CF_IRQ) -#define SPITZ_IRQ_GPIO_CF_CD IRQ_GPIO(SPITZ_GPIO_CF_CD) -#define SPITZ_IRQ_GPIO_CF2_IRQ IRQ_GPIO(SPITZ_GPIO_CF2_IRQ) -#define SPITZ_IRQ_GPIO_nSD_INT IRQ_GPIO(SPITZ_GPIO_nSD_INT) -#define SPITZ_IRQ_GPIO_nSD_DETECT IRQ_GPIO(SPITZ_GPIO_nSD_DETECT) +#define SPITZ_IRQ_GPIO_KEY_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_KEY_INT) +#define SPITZ_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_AC_IN) +#define SPITZ_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_AK_INT) +#define SPITZ_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_HP_IN) +#define SPITZ_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT) +#define SPITZ_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(SPITZ_GPIO_SYNC) +#define SPITZ_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(SPITZ_GPIO_ON_KEY) +#define SPITZ_IRQ_GPIO_SWA PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWA) +#define SPITZ_IRQ_GPIO_SWB PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWB) +#define SPITZ_IRQ_GPIO_BAT_COVER PXA_GPIO_TO_IRQ(SPITZ_GPIO_BAT_COVER) +#define SPITZ_IRQ_GPIO_FATAL_BAT PXA_GPIO_TO_IRQ(SPITZ_GPIO_FATAL_BAT) +#define SPITZ_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(SPITZ_GPIO_CO) +#define SPITZ_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_IRQ) +#define SPITZ_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_CD) +#define SPITZ_IRQ_GPIO_CF2_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF2_IRQ) +#define SPITZ_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_INT) +#define SPITZ_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_DETECT) /* * Shared data structures diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index 1272c4b56ceb..4653539a2acc 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -141,30 +141,30 @@ /* * Interrupts */ -#define TOSA_IRQ_GPIO_WAKEUP IRQ_GPIO(TOSA_GPIO_WAKEUP) -#define TOSA_IRQ_GPIO_AC_IN IRQ_GPIO(TOSA_GPIO_AC_IN) -#define TOSA_IRQ_GPIO_RECORD_BTN IRQ_GPIO(TOSA_GPIO_RECORD_BTN) -#define TOSA_IRQ_GPIO_SYNC IRQ_GPIO(TOSA_GPIO_SYNC) -#define TOSA_IRQ_GPIO_USB_IN IRQ_GPIO(TOSA_GPIO_USB_IN) -#define TOSA_IRQ_GPIO_JACKET_DETECT IRQ_GPIO(TOSA_GPIO_JACKET_DETECT) -#define TOSA_IRQ_GPIO_nSD_INT IRQ_GPIO(TOSA_GPIO_nSD_INT) -#define TOSA_IRQ_GPIO_nSD_DETECT IRQ_GPIO(TOSA_GPIO_nSD_DETECT) -#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG) -#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD) -#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG) -#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT) -#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW) -#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN) -#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ) -#define TOSA_IRQ_GPIO_ON_KEY IRQ_GPIO(TOSA_GPIO_ON_KEY) -#define TOSA_IRQ_GPIO_VGA_LINE IRQ_GPIO(TOSA_GPIO_VGA_LINE) -#define TOSA_IRQ_GPIO_TP_INT IRQ_GPIO(TOSA_GPIO_TP_INT) -#define TOSA_IRQ_GPIO_JC_CF_IRQ IRQ_GPIO(TOSA_GPIO_JC_CF_IRQ) -#define TOSA_IRQ_GPIO_BAT_LOCKED IRQ_GPIO(TOSA_GPIO_BAT_LOCKED) -#define TOSA_IRQ_GPIO_BAT1_LOW IRQ_GPIO(TOSA_GPIO_BAT1_LOW) -#define TOSA_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(69+(a)) - -#define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW) +#define TOSA_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(TOSA_GPIO_WAKEUP) +#define TOSA_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN) +#define TOSA_IRQ_GPIO_RECORD_BTN PXA_GPIO_TO_IRQ(TOSA_GPIO_RECORD_BTN) +#define TOSA_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(TOSA_GPIO_SYNC) +#define TOSA_IRQ_GPIO_USB_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_USB_IN) +#define TOSA_IRQ_GPIO_JACKET_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_JACKET_DETECT) +#define TOSA_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_INT) +#define TOSA_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_DETECT) +#define TOSA_IRQ_GPIO_BAT1_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_CRG) +#define TOSA_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_CD) +#define TOSA_IRQ_GPIO_BAT0_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_CRG) +#define TOSA_IRQ_GPIO_TC6393XB_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TC6393XB_INT) +#define TOSA_IRQ_GPIO_BAT0_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_LOW) +#define TOSA_IRQ_GPIO_EAR_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_EAR_IN) +#define TOSA_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_IRQ) +#define TOSA_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(TOSA_GPIO_ON_KEY) +#define TOSA_IRQ_GPIO_VGA_LINE PXA_GPIO_TO_IRQ(TOSA_GPIO_VGA_LINE) +#define TOSA_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TP_INT) +#define TOSA_IRQ_GPIO_JC_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_JC_CF_IRQ) +#define TOSA_IRQ_GPIO_BAT_LOCKED PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT_LOCKED) +#define TOSA_IRQ_GPIO_BAT1_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_LOW) +#define TOSA_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(69+(a)) + +#define TOSA_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_MAIN_BAT_LOW) #define TOSA_KEY_SYNC KEY_102ND /* ??? */ diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h index 903e1a2e6641..d2ca01053f69 100644 --- a/arch/arm/mach-pxa/include/mach/trizeps4.h +++ b/arch/arm/mach-pxa/include/mach/trizeps4.h @@ -43,30 +43,30 @@ /* Ethernet Controller Davicom DM9000 */ #define GPIO_DM9000 101 -#define TRIZEPS4_ETH_IRQ IRQ_GPIO(GPIO_DM9000) +#define TRIZEPS4_ETH_IRQ PXA_GPIO_TO_IRQ(GPIO_DM9000) /* UCB1400 audio / TS-controller */ #define GPIO_UCB1400 1 -#define TRIZEPS4_UCB1400_IRQ IRQ_GPIO(GPIO_UCB1400) +#define TRIZEPS4_UCB1400_IRQ PXA_GPIO_TO_IRQ(GPIO_UCB1400) /* PCMCIA socket Compact Flash */ #define GPIO_PCD 11 /* PCMCIA Card Detect */ -#define TRIZEPS4_CD_IRQ IRQ_GPIO(GPIO_PCD) +#define TRIZEPS4_CD_IRQ PXA_GPIO_TO_IRQ(GPIO_PCD) #define GPIO_PRDY 13 /* READY / nINT */ -#define TRIZEPS4_READY_NINT IRQ_GPIO(GPIO_PRDY) +#define TRIZEPS4_READY_NINT PXA_GPIO_TO_IRQ(GPIO_PRDY) /* MMC socket */ #define GPIO_MMC_DET 12 -#define TRIZEPS4_MMC_IRQ IRQ_GPIO(GPIO_MMC_DET) +#define TRIZEPS4_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO_MMC_DET) /* DOC NAND chip */ #define GPIO_DOC_LOCK 94 #define GPIO_DOC_IRQ 93 -#define TRIZEPS4_DOC_IRQ IRQ_GPIO(GPIO_DOC_IRQ) +#define TRIZEPS4_DOC_IRQ PXA_GPIO_TO_IRQ(GPIO_DOC_IRQ) /* SPI interface */ #define GPIO_SPI 53 -#define TRIZEPS4_SPI_IRQ IRQ_GPIO(GPIO_SPI) +#define TRIZEPS4_SPI_IRQ PXA_GPIO_TO_IRQ(GPIO_SPI) /* LEDS using tx2 / rx2 */ #define GPIO_SYS_BUSY_LED 46 @@ -74,7 +74,7 @@ /* Off-module PIC on ConXS board */ #define GPIO_PIC 0 -#define TRIZEPS4_PIC_IRQ IRQ_GPIO(GPIO_PIC) +#define TRIZEPS4_PIC_IRQ PXA_GPIO_TO_IRQ(GPIO_PIC) #ifdef CONFIG_MACH_TRIZEPS_CONXS /* for CONXS base board define these registers */ diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 0037e57e0cec..9cd235698771 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -124,8 +124,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), - .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, } }; diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 1dd530279e0b..565dd2f2eaa2 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -152,8 +152,8 @@ static void __init lpd270_init_irq(void) handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); - irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lpd270_irq_handler); + irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); } diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index c48ce6da9184..2fb2b50831d1 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -170,8 +170,8 @@ static void __init lubbock_init_irq(void) set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); - irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lubbock_irq_handler); + irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 0567d3965fda..ea62a990ae4b 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -178,8 +178,8 @@ static void __init mainstone_init_irq(void) MST_INTMSKENA = 0; MST_INTSETCLR = 0; - irq_set_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); - irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), mainstone_irq_handler); + irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 50c833177866..1e6d796829ac 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -166,8 +166,8 @@ static struct resource locomo_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(10), - .end = IRQ_GPIO(10), + .start = PXA_GPIO_TO_IRQ(10), + .end = PXA_GPIO_TO_IRQ(10), .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 785880f67b60..8d5168d253a9 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -907,24 +907,24 @@ static int __devinit sharpsl_pm_probe(struct platform_device *pdev) gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock); /* Register interrupt handlers */ - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); + if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_acin)); } - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); + if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batlock)); } if (sharpsl_pm.machinfo->gpio_fatal) { - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); + if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_fatal)); } } if (sharpsl_pm.machinfo->batfull_irq) { /* Register interrupt handler. */ - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); + if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batfull)); } } @@ -953,14 +953,14 @@ static int sharpsl_pm_remove(struct platform_device *pdev) led_trigger_unregister_simple(sharpsl_charge_led_trigger); - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); + free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); + free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); if (sharpsl_pm.machinfo->gpio_fatal) - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); + free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); if (sharpsl_pm.machinfo->batfull_irq) - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); + free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); gpio_free(sharpsl_pm.machinfo->gpio_batlock); gpio_free(sharpsl_pm.machinfo->gpio_batfull); diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 4c9a48bef569..bbf79d532d1e 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -376,7 +376,7 @@ static struct spi_board_info spi_board_info[] __initdata = { .bus_num = 1, .chip_select = 0, .controller_data = &staccel_chip_info, - .irq = IRQ_GPIO(96), + .irq = PXA_GPIO_TO_IRQ(96), }, { .modalias = "cc2420", .max_speed_hz = 6500000, @@ -560,18 +560,18 @@ static struct i2c_board_info __initdata imote2_i2c_board_info[] = { /* Through a nand gate - Also beware, on V2 sensor board the * pull up resistors are missing. */ - .irq = IRQ_GPIO(99), + .irq = PXA_GPIO_TO_IRQ(99), }, { /* ITS400 Sensor board only */ .type = "tsl2561", .addr = 0x49, /* Through a nand gate - Also beware, on V2 sensor board the * pull up resistors are missing. */ - .irq = IRQ_GPIO(99), + .irq = PXA_GPIO_TO_IRQ(99), }, { /* ITS400 Sensor board only */ .type = "tmp175", .addr = 0x4A, - .irq = IRQ_GPIO(96), + .irq = PXA_GPIO_TO_IRQ(96), }, { /* IMB400 Multimedia board */ .type = "wm8940", .addr = 0x1A, @@ -661,8 +661,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(40), - .end = IRQ_GPIO(40), + .start = PXA_GPIO_TO_IRQ(40), + .end = PXA_GPIO_TO_IRQ(40), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; @@ -707,7 +707,7 @@ static int stargate2_mci_init(struct device *dev, } gpio_direction_input(SG2_GPIO_nSD_DETECT); - err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), + err = request_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), stargate2_detect_int, IRQ_TYPE_EDGE_BOTH, "MMC card detect", @@ -738,7 +738,7 @@ static void stargate2_mci_setpower(struct device *dev, unsigned int vdd) static void stargate2_mci_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), data); + free_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), data); gpio_free(SG2_SD_POWER_ENABLE); gpio_free(SG2_GPIO_nSD_DETECT); } @@ -938,18 +938,18 @@ static struct i2c_board_info __initdata stargate2_i2c_board_info[] = { /* Through a nand gate - Also beware, on V2 sensor board the * pull up resistors are missing. */ - .irq = IRQ_GPIO(99), + .irq = PXA_GPIO_TO_IRQ(99), }, { /* ITS400 Sensor board only */ .type = "tsl2561", .addr = 0x49, /* Through a nand gate - Also beware, on V2 sensor board the * pull up resistors are missing. */ - .irq = IRQ_GPIO(99), + .irq = PXA_GPIO_TO_IRQ(99), }, { /* ITS400 Sensor board only */ .type = "tmp175", .addr = 0x4A, - .irq = IRQ_GPIO(96), + .irq = PXA_GPIO_TO_IRQ(96), }, }; diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index a7539a6ed1ff..585e4f443e15 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -395,8 +395,8 @@ static struct resource vpac270_dm9000_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ), - .end = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; @@ -433,7 +433,7 @@ static pxa2xx_audio_ops_t vpac270_ac97_pdata = { }; static struct ucb1400_pdata vpac270_ucb1400_pdata = { - .irq = IRQ_GPIO(GPIO113_VPAC270_TS_IRQ), + .irq = PXA_GPIO_TO_IRQ(GPIO113_VPAC270_TS_IRQ), }; static struct platform_device vpac270_ucb1400_device = { diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 93c64d8d7de9..86e59c043de2 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -231,12 +231,12 @@ static struct i2c_board_info zylonite_i2c_board_info[] = { .type = "pca9539", .addr = 0x74, .platform_data = &gpio_exp[0], - .irq = IRQ_GPIO(18), + .irq = PXA_GPIO_TO_IRQ(18), }, { .type = "pca9539", .addr = 0x75, .platform_data = &gpio_exp[1], - .irq = IRQ_GPIO(19), + .irq = PXA_GPIO_TO_IRQ(19), }, }; -- cgit v1.2.3 From 87c49e20579c933d531a376596875b8fd5dcb04f Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 10 Oct 2011 14:38:46 +0800 Subject: ARM: pxa: use chained interrupt for GPIO0 and GPIO1 GPIO0 and GPIO1 are linked to unique interrupt line in PXA series, others are linked to another interrupt line. All GPIO are linked to one interrupt line in MMP series. Since gpio driver is shared between PXA series and MMP series, define GPIO0 and GPIO1 as chained interrupt chip. So we can move out gpio code from irq.c to gpio-pxa.c. Signed-off-by: Haojian Zhuang Acked-by: Grant Likely --- arch/arm/mach-pxa/include/mach/gpio.h | 15 +-------- arch/arm/mach-pxa/include/mach/irqs.h | 4 +-- arch/arm/mach-pxa/irq.c | 58 ----------------------------------- drivers/gpio/gpio-pxa.c | 14 +++++++++ 4 files changed, 16 insertions(+), 75 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h index 07fa3ba7a818..13b903907087 100644 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -29,20 +29,7 @@ #include "gpio-pxa.h" #define gpio_to_irq(gpio) PXA_GPIO_TO_IRQ(gpio) - -static inline int irq_to_gpio(unsigned int irq) -{ - int gpio; - - if (irq == IRQ_GPIO0 || irq == IRQ_GPIO1) - return irq - IRQ_GPIO0; - - gpio = irq - PXA_GPIO_IRQ_BASE; - if (gpio >= 2 && gpio < NR_BUILTIN_GPIO) - return gpio; - - return -1; -} +#define irq_to_gpio(irq) (irq - PXA_GPIO_TO_IRQ(0)) #include #endif diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 1f996643b9de..b83d8ff4eae8 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -89,9 +89,7 @@ #define PXA_GPIO_IRQ_BASE PXA_IRQ(96) #define PXA_GPIO_IRQ_NUM (192) - -#define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x)) -#define PXA_GPIO_TO_IRQ(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x)) +#define PXA_GPIO_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x)) /* * The following interrupts are for board specific purposes. Since diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 532c5d3a97d2..36c538f48fa6 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -92,44 +92,6 @@ static struct irq_chip pxa_internal_irq_chip = { .irq_unmask = pxa_unmask_irq, }; -/* - * GPIO IRQs for GPIO 0 and 1 - */ -static int pxa_set_low_gpio_type(struct irq_data *d, unsigned int type) -{ - int gpio = d->irq - IRQ_GPIO0; - - if (__gpio_is_occupied(gpio)) { - pr_err("%s failed: GPIO is configured\n", __func__); - return -EINVAL; - } - - if (type & IRQ_TYPE_EDGE_RISING) - GRER0 |= GPIO_bit(gpio); - else - GRER0 &= ~GPIO_bit(gpio); - - if (type & IRQ_TYPE_EDGE_FALLING) - GFER0 |= GPIO_bit(gpio); - else - GFER0 &= ~GPIO_bit(gpio); - - return 0; -} - -static void pxa_ack_low_gpio(struct irq_data *d) -{ - GEDR0 = (1 << (d->irq - IRQ_GPIO0)); -} - -static struct irq_chip pxa_low_gpio_chip = { - .name = "GPIO-l", - .irq_ack = pxa_ack_low_gpio, - .irq_mask = pxa_mask_irq, - .irq_unmask = pxa_unmask_irq, - .irq_set_type = pxa_set_low_gpio_type, -}; - asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs) { uint32_t icip, icmr, mask; @@ -160,25 +122,6 @@ asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs) } while (1); } -static void __init pxa_init_low_gpio_irq(set_wake_t fn) -{ - int irq; - - /* clear edge detection on GPIO 0 and 1 */ - GFER0 &= ~0x3; - GRER0 &= ~0x3; - GEDR0 = 0x3; - - for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { - irq_set_chip_and_handler(irq, &pxa_low_gpio_chip, - handle_edge_irq); - irq_set_chip_data(irq, irq_base(0)); - set_irq_flags(irq, IRQF_VALID); - } - - pxa_low_gpio_chip.irq_set_wake = fn; -} - void __init pxa_init_irq(int irq_nr, set_wake_t fn) { int irq, i, n; @@ -209,7 +152,6 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn) __raw_writel(1, irq_base(0) + ICCR); pxa_internal_irq_chip.irq_set_wake = fn; - pxa_init_low_gpio_irq(fn); } #ifdef CONFIG_PM diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index ee137712f9db..a4121bb50cf2 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -283,6 +283,20 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) __raw_writel(~0,c->regbase + GEDR_OFFSET); } +#ifdef CONFIG_ARCH_PXA + irq = gpio_to_irq(0); + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); + + irq = gpio_to_irq(1); + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); +#endif + for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); -- cgit v1.2.3 From 4929f5a8a99f64378659c5658621e45c90c2aaa9 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 10 Oct 2011 16:03:51 +0800 Subject: ARM: pxa: rename gpio_to_irq and irq_to_gpio Avoid to define gpio_to_irq() and irq_to_gpio() for potential name confliction since multiple architecture will be built together. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/aspenite.c | 4 +- arch/arm/mach-mmp/flint.c | 4 +- arch/arm/mach-mmp/include/mach/gpio-pxa.h | 1 + arch/arm/mach-mmp/include/mach/gpio.h | 3 -- arch/arm/mach-mmp/include/mach/irqs.h | 1 + arch/arm/mach-mmp/tavorevb.c | 4 +- arch/arm/mach-mmp/teton_bga.c | 2 +- arch/arm/mach-pxa/capc7117.c | 12 ++--- arch/arm/mach-pxa/cm-x270.c | 2 +- arch/arm/mach-pxa/colibri-pxa270.c | 6 +-- arch/arm/mach-pxa/colibri-pxa300.c | 4 +- arch/arm/mach-pxa/colibri-pxa320.c | 4 +- arch/arm/mach-pxa/corgi.c | 2 +- arch/arm/mach-pxa/hx4700.c | 18 +++---- arch/arm/mach-pxa/icontrol.c | 8 +-- arch/arm/mach-pxa/include/mach/csb726.h | 4 +- arch/arm/mach-pxa/include/mach/gpio.h | 3 -- arch/arm/mach-pxa/littleton.c | 2 +- arch/arm/mach-pxa/magician.c | 8 +-- arch/arm/mach-pxa/mioa701.c | 8 +-- arch/arm/mach-pxa/mxm8x10.c | 4 +- arch/arm/mach-pxa/poodle.c | 2 +- arch/arm/mach-pxa/pxa25x.c | 2 +- arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/raumfeld.c | 8 +-- arch/arm/mach-pxa/saar.c | 6 +-- arch/arm/mach-pxa/saarb.c | 2 +- arch/arm/mach-pxa/spitz.c | 2 +- arch/arm/mach-pxa/stargate2.c | 4 +- arch/arm/mach-pxa/tavorevb.c | 4 +- arch/arm/mach-pxa/tavorevb3.c | 2 +- arch/arm/mach-pxa/tosa.c | 4 +- arch/arm/mach-pxa/viper.c | 12 ++--- arch/arm/mach-pxa/vpac270.c | 4 +- arch/arm/mach-pxa/z2.c | 2 +- arch/arm/mach-pxa/zeus.c | 20 +++---- arch/arm/mach-pxa/zylonite.c | 4 +- arch/arm/plat-pxa/include/plat/gpio-pxa.h | 1 + drivers/gpio/gpio-pxa.c | 89 +++++++++++++++++++++++++++++-- 39 files changed, 176 insertions(+), 98 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 06b5ad774604..fb7dfc157a5c 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -120,8 +120,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(27), - .end = gpio_to_irq(27), + .start = MMP_GPIO_TO_IRQ(27), + .end = MMP_GPIO_TO_IRQ(27), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index c4fd806b15b4..a64c172082c4 100644 --- a/arch/arm/mach-mmp/flint.c +++ b/arch/arm/mach-mmp/flint.c @@ -87,8 +87,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(155), - .end = gpio_to_irq(155), + .start = MMP_GPIO_TO_IRQ(155), + .end = MMP_GPIO_TO_IRQ(155), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-mmp/include/mach/gpio-pxa.h b/arch/arm/mach-mmp/include/mach/gpio-pxa.h index d14eeaf16322..a462d1ca214e 100644 --- a/arch/arm/mach-mmp/include/mach/gpio-pxa.h +++ b/arch/arm/mach-mmp/include/mach/gpio-pxa.h @@ -2,6 +2,7 @@ #define __ASM_MACH_GPIO_PXA_H #include +#include #include #define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000) diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h index 681262359d1c..32b684aacea8 100644 --- a/arch/arm/mach-mmp/include/mach/gpio.h +++ b/arch/arm/mach-mmp/include/mach/gpio.h @@ -3,9 +3,6 @@ #include -#define gpio_to_irq(gpio) (IRQ_GPIO_START + (gpio)) -#define irq_to_gpio(irq) ((irq) - IRQ_GPIO_START) - #define __gpio_is_inverted(gpio) (0) #define __gpio_is_occupied(gpio) (0) diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index a09d328e2ddd..ec95951f0983 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -221,6 +221,7 @@ #define IRQ_GPIO_START 128 #define IRQ_GPIO_NUM 192 #define IRQ_GPIO(x) (IRQ_GPIO_START + (x)) +#define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio)) #define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM) diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c index eb5be879fd8c..0afe3a39982f 100644 --- a/arch/arm/mach-mmp/tavorevb.c +++ b/arch/arm/mach-mmp/tavorevb.c @@ -71,8 +71,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(80), - .end = gpio_to_irq(80), + .start = MMP_GPIO_TO_IRQ(80), + .end = MMP_GPIO_TO_IRQ(80), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c index bbe4727b96cc..825a01cdcccd 100644 --- a/arch/arm/mach-mmp/teton_bga.c +++ b/arch/arm/mach-mmp/teton_bga.c @@ -66,7 +66,7 @@ static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = { static struct i2c_board_info teton_bga_i2c_info[] __initdata = { { I2C_BOARD_INFO("ds1337", 0x68), - .irq = gpio_to_irq(RTC_INT_GPIO) + .irq = MMP_GPIO_TO_IRQ(RTC_INT_GPIO) }, }; diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c index 4efc16d39c79..5516317b9e64 100644 --- a/arch/arm/mach-pxa/capc7117.c +++ b/arch/arm/mach-pxa/capc7117.c @@ -50,8 +50,8 @@ static struct resource capc7117_ide_resources[] = { .flags = IORESOURCE_MEM }, [2] = { - .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)), - .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING } }; @@ -80,7 +80,7 @@ static void __init capc7117_ide_init(void) static struct plat_serial8250_port ti16c752_platform_data[] = { [0] = { .mapbase = 0x14000000, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO78)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO78)), .irqflags = IRQF_TRIGGER_RISING, .flags = TI16C752_FLAGS, .iotype = UPIO_MEM, @@ -89,7 +89,7 @@ static struct plat_serial8250_port ti16c752_platform_data[] = { }, [1] = { .mapbase = 0x14000040, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO79)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO79)), .irqflags = IRQF_TRIGGER_RISING, .flags = TI16C752_FLAGS, .iotype = UPIO_MEM, @@ -98,7 +98,7 @@ static struct plat_serial8250_port ti16c752_platform_data[] = { }, [2] = { .mapbase = 0x14000080, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO80)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO80)), .irqflags = IRQF_TRIGGER_RISING, .flags = TI16C752_FLAGS, .iotype = UPIO_MEM, @@ -107,7 +107,7 @@ static struct plat_serial8250_port ti16c752_platform_data[] = { }, [3] = { .mapbase = 0x140000c0, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO81)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO81)), .irqflags = IRQF_TRIGGER_RISING, .flags = TI16C752_FLAGS, .iotype = UPIO_MEM, diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 4ebcee5756b1..431ef56700c4 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -380,7 +380,7 @@ static struct spi_board_info cm_x270_spi_devices[] __initdata = { .modalias = "libertas_spi", .max_speed_hz = 13000000, .bus_num = 2, - .irq = gpio_to_irq(95), + .irq = PXA_GPIO_TO_IRQ(95), .chip_select = 0, .controller_data = &cm_x270_libertas_chip, .platform_data = &cm_x270_libertas_pdata, diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c index 05bfa1b1c001..f0fe9a51dfcc 100644 --- a/arch/arm/mach-pxa/colibri-pxa270.c +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -218,8 +218,8 @@ static struct resource colibri_pxa270_dm9000_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = gpio_to_irq(GPIO114_COLIBRI_PXA270_ETH_IRQ), - .end = gpio_to_irq(GPIO114_COLIBRI_PXA270_ETH_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, }, }; @@ -249,7 +249,7 @@ static pxa2xx_audio_ops_t colibri_pxa270_ac97_pdata = { }; static struct ucb1400_pdata colibri_pxa270_ucb1400_pdata = { - .irq = gpio_to_irq(GPIO113_COLIBRI_PXA270_TS_IRQ), + .irq = PXA_GPIO_TO_IRQ(GPIO113_COLIBRI_PXA270_TS_IRQ), }; static struct platform_device colibri_pxa270_ucb1400_device = { diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index c825e8bf2db1..0a6222e20f9b 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -78,8 +78,8 @@ static struct resource colibri_asix_resource[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), - .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), + .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), + .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, } }; diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index 692e1ffc5586..8cbb2b43ed11 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -115,8 +115,8 @@ static struct resource colibri_asix_resource[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), - .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), + .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), + .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, } }; diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 549468d088b9..3812ba0ff50c 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -531,7 +531,7 @@ static struct spi_board_info corgi_spi_devices[] = { .chip_select = 0, .platform_data = &corgi_ads7846_info, .controller_data= &corgi_ads7846_chip, - .irq = gpio_to_irq(CORGI_GPIO_TP_INT), + .irq = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT), }, { .modalias = "corgi-lcd", .max_speed_hz = 50000, diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 6f6368ece9bd..82e9976e5657 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -252,8 +252,8 @@ static struct resource asic3_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ), - .end = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ), .flags = IORESOURCE_IRQ, }, /* SD part */ @@ -263,8 +263,8 @@ static struct resource asic3_resources[] = { .flags = IORESOURCE_MEM, }, [3] = { - .start = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ), - .end = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ), .flags = IORESOURCE_IRQ, }, }; @@ -587,7 +587,7 @@ static struct spi_board_info tsc2046_board_info[] __initdata = { .modalias = "ads7846", .bus_num = 2, .max_speed_hz = 2600000, /* 100 kHz sample rate */ - .irq = gpio_to_irq(GPIO58_HX4700_TSC2046_nPENIRQ), + .irq = PXA_GPIO_TO_IRQ(GPIO58_HX4700_TSC2046_nPENIRQ), .platform_data = &tsc2046_info, .controller_data = &tsc2046_chip, }, @@ -635,15 +635,15 @@ static struct resource power_supply_resources[] = { .name = "ac", .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, - .start = gpio_to_irq(GPIOD9_nAC_IN), - .end = gpio_to_irq(GPIOD9_nAC_IN), + .start = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), + .end = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), }, [1] = { .name = "usb", .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, - .start = gpio_to_irq(GPIOD14_nUSBC_DETECT), - .end = gpio_to_irq(GPIOD14_nUSBC_DETECT), + .start = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), + .end = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), }, }; diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index f78d5db758da..33e81e87a9da 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c @@ -86,7 +86,7 @@ static struct spi_board_info mcp251x_board_info[] = { .chip_select = 0, .platform_data = &mcp251x_info, .controller_data = &mcp251x_chip_info1, - .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1) + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1) }, { .modalias = "mcp2515", @@ -95,7 +95,7 @@ static struct spi_board_info mcp251x_board_info[] = { .chip_select = 1, .platform_data = &mcp251x_info, .controller_data = &mcp251x_chip_info2, - .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2) + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2) }, { .modalias = "mcp2515", @@ -104,7 +104,7 @@ static struct spi_board_info mcp251x_board_info[] = { .chip_select = 0, .platform_data = &mcp251x_info, .controller_data = &mcp251x_chip_info3, - .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3) + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3) }, { .modalias = "mcp2515", @@ -113,7 +113,7 @@ static struct spi_board_info mcp251x_board_info[] = { .chip_select = 1, .platform_data = &mcp251x_info, .controller_data = &mcp251x_chip_info4, - .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ4) + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4) } }; diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h index 747ab1a71f2f..2628e7b72116 100644 --- a/arch/arm/mach-pxa/include/mach/csb726.h +++ b/arch/arm/mach-pxa/include/mach/csb726.h @@ -19,8 +19,8 @@ #define CSB726_FLASH_SIZE (64 * 1024 * 1024) #define CSB726_FLASH_uMON (8 * 1024 * 1024) -#define CSB726_IRQ_LAN gpio_to_irq(CSB726_GPIO_IRQ_LAN) -#define CSB726_IRQ_SM501 gpio_to_irq(CSB726_GPIO_IRQ_SM501) +#define CSB726_IRQ_LAN PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_LAN) +#define CSB726_IRQ_SM501 PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_SM501) #endif diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h index 13b903907087..5cf0137e64d9 100644 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -28,8 +28,5 @@ /* The defines for the driver are needed for the accelerated accessors */ #include "gpio-pxa.h" -#define gpio_to_irq(gpio) PXA_GPIO_TO_IRQ(gpio) -#define irq_to_gpio(irq) (irq - PXA_GPIO_TO_IRQ(0)) - #include #endif diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 9cd235698771..27147f6ff7cb 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -395,7 +395,7 @@ static struct i2c_board_info littleton_i2c_info[] = { .type = "da9034", .addr = 0x34, .platform_data = &littleton_da9034_info, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO18)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO18)), }, [1] = { .type = "max7320", diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 4b796c37af3e..e340ea084248 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -184,8 +184,8 @@ static struct resource egpio_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ), - .end = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ), .flags = IORESOURCE_IRQ, }, }; @@ -468,8 +468,8 @@ static struct resource pasic3_resources[] = { }, /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */ [1] = { - .start = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ), - .end = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index b938fc2c316a..23f90c74c191 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -541,15 +541,15 @@ static struct pda_power_pdata power_pdata = { static struct resource power_resources[] = { [0] = { .name = "ac", - .start = gpio_to_irq(GPIO96_AC_DETECT), - .end = gpio_to_irq(GPIO96_AC_DETECT), + .start = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT), + .end = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, }, [1] = { .name = "usb", - .start = gpio_to_irq(GPIO13_nUSB_DETECT), - .end = gpio_to_irq(GPIO13_nUSB_DETECT), + .start = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT), + .end = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, }, diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index b5a8fd3fce04..a13a1e365851 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c @@ -416,8 +416,8 @@ static struct resource dm9k_resources[] = { .flags = IORESOURCE_MEM }, [2] = { - .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)), - .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE } }; diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 1e6d796829ac..8ee4b6cfa385 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -212,7 +212,7 @@ static struct spi_board_info poodle_spi_devices[] = { .bus_num = 1, .platform_data = &poodle_ads7846_info, .controller_data= &poodle_ads7846_chip, - .irq = gpio_to_irq(POODLE_GPIO_TP_INT), + .irq = PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT), }, }; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index f05f9486b0cb..0f38cfce5c35 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -287,7 +287,7 @@ static inline void pxa25x_init_pm(void) {} static int pxa25x_set_wake(struct irq_data *d, unsigned int on) { - int gpio = irq_to_gpio(d->irq); + int gpio = pxa_irq_to_gpio(d->irq); uint32_t mask = 0; if (gpio >= 0 && gpio < 85) diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index bc5a98ebaa72..44563a0997bd 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -355,7 +355,7 @@ static inline void pxa27x_init_pm(void) {} */ static int pxa27x_set_wake(struct irq_data *d, unsigned int on) { - int gpio = irq_to_gpio(d->irq); + int gpio = pxa_irq_to_gpio(d->irq); uint32_t mask; if (gpio >= 0 && gpio < 128) diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 6810cddec927..9c58e87f2b82 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -292,8 +292,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = gpio_to_irq(GPIO_ETH_IRQ), - .end = gpio_to_irq(GPIO_ETH_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, } }; @@ -671,7 +671,7 @@ static struct lis3lv02d_platform_data lis3_pdata = { .chip_select = 1, \ .controller_data = (void *) GPIO_ACCEL_CS, \ .platform_data = &lis3_pdata, \ - .irq = gpio_to_irq(GPIO_ACCEL_IRQ), \ + .irq = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ), \ } #define SPI_DAC7512 \ @@ -955,7 +955,7 @@ static struct eeti_ts_platform_data eeti_ts_pdata = { static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { .type = "eeti_ts", .addr = 0x0a, - .irq = gpio_to_irq(GPIO_TOUCH_IRQ), + .irq = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ), .platform_data = &eeti_ts_pdata, }; diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index fc2c1e05af9c..423ec899a8a8 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -96,8 +96,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), - .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; @@ -502,7 +502,7 @@ static struct i2c_board_info saar_i2c_info[] = { .type = "da9034", .addr = 0x34, .platform_data = &saar_da9034_info, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)), }, }; diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c index 3e999e308a2d..d1cdd6a081ed 100644 --- a/arch/arm/mach-pxa/saarb.c +++ b/arch/arm/mach-pxa/saarb.c @@ -92,7 +92,7 @@ static struct i2c_board_info saarb_i2c_info[] = { .type = "88PM860x", .addr = 0x34, .platform_data = &saarb_pm8607_info, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)), }, }; diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 953a9195f9e5..1b39cec03cce 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -552,7 +552,7 @@ static struct spi_board_info spitz_spi_devices[] = { .chip_select = 0, .platform_data = &spitz_ads7846_info, .controller_data = &spitz_ads7846_chip, - .irq = gpio_to_irq(SPITZ_GPIO_TP_INT), + .irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT), }, { .modalias = "corgi-lcd", .max_speed_hz = 50000, diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index bbf79d532d1e..940ca56b37f9 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -546,7 +546,7 @@ static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = { .type = "da9030", .addr = 0x49, .platform_data = &imote2_da9030_pdata, - .irq = gpio_to_irq(1), + .irq = PXA_GPIO_TO_IRQ(1), }, }; @@ -913,7 +913,7 @@ static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = { .type = "da9030", .addr = 0x49, .platform_data = &stargate2_da9030_pdata, - .irq = gpio_to_irq(1), + .irq = PXA_GPIO_TO_IRQ(1), }, }; diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index ad47bb98f30d..43bdcb9761f2 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -85,8 +85,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), - .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c index fd569167302a..46c60b3cbe79 100644 --- a/arch/arm/mach-pxa/tavorevb3.c +++ b/arch/arm/mach-pxa/tavorevb3.c @@ -101,7 +101,7 @@ static struct i2c_board_info evb3_i2c_info[] = { .type = "88PM860x", .addr = 0x34, .platform_data = &evb3_pm8607_info, - .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)), }, }; diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 402b0c96613b..1ddb9826448a 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -404,8 +404,8 @@ static struct pda_power_pdata tosa_power_data = { static struct resource tosa_power_resource[] = { { .name = "ac", - .start = gpio_to_irq(TOSA_GPIO_AC_IN), - .end = gpio_to_irq(TOSA_GPIO_AC_IN), + .start = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN), + .end = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 242ddae332d3..d9a653a77176 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -422,8 +422,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(VIPER_ETH_GPIO), - .end = gpio_to_irq(VIPER_ETH_GPIO), + .start = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO), + .end = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, [2] = { @@ -546,7 +546,7 @@ static struct plat_serial8250_port serial_platform_data[] = { /* External UARTs */ { .mapbase = VIPER_UARTA_PHYS, - .irq = gpio_to_irq(VIPER_UARTA_GPIO), + .irq = PXA_GPIO_TO_IRQ(VIPER_UARTA_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 1843200, .regshift = 1, @@ -556,7 +556,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { .mapbase = VIPER_UARTB_PHYS, - .irq = gpio_to_irq(VIPER_UARTB_GPIO), + .irq = PXA_GPIO_TO_IRQ(VIPER_UARTB_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 1843200, .regshift = 1, @@ -596,8 +596,8 @@ static struct resource isp116x_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = gpio_to_irq(VIPER_USB_GPIO), - .end = gpio_to_irq(VIPER_USB_GPIO), + .start = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO), + .end = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 585e4f443e15..bf2403c424bf 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -610,8 +610,8 @@ static struct resource vpac270_ide_resources[] = { .flags = IORESOURCE_DMA }, [3] = { /* IDE IRQ pin */ - .start = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ), - .end = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ), .flags = IORESOURCE_IRQ } }; diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index ead32c90fec1..424661833ce2 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -573,7 +573,7 @@ static struct spi_board_info spi_board_info[] __initdata = { .modalias = "libertas_spi", .platform_data = &z2_lbs_pdata, .controller_data = &z2_lbs_chip_info, - .irq = gpio_to_irq(GPIO36_ZIPITZ2_WIFI_IRQ), + .irq = PXA_GPIO_TO_IRQ(GPIO36_ZIPITZ2_WIFI_IRQ), .max_speed_hz = 13000000, .bus_num = 1, .chip_select = 0, diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 498b83b089f3..68de9c17e4c5 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -233,7 +233,7 @@ static struct plat_serial8250_port serial_platform_data[] = { /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */ { /* COM1 */ .mapbase = 0x10000000, - .irq = gpio_to_irq(ZEUS_UARTA_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTA_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -242,7 +242,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { /* COM2 */ .mapbase = 0x10800000, - .irq = gpio_to_irq(ZEUS_UARTB_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTB_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -251,7 +251,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { /* COM3 */ .mapbase = 0x11000000, - .irq = gpio_to_irq(ZEUS_UARTC_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTC_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -260,7 +260,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { /* COM4 */ .mapbase = 0x11800000, - .irq = gpio_to_irq(ZEUS_UARTD_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTD_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -321,8 +321,8 @@ static struct resource zeus_dm9k0_resource[] = { .flags = IORESOURCE_MEM }, [2] = { - .start = gpio_to_irq(ZEUS_ETH0_GPIO), - .end = gpio_to_irq(ZEUS_ETH0_GPIO), + .start = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO), + .end = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -339,8 +339,8 @@ static struct resource zeus_dm9k1_resource[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = gpio_to_irq(ZEUS_ETH1_GPIO), - .end = gpio_to_irq(ZEUS_ETH1_GPIO), + .start = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO), + .end = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -423,7 +423,7 @@ static struct spi_board_info zeus_spi_board_info[] = { [0] = { .modalias = "mcp2515", .platform_data = &zeus_mcp2515_pdata, - .irq = gpio_to_irq(ZEUS_CAN_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_CAN_GPIO), .max_speed_hz = 1*1000*1000, .bus_num = 3, .mode = SPI_MODE_0, @@ -753,7 +753,7 @@ static struct i2c_board_info __initdata zeus_i2c_devices[] = { { I2C_BOARD_INFO("pca9535", 0x20), .platform_data = &zeus_pca953x_pdata[2], - .irq = gpio_to_irq(ZEUS_EXTGPIO_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_EXTGPIO_GPIO), }, { I2C_BOARD_INFO("lm75a", 0x48) }, { I2C_BOARD_INFO("24c01", 0x50) }, diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 31d496891891..2406fd2727ef 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -407,8 +407,8 @@ static void __init zylonite_init(void) * Note: We depend that the bootloader set * the correct value to MSC register for SMC91x. */ - smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq); - smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); + smc91x_resources[1].start = PXA_GPIO_TO_IRQ(gpio_eth_irq); + smc91x_resources[1].end = PXA_GPIO_TO_IRQ(gpio_eth_irq); platform_device_register(&smc91x_device); pxa_set_ac97_info(NULL); diff --git a/arch/arm/plat-pxa/include/plat/gpio-pxa.h b/arch/arm/plat-pxa/include/plat/gpio-pxa.h index b6390beff323..15bf9be051e8 100644 --- a/arch/arm/plat-pxa/include/plat/gpio-pxa.h +++ b/arch/arm/plat-pxa/include/plat/gpio-pxa.h @@ -40,5 +40,6 @@ extern int pxa_last_gpio; typedef int (*set_wake_t)(struct irq_data *d, unsigned int on); extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn); +extern int pxa_irq_to_gpio(int irq); #endif /* __PLAT_PXA_GPIO_H */ diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index a4121bb50cf2..3e76c588f080 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -39,8 +39,19 @@ struct pxa_gpio_chip { #endif }; +enum { + PXA25X_GPIO = 0, + PXA26X_GPIO, + PXA27X_GPIO, + PXA3XX_GPIO, + PXA93X_GPIO, + MMP_GPIO = 0x10, + MMP2_GPIO, +}; + static DEFINE_SPINLOCK(gpio_lock); static struct pxa_gpio_chip *pxa_gpio_chips; +static int gpio_type; #define for_each_gpio_chip(i, c) \ for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) @@ -55,6 +66,75 @@ static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) return &pxa_gpio_chips[gpio_to_bank(gpio)]; } +static inline int gpio_is_pxa_type(int type) +{ + return (type & MMP_GPIO) == 0; +} + +static inline int gpio_is_mmp_type(int type) +{ + return (type & MMP_GPIO) != 0; +} + +#ifdef CONFIG_ARCH_PXA +static inline int __pxa_gpio_to_irq(int gpio) +{ + if (gpio_is_pxa_type(gpio_type)) + return PXA_GPIO_TO_IRQ(gpio); + return -1; +} + +static inline int __pxa_irq_to_gpio(int irq) +{ + if (gpio_is_pxa_type(gpio_type)) + return irq - PXA_GPIO_TO_IRQ(0); + return -1; +} +#else +static inline int __pxa_gpio_to_irq(int gpio) { return -1; } +static inline int __pxa_irq_to_gpio(int irq) { return -1; } +#endif + +#ifdef CONFIG_ARCH_MMP +static inline int __mmp_gpio_to_irq(int gpio) +{ + if (gpio_is_mmp_type(gpio_type)) + return MMP_GPIO_TO_IRQ(gpio); + return -1; +} + +static inline int __mmp_irq_to_gpio(int irq) +{ + if (gpio_is_mmp_type(gpio_type)) + return irq - MMP_GPIO_TO_IRQ(0); + return -1; +} +#else +static inline int __mmp_gpio_to_irq(int gpio) { return -1; } +static inline int __mmp_irq_to_gpio(int irq) { return -1; } +#endif + +static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + int gpio, ret; + + gpio = chip->base + offset; + ret = __pxa_gpio_to_irq(gpio); + if (ret >= 0) + return ret; + return __mmp_gpio_to_irq(gpio); +} + +int pxa_irq_to_gpio(int irq) +{ + int ret; + + ret = __pxa_irq_to_gpio(irq); + if (ret >= 0) + return ret; + return __mmp_irq_to_gpio(irq); +} + static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { void __iomem *base = gpio_chip_base(chip); @@ -131,6 +211,7 @@ static int __init pxa_init_gpio_chip(int gpio_end) c->direction_output = pxa_gpio_direction_output; c->get = pxa_gpio_get; c->set = pxa_gpio_set; + c->to_irq = pxa_gpio_to_irq; /* number of GPIOs on last bank may be less than 32 */ c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; @@ -158,7 +239,7 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c) static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) { struct pxa_gpio_chip *c; - int gpio = irq_to_gpio(d->irq); + int gpio = pxa_irq_to_gpio(d->irq); unsigned long gpdr, mask = GPIO_bit(gpio); c = gpio_to_pxachip(gpio); @@ -229,7 +310,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) static void pxa_ack_muxed_gpio(struct irq_data *d) { - int gpio = irq_to_gpio(d->irq); + int gpio = pxa_irq_to_gpio(d->irq); struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); @@ -237,7 +318,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d) static void pxa_mask_muxed_gpio(struct irq_data *d) { - int gpio = irq_to_gpio(d->irq); + int gpio = pxa_irq_to_gpio(d->irq); struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); uint32_t grer, gfer; @@ -251,7 +332,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d) static void pxa_unmask_muxed_gpio(struct irq_data *d) { - int gpio = irq_to_gpio(d->irq); + int gpio = pxa_irq_to_gpio(d->irq); struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); c->irq_mask |= GPIO_bit(gpio); -- cgit v1.2.3 From 1a8d5fab16ed9401d99d0c463b5e57bdd744c8d3 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 8 Nov 2011 14:15:59 +0800 Subject: ARM: pxa: rename NR_BUILTIN_GPIO NR_BUILTIN_GPIO is both defined in arch-pxa and arch-mmp. Now replace it with PXA_NR_BUILTIN_GPIO and MMP_NR_BUILTIN_GPIO. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/include/mach/gpio-pxa.h | 2 -- arch/arm/mach-mmp/include/mach/gpio.h | 1 - arch/arm/mach-mmp/include/mach/irqs.h | 5 ++--- arch/arm/mach-mmp/tavorevb.c | 1 + arch/arm/mach-mmp/ttc_dkb.c | 7 ++++--- arch/arm/mach-pxa/include/mach/corgi.h | 2 +- arch/arm/mach-pxa/include/mach/gpio-pxa.h | 2 -- arch/arm/mach-pxa/include/mach/gpio.h | 1 - arch/arm/mach-pxa/include/mach/hx4700.h | 2 +- arch/arm/mach-pxa/include/mach/irqs.h | 4 ++-- arch/arm/mach-pxa/include/mach/littleton.h | 2 +- arch/arm/mach-pxa/include/mach/magician.h | 2 +- arch/arm/mach-pxa/include/mach/poodle.h | 2 +- arch/arm/mach-pxa/include/mach/spitz.h | 6 +++--- arch/arm/mach-pxa/include/mach/tosa.h | 6 +++--- arch/arm/mach-pxa/pcm990-baseboard.c | 6 +++--- arch/arm/plat-pxa/include/plat/gpio.h | 30 ------------------------------ 17 files changed, 23 insertions(+), 58 deletions(-) delete mode 100644 arch/arm/plat-pxa/include/plat/gpio.h (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/gpio-pxa.h b/arch/arm/mach-mmp/include/mach/gpio-pxa.h index a462d1ca214e..9b79937d7817 100644 --- a/arch/arm/mach-mmp/include/mach/gpio-pxa.h +++ b/arch/arm/mach-mmp/include/mach/gpio-pxa.h @@ -10,8 +10,6 @@ #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) #define GPIO_REG(x) (GPIO_REGS_VIRT + (x)) -#define NR_BUILTIN_GPIO IRQ_GPIO_NUM - #define gpio_to_bank(gpio) ((gpio) >> 5) /* NOTE: these macros are defined here to make optimization of diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h index 32b684aacea8..904466d7eb95 100644 --- a/arch/arm/mach-mmp/include/mach/gpio.h +++ b/arch/arm/mach-mmp/include/mach/gpio.h @@ -6,5 +6,4 @@ #define __gpio_is_inverted(gpio) (0) #define __gpio_is_occupied(gpio) (0) -#include #endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index ec95951f0983..34635a0bbb59 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -219,11 +219,10 @@ #define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2) #define IRQ_GPIO_START 128 -#define IRQ_GPIO_NUM 192 -#define IRQ_GPIO(x) (IRQ_GPIO_START + (x)) +#define MMP_NR_BUILTIN_GPIO 192 #define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio)) -#define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM) +#define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO) #define NR_IRQS (IRQ_BOARD_START) diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c index 0afe3a39982f..331f5f358b59 100644 --- a/arch/arm/mach-mmp/tavorevb.c +++ b/arch/arm/mach-mmp/tavorevb.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "common.h" diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 176515a76989..fac0d5d9d464 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -24,12 +24,13 @@ #include #include #include +#include #include "common.h" -#define TTCDKB_GPIO_EXT0(x) (NR_BUILTIN_GPIO + ((x < 0) ? 0 : \ +#define TTCDKB_GPIO_EXT0(x) (MMP_NR_BUILTIN_GPIO + ((x < 0) ? 0 : \ ((x < 16) ? x : 15))) -#define TTCDKB_GPIO_EXT1(x) (NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \ +#define TTCDKB_GPIO_EXT1(x) (MMP_NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \ ((x < 16) ? x : 15))) /* @@ -136,7 +137,7 @@ static struct i2c_board_info ttc_dkb_i2c_info[] = { { .type = "max7312", .addr = 0x23, - .irq = IRQ_GPIO(80), + .irq = MMP_GPIO_TO_IRQ(80), .platform_data = &max7312_data, }, }; diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h index c9f86172520e..f3c3493b468d 100644 --- a/arch/arm/mach-pxa/include/mach/corgi.h +++ b/arch/arm/mach-pxa/include/mach/corgi.h @@ -98,7 +98,7 @@ CORGI_SCP_MIC_BIAS ) #define CORGI_SCOOP_IO_OUT ( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R ) -#define CORGI_SCOOP_GPIO_BASE (NR_BUILTIN_GPIO) +#define CORGI_SCOOP_GPIO_BASE (PXA_NR_BUILTIN_GPIO) #define CORGI_GPIO_LED_GREEN (CORGI_SCOOP_GPIO_BASE + 0) #define CORGI_GPIO_SWA (CORGI_SCOOP_GPIO_BASE + 1) /* Hinge Switch A */ #define CORGI_GPIO_SWB (CORGI_SCOOP_GPIO_BASE + 2) /* Hinge Switch B */ diff --git a/arch/arm/mach-pxa/include/mach/gpio-pxa.h b/arch/arm/mach-pxa/include/mach/gpio-pxa.h index 41b4c93a96c2..134b3bc332cd 100644 --- a/arch/arm/mach-pxa/include/mach/gpio-pxa.h +++ b/arch/arm/mach-pxa/include/mach/gpio-pxa.h @@ -93,8 +93,6 @@ #define GAFR(x) GPIO_REG(0x54 + (((x) & 0x70) >> 2)) -#define NR_BUILTIN_GPIO PXA_GPIO_IRQ_NUM - #define gpio_to_bank(gpio) ((gpio) >> 5) #ifdef CONFIG_CPU_PXA26x diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h index 5cf0137e64d9..561cdbfd7ccf 100644 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -28,5 +28,4 @@ /* The defines for the driver are needed for the accelerated accessors */ #include "gpio-pxa.h" -#include #endif diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h index 37408449ec25..8bc02913517c 100644 --- a/arch/arm/mach-pxa/include/mach/hx4700.h +++ b/arch/arm/mach-pxa/include/mach/hx4700.h @@ -15,7 +15,7 @@ #include #include -#define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO +#define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO #define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS) #define HX4700_NR_IRQS (IRQ_BOARD_START + 70) diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index b83d8ff4eae8..32975adf3ca4 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -88,7 +88,7 @@ #define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */ #define PXA_GPIO_IRQ_BASE PXA_IRQ(96) -#define PXA_GPIO_IRQ_NUM (192) +#define PXA_NR_BUILTIN_GPIO (192) #define PXA_GPIO_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x)) /* @@ -98,7 +98,7 @@ * By default, no board IRQ is reserved. It should be finished in * custom board since sparse IRQ is already enabled. */ -#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM) +#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO) #define NR_IRQS (IRQ_BOARD_START) diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h index b6238cbd8aea..e20ac1b64b00 100644 --- a/arch/arm/mach-pxa/include/mach/littleton.h +++ b/arch/arm/mach-pxa/include/mach/littleton.h @@ -7,7 +7,7 @@ #define LITTLETON_GPIO_LCD_CS (17) -#define EXT0_GPIO_BASE (NR_BUILTIN_GPIO) +#define EXT0_GPIO_BASE (PXA_NR_BUILTIN_GPIO) #define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x)) #define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8) diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h index 7cbfc5d3f9df..ba6a6e1d29e9 100644 --- a/arch/arm/mach-pxa/include/mach/magician.h +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -78,7 +78,7 @@ * CPLD EGPIOs */ -#define MAGICIAN_EGPIO_BASE NR_BUILTIN_GPIO +#define MAGICIAN_EGPIO_BASE PXA_NR_BUILTIN_GPIO #define MAGICIAN_EGPIO(reg,bit) \ (MAGICIAN_EGPIO_BASE + 8*reg + bit) diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h index 763fdc4f2b4b..f32ff75dcca8 100644 --- a/arch/arm/mach-pxa/include/mach/poodle.h +++ b/arch/arm/mach-pxa/include/mach/poodle.h @@ -71,7 +71,7 @@ #define POODLE_SCOOP_IO_DIR ( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT ) #define POODLE_SCOOP_IO_OUT ( 0 ) -#define POODLE_SCOOP_GPIO_BASE (NR_BUILTIN_GPIO) +#define POODLE_SCOOP_GPIO_BASE (PXA_NR_BUILTIN_GPIO) #define POODLE_GPIO_CHARGE_ON (POODLE_SCOOP_GPIO_BASE + 0) #define POODLE_GPIO_CP401 (POODLE_SCOOP_GPIO_BASE + 2) #define POODLE_GPIO_VPEN (POODLE_SCOOP_GPIO_BASE + 7) diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h index 273381a5c497..0bfe6507c95d 100644 --- a/arch/arm/mach-pxa/include/mach/spitz.h +++ b/arch/arm/mach-pxa/include/mach/spitz.h @@ -108,7 +108,7 @@ #define SPITZ_SCP_SUS_CLR (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON) #define SPITZ_SCP_SUS_SET 0 -#define SPITZ_SCP_GPIO_BASE (NR_BUILTIN_GPIO) +#define SPITZ_SCP_GPIO_BASE (PXA_NR_BUILTIN_GPIO) #define SPITZ_GPIO_LED_GREEN (SPITZ_SCP_GPIO_BASE + 0) #define SPITZ_GPIO_JK_B (SPITZ_SCP_GPIO_BASE + 1) #define SPITZ_GPIO_CHRG_ON (SPITZ_SCP_GPIO_BASE + 2) @@ -140,7 +140,7 @@ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS) #define SPITZ_SCP2_SUS_SET (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1) -#define SPITZ_SCP2_GPIO_BASE (NR_BUILTIN_GPIO + 12) +#define SPITZ_SCP2_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12) #define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0) #define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1) #define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2) @@ -152,7 +152,7 @@ #define SPITZ_GPIO_MIC_BIAS (SPITZ_SCP2_GPIO_BASE + 8) /* Akita IO Expander GPIOs */ -#define AKITA_IOEXP_GPIO_BASE (NR_BUILTIN_GPIO + 12) +#define AKITA_IOEXP_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12) #define AKITA_GPIO_RESERVED_0 (AKITA_IOEXP_GPIO_BASE + 0) #define AKITA_GPIO_RESERVED_1 (AKITA_IOEXP_GPIO_BASE + 1) #define AKITA_GPIO_MIC_BIAS (AKITA_IOEXP_GPIO_BASE + 2) diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index 4653539a2acc..2bb0e862598c 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -24,7 +24,7 @@ /* * SCOOP2 internal GPIOs */ -#define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO +#define TOSA_SCOOP_GPIO_BASE PXA_NR_BUILTIN_GPIO #define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11 #define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1) #define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) @@ -42,7 +42,7 @@ /* * SCOOP2 jacket GPIOs */ -#define TOSA_SCOOP_JC_GPIO_BASE (NR_BUILTIN_GPIO + 12) +#define TOSA_SCOOP_JC_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12) #define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0) #define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1) #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) @@ -59,7 +59,7 @@ /* * TC6393XB GPIOs */ -#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12) +#define TOSA_TC6393XB_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 2 * 12) #define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0) #define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1) diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 6d38c6548b3d..abab4e2b122c 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -378,7 +378,7 @@ struct pxacamera_platform_data pcm990_pxacamera_platform_data = { #include static struct pca953x_platform_data pca9536_data = { - .gpio_base = NR_BUILTIN_GPIO, + .gpio_base = PXA_NR_BUILTIN_GPIO, }; static int gpio_bus_switch = -EINVAL; @@ -406,9 +406,9 @@ static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link) int ret; if (gpio_bus_switch < 0) { - ret = gpio_request(NR_BUILTIN_GPIO, "camera"); + ret = gpio_request(PXA_NR_BUILTIN_GPIO, "camera"); if (!ret) { - gpio_bus_switch = NR_BUILTIN_GPIO; + gpio_bus_switch = PXA_NR_BUILTIN_GPIO; gpio_direction_output(gpio_bus_switch, 0); } } diff --git a/arch/arm/plat-pxa/include/plat/gpio.h b/arch/arm/plat-pxa/include/plat/gpio.h deleted file mode 100644 index 258f77210b02..000000000000 --- a/arch/arm/plat-pxa/include/plat/gpio.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __PLAT_GPIO_H -#define __PLAT_GPIO_H - -#define __ARM_GPIOLIB_COMPLEX - -/* The individual machine provides register offsets and NR_BUILTIN_GPIO */ -#include - -static inline int gpio_get_value(unsigned gpio) -{ - if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) - return GPLR(gpio) & GPIO_bit(gpio); - else - return __gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) { - if (value) - GPSR(gpio) = GPIO_bit(gpio); - else - GPCR(gpio) = GPIO_bit(gpio); - } else - __gpio_set_value(gpio, value); -} - -#define gpio_cansleep __gpio_cansleep - -#endif /* __PLAT_GPIO_H */ -- cgit v1.2.3 From 9bf448c66d4b4cb03813b39195d408701ecf1fab Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 17 Oct 2011 13:37:23 +0800 Subject: ARM: pxa: use generic gpio operation instead of gpio register Remove the code of accessing gpio register. Use the generic read operation instead. Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/corgi_pm.c | 20 +++++++++++++++++--- arch/arm/mach-pxa/spitz_pm.c | 10 ++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 29034778bfda..eca862fb2cd5 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -40,7 +40,9 @@ static struct gpio charger_gpios[] = { { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, { CORGI_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, { CORGI_GPIO_CHRG_UKN, GPIOF_OUT_INIT_LOW, "Charger Unknown" }, + { CORGI_GPIO_AC_IN, GPIOF_IN, "Charger Detection" }, { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" }, + { CORGI_GPIO_WAKEUP, GPIOF_IN, "System wakeup notification" }, }; static void corgi_charger_init(void) @@ -90,7 +92,12 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm) { int is_resume = 0; - dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR); + dev_dbg(sharpsl_pm.dev, "PEDR = %x, GPIO_AC_IN = %d, " + "GPIO_CHRG_FULL = %d, GPIO_KEY_INT = %d, GPIO_WAKEUP = %d\n", + PEDR, gpio_get_value(CORGI_GPIO_AC_IN), + gpio_get_value(CORGI_GPIO_CHRG_FULL), + gpio_get_value(CORGI_GPIO_KEY_INT), + gpio_get_value(CORGI_GPIO_WAKEUP)); if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) { if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { @@ -124,14 +131,21 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm) static unsigned long corgi_charger_wakeup(void) { - return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) ); + unsigned long ret; + + ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN)) + | (!gpio_get_value(CORGI_GPIO_KEY_INT) + << GPIO_bit(CORGI_GPIO_KEY_INT)) + | (!gpio_get_value(CORGI_GPIO_WAKEUP) + << GPIO_bit(CORGI_GPIO_WAKEUP)); + return ret; } unsigned long corgipm_read_devdata(int type) { switch(type) { case SHARPSL_STATUS_ACIN: - return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0); + return !gpio_get_value(CORGI_GPIO_AC_IN); case SHARPSL_STATUS_LOCK: return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); case SHARPSL_STATUS_CHRGFULL: diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 094279aefe9c..5cc05d122d0c 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -41,6 +41,7 @@ static int spitz_last_ac_status; static struct gpio spitz_charger_gpios[] = { { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" }, { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" }, + { SPITZ_GPIO_AC_IN, GPIOF_IN, "Charger Detection" }, { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" }, { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, @@ -169,14 +170,19 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm) static unsigned long spitz_charger_wakeup(void) { - return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC)); + unsigned long ret; + ret = (!gpio_get_value(SPITZ_GPIO_KEY_INT) + << GPIO_bit(SPITZ_GPIO_KEY_INT)) + | (!gpio_get_value(SPITZ_GPIO_SYNC) + << GPIO_bit(SPITZ_GPIO_SYNC)); + return ret; } unsigned long spitzpm_read_devdata(int type) { switch (type) { case SHARPSL_STATUS_ACIN: - return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0); + return !gpio_get_value(SPITZ_GPIO_AC_IN); case SHARPSL_STATUS_LOCK: return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); case SHARPSL_STATUS_CHRGFULL: -- cgit v1.2.3 From 157d2644cb0c1e71a18baaffca56d2b1d0ebf10f Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 17 Oct 2011 20:37:52 +0800 Subject: ARM: pxa: change gpio to platform device Remove most gpio macros and change gpio driver to platform driver. Signed-off-by: Haojian Zhuang --- arch/arm/Kconfig | 2 + arch/arm/mach-mmp/aspenite.c | 1 + arch/arm/mach-mmp/avengers_lite.c | 1 + arch/arm/mach-mmp/brownstone.c | 1 + arch/arm/mach-mmp/flint.c | 1 + arch/arm/mach-mmp/gplugd.c | 1 + arch/arm/mach-mmp/include/mach/gpio.h | 3 +- arch/arm/mach-mmp/include/mach/mmp2.h | 2 + arch/arm/mach-mmp/include/mach/pxa168.h | 2 + arch/arm/mach-mmp/include/mach/pxa910.h | 2 + arch/arm/mach-mmp/mmp2.c | 28 ++++-- arch/arm/mach-mmp/pxa168.c | 29 +++++-- arch/arm/mach-mmp/pxa910.c | 29 +++++-- arch/arm/mach-mmp/tavorevb.c | 1 + arch/arm/mach-mmp/teton_bga.c | 1 + arch/arm/mach-mmp/ttc_dkb.c | 1 + arch/arm/mach-pxa/devices.c | 30 +++++++ arch/arm/mach-pxa/devices.h | 1 + arch/arm/mach-pxa/include/mach/gpio-pxa.h | 131 ---------------------------- arch/arm/mach-pxa/include/mach/gpio.h | 5 +- arch/arm/mach-pxa/include/mach/idp.h | 2 - arch/arm/mach-pxa/include/mach/littleton.h | 2 - arch/arm/mach-pxa/irq.c | 3 +- arch/arm/mach-pxa/mfp-pxa2xx.c | 6 +- arch/arm/mach-pxa/pxa25x.c | 3 +- arch/arm/mach-pxa/pxa27x.c | 3 +- arch/arm/mach-pxa/pxa3xx.c | 6 +- arch/arm/mach-pxa/pxa95x.c | 3 +- arch/arm/plat-pxa/include/plat/gpio-pxa.h | 45 ---------- drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 2 +- drivers/gpio/gpio-pxa.c | 135 ++++++++++++++++++++++++++--- include/linux/gpio-pxa.h | 16 ++++ 33 files changed, 271 insertions(+), 233 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/gpio-pxa.h delete mode 100644 arch/arm/plat-pxa/include/plat/gpio-pxa.h create mode 100644 include/linux/gpio-pxa.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 44789eff983f..57e16d4e14dc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -591,6 +591,7 @@ config ARCH_MMP select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS + select GPIO_PXA select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA @@ -673,6 +674,7 @@ config ARCH_PXA select CLKSRC_MMIO select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select GPIO_PXA select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index fb7dfc157a5c..edcbadad31c1 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -231,6 +231,7 @@ static void __init common_init(void) pxa168_add_nand(&aspenite_nand_info); pxa168_add_fb(&aspenite_lcd_info); pxa168_add_keypad(&aspenite_keypad_info); + platform_device_register(&pxa168_device_gpio); /* off-chip devices */ platform_device_register(&smc91x_device); diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c index 39f0878d64a0..c5d53e0742e9 100644 --- a/arch/arm/mach-mmp/avengers_lite.c +++ b/arch/arm/mach-mmp/avengers_lite.c @@ -38,6 +38,7 @@ static void __init avengers_lite_init(void) /* on-chip devices */ pxa168_add_uart(2); + platform_device_register(&pxa168_device_gpio); } MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform") diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index 983cfb15fbde..eb07565a06a3 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -202,6 +202,7 @@ static void __init brownstone_init(void) /* on-chip devices */ mmp2_add_uart(1); mmp2_add_uart(3); + platform_device_register(&mmp2_device_gpio); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */ diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index a64c172082c4..c1f0aa88dd8a 100644 --- a/arch/arm/mach-mmp/flint.c +++ b/arch/arm/mach-mmp/flint.c @@ -110,6 +110,7 @@ static void __init flint_init(void) /* on-chip devices */ mmp2_add_uart(1); mmp2_add_uart(2); + platform_device_register(&mmp2_device_gpio); /* off-chip devices */ platform_device_register(&smc91x_device); diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index 69156568bc41..933420a7c3ba 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c @@ -184,6 +184,7 @@ static void __init gplugd_init(void) pxa168_add_uart(3); pxa168_add_ssp(0); pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info)); + platform_device_register(&pxa168_device_gpio); pxa168_add_eth(&gplugd_eth_platform_data); } diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h index 904466d7eb95..13219ebf5128 100644 --- a/arch/arm/mach-mmp/include/mach/gpio.h +++ b/arch/arm/mach-mmp/include/mach/gpio.h @@ -3,7 +3,6 @@ #include -#define __gpio_is_inverted(gpio) (0) -#define __gpio_is_occupied(gpio) (0) +#include #endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index 2f7b2d3c2b18..cba22fed2265 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h @@ -32,6 +32,8 @@ extern struct pxa_device_desc mmp2_device_sdh3; extern struct pxa_device_desc mmp2_device_asram; extern struct pxa_device_desc mmp2_device_isram; +extern struct platform_device mmp2_device_gpio; + static inline int mmp2_add_uart(int id) { struct pxa_device_desc *d = NULL; diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h index 7fb568d2845b..f9286089da3a 100644 --- a/arch/arm/mach-mmp/include/mach/pxa168.h +++ b/arch/arm/mach-mmp/include/mach/pxa168.h @@ -42,6 +42,8 @@ struct pxa168_usb_pdata { /* pdata can be NULL */ int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata); +extern struct platform_device pxa168_device_gpio; + static inline int pxa168_add_uart(int id) { struct pxa_device_desc *d = NULL; diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h index 91be75591398..4de13abef7bb 100644 --- a/arch/arm/mach-mmp/include/mach/pxa910.h +++ b/arch/arm/mach-mmp/include/mach/pxa910.h @@ -21,6 +21,8 @@ extern struct pxa_device_desc pxa910_device_pwm3; extern struct pxa_device_desc pxa910_device_pwm4; extern struct pxa_device_desc pxa910_device_nand; +extern struct platform_device pxa910_device_gpio; + static inline int pxa910_add_uart(int id) { struct pxa_device_desc *d = NULL; diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 5dd1d4a6aeb9..1ed222d3e22b 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -24,7 +25,6 @@ #include #include #include -#include #include #include @@ -33,8 +33,6 @@ #define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000) -#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c) - static struct mfp_addr_map mmp2_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO58, 0x54), @@ -101,12 +99,6 @@ static void __init mmp2_init_gpio(void) /* enable GPIO clock */ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO); - - /* unmask GPIO edge detection for all 6 banks -- APMASKx */ - for (i = 0; i < 6; i++) - __raw_writel(0xffffffff, APMASK(i)); - - pxa_init_gpio(IRQ_MMP2_GPIO, 0, 167, NULL); } void __init mmp2_init_irq(void) @@ -230,3 +222,21 @@ MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000); /* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */ MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000); +struct resource mmp2_resource_gpio[] = { + { + .start = 0xd4019000, + .end = 0xd4019fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MMP2_GPIO, + .end = IRQ_MMP2_GPIO, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mmp2_device_gpio = { + .name = "pxa-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(mmp2_resource_gpio), + .resource = mmp2_resource_gpio, +}; diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index 76ca15c00e45..fefdfe59c07c 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -20,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -43,20 +43,12 @@ static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata = MFP_ADDR_END, }; -#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c) - static void __init pxa168_init_gpio(void) { int i; /* enable GPIO clock */ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO); - - /* unmask GPIO edge detection for all 4 banks - APMASKx */ - for (i = 0; i < 4; i++) - __raw_writel(0xffffffff, APMASK(i)); - - pxa_init_gpio(IRQ_PXA168_GPIOX, 0, 127, NULL); } void __init pxa168_init_irq(void) @@ -174,6 +166,25 @@ PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8); PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c); PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff); +struct resource pxa168_resource_gpio[] = { + { + .start = 0xd4019000, + .end = 0xd4019fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PXA168_GPIOX, + .end = IRQ_PXA168_GPIOX, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa168_device_gpio = { + .name = "pxa-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(pxa168_resource_gpio), + .resource = pxa168_resource_gpio, +}; + struct resource pxa168_usb_host_resources[] = { /* USB Host conroller register base */ [0] = { diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 4ebbfbba39fc..7b992ced095c 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -77,20 +77,12 @@ static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata = MFP_ADDR_END, }; -#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c) - static void __init pxa910_init_gpio(void) { int i; /* enable GPIO clock */ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO); - - /* unmask GPIO edge detection for all 4 banks - APMASKx */ - for (i = 0; i < 4; i++) - __raw_writel(0xffffffff, APMASK(i)); - - pxa_init_gpio(IRQ_PXA910_AP_GPIO, 0, 127, NULL); } void __init pxa910_init_irq(void) @@ -179,3 +171,22 @@ PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10); PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10); PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10); PXA910_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99); + +struct resource pxa910_resource_gpio[] = { + { + .start = 0xd4019000, + .end = 0xd4019fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PXA910_AP_GPIO, + .end = IRQ_PXA910_AP_GPIO, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa910_device_gpio = { + .name = "pxa-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(pxa910_resource_gpio), + .resource = pxa910_resource_gpio, +}; diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c index 331f5f358b59..bb2ddb72bca2 100644 --- a/arch/arm/mach-mmp/tavorevb.c +++ b/arch/arm/mach-mmp/tavorevb.c @@ -94,6 +94,7 @@ static void __init tavorevb_init(void) /* on-chip devices */ pxa910_add_uart(1); + platform_device_register(&pxa910_device_gpio); /* off-chip devices */ platform_device_register(&smc91x_device); diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c index 825a01cdcccd..703de85b571c 100644 --- a/arch/arm/mach-mmp/teton_bga.c +++ b/arch/arm/mach-mmp/teton_bga.c @@ -78,6 +78,7 @@ static void __init teton_bga_init(void) pxa168_add_uart(1); pxa168_add_keypad(&teton_bga_keypad_info); pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info)); + platform_device_register(&pxa168_device_gpio); } MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index fac0d5d9d464..a80ed262df1c 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -123,6 +123,7 @@ static struct platform_device ttc_dkb_device_onenand = { }; static struct platform_device *ttc_dkb_devices[] = { + &pxa910_device_gpio, &ttc_dkb_device_onenand, }; diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 2e0425404de5..5bc13121eac5 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -1051,6 +1051,36 @@ struct platform_device pxa3xx_device_ssp4 = { }; #endif /* CONFIG_PXA3xx || CONFIG_PXA95x */ +struct resource pxa_resource_gpio[] = { + { + .start = 0x40e00000, + .end = 0x40e0ffff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_GPIO0, + .end = IRQ_GPIO0, + .name = "gpio0", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_GPIO1, + .end = IRQ_GPIO1, + .name = "gpio1", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_GPIO_2_x, + .end = IRQ_GPIO_2_x, + .name = "gpio_mux", + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa_device_gpio = { + .name = "pxa-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(pxa_resource_gpio), + .resource = pxa_resource_gpio, +}; + /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 2fd5a8b35757..1475db107254 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -16,6 +16,7 @@ extern struct platform_device pxa_device_ficp; extern struct platform_device sa1100_device_rtc; extern struct platform_device pxa_device_rtc; extern struct platform_device pxa_device_ac97; +extern struct platform_device pxa_device_gpio; extern struct platform_device pxa27x_device_i2c_power; extern struct platform_device pxa27x_device_ohci; diff --git a/arch/arm/mach-pxa/include/mach/gpio-pxa.h b/arch/arm/mach-pxa/include/mach/gpio-pxa.h deleted file mode 100644 index 134b3bc332cd..000000000000 --- a/arch/arm/mach-pxa/include/mach/gpio-pxa.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Written by Philipp Zabel - * - * 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 __MACH_PXA_GPIO_PXA_H -#define __MACH_PXA_GPIO_PXA_H - -#include -#include - -#define GPIO_REGS_VIRT io_p2v(0x40E00000) - -#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) -#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x))) - -/* GPIO Pin Level Registers */ -#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00) -#define GPLR1 GPIO_REG(BANK_OFF(1) + 0x00) -#define GPLR2 GPIO_REG(BANK_OFF(2) + 0x00) -#define GPLR3 GPIO_REG(BANK_OFF(3) + 0x00) - -/* GPIO Pin Direction Registers */ -#define GPDR0 GPIO_REG(BANK_OFF(0) + 0x0c) -#define GPDR1 GPIO_REG(BANK_OFF(1) + 0x0c) -#define GPDR2 GPIO_REG(BANK_OFF(2) + 0x0c) -#define GPDR3 GPIO_REG(BANK_OFF(3) + 0x0c) - -/* GPIO Pin Output Set Registers */ -#define GPSR0 GPIO_REG(BANK_OFF(0) + 0x18) -#define GPSR1 GPIO_REG(BANK_OFF(1) + 0x18) -#define GPSR2 GPIO_REG(BANK_OFF(2) + 0x18) -#define GPSR3 GPIO_REG(BANK_OFF(3) + 0x18) - -/* GPIO Pin Output Clear Registers */ -#define GPCR0 GPIO_REG(BANK_OFF(0) + 0x24) -#define GPCR1 GPIO_REG(BANK_OFF(1) + 0x24) -#define GPCR2 GPIO_REG(BANK_OFF(2) + 0x24) -#define GPCR3 GPIO_REG(BANK_OFF(3) + 0x24) - -/* GPIO Rising Edge Detect Registers */ -#define GRER0 GPIO_REG(BANK_OFF(0) + 0x30) -#define GRER1 GPIO_REG(BANK_OFF(1) + 0x30) -#define GRER2 GPIO_REG(BANK_OFF(2) + 0x30) -#define GRER3 GPIO_REG(BANK_OFF(3) + 0x30) - -/* GPIO Falling Edge Detect Registers */ -#define GFER0 GPIO_REG(BANK_OFF(0) + 0x3c) -#define GFER1 GPIO_REG(BANK_OFF(1) + 0x3c) -#define GFER2 GPIO_REG(BANK_OFF(2) + 0x3c) -#define GFER3 GPIO_REG(BANK_OFF(3) + 0x3c) - -/* GPIO Edge Detect Status Registers */ -#define GEDR0 GPIO_REG(BANK_OFF(0) + 0x48) -#define GEDR1 GPIO_REG(BANK_OFF(1) + 0x48) -#define GEDR2 GPIO_REG(BANK_OFF(2) + 0x48) -#define GEDR3 GPIO_REG(BANK_OFF(3) + 0x48) - -/* GPIO Alternate Function Select Registers */ -#define GAFR0_L GPIO_REG(0x0054) -#define GAFR0_U GPIO_REG(0x0058) -#define GAFR1_L GPIO_REG(0x005C) -#define GAFR1_U GPIO_REG(0x0060) -#define GAFR2_L GPIO_REG(0x0064) -#define GAFR2_U GPIO_REG(0x0068) -#define GAFR3_L GPIO_REG(0x006C) -#define GAFR3_U GPIO_REG(0x0070) - -/* More handy macros. The argument is a literal GPIO number. */ - -#define GPIO_bit(x) (1 << ((x) & 0x1f)) - -#define GPLR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x00) -#define GPDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x0c) -#define GPSR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x18) -#define GPCR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x24) -#define GRER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x30) -#define GFER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x3c) -#define GEDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x48) -#define GAFR(x) GPIO_REG(0x54 + (((x) & 0x70) >> 2)) - - -#define gpio_to_bank(gpio) ((gpio) >> 5) - -#ifdef CONFIG_CPU_PXA26x -/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted, - * as well as their Alternate Function value being '1' for GPIO in GAFRx. - */ -static inline int __gpio_is_inverted(unsigned gpio) -{ - return cpu_is_pxa25x() && gpio > 85; -} -#else -static inline int __gpio_is_inverted(unsigned gpio) { return 0; } -#endif - -/* - * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate - * function of a GPIO, and GPDRx cannot be altered once configured. It - * is attributed as "occupied" here (I know this terminology isn't - * accurate, you are welcome to propose a better one :-) - */ -static inline int __gpio_is_occupied(unsigned gpio) -{ - if (cpu_is_pxa27x() || cpu_is_pxa25x()) { - int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3; - int dir = GPDR(gpio) & GPIO_bit(gpio); - - if (__gpio_is_inverted(gpio)) - return af != 1 || dir == 0; - else - return af != 0 || dir != 0; - } else - return GPDR(gpio) & GPIO_bit(gpio); -} - -#include -#endif /* __MACH_PXA_GPIO_PXA_H */ diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h index 561cdbfd7ccf..0248e433bc98 100644 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -25,7 +25,8 @@ #define __ASM_ARCH_PXA_GPIO_H #include -/* The defines for the driver are needed for the accelerated accessors */ -#include "gpio-pxa.h" + +#include +#include #endif diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h index a7f912f5ea2f..22a96f87232b 100644 --- a/arch/arm/mach-pxa/include/mach/idp.h +++ b/arch/arm/mach-pxa/include/mach/idp.h @@ -131,8 +131,6 @@ #define PCC_VS2 (1 << 1) #define PCC_VS1 (1 << 0) -#define PCC_DETECT(x) (GPLR(7 + (x)) & GPIO_bit(7 + (x))) - /* A listing of interrupts used by external hardware devices */ #define TOUCH_PANEL_IRQ PXA_GPIO_TO_IRQ(5) diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h index e20ac1b64b00..8066be54e9f5 100644 --- a/arch/arm/mach-pxa/include/mach/littleton.h +++ b/arch/arm/mach-pxa/include/mach/littleton.h @@ -1,8 +1,6 @@ #ifndef __ASM_ARCH_LITTLETON_H #define __ASM_ARCH_LITTLETON_H -#include - #define LITTLETON_ETH_PHYS 0x30000000 #define LITTLETON_GPIO_LCD_CS (17) diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 36c538f48fa6..5dae15ea6718 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -22,7 +22,6 @@ #include #include -#include #include "generic.h" @@ -122,7 +121,7 @@ asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs) } while (1); } -void __init pxa_init_irq(int irq_nr, set_wake_t fn) +void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int)) { int irq, i, n; diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 43a5f6861ca3..f14775536b83 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -13,6 +13,7 @@ * published by the Free Software Foundation. */ #include +#include #include #include #include @@ -20,7 +21,6 @@ #include #include -#include #include "generic.h" @@ -29,6 +29,10 @@ #define GAFR_L(x) __GAFR(0, x) #define GAFR_U(x) __GAFR(1, x) +#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) +#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5)) +#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c) + #define PWER_WE35 (1 << 24) struct gpio_desc { diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 0f38cfce5c35..91e4f6c03766 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -17,6 +17,7 @@ * need be. */ #include +#include #include #include #include @@ -312,14 +313,12 @@ set_pwer: void __init pxa25x_init_irq(void) { pxa_init_irq(32, pxa25x_set_wake); - pxa_init_gpio(IRQ_GPIO_2_x, 2, 84, pxa25x_set_wake); } #ifdef CONFIG_CPU_PXA26x void __init pxa26x_init_irq(void) { pxa_init_irq(32, pxa25x_set_wake); - pxa_init_gpio(IRQ_GPIO_2_x, 2, 89, pxa25x_set_wake); } #endif diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 44563a0997bd..aed6cbcf3866 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -12,6 +12,7 @@ * published by the Free Software Foundation. */ #include +#include #include #include #include @@ -386,7 +387,6 @@ static int pxa27x_set_wake(struct irq_data *d, unsigned int on) void __init pxa27x_init_irq(void) { pxa_init_irq(34, pxa27x_set_wake); - pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake); } static struct map_desc pxa27x_io_desc[] __initdata = { @@ -422,6 +422,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { + &pxa_device_gpio, &pxa27x_device_udc, &pxa_device_pmu, &pxa_device_i2s, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 0737c59b88ae..06cfe348c709 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -365,7 +364,8 @@ static struct irq_chip pxa_ext_wakeup_chip = { .irq_set_type = pxa_set_ext_wakeup_type, }; -static void __init pxa_init_ext_wakeup_irq(set_wake_t fn) +static void __init pxa_init_ext_wakeup_irq(int (*fn)(struct irq_data *, + unsigned int)) { int irq; @@ -388,7 +388,6 @@ void __init pxa3xx_init_irq(void) pxa_init_irq(56, pxa3xx_set_wake); pxa_init_ext_wakeup_irq(pxa3xx_set_wake); - pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); } static struct map_desc pxa3xx_io_desc[] __initdata = { @@ -417,6 +416,7 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { + &pxa_device_gpio, &pxa27x_device_udc, &pxa_device_pmu, &pxa_device_i2s, diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c index 51371b39d2a3..0961093dd033 100644 --- a/arch/arm/mach-pxa/pxa95x.c +++ b/arch/arm/mach-pxa/pxa95x.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -235,7 +234,6 @@ static struct clk_lookup pxa95x_clkregs[] = { void __init pxa95x_init_irq(void) { pxa_init_irq(96, NULL); - pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); } /* @@ -248,6 +246,7 @@ void __init pxa95x_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { + &pxa_device_gpio, &sa1100_device_rtc, &pxa_device_rtc, &pxa27x_device_ssp1, diff --git a/arch/arm/plat-pxa/include/plat/gpio-pxa.h b/arch/arm/plat-pxa/include/plat/gpio-pxa.h deleted file mode 100644 index 15bf9be051e8..000000000000 --- a/arch/arm/plat-pxa/include/plat/gpio-pxa.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __PLAT_PXA_GPIO_H -#define __PLAT_PXA_GPIO_H - -struct irq_data; - -/* - * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with - * one set of registers. The register offsets are organized below: - * - * GPLR GPDR GPSR GPCR GRER GFER GEDR - * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 - * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C - * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 - * - * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 - * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C - * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 - * - * NOTE: - * BANK 3 is only available on PXA27x and later processors. - * BANK 4 and 5 are only available on PXA935 - */ - -#define GPIO_BANK(n) (GPIO_REGS_VIRT + BANK_OFF(n)) - -#define GPLR_OFFSET 0x00 -#define GPDR_OFFSET 0x0C -#define GPSR_OFFSET 0x18 -#define GPCR_OFFSET 0x24 -#define GRER_OFFSET 0x30 -#define GFER_OFFSET 0x3C -#define GEDR_OFFSET 0x48 - -/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). - * Those cases currently cause holes in the GPIO number space, the - * actual number of the last GPIO is recorded by 'pxa_last_gpio'. - */ -extern int pxa_last_gpio; - -typedef int (*set_wake_t)(struct irq_data *d, unsigned int on); - -extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn); -extern int pxa_irq_to_gpio(int irq); - -#endif /* __PLAT_PXA_GPIO_H */ diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8482a23887dc..aa0b94ff36d0 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -141,6 +141,12 @@ config GPIO_PL061 help Say yes here to support the PrimeCell PL061 GPIO device +config GPIO_PXA + bool "PXA GPIO support" + depends on ARCH_PXA || ARCH_MMP + help + Say yes here to support the PXA GPIO device + config GPIO_XILINX bool "Xilinx GPIO support" depends on PPC_OF || MICROBLAZE diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index dbcb0bcfd8da..5b2b9e26f49c 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -40,7 +40,7 @@ obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o obj-$(CONFIG_GPIO_PCH) += gpio-pch.o obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o -obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o +obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 31d2da4100cd..079f97fde2c7 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -12,13 +12,42 @@ * published by the Free Software Foundation. */ #include +#include #include #include #include +#include #include #include -#include +/* + * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with + * one set of registers. The register offsets are organized below: + * + * GPLR GPDR GPSR GPCR GRER GFER GEDR + * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 + * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C + * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 + * + * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 + * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C + * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 + * + * NOTE: + * BANK 3 is only available on PXA27x and later processors. + * BANK 4 and 5 are only available on PXA935 + */ + +#define GPLR_OFFSET 0x00 +#define GPDR_OFFSET 0x0C +#define GPSR_OFFSET 0x18 +#define GPCR_OFFSET 0x24 +#define GRER_OFFSET 0x30 +#define GFER_OFFSET 0x3C +#define GEDR_OFFSET 0x48 +#define GAFR_OFFSET 0x54 + +#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) int pxa_last_gpio; @@ -52,6 +81,7 @@ enum { static DEFINE_SPINLOCK(gpio_lock); static struct pxa_gpio_chip *pxa_gpio_chips; static int gpio_type; +static void __iomem *gpio_reg_base; #define for_each_gpio_chip(i, c) \ for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) @@ -76,6 +106,53 @@ static inline int gpio_is_mmp_type(int type) return (type & MMP_GPIO) != 0; } +/* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, + * as well as their Alternate Function value being '1' for GPIO in GAFRx. + */ +static inline int __gpio_is_inverted(int gpio) +{ + if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) + return 1; + return 0; +} + +/* + * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate + * function of a GPIO, and GPDRx cannot be altered once configured. It + * is attributed as "occupied" here (I know this terminology isn't + * accurate, you are welcome to propose a better one :-) + */ +static inline int __gpio_is_occupied(unsigned gpio) +{ + struct pxa_gpio_chip *pxachip; + void __iomem *base; + unsigned long gafr = 0, gpdr = 0; + int ret, af = 0, dir = 0; + + pxachip = gpio_to_pxachip(gpio); + base = gpio_chip_base(&pxachip->chip); + gpdr = readl_relaxed(base + GPDR_OFFSET); + + switch (gpio_type) { + case PXA25X_GPIO: + case PXA26X_GPIO: + case PXA27X_GPIO: + gafr = readl_relaxed(base + GAFR_OFFSET); + af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; + dir = gpdr & GPIO_bit(gpio); + + if (__gpio_is_inverted(gpio)) + ret = (af != 1) || (dir == 0); + else + ret = (af != 0) || (dir != 0); + break; + default: + ret = gpdr & GPIO_bit(gpio); + break; + } + return ret; +} + #ifdef CONFIG_ARCH_PXA static inline int __pxa_gpio_to_irq(int gpio) { @@ -187,7 +264,7 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) (value ? GPSR_OFFSET : GPCR_OFFSET)); } -static int __init pxa_init_gpio_chip(int gpio_end) +static int __devinit pxa_init_gpio_chip(int gpio_end) { int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; struct pxa_gpio_chip *chips; @@ -202,7 +279,7 @@ static int __init pxa_init_gpio_chip(int gpio_end) struct gpio_chip *c = &chips[i].chip; sprintf(chips[i].label, "gpio-%d", i); - chips[i].regbase = GPIO_BANK(i); + chips[i].regbase = gpio_reg_base + BANK_OFF(i); c->base = gpio; c->label = chips[i].label; @@ -384,17 +461,35 @@ static int pxa_gpio_nums(void) return count; } -void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) +static int __devinit pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; + struct resource *res; int gpio, irq; + int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; pxa_last_gpio = pxa_gpio_nums(); if (!pxa_last_gpio) - return; + return -EINVAL; + + irq0 = platform_get_irq_byname(pdev, "gpio0"); + irq1 = platform_get_irq_byname(pdev, "gpio1"); + irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); + if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) + || (irq_mux <= 0)) + return -EINVAL; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + gpio_reg_base = ioremap(res->start, resource_size(res)); + if (!gpio_reg_base) + return -EINVAL; + + if (irq0 > 0) + gpio_offset = 2; /* Initialize GPIO chips */ - pxa_init_gpio_chip(end); + pxa_init_gpio_chip(pxa_last_gpio); /* clear all GPIO edge detects */ for_each_gpio_chip(gpio, c) { @@ -417,16 +512,29 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); #endif - for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { + for (irq = gpio_to_irq(gpio_offset); + irq <= gpio_to_irq(pxa_last_gpio); irq++) { irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - /* Install handler for GPIO>=2 edge detect interrupts */ - irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler); - pxa_muxed_gpio_chip.irq_set_wake = fn; + irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); + return 0; +} + +static struct platform_driver pxa_gpio_driver = { + .probe = pxa_gpio_probe, + .driver = { + .name = "pxa-gpio", + }, +}; + +static int __init pxa_gpio_init(void) +{ + return platform_driver_register(&pxa_gpio_driver); } +postcore_initcall(pxa_gpio_init); #ifdef CONFIG_PM static int pxa_gpio_suspend(void) @@ -470,3 +578,10 @@ struct syscore_ops pxa_gpio_syscore_ops = { .suspend = pxa_gpio_suspend, .resume = pxa_gpio_resume, }; + +static int __init pxa_gpio_sysinit(void) +{ + register_syscore_ops(&pxa_gpio_syscore_ops); + return 0; +} +postcore_initcall(pxa_gpio_sysinit); diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h new file mode 100644 index 000000000000..05071ee34c3f --- /dev/null +++ b/include/linux/gpio-pxa.h @@ -0,0 +1,16 @@ +#ifndef __GPIO_PXA_H +#define __GPIO_PXA_H + +#define GPIO_bit(x) (1 << ((x) & 0x1f)) + +#define gpio_to_bank(gpio) ((gpio) >> 5) + +/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). + * Those cases currently cause holes in the GPIO number space, the + * actual number of the last GPIO is recorded by 'pxa_last_gpio'. + */ +extern int pxa_last_gpio; + +extern int pxa_irq_to_gpio(int irq); + +#endif /* __GPIO_PXA_H */ -- cgit v1.2.3 From 389eda15e0f41112d7c44213b3c4f8bd1c9398bc Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 17 Oct 2011 21:26:55 +0800 Subject: ARM: pxa: add clk support in gpio driver Support clk in gpio driver. There's no gpio clock in PXA25x and PXA27x. So use dummy clk instead. And move the gpio edge initialization into gpio driver for arch-mmp. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/mmp2.c | 11 ++--------- arch/arm/mach-mmp/pxa168.c | 11 ++--------- arch/arm/mach-mmp/pxa910.c | 11 ++--------- arch/arm/mach-pxa/pxa25x.c | 1 + arch/arm/mach-pxa/pxa27x.c | 1 + arch/arm/mach-pxa/pxa3xx.c | 2 ++ arch/arm/mach-pxa/pxa95x.c | 2 ++ drivers/gpio/gpio-pxa.c | 26 +++++++++++++++++++++++++- 8 files changed, 37 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 1ed222d3e22b..617c60a170a4 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -93,18 +93,9 @@ void mmp2_clear_pmic_int(void) __raw_writel(data, mfpr_pmic); } -static void __init mmp2_init_gpio(void) -{ - int i; - - /* enable GPIO clock */ - __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO); -} - void __init mmp2_init_irq(void) { mmp2_init_icu(); - mmp2_init_gpio(); } static void sdhc_clk_enable(struct clk *clk) @@ -141,6 +132,7 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000); static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); +static APBC_CLK(gpio, MMP2_GPIO, 0, 26000000); static APMU_CLK(nand, NAND, 0xbf, 100000000); static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops); @@ -160,6 +152,7 @@ static struct clk_lookup mmp2_clkregs[] = { INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL), INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"), INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"), INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"), diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index fefdfe59c07c..84245035f351 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -43,18 +43,9 @@ static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata = MFP_ADDR_END, }; -static void __init pxa168_init_gpio(void) -{ - int i; - - /* enable GPIO clock */ - __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO); -} - void __init pxa168_init_irq(void) { icu_init_irq(); - pxa168_init_gpio(); } /* APB peripheral clocks */ @@ -72,6 +63,7 @@ static APBC_CLK(ssp2, PXA168_SSP2, 4, 0); static APBC_CLK(ssp3, PXA168_SSP3, 4, 0); 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 APMU_CLK(nand, NAND, 0x19b, 156000000); @@ -97,6 +89,7 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), + INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"), diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 7b992ced095c..3241a25784d0 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -77,18 +77,9 @@ static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata = MFP_ADDR_END, }; -static void __init pxa910_init_gpio(void) -{ - int i; - - /* enable GPIO clock */ - __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO); -} - void __init pxa910_init_irq(void) { icu_init_irq(); - pxa910_init_gpio(); } /* APB peripheral clocks */ @@ -100,6 +91,7 @@ static APBC_CLK(pwm1, PXA910_PWM1, 1, 13000000); 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 APMU_CLK(nand, NAND, 0x19b, 156000000); static APMU_CLK(u2o, USB, 0x1b, 480000000); @@ -115,6 +107,7 @@ static struct clk_lookup pxa910_clkregs[] = { INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL), INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"), }; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 91e4f6c03766..8a775f631c55 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -209,6 +209,7 @@ static struct clk_lookup pxa25x_clkregs[] = { INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), }; static struct clk_lookup pxa25x_hwuart_clkreg = diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index aed6cbcf3866..6c49e66057e3 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -230,6 +230,7 @@ static struct clk_lookup pxa27x_clkregs[] = { INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), }; #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 06cfe348c709..4f402afa6609 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -55,6 +55,7 @@ static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0); static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_gpio, GPIO, 13000000, 0); static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); @@ -87,6 +88,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), 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), }; #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c index 0961093dd033..d082a583df78 100644 --- a/arch/arm/mach-pxa/pxa95x.c +++ b/arch/arm/mach-pxa/pxa95x.c @@ -211,6 +211,7 @@ static DEFINE_PXA3_CKEN(pxa95x_ssp3, SSP3, 13000000, 0); static DEFINE_PXA3_CKEN(pxa95x_ssp4, SSP4, 13000000, 0); static DEFINE_PXA3_CKEN(pxa95x_pwm0, PWM0, 13000000, 0); static DEFINE_PXA3_CKEN(pxa95x_pwm1, PWM1, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa95x_gpio, GPIO, 13000000, 0); static struct clk_lookup pxa95x_clkregs[] = { INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"), @@ -229,6 +230,7 @@ static struct clk_lookup pxa95x_clkregs[] = { INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL), 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), }; void __init pxa95x_init_irq(void) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index bfd755531f7a..b2d3ee1d183a 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -11,6 +11,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include +#include #include #include #include @@ -466,7 +468,8 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; struct resource *res; - int gpio, irq; + struct clk *clk; + int gpio, irq, ret; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; pxa_last_gpio = pxa_gpio_nums(); @@ -489,6 +492,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) if (irq0 > 0) gpio_offset = 2; + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Error %ld to get gpio clock\n", + PTR_ERR(clk)); + iounmap(gpio_reg_base); + return PTR_ERR(clk); + } + ret = clk_prepare(clk); + if (ret) { + clk_put(clk); + iounmap(gpio_reg_base); + return ret; + } + ret = clk_enable(clk); + if (ret) { + clk_unprepare(clk); + clk_put(clk); + iounmap(gpio_reg_base); + return ret; + } + /* Initialize GPIO chips */ pxa_init_gpio_chip(pxa_last_gpio); -- cgit v1.2.3 From bcb71abe7d4c5a0d0368c67da0a7def4fc73497a Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 21 Oct 2011 15:56:24 -0400 Subject: iommu: Add option to group multi-function devices The option iommu=group_mf indicates the that the iommu driver should expose all functions of a multi-function PCI device as the same iommu_device_group. This is useful for disallowing individual functions being exposed as independent devices to userspace as there are often hidden dependencies. Virtual functions are not affected by this option. Signed-off-by: Alex Williamson Signed-off-by: Joerg Roedel --- Documentation/kernel-parameters.txt | 4 +++- arch/ia64/include/asm/iommu.h | 2 ++ arch/ia64/kernel/pci-dma.c | 1 + arch/x86/include/asm/iommu.h | 1 + arch/x86/kernel/pci-dma.c | 11 +++++++++++ drivers/iommu/amd_iommu.c | 10 +++++++++- drivers/iommu/intel-iommu.c | 3 +++ 7 files changed, 30 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a0c5c5f4fce6..e1b6e4469845 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1059,7 +1059,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nomerge forcesac soft - pt [x86, IA-64] + pt [x86, IA-64] + group_mf [x86, IA-64] + io7= [HW] IO7 for Marvel based alpha systems See comment before marvel_specify_io7 in diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h index 105c93b00b1b..b6a809fa2995 100644 --- a/arch/ia64/include/asm/iommu.h +++ b/arch/ia64/include/asm/iommu.h @@ -11,10 +11,12 @@ extern void no_iommu_init(void); extern int force_iommu, no_iommu; extern int iommu_pass_through; extern int iommu_detected; +extern int iommu_group_mf; #else #define iommu_pass_through (0) #define no_iommu (1) #define iommu_detected (0) +#define iommu_group_mf (0) #endif extern void iommu_dma_init(void); extern void machvec_init(const char *name); diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index c16162c70860..eb1175720050 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -33,6 +33,7 @@ int force_iommu __read_mostly; #endif int iommu_pass_through; +int iommu_group_mf; /* Dummy device used for NULL arguments (normally ISA). Better would be probably a smaller DMA mask, but this is bug-to-bug compatible diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index 345c99cef152..dffc38ee6255 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -5,6 +5,7 @@ extern struct dma_map_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; extern int iommu_pass_through; +extern int iommu_group_mf; /* 10 seconds */ #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 80dc793b3f63..1c4d769e21ea 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -45,6 +45,15 @@ int iommu_detected __read_mostly = 0; */ int iommu_pass_through __read_mostly; +/* + * Group multi-function PCI devices into a single device-group for the + * iommu_device_group interface. This tells the iommu driver to pretend + * it cannot distinguish between functions of a device, exposing only one + * group for the device. Useful for disallowing use of individual PCI + * functions from userspace drivers. + */ +int iommu_group_mf __read_mostly; + extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; /* Dummy device used for NULL arguments (normally ISA). */ @@ -169,6 +178,8 @@ static __init int iommu_setup(char *p) #endif if (!strncmp(p, "pt", 2)) iommu_pass_through = 1; + if (!strncmp(p, "group_mf", 8)) + iommu_group_mf = 1; gart_parse_options(p); diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 1d82b631d09c..6f7553684c1e 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2776,11 +2776,19 @@ static int amd_iommu_domain_has_cap(struct iommu_domain *domain, static int amd_iommu_device_group(struct device *dev, unsigned int *groupid) { struct iommu_dev_data *dev_data = dev->archdata.iommu; + struct pci_dev *pdev = to_pci_dev(dev); + u16 devid; if (!dev_data) return -ENODEV; - *groupid = amd_iommu_alias_table[dev_data->devid]; + if (pdev->is_virtfn || !iommu_group_mf) + devid = dev_data->devid; + else + devid = calc_devid(pdev->bus->number, + PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); + + *groupid = amd_iommu_alias_table[devid]; return 0; } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 39ca6bb17e13..9ef16d664a99 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4100,6 +4100,9 @@ static int intel_iommu_device_group(struct device *dev, unsigned int *groupid) } } + if (!pdev->is_virtfn && iommu_group_mf) + id.pci.devfn = PCI_DEVFN(PCI_SLOT(id.pci.devfn), 0); + *groupid = id.group; return 0; -- cgit v1.2.3 From 8d964a2872ea0914e00bc7798e68899e01715185 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 7 Nov 2011 23:59:41 -0800 Subject: Input: samsung-keypad - enable compiling on other platforms There is nothing in keypad platform definitions that requires the driver be complied on Samsung platform only, so let's move them out of the platform subdirectory and relax the dependencies. Signed-off-by: Dmitry Torokhov --- arch/arm/plat-samsung/include/plat/keypad.h | 27 +----------------- drivers/input/keyboard/Kconfig | 5 ++-- drivers/input/keyboard/samsung-keypad.c | 2 +- include/linux/input/samsung-keypad.h | 43 +++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 include/linux/input/samsung-keypad.h (limited to 'arch') diff --git a/arch/arm/plat-samsung/include/plat/keypad.h b/arch/arm/plat-samsung/include/plat/keypad.h index b59a6483cd8a..c81ace332a1e 100644 --- a/arch/arm/plat-samsung/include/plat/keypad.h +++ b/arch/arm/plat-samsung/include/plat/keypad.h @@ -13,32 +13,7 @@ #ifndef __PLAT_SAMSUNG_KEYPAD_H #define __PLAT_SAMSUNG_KEYPAD_H -#include - -#define SAMSUNG_MAX_ROWS 8 -#define SAMSUNG_MAX_COLS 8 - -/** - * struct samsung_keypad_platdata - Platform device data for Samsung Keypad. - * @keymap_data: pointer to &matrix_keymap_data. - * @rows: number of keypad row supported. - * @cols: number of keypad col supported. - * @no_autorepeat: disable key autorepeat. - * @wakeup: controls whether the device should be set up as wakeup source. - * @cfg_gpio: configure the GPIO. - * - * Initialisation data specific to either the machine or the platform - * for the device driver to use or call-back when configuring gpio. - */ -struct samsung_keypad_platdata { - const struct matrix_keymap_data *keymap_data; - unsigned int rows; - unsigned int cols; - bool no_autorepeat; - bool wakeup; - - void (*cfg_gpio)(unsigned int rows, unsigned int cols); -}; +#include /** * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device. diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 90d5f0a8f882..cdc385b2cf7d 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -441,9 +441,10 @@ config KEYBOARD_PMIC8XXX config KEYBOARD_SAMSUNG tristate "Samsung keypad support" - depends on SAMSUNG_DEV_KEYPAD + depends on HAVE_CLK help - Say Y here if you want to use the Samsung keypad. + Say Y here if you want to use the keypad on your Samsung mobile + device. To compile this driver as a module, choose M here: the module will be called samsung-keypad. diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index d244fdf9ecdf..1a2b755564f2 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #define SAMSUNG_KEYIFCON 0x00 #define SAMSUNG_KEYIFSTSCLR 0x04 diff --git a/include/linux/input/samsung-keypad.h b/include/linux/input/samsung-keypad.h new file mode 100644 index 000000000000..f25619bfd8a8 --- /dev/null +++ b/include/linux/input/samsung-keypad.h @@ -0,0 +1,43 @@ +/* + * Samsung Keypad platform data definitions + * + * Copyright (C) 2010 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * 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 __SAMSUNG_KEYPAD_H +#define __SAMSUNG_KEYPAD_H + +#include + +#define SAMSUNG_MAX_ROWS 8 +#define SAMSUNG_MAX_COLS 8 + +/** + * struct samsung_keypad_platdata - Platform device data for Samsung Keypad. + * @keymap_data: pointer to &matrix_keymap_data. + * @rows: number of keypad row supported. + * @cols: number of keypad col supported. + * @no_autorepeat: disable key autorepeat. + * @wakeup: controls whether the device should be set up as wakeup source. + * @cfg_gpio: configure the GPIO. + * + * Initialisation data specific to either the machine or the platform + * for the device driver to use or call-back when configuring gpio. + */ +struct samsung_keypad_platdata { + const struct matrix_keymap_data *keymap_data; + unsigned int rows; + unsigned int cols; + bool no_autorepeat; + bool wakeup; + + void (*cfg_gpio)(unsigned int rows, unsigned int cols); +}; + +#endif /* __SAMSUNG_KEYPAD_H */ -- cgit v1.2.3 From b82e324b3c46a554595c12b45465d1943a57326c Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 10 Nov 2011 13:18:09 +0000 Subject: serial, mfd: don't hardcode the console Add support to specify which HSU port to use as an early console. This can be selected by passing "earlyprintk=hsu" on the kernel command line. By default port 0 is still used. Signed-off-by: Mika Westerberg Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/mrst.h | 2 +- arch/x86/kernel/early_printk.c | 2 +- arch/x86/platform/mrst/early_printk_mrst.c | 16 ++++++++++++---- drivers/tty/serial/mfd.c | 18 +++++++----------- 4 files changed, 21 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h index 719f00b28ff5..470776039af9 100644 --- a/arch/x86/include/asm/mrst.h +++ b/arch/x86/include/asm/mrst.h @@ -51,7 +51,7 @@ extern struct console early_mrst_console; extern void mrst_early_console_init(void); extern struct console early_hsu_console; -extern void hsu_early_console_init(void); +extern void hsu_early_console_init(const char *); extern void intel_scu_devices_create(void); extern void intel_scu_devices_destroy(void); diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index cd28a350f7f9..9d42a52d2331 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -247,7 +247,7 @@ static int __init setup_early_printk(char *buf) } if (!strncmp(buf, "hsu", 3)) { - hsu_early_console_init(); + hsu_early_console_init(buf + 3); early_console_register(&early_hsu_console, keep); } #endif diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/mrst/early_printk_mrst.c index 25bfdbb5b130..3c6e328483c7 100644 --- a/arch/x86/platform/mrst/early_printk_mrst.c +++ b/arch/x86/platform/mrst/early_printk_mrst.c @@ -245,16 +245,24 @@ struct console early_mrst_console = { * Following is the early console based on Medfield HSU (High * Speed UART) device. */ -#define HSU_PORT2_PADDR 0xffa28180 +#define HSU_PORT_BASE 0xffa28080 static void __iomem *phsu; -void hsu_early_console_init(void) +void hsu_early_console_init(const char *s) { + unsigned long paddr, port = 0; u8 lcr; - phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, - HSU_PORT2_PADDR); + /* + * Select the early HSU console port if specified by user in the + * kernel command line. + */ + if (*s && !kstrtoul(s, 10, &port)) + port = clamp_val(port, 0, 2); + + paddr = HSU_PORT_BASE + port * 0x80; + phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr); /* Disable FIFO */ writeb(0x0, phsu + UART_FCR); diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 286c386d9c46..565f3fe3dd77 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -1156,7 +1156,6 @@ serial_hsu_console_setup(struct console *co, char *options) int bits = 8; int parity = 'n'; int flow = 'n'; - int ret; if (co->index == -1 || co->index >= serial_hsu_reg.nr) co->index = 0; @@ -1167,9 +1166,7 @@ serial_hsu_console_setup(struct console *co, char *options) if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - ret = uart_set_options(&up->port, co, baud, parity, bits, flow); - - return ret; + return uart_set_options(&up->port, co, baud, parity, bits, flow); } static struct console serial_hsu_console = { @@ -1178,9 +1175,13 @@ static struct console serial_hsu_console = { .device = uart_console_device, .setup = serial_hsu_console_setup, .flags = CON_PRINTBUFFER, - .index = 2, + .index = -1, .data = &serial_hsu_reg, }; + +#define SERIAL_HSU_CONSOLE (&serial_hsu_console) +#else +#define SERIAL_HSU_CONSOLE NULL #endif struct uart_ops serial_hsu_pops = { @@ -1210,6 +1211,7 @@ static struct uart_driver serial_hsu_reg = { .major = TTY_MAJOR, .minor = 128, .nr = 3, + .cons = SERIAL_HSU_CONSOLE, }; #ifdef CONFIG_PM @@ -1344,12 +1346,6 @@ static int serial_hsu_probe(struct pci_dev *pdev, } uart_add_one_port(&serial_hsu_reg, &uport->port); -#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE - if (index == 2) { - register_console(&serial_hsu_console); - uport->port.cons = &serial_hsu_console; - } -#endif pci_set_drvdata(pdev, uport); } -- cgit v1.2.3 From 63b870f149cdcd253ae8da88d8b5a0b43a68965c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 17 Nov 2011 01:19:11 +0900 Subject: ARM: EXYNOS: remove exynos4_scu_enable() The exynos4_scu_enable() is a duplication of scu_enable(). Since commit '26a527e ARM: 7100/1: smp_scu: remove __init annotation from scu_enable()' makes scu_enable() available for non-init codes, exynos can directly call scu_enable() and save exynos4_scu_enable() now. Signed-off-by: Shawn Guo [kgene.kim@samsung.com: added missing header] Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/pm.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 509a435afd4b..4093fea849c3 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -213,27 +214,6 @@ static int exynos4_pm_add(struct sys_device *sysdev) return 0; } -/* This function copy from linux/arch/arm/kernel/smp_scu.c */ - -void exynos4_scu_enable(void __iomem *scu_base) -{ - u32 scu_ctrl; - - scu_ctrl = __raw_readl(scu_base); - /* already enabled? */ - if (scu_ctrl & 1) - return; - - scu_ctrl |= 1; - __raw_writel(scu_ctrl, scu_base); - - /* - * Ensure that the data accessed by CPU0 before the SCU was - * initialised is visible to the other CPUs. - */ - flush_cache_all(); -} - static unsigned long pll_base_rate; static void exynos4_restore_pll(void) @@ -402,7 +382,7 @@ static void exynos4_pm_resume(void) exynos4_restore_pll(); - exynos4_scu_enable(S5P_VA_SCU); + scu_enable(S5P_VA_SCU); #ifdef CONFIG_CACHE_L2X0 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); -- cgit v1.2.3 From 80df46494846e857399618c54df30ce294dc1edd Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Fri, 14 Oct 2011 15:36:51 -0700 Subject: xen: Make XEN_MAX_DOMAIN_MEMORY have more sensible defaults Which is that 128GB is not going to happen with 32-bit PV DomU. Lets use something more realistic. Also update the 64-bit to 500GB which is the max a PV guest can do. Signed-off-by: Maxim Uvarov [v1: Updated 128GB->500GB for 64-bit] Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 26c731a106af..fdce49c7aff6 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig @@ -29,7 +29,8 @@ config XEN_PVHVM config XEN_MAX_DOMAIN_MEMORY int - default 128 + default 500 if X86_64 + default 64 if X86_32 depends on XEN help This only affects the sizing of some bss arrays, the unused @@ -48,3 +49,4 @@ config XEN_DEBUG_FS help Enable statistics output and various tuning options in debugfs. Enabling this option may incur a significant performance overhead. + -- cgit v1.2.3 From 0f9f5a9588468cddeccc9146b86798492c7cd4f5 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Tue, 22 Nov 2011 09:58:06 +0800 Subject: xen/granttable: Introducing grant table V2 stucture This patch introduces new structures of grant table V2, grant table V2 is an extension from V1. Grant table is shared between guest and Xen, and Xen is responsible to do corresponding work for grant operations, such as: figure out guest's grant table version, perform different actions based on different grant table version, etc. Although full-page structure of V2 is different from V1, it play the same role as V1. Acked-by: Ian Campbell Signed-off-by: Annie Li Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/grant-table.c | 7 +- drivers/xen/grant-table.c | 181 ++++++++++++++++++++++++++++-------- include/xen/grant_table.h | 4 +- include/xen/interface/grant_table.h | 167 ++++++++++++++++++++++++++++++++- include/xen/interface/xen.h | 2 + 5 files changed, 310 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c index 6bbfd7ac5e81..c6ab2e7ca3a6 100644 --- a/arch/x86/xen/grant-table.c +++ b/arch/x86/xen/grant-table.c @@ -64,10 +64,10 @@ static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, unsigned long max_nr_gframes, - struct grant_entry **__shared) + void **__shared) { int rc; - struct grant_entry *shared = *__shared; + void *shared = *__shared; if (shared == NULL) { struct vm_struct *area = @@ -83,8 +83,7 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, return rc; } -void arch_gnttab_unmap_shared(struct grant_entry *shared, - unsigned long nr_gframes) +void arch_gnttab_unmap_shared(void *shared, unsigned long nr_gframes) { apply_to_page_range(&init_mm, (unsigned long)shared, PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index bf1c094f4ebf..18355a53763f 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -53,7 +53,7 @@ /* External tools reserve first few grant table entries. */ #define NR_RESERVED_ENTRIES 8 #define GNTTAB_LIST_END 0xffffffff -#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(struct grant_entry)) +#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(struct grant_entry_v1)) static grant_ref_t **gnttab_list; static unsigned int nr_grant_frames; @@ -64,7 +64,63 @@ static DEFINE_SPINLOCK(gnttab_list_lock); unsigned long xen_hvm_resume_frames; EXPORT_SYMBOL_GPL(xen_hvm_resume_frames); -static struct grant_entry *shared; +static union { + struct grant_entry_v1 *v1; + void *addr; +} gnttab_shared; + +/*This is a structure of function pointers for grant table*/ +struct gnttab_ops { + /* + * Mapping a list of frames for storing grant entries. First input + * parameter is used to storing grant table address when grant table + * being setup, second parameter is the number of frames to map grant + * table. Returning GNTST_okay means success and negative value means + * failure. + */ + int (*map_frames)(unsigned long *, unsigned int); + /* + * Release a list of frames which are mapped in map_frames for grant + * entry status. + */ + void (*unmap_frames)(void); + /* + * Introducing a valid entry into the grant table, granting the frame + * of this grant entry to domain for accessing, or transfering, or + * transitively accessing. First input parameter is reference of this + * introduced grant entry, second one is domid of granted domain, third + * one is the frame to be granted, and the last one is status of the + * grant entry to be updated. + */ + void (*update_entry)(grant_ref_t, domid_t, unsigned long, unsigned); + /* + * Stop granting a grant entry to domain for accessing. First input + * parameter is reference of a grant entry whose grant access will be + * stopped, second one is not in use now. If the grant entry is + * currently mapped for reading or writing, just return failure(==0) + * directly and don't tear down the grant access. Otherwise, stop grant + * access for this entry and return success(==1). + */ + int (*end_foreign_access_ref)(grant_ref_t, int); + /* + * Stop granting a grant entry to domain for transfer. If tranfer has + * not started, just reclaim the grant entry and return failure(==0). + * Otherwise, wait for the transfer to complete and then return the + * frame. + */ + unsigned long (*end_foreign_transfer_ref)(grant_ref_t); + /* + * Query the status of a grant entry. Input parameter is reference of + * queried grant entry, return value is the status of queried entry. + * Detailed status(writing/reading) can be gotten from the return value + * by bit operations. + */ + int (*query_foreign_access)(grant_ref_t); +}; + +static struct gnttab_ops *gnttab_interface; + +static int grant_table_version; static struct gnttab_free_callback *gnttab_free_callback_list; @@ -142,23 +198,23 @@ static void put_free_entry(grant_ref_t ref) spin_unlock_irqrestore(&gnttab_list_lock, flags); } -static void update_grant_entry(grant_ref_t ref, domid_t domid, - unsigned long frame, unsigned flags) +/* + * Introducing a valid entry into the grant table: + * 1. Write ent->domid. + * 2. Write ent->frame: + * GTF_permit_access: Frame to which access is permitted. + * GTF_accept_transfer: Pseudo-phys frame slot being filled by new + * frame, or zero if none. + * 3. Write memory barrier (WMB). + * 4. Write ent->flags, inc. valid type. + */ +static void gnttab_update_entry_v1(grant_ref_t ref, domid_t domid, + unsigned long frame, unsigned flags) { - /* - * Introducing a valid entry into the grant table: - * 1. Write ent->domid. - * 2. Write ent->frame: - * GTF_permit_access: Frame to which access is permitted. - * GTF_accept_transfer: Pseudo-phys frame slot being filled by new - * frame, or zero if none. - * 3. Write memory barrier (WMB). - * 4. Write ent->flags, inc. valid type. - */ - shared[ref].frame = frame; - shared[ref].domid = domid; + gnttab_shared.v1[ref].domid = domid; + gnttab_shared.v1[ref].frame = frame; wmb(); - shared[ref].flags = flags; + gnttab_shared.v1[ref].flags = flags; } /* @@ -167,7 +223,7 @@ static void update_grant_entry(grant_ref_t ref, domid_t domid, void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, unsigned long frame, int readonly) { - update_grant_entry(ref, domid, frame, + gnttab_interface->update_entry(ref, domid, frame, GTF_permit_access | (readonly ? GTF_readonly : 0)); } EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); @@ -187,31 +243,37 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, } EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); -int gnttab_query_foreign_access(grant_ref_t ref) +static int gnttab_query_foreign_access_v1(grant_ref_t ref) { - u16 nflags; - - nflags = shared[ref].flags; + return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); +} - return nflags & (GTF_reading|GTF_writing); +int gnttab_query_foreign_access(grant_ref_t ref) +{ + return gnttab_interface->query_foreign_access(ref); } EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); -int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) +static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly) { u16 flags, nflags; - nflags = shared[ref].flags; + nflags = gnttab_shared.v1[ref].flags; do { flags = nflags; if (flags & (GTF_reading|GTF_writing)) { printk(KERN_ALERT "WARNING: g.e. still in use!\n"); return 0; } - } while ((nflags = sync_cmpxchg(&shared[ref].flags, flags, 0)) != flags); + } while ((nflags = sync_cmpxchg(&gnttab_shared.v1[ref].flags, flags, 0)) != flags); return 1; } + +int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) +{ + return gnttab_interface->end_foreign_access_ref(ref, readonly); +} EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); void gnttab_end_foreign_access(grant_ref_t ref, int readonly, @@ -246,11 +308,11 @@ EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer); void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, unsigned long pfn) { - update_grant_entry(ref, domid, pfn, GTF_accept_transfer); + gnttab_interface->update_entry(ref, domid, pfn, GTF_accept_transfer); } EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref); -unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) +static unsigned long gnttab_end_foreign_transfer_ref_v1(grant_ref_t ref) { unsigned long frame; u16 flags; @@ -259,24 +321,29 @@ unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) * If a transfer is not even yet started, try to reclaim the grant * reference and return failure (== 0). */ - while (!((flags = shared[ref].flags) & GTF_transfer_committed)) { - if (sync_cmpxchg(&shared[ref].flags, flags, 0) == flags) + while (!((flags = gnttab_shared.v1[ref].flags) & GTF_transfer_committed)) { + if (sync_cmpxchg(&gnttab_shared.v1[ref].flags, flags, 0) == flags) return 0; cpu_relax(); } /* If a transfer is in progress then wait until it is completed. */ while (!(flags & GTF_transfer_completed)) { - flags = shared[ref].flags; + flags = gnttab_shared.v1[ref].flags; cpu_relax(); } rmb(); /* Read the frame number /after/ reading completion status. */ - frame = shared[ref].frame; + frame = gnttab_shared.v1[ref].frame; BUG_ON(frame == 0); return frame; } + +unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) +{ + return gnttab_interface->end_foreign_transfer_ref(ref); +} EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref); unsigned long gnttab_end_foreign_transfer(grant_ref_t ref) @@ -520,6 +587,23 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, } EXPORT_SYMBOL_GPL(gnttab_unmap_refs); +static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes) +{ + int rc; + + rc = arch_gnttab_map_shared(frames, nr_gframes, + gnttab_max_grant_frames(), + &gnttab_shared.addr); + BUG_ON(rc); + + return 0; +} + +static void gnttab_unmap_frames_v1(void) +{ + arch_gnttab_unmap_shared(gnttab_shared.addr, nr_grant_frames); +} + static int gnttab_map(unsigned int start_idx, unsigned int end_idx) { struct gnttab_setup_table setup; @@ -567,19 +651,35 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) BUG_ON(rc || setup.status); - rc = arch_gnttab_map_shared(frames, nr_gframes, gnttab_max_grant_frames(), - &shared); - BUG_ON(rc); + rc = gnttab_interface->map_frames(frames, nr_gframes); kfree(frames); - return 0; + return rc; +} + +static struct gnttab_ops gnttab_v1_ops = { + .map_frames = gnttab_map_frames_v1, + .unmap_frames = gnttab_unmap_frames_v1, + .update_entry = gnttab_update_entry_v1, + .end_foreign_access_ref = gnttab_end_foreign_access_ref_v1, + .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v1, + .query_foreign_access = gnttab_query_foreign_access_v1, +}; + +static void gnttab_request_version(void) +{ + grant_table_version = 1; + gnttab_interface = &gnttab_v1_ops; + printk(KERN_INFO "Grant tables using version %d layout.\n", + grant_table_version); } int gnttab_resume(void) { unsigned int max_nr_gframes; + gnttab_request_version(); max_nr_gframes = gnttab_max_grant_frames(); if (max_nr_gframes < nr_grant_frames) return -ENOSYS; @@ -587,9 +687,10 @@ int gnttab_resume(void) if (xen_pv_domain()) return gnttab_map(0, nr_grant_frames - 1); - if (!shared) { - shared = ioremap(xen_hvm_resume_frames, PAGE_SIZE * max_nr_gframes); - if (shared == NULL) { + if (gnttab_shared.addr == NULL) { + gnttab_shared.addr = ioremap(xen_hvm_resume_frames, + PAGE_SIZE * max_nr_gframes); + if (gnttab_shared.addr == NULL) { printk(KERN_WARNING "Failed to ioremap gnttab share frames!"); return -ENOMEM; @@ -603,7 +704,7 @@ int gnttab_resume(void) int gnttab_suspend(void) { - arch_gnttab_unmap_shared(shared, nr_grant_frames); + gnttab_interface->unmap_frames(); return 0; } diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 11e2dfce42f8..c7a40f8d455a 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -145,8 +145,8 @@ gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, phys_addr_t addr, int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, unsigned long max_nr_gframes, - struct grant_entry **__shared); -void arch_gnttab_unmap_shared(struct grant_entry *shared, + void **__shared); +void arch_gnttab_unmap_shared(void *shared, unsigned long nr_gframes); extern unsigned long xen_hvm_resume_frames; diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h index 39e571796e32..a17d84433e6a 100644 --- a/include/xen/interface/grant_table.h +++ b/include/xen/interface/grant_table.h @@ -84,13 +84,23 @@ * Use SMP-safe bit-setting instruction. */ +/* + * Reference to a grant entry in a specified domain's grant table. + */ +typedef uint32_t grant_ref_t; + /* * A grant table comprises a packed array of grant entries in one or more * page frames shared between Xen and a guest. * [XEN]: This field is written by Xen and read by the sharing guest. * [GST]: This field is written by the guest and read by Xen. */ -struct grant_entry { + +/* + * Version 1 of the grant table entry structure is maintained purely + * for backwards compatibility. New guests should use version 2. + */ +struct grant_entry_v1 { /* GTF_xxx: various type and flag information. [XEN,GST] */ uint16_t flags; /* The domain being granted foreign privileges. [GST] */ @@ -108,10 +118,13 @@ struct grant_entry { * GTF_permit_access: Allow @domid to map/access @frame. * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame * to this guest. Xen writes the page number to @frame. + * GTF_transitive: Allow @domid to transitively access a subrange of + * @trans_grant in @trans_domid. No mappings are allowed. */ #define GTF_invalid (0U<<0) #define GTF_permit_access (1U<<0) #define GTF_accept_transfer (2U<<0) +#define GTF_transitive (3U<<0) #define GTF_type_mask (3U<<0) /* @@ -119,6 +132,9 @@ struct grant_entry { * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] + * GTF_sub_page: Grant access to only a subrange of the page. @domid + * will only be allowed to copy from the grant, and not + * map it. [GST] */ #define _GTF_readonly (2) #define GTF_readonly (1U<<_GTF_readonly) @@ -126,6 +142,8 @@ struct grant_entry { #define GTF_reading (1U<<_GTF_reading) #define _GTF_writing (4) #define GTF_writing (1U<<_GTF_writing) +#define _GTF_sub_page (8) +#define GTF_sub_page (1U<<_GTF_sub_page) /* * Subflags for GTF_accept_transfer: @@ -142,15 +160,81 @@ struct grant_entry { #define _GTF_transfer_completed (3) #define GTF_transfer_completed (1U<<_GTF_transfer_completed) +/* + * Version 2 grant table entries. These fulfil the same role as + * version 1 entries, but can represent more complicated operations. + * Any given domain will have either a version 1 or a version 2 table, + * and every entry in the table will be the same version. + * + * The interface by which domains use grant references does not depend + * on the grant table version in use by the other domain. + */ -/*********************************** - * GRANT TABLE QUERIES AND USES +/* + * Version 1 and version 2 grant entries share a common prefix. The + * fields of the prefix are documented as part of struct + * grant_entry_v1. */ +struct grant_entry_header { + uint16_t flags; + domid_t domid; +}; /* - * Reference to a grant entry in a specified domain's grant table. + * Version 2 of the grant entry structure, here is an union because three + * different types are suppotted: full_page, sub_page and transitive. + */ +union grant_entry_v2 { + struct grant_entry_header hdr; + + /* + * This member is used for V1-style full page grants, where either: + * + * -- hdr.type is GTF_accept_transfer, or + * -- hdr.type is GTF_permit_access and GTF_sub_page is not set. + * + * In that case, the frame field has the same semantics as the + * field of the same name in the V1 entry structure. + */ + struct { + struct grant_entry_header hdr; + uint32_t pad0; + uint64_t frame; + } full_page; + + /* + * If the grant type is GTF_grant_access and GTF_sub_page is set, + * @domid is allowed to access bytes [@page_off,@page_off+@length) + * in frame @frame. + */ + struct { + struct grant_entry_header hdr; + uint16_t page_off; + uint16_t length; + uint64_t frame; + } sub_page; + + /* + * If the grant is GTF_transitive, @domid is allowed to use the + * grant @gref in domain @trans_domid, as if it was the local + * domain. Obviously, the transitive access must be compatible + * with the original grant. + */ + struct { + struct grant_entry_header hdr; + domid_t trans_domid; + uint16_t pad0; + grant_ref_t gref; + } transitive; + + uint32_t __spacer[4]; /* Pad to a power of two */ +}; + +typedef uint16_t grant_status_t; + +/*********************************** + * GRANT TABLE QUERIES AND USES */ -typedef uint32_t grant_ref_t; /* * Handle to track a mapping created via a grant reference. @@ -321,6 +405,79 @@ struct gnttab_query_size { }; DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size); +/* + * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings + * tracked by but atomically replace the page table entry with one + * pointing to the machine address under . will be + * redirected to the null entry. + * NOTES: + * 1. The call may fail in an undefined manner if either mapping is not + * tracked by . + * 2. After executing a batch of unmaps, it is guaranteed that no stale + * mappings will remain in the device or host TLBs. + */ +#define GNTTABOP_unmap_and_replace 7 +struct gnttab_unmap_and_replace { + /* IN parameters. */ + uint64_t host_addr; + uint64_t new_addr; + grant_handle_t handle; + /* OUT parameters. */ + int16_t status; /* GNTST_* */ +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_and_replace); + +/* + * GNTTABOP_set_version: Request a particular version of the grant + * table shared table structure. This operation can only be performed + * once in any given domain. It must be performed before any grants + * are activated; otherwise, the domain will be stuck with version 1. + * The only defined versions are 1 and 2. + */ +#define GNTTABOP_set_version 8 +struct gnttab_set_version { + /* IN parameters */ + uint32_t version; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_set_version); + +/* + * GNTTABOP_get_status_frames: Get the list of frames used to store grant + * status for . In grant format version 2, the status is separated + * from the other shared grant fields to allow more efficient synchronization + * using barriers instead of atomic cmpexch operations. + * specify the size of vector . + * The frame addresses are returned in the . + * Only addresses are returned, even if the table is larger. + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may specify != DOMID_SELF. + */ +#define GNTTABOP_get_status_frames 9 +struct gnttab_get_status_frames { + /* IN parameters. */ + uint32_t nr_frames; + domid_t dom; + /* OUT parameters. */ + int16_t status; /* GNTST_* */ + GUEST_HANDLE(uint64_t) frame_list; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_status_frames); + +/* + * GNTTABOP_get_version: Get the grant table version which is in + * effect for domain . + */ +#define GNTTABOP_get_version 10 +struct gnttab_get_version { + /* IN parameters */ + domid_t dom; + uint16_t pad; + /* OUT parameters */ + uint32_t version; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version); + /* * Bitfield values for update_pin_status.flags. */ diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index 6a6e91449347..a890804945e3 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h @@ -523,6 +523,8 @@ struct tmem_op { } u; }; +DEFINE_GUEST_HANDLE(u64); + #else /* __ASSEMBLY__ */ /* In assembly code we cannot use C numeric constant suffixes. */ -- cgit v1.2.3 From 85ff6acb075a484780b3d763fdf41596d8fc0970 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Tue, 22 Nov 2011 09:59:21 +0800 Subject: xen/granttable: Grant tables V2 implementation Receiver-side copying of packets is based on this implementation, it gives better performance and better CPU accounting. It totally supports three types: full-page, sub-page and transitive grants. However this patch does not cover sub-page and transitive grants, it mainly focus on Full-page part and implements grant table V2 interfaces corresponding to what already exists in grant table V1, such as: grant table V2 initialization, mapping, releasing and exported interfaces. Each guest can only supports one type of grant table type, every entry in grant table should be the same version. It is necessary to set V1 or V2 version before initializing the grant table. Grant table exported interfaces of V2 are same with those of V1, Xen is responsible to judge what grant table version guests are using in every grant operation. V2 fulfills the same role of V1, and it is totally backwards compitable with V1. If dom0 support grant table V2, the guests runing on it can run with either V1 or V2. Acked-by: Ian Campbell Signed-off-by: Annie Li [v1: Modified alloc_vm_area call (new parameters), indentation, and cleanpatch warnings] Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/grant-table.c | 39 ++++++++++- drivers/xen/grant-table.c | 171 +++++++++++++++++++++++++++++++++++++++++++-- include/xen/grant_table.h | 6 +- 3 files changed, 209 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c index c6ab2e7ca3a6..65160a8a0ba3 100644 --- a/arch/x86/xen/grant-table.c +++ b/arch/x86/xen/grant-table.c @@ -54,6 +54,20 @@ static int map_pte_fn(pte_t *pte, struct page *pmd_page, return 0; } +/* + * This function is used to map shared frames to store grant status. It is + * different from map_pte_fn above, the frames type here is uint64_t. + */ +static int map_pte_fn_status(pte_t *pte, struct page *pmd_page, + unsigned long addr, void *data) +{ + uint64_t **frames = (uint64_t **)data; + + set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL)); + (*frames)++; + return 0; +} + static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) { @@ -83,7 +97,30 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, return rc; } -void arch_gnttab_unmap_shared(void *shared, unsigned long nr_gframes) +int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes, + unsigned long max_nr_gframes, + grant_status_t **__shared) +{ + int rc; + grant_status_t *shared = *__shared; + + if (shared == NULL) { + /* No need to pass in PTE as we are going to do it + * in apply_to_page_range anyhow. */ + struct vm_struct *area = + alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL); + BUG_ON(area == NULL); + shared = area->addr; + *__shared = shared; + } + + rc = apply_to_page_range(&init_mm, (unsigned long)shared, + PAGE_SIZE * nr_gframes, + map_pte_fn_status, &frames); + return rc; +} + +void arch_gnttab_unmap(void *shared, unsigned long nr_gframes) { apply_to_page_range(&init_mm, (unsigned long)shared, PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 0518d0404942..301869f60dc7 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,10 @@ /* External tools reserve first few grant table entries. */ #define NR_RESERVED_ENTRIES 8 #define GNTTAB_LIST_END 0xffffffff -#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(struct grant_entry_v1)) +#define GREFS_PER_GRANT_FRAME \ +(grant_table_version == 1 ? \ +(PAGE_SIZE / sizeof(struct grant_entry_v1)) : \ +(PAGE_SIZE / sizeof(union grant_entry_v2))) static grant_ref_t **gnttab_list; static unsigned int nr_grant_frames; @@ -66,6 +70,7 @@ EXPORT_SYMBOL_GPL(xen_hvm_resume_frames); static union { struct grant_entry_v1 *v1; + union grant_entry_v2 *v2; void *addr; } gnttab_shared; @@ -120,6 +125,9 @@ struct gnttab_ops { static struct gnttab_ops *gnttab_interface; +/*This reflects status of grant entries, so act as a global value*/ +static grant_status_t *grstatus; + static int grant_table_version; static struct gnttab_free_callback *gnttab_free_callback_list; @@ -127,6 +135,7 @@ static struct gnttab_free_callback *gnttab_free_callback_list; static int gnttab_expand(unsigned int req_entries); #define RPP (PAGE_SIZE / sizeof(grant_ref_t)) +#define SPP (PAGE_SIZE / sizeof(grant_status_t)) static inline grant_ref_t *__gnttab_entry(grant_ref_t entry) { @@ -199,6 +208,7 @@ static void put_free_entry(grant_ref_t ref) } /* + * Following applies to gnttab_update_entry_v1 and gnttab_update_entry_v2. * Introducing a valid entry into the grant table: * 1. Write ent->domid. * 2. Write ent->frame: @@ -217,6 +227,15 @@ static void gnttab_update_entry_v1(grant_ref_t ref, domid_t domid, gnttab_shared.v1[ref].flags = flags; } +static void gnttab_update_entry_v2(grant_ref_t ref, domid_t domid, + unsigned long frame, unsigned flags) +{ + gnttab_shared.v2[ref].hdr.domid = domid; + gnttab_shared.v2[ref].full_page.frame = frame; + wmb(); + gnttab_shared.v2[ref].hdr.flags = GTF_permit_access | flags; +} + /* * Public grant-issuing interface functions */ @@ -248,6 +267,11 @@ static int gnttab_query_foreign_access_v1(grant_ref_t ref) return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); } +static int gnttab_query_foreign_access_v2(grant_ref_t ref) +{ + return grstatus[ref] & (GTF_reading|GTF_writing); +} + int gnttab_query_foreign_access(grant_ref_t ref) { return gnttab_interface->query_foreign_access(ref); @@ -272,6 +296,29 @@ static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly) return 1; } +static int gnttab_end_foreign_access_ref_v2(grant_ref_t ref, int readonly) +{ + gnttab_shared.v2[ref].hdr.flags = 0; + mb(); + if (grstatus[ref] & (GTF_reading|GTF_writing)) { + return 0; + } else { + /* The read of grstatus needs to have acquire + semantics. On x86, reads already have + that, and we just need to protect against + compiler reorderings. On other + architectures we may need a full + barrier. */ +#ifdef CONFIG_X86 + barrier(); +#else + mb(); +#endif + } + + return 1; +} + int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) { return gnttab_interface->end_foreign_access_ref(ref, readonly); @@ -345,6 +392,37 @@ static unsigned long gnttab_end_foreign_transfer_ref_v1(grant_ref_t ref) return frame; } +static unsigned long gnttab_end_foreign_transfer_ref_v2(grant_ref_t ref) +{ + unsigned long frame; + u16 flags; + u16 *pflags; + + pflags = &gnttab_shared.v2[ref].hdr.flags; + + /* + * If a transfer is not even yet started, try to reclaim the grant + * reference and return failure (== 0). + */ + while (!((flags = *pflags) & GTF_transfer_committed)) { + if (sync_cmpxchg(pflags, flags, 0) == flags) + return 0; + cpu_relax(); + } + + /* If a transfer is in progress then wait until it is completed. */ + while (!(flags & GTF_transfer_completed)) { + flags = *pflags; + cpu_relax(); + } + + rmb(); /* Read the frame number /after/ reading completion status. */ + frame = gnttab_shared.v2[ref].full_page.frame; + BUG_ON(frame == 0); + + return frame; +} + unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) { return gnttab_interface->end_foreign_transfer_ref(ref); @@ -592,6 +670,11 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, } EXPORT_SYMBOL_GPL(gnttab_unmap_refs); +static unsigned nr_status_frames(unsigned nr_grant_frames) +{ + return (nr_grant_frames * GREFS_PER_GRANT_FRAME + SPP - 1) / SPP; +} + static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes) { int rc; @@ -606,7 +689,56 @@ static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes) static void gnttab_unmap_frames_v1(void) { - arch_gnttab_unmap_shared(gnttab_shared.addr, nr_grant_frames); + arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); +} + +static int gnttab_map_frames_v2(unsigned long *frames, unsigned int nr_gframes) +{ + uint64_t *sframes; + unsigned int nr_sframes; + struct gnttab_get_status_frames getframes; + int rc; + + nr_sframes = nr_status_frames(nr_gframes); + + /* No need for kzalloc as it is initialized in following hypercall + * GNTTABOP_get_status_frames. + */ + sframes = kmalloc(nr_sframes * sizeof(uint64_t), GFP_ATOMIC); + if (!sframes) + return -ENOMEM; + + getframes.dom = DOMID_SELF; + getframes.nr_frames = nr_sframes; + set_xen_guest_handle(getframes.frame_list, sframes); + + rc = HYPERVISOR_grant_table_op(GNTTABOP_get_status_frames, + &getframes, 1); + if (rc == -ENOSYS) { + kfree(sframes); + return -ENOSYS; + } + + BUG_ON(rc || getframes.status); + + rc = arch_gnttab_map_status(sframes, nr_sframes, + nr_status_frames(gnttab_max_grant_frames()), + &grstatus); + BUG_ON(rc); + kfree(sframes); + + rc = arch_gnttab_map_shared(frames, nr_gframes, + gnttab_max_grant_frames(), + &gnttab_shared.addr); + BUG_ON(rc); + + return 0; +} + +static void gnttab_unmap_frames_v2(void) +{ + arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); + arch_gnttab_unmap(grstatus, nr_status_frames(nr_grant_frames)); } static int gnttab_map(unsigned int start_idx, unsigned int end_idx) @@ -640,6 +772,9 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) return rc; } + /* No need for kzalloc as it is initialized in following hypercall + * GNTTABOP_setup_table. + */ frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC); if (!frames) return -ENOMEM; @@ -672,10 +807,38 @@ static struct gnttab_ops gnttab_v1_ops = { .query_foreign_access = gnttab_query_foreign_access_v1, }; +static struct gnttab_ops gnttab_v2_ops = { + .map_frames = gnttab_map_frames_v2, + .unmap_frames = gnttab_unmap_frames_v2, + .update_entry = gnttab_update_entry_v2, + .end_foreign_access_ref = gnttab_end_foreign_access_ref_v2, + .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v2, + .query_foreign_access = gnttab_query_foreign_access_v2, +}; + static void gnttab_request_version(void) { - grant_table_version = 1; - gnttab_interface = &gnttab_v1_ops; + int rc; + struct gnttab_set_version gsv; + + gsv.version = 2; + rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); + if (rc == 0) { + grant_table_version = 2; + gnttab_interface = &gnttab_v2_ops; + } else if (grant_table_version == 2) { + /* + * If we've already used version 2 features, + * but then suddenly discover that they're not + * available (e.g. migrating to an older + * version of Xen), almost unbounded badness + * can happen. + */ + panic("we need grant tables version 2, but only version 1 is available"); + } else { + grant_table_version = 1; + gnttab_interface = &gnttab_v1_ops; + } printk(KERN_INFO "Grant tables using version %d layout.\n", grant_table_version); } diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index c7a40f8d455a..5494c402c83a 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -146,8 +146,10 @@ gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, phys_addr_t addr, int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, unsigned long max_nr_gframes, void **__shared); -void arch_gnttab_unmap_shared(void *shared, - unsigned long nr_gframes); +int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes, + unsigned long max_nr_gframes, + grant_status_t **__shared); +void arch_gnttab_unmap(void *shared, unsigned long nr_gframes); extern unsigned long xen_hvm_resume_frames; unsigned int gnttab_max_grant_frames(void); -- cgit v1.2.3 From 865d605ee81813dc73d5422fd2f9bd132d10d194 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Tue, 9 Aug 2011 16:51:11 +0200 Subject: at91: provide macb clks with "pclk" and "hclk" name The macb driver expects clocks with the names "pclk" and "hclk". We currently provide "macb_clk" but to fit in line with other architectures (namely AVR32), provide "pclk" and a fake "hclk". Cc: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Jamie Iles Acked-by: David S. Miller Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91cap9.c | 4 +++- arch/arm/mach-at91/at91sam9260.c | 4 +++- arch/arm/mach-at91/at91sam9263.c | 4 +++- arch/arm/mach-at91/at91sam9g45.c | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index ecdd54dd68c6..17632b82dd76 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -137,7 +137,7 @@ static struct clk pwm_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91CAP9_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -210,6 +210,8 @@ static struct clk *periph_clocks[] __initdata = { }; 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), diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b84a9f642f59..249ed1f5912d 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -120,7 +120,7 @@ static struct clk ohci_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91SAM9260_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -190,6 +190,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_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", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index f83fbb0ee0c5..182d112dc59d 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -118,7 +118,7 @@ static struct clk pwm_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91SAM9263_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -182,6 +182,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 318b0407ea04..5a0e522ffa94 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -150,7 +150,7 @@ static struct clk ac97_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -209,6 +209,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_clk), /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), -- cgit v1.2.3 From 84e0cdb0a262483a3618091c43dae33d36226430 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Tue, 8 Mar 2011 20:17:06 +0000 Subject: macb: unify at91 and avr32 platform data Both at91 and avr32 defines its own platform data structure for the macb driver and both share common structures though at91 includes a currently unused phy_irq_pin. Create a common macb_platform_data for macb that both at91 and avr32 can use. In future we can use this to support other architectures that use the same IP block with the macb driver. v2: rename eth_platform_data to macb_platform_data and allow at91_ether to share the platform data with macb. Signed-off-by: Jamie Iles Acked-by: Nicolas Ferre Tested-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91cap9_devices.c | 6 +++--- arch/arm/mach-at91/at91rm9200_devices.c | 6 +++--- arch/arm/mach-at91/at91sam9260_devices.c | 6 +++--- arch/arm/mach-at91/at91sam9263_devices.c | 6 +++--- arch/arm/mach-at91/at91sam9g45_devices.c | 6 +++--- arch/arm/mach-at91/board-1arm.c | 2 +- arch/arm/mach-at91/board-afeb-9260v1.c | 2 +- arch/arm/mach-at91/board-cam60.c | 2 +- arch/arm/mach-at91/board-cap9adk.c | 2 +- arch/arm/mach-at91/board-carmeva.c | 2 +- arch/arm/mach-at91/board-cpu9krea.c | 2 +- arch/arm/mach-at91/board-cpuat91.c | 2 +- arch/arm/mach-at91/board-csb337.c | 2 +- arch/arm/mach-at91/board-csb637.c | 2 +- arch/arm/mach-at91/board-eb9200.c | 2 +- arch/arm/mach-at91/board-ecbat91.c | 2 +- arch/arm/mach-at91/board-eco920.c | 2 +- arch/arm/mach-at91/board-foxg20.c | 2 +- arch/arm/mach-at91/board-gsia18s.c | 2 +- arch/arm/mach-at91/board-kafa.c | 2 +- arch/arm/mach-at91/board-kb9202.c | 2 +- arch/arm/mach-at91/board-neocore926.c | 2 +- arch/arm/mach-at91/board-pcontrol-g20.c | 2 +- arch/arm/mach-at91/board-picotux200.c | 2 +- arch/arm/mach-at91/board-qil-a9260.c | 2 +- arch/arm/mach-at91/board-rm9200dk.c | 2 +- arch/arm/mach-at91/board-rm9200ek.c | 2 +- arch/arm/mach-at91/board-rsi-ews.c | 2 +- arch/arm/mach-at91/board-sam9-l9260.c | 2 +- arch/arm/mach-at91/board-sam9260ek.c | 2 +- arch/arm/mach-at91/board-sam9263ek.c | 2 +- arch/arm/mach-at91/board-sam9g20ek.c | 2 +- arch/arm/mach-at91/board-sam9m10g45ek.c | 2 +- arch/arm/mach-at91/board-snapper9260.c | 2 +- arch/arm/mach-at91/board-stamp9g20.c | 2 +- arch/arm/mach-at91/board-usb-a926x.c | 2 +- arch/arm/mach-at91/board-yl-9200.c | 2 +- arch/arm/mach-at91/include/mach/board.h | 14 ++------------ arch/avr32/boards/atngw100/setup.c | 2 +- arch/avr32/boards/atstk1000/atstk1002.c | 2 +- arch/avr32/boards/favr-32/setup.c | 2 +- arch/avr32/boards/hammerhead/setup.c | 2 +- arch/avr32/boards/merisc/setup.c | 2 +- arch/avr32/boards/mimc200/setup.c | 2 +- arch/avr32/mach-at32ap/at32ap700x.c | 8 ++++---- arch/avr32/mach-at32ap/include/mach/board.h | 7 ++----- drivers/net/ethernet/cadence/at91_ether.c | 3 ++- drivers/net/ethernet/cadence/at91_ether.h | 4 +++- drivers/net/ethernet/cadence/macb.c | 10 ++++------ include/linux/platform_data/macb.h | 17 +++++++++++++++++ 50 files changed, 87 insertions(+), 82 deletions(-) create mode 100644 include/linux/platform_data/macb.h (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index adad70db70eb..695aecab0a67 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -200,7 +200,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -227,7 +227,7 @@ static struct platform_device at91cap9_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -264,7 +264,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91cap9_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 66591fa53e05..5610f14e342e 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -135,7 +135,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -162,7 +162,7 @@ static struct platform_device at91rm9200_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -199,7 +199,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91rm9200_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 25e3464fb07f..ff75f7d4091b 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -136,7 +136,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -163,7 +163,7 @@ static struct platform_device at91sam9260_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -200,7 +200,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91sam9260_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ad017eb1f8df..68562ce2af94 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -144,7 +144,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -171,7 +171,7 @@ static struct platform_device at91sam9263_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -208,7 +208,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91sam9263_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 09a16d6bd5cd..e2cb835c4d7c 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -284,7 +284,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -311,7 +311,7 @@ static struct platform_device at91sam9g45_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -348,7 +348,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91sam9g45_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index 367d5cd5e362..a60d98d7c3e2 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c @@ -63,7 +63,7 @@ static void __init onearm_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata onearm_eth_data = { +static struct macb_platform_data __initdata onearm_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 4282d96dffa8..17fc77925707 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -103,7 +103,7 @@ static struct spi_board_info afeb9260_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata afeb9260_macb_data = { +static struct macb_platform_data __initdata afeb9260_macb_data = { .phy_irq_pin = AT91_PIN_PA9, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index f90cfb32bad2..2037d2c40eb4 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -115,7 +115,7 @@ static struct spi_board_info cam60_spi_devices[] __initdata = { /* * MACB Ethernet device */ -static struct __initdata at91_eth_data cam60_macb_data = { +static struct __initdata macb_platform_data cam60_macb_data = { .phy_irq_pin = AT91_PIN_PB5, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 5dffd3be62d2..af5520c366fe 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -153,7 +153,7 @@ static struct at91_mmc_data __initdata cap9adk_mmc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata cap9adk_macb_data = { +static struct macb_platform_data __initdata cap9adk_macb_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index 774c87fcbd5b..529b356cdb7d 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -57,7 +57,7 @@ static void __init carmeva_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata carmeva_eth_data = { +static struct macb_platform_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index fc885a4ce243..04d2b9b50464 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -99,7 +99,7 @@ static struct at91_udc_data __initdata cpu9krea_udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata cpu9krea_macb_data = { +static struct macb_platform_data __initdata cpu9krea_macb_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index d35e65b08ccd..7a4c82e8da51 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -82,7 +82,7 @@ static void __init cpuat91_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata cpuat91_eth_data = { +static struct macb_platform_data __initdata cpuat91_eth_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index c3936665e645..b004b20b8e42 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c @@ -58,7 +58,7 @@ static void __init csb337_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata csb337_eth_data = { +static struct macb_platform_data __initdata csb337_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index 586100e2acbb..e966de5219c7 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c @@ -52,7 +52,7 @@ static void __init csb637_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata csb637_eth_data = { +static struct macb_platform_data __initdata csb637_eth_data = { .phy_irq_pin = AT91_PIN_PC0, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c index 45db7a3dbef0..3788fa527121 100644 --- a/arch/arm/mach-at91/board-eb9200.c +++ b/arch/arm/mach-at91/board-eb9200.c @@ -60,7 +60,7 @@ static void __init eb9200_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata eb9200_eth_data = { +static struct macb_platform_data __initdata eb9200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index 2f9c16d29212..af7622eae1a9 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -64,7 +64,7 @@ static void __init ecb_at91init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata ecb_at91eth_data = { +static struct macb_platform_data __initdata ecb_at91eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index 8252c722607b..8e75867d1d18 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -47,7 +47,7 @@ static void __init eco920_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata eco920_eth_data = { +static struct macb_platform_data __initdata eco920_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index f27d1a780cfa..de8e09642f4e 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c @@ -135,7 +135,7 @@ static struct spi_board_info foxg20_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata foxg20_macb_data = { +static struct macb_platform_data __initdata foxg20_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index 2e95949737e6..51c82f151119 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -93,7 +93,7 @@ static struct at91_udc_data __initdata udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata macb_data = { +static struct macb_platform_data __initdata macb_data = { .phy_irq_pin = AT91_PIN_PA28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c index 3bae73e63633..9628a3defcf4 100644 --- a/arch/arm/mach-at91/board-kafa.c +++ b/arch/arm/mach-at91/board-kafa.c @@ -61,7 +61,7 @@ static void __init kafa_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata kafa_eth_data = { +static struct macb_platform_data __initdata kafa_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index e61351ffad50..5ba5244cb632 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -69,7 +69,7 @@ static void __init kb9202_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata kb9202_eth_data = { +static struct macb_platform_data __initdata kb9202_eth_data = { .phy_irq_pin = AT91_PIN_PB29, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index ef816c17dc61..56e7aee11b59 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -155,7 +155,7 @@ static struct at91_mmc_data __initdata neocore926_mmc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata neocore926_macb_data = { +static struct macb_platform_data __initdata neocore926_macb_data = { .phy_irq_pin = AT91_PIN_PE31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 49e3f699b48e..c545a3e635a4 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -122,7 +122,7 @@ static struct at91_udc_data __initdata pcontrol_g20_udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata macb_data = { +static struct macb_platform_data __initdata macb_data = { .phy_irq_pin = AT91_PIN_PA28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index 0a8fe6a1b7c8..dc18759a24b4 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -60,7 +60,7 @@ static void __init picotux200_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata picotux200_eth_data = { +static struct macb_platform_data __initdata picotux200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 07421bdb88ea..5444d6ac514a 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -104,7 +104,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 80a8c9c6e922..022d0cebda9d 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -65,7 +65,7 @@ static void __init dk_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata dk_eth_data = { +static struct macb_platform_data __initdata dk_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index 99fd7f8aee0e..ed275861adef 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -65,7 +65,7 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata ek_eth_data = { +static struct macb_platform_data __initdata ek_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-rsi-ews.c b/arch/arm/mach-at91/board-rsi-ews.c index e927df0175df..ed3b21f77674 100644 --- a/arch/arm/mach-at91/board-rsi-ews.c +++ b/arch/arm/mach-at91/board-rsi-ews.c @@ -60,7 +60,7 @@ static void __init rsi_ews_init_early(void) /* * Ethernet */ -static struct at91_eth_data rsi_ews_eth_data __initdata = { +static struct macb_platform_data rsi_ews_eth_data __initdata = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 072d53af98d9..3e4b50e6f6ab 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -109,7 +109,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 4f10181a0782..13478e14a543 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -151,7 +151,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index bccdcf23caa1..fcf194e6e4fe 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -158,7 +158,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PE31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 64fc75c9d0ac..78d27cc3cc09 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -123,7 +123,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 92de9127923a..4e1ee9d87096 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -115,7 +115,7 @@ static struct mci_platform_data __initdata mci1_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PD5, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 0df01c6e2d0c..fbec934a7ce9 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -65,7 +65,7 @@ static struct at91_udc_data __initdata snapper9260_udc_data = { .vbus_polled = 1, }; -static struct at91_eth_data snapper9260_macb_data = { +static struct macb_platform_data snapper9260_macb_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 936e5fd7f406..7c06c07d872b 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -157,7 +157,7 @@ static struct at91_udc_data __initdata stamp9g20evb_udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata macb_data = { +static struct macb_platform_data __initdata macb_data = { .phy_irq_pin = AT91_PIN_PA28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 0a20bab21f99..3d84233f78eb 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -146,7 +146,7 @@ static void __init ek_add_device_spi(void) /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PE31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index 12a3f955162b..2c40a21b2794 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -110,7 +110,7 @@ static struct gpio_led yl9200_leds[] = { /* * Ethernet */ -static struct at91_eth_data __initdata yl9200_eth_data = { +static struct macb_platform_data __initdata yl9200_eth_data = { .phy_irq_pin = AT91_PIN_PB28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index eac92e995bb5..e209a2992245 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -40,6 +40,7 @@ #include #include #include +#include /* USB Device */ struct at91_udc_data { @@ -81,18 +82,7 @@ extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) /* atmel-mci platform config */ extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); - /* Ethernet (EMAC & MACB) */ -struct at91_eth_data { - u32 phy_mask; - u8 phy_irq_pin; /* PHY IRQ */ - u8 is_rmii; /* using RMII interface? */ -}; -extern void __init at91_add_device_eth(struct at91_eth_data *data); - -#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -#define eth_platform_data at91_eth_data -#endif +extern void __init at91_add_device_eth(struct macb_platform_data *data); /* USB Host */ struct at91_usbh_data { diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 1f17bde52cd4..7c756fb189f7 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -109,7 +109,7 @@ struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2]; +static struct macb_platform_data __initdata eth_data[2]; static struct spi_board_info spi0_board_info[] __initdata = { { diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 4643ff5107c9..c56ddac85d61 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -105,7 +105,7 @@ struct eth_addr { }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2] = { +static struct macb_platform_data __initdata eth_data[2] = { { /* * The MDIO pullups on STK1000 are a bit too weak for diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c index 86fab77a5a00..27bd6fbe21cb 100644 --- a/arch/avr32/boards/favr-32/setup.c +++ b/arch/avr32/boards/favr-32/setup.c @@ -50,7 +50,7 @@ struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[1]; -static struct eth_platform_data __initdata eth_data[1] = { +static struct macb_platform_data __initdata eth_data[1] = { { .phy_mask = ~(1U << 1), }, diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c index da14fbdd4e8e..9d1efd1cd425 100644 --- a/arch/avr32/boards/hammerhead/setup.c +++ b/arch/avr32/boards/hammerhead/setup.c @@ -102,7 +102,7 @@ struct eth_addr { }; static struct eth_addr __initdata hw_addr[1]; -static struct eth_platform_data __initdata eth_data[1]; +static struct macb_platform_data __initdata eth_data[1]; /* * The next two functions should go away as the boot loader is diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c index e61bc948f959..ed137e335796 100644 --- a/arch/avr32/boards/merisc/setup.c +++ b/arch/avr32/boards/merisc/setup.c @@ -52,7 +52,7 @@ struct eth_addr { }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2]; +static struct macb_platform_data __initdata eth_data[2]; static int ads7846_get_pendown_state_PB26(void) { diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c index c4da5cba2dbf..05358aa5ef7d 100644 --- a/arch/avr32/boards/mimc200/setup.c +++ b/arch/avr32/boards/mimc200/setup.c @@ -86,7 +86,7 @@ struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2]; +static struct macb_platform_data __initdata eth_data[2]; static struct spi_eeprom eeprom_25lc010 = { .name = "25lc010", diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 7fbf0dcb9afe..402a7bb72669 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1067,7 +1067,7 @@ void __init at32_setup_serial_console(unsigned int usart_id) * -------------------------------------------------------------------- */ #ifdef CONFIG_CPU_AT32AP7000 -static struct eth_platform_data macb0_data; +static struct macb_platform_data macb0_data; static struct resource macb0_resource[] = { PBMEM(0xfff01800), IRQ(25), @@ -1076,7 +1076,7 @@ DEFINE_DEV_DATA(macb, 0); DEV_CLK(hclk, macb0, hsb, 8); DEV_CLK(pclk, macb0, pbb, 6); -static struct eth_platform_data macb1_data; +static struct macb_platform_data macb1_data; static struct resource macb1_resource[] = { PBMEM(0xfff01c00), IRQ(26), @@ -1086,7 +1086,7 @@ DEV_CLK(hclk, macb1, hsb, 9); DEV_CLK(pclk, macb1, pbb, 7); struct platform_device *__init -at32_add_device_eth(unsigned int id, struct eth_platform_data *data) +at32_add_device_eth(unsigned int id, struct macb_platform_data *data) { struct platform_device *pdev; u32 pin_mask; @@ -1163,7 +1163,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) return NULL; } - memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data)); + memcpy(pdev->dev.platform_data, data, sizeof(struct macb_platform_data)); platform_device_register(pdev); return pdev; diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index 5d7ffca7d69f..67b111ce332d 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h @@ -6,6 +6,7 @@ #include #include +#include #define GPIO_PIN_NONE (-1) @@ -42,12 +43,8 @@ struct atmel_uart_data { void at32_map_usart(unsigned int hw_id, unsigned int line, int flags); struct platform_device *at32_add_device_usart(unsigned int id); -struct eth_platform_data { - u32 phy_mask; - u8 is_rmii; -}; struct platform_device * -at32_add_device_eth(unsigned int id, struct eth_platform_data *data); +at32_add_device_eth(unsigned int id, struct macb_platform_data *data); struct spi_board_info; struct platform_device * diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 56624d303487..dfeb46cb3f74 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -984,7 +985,7 @@ static const struct net_device_ops at91ether_netdev_ops = { static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev, struct clk *ether_clk) { - struct at91_eth_data *board_data = pdev->dev.platform_data; + struct macb_platform_data *board_data = pdev->dev.platform_data; struct net_device *dev; struct at91_private *lp; unsigned int val; diff --git a/drivers/net/ethernet/cadence/at91_ether.h b/drivers/net/ethernet/cadence/at91_ether.h index 353f4dab62be..3725fbb0defe 100644 --- a/drivers/net/ethernet/cadence/at91_ether.h +++ b/drivers/net/ethernet/cadence/at91_ether.h @@ -85,7 +85,9 @@ struct recv_desc_bufs struct at91_private { struct mii_if_info mii; /* ethtool support */ - struct at91_eth_data board_data; /* board-specific configuration */ + struct macb_platform_data board_data; /* board-specific + * configuration (shared with + * macb for common data */ struct clk *ether_clk; /* clock */ /* PHY */ diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index b0fa47870add..d97d9ce986f8 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -19,12 +19,10 @@ #include #include #include +#include #include #include -#include -#include - #include "macb.h" #define RX_BUFFER_SIZE 128 @@ -191,7 +189,7 @@ static int macb_mii_probe(struct net_device *dev) { struct macb *bp = netdev_priv(dev); struct phy_device *phydev; - struct eth_platform_data *pdata; + struct macb_platform_data *pdata; int ret; phydev = phy_find_first(bp->mii_bus); @@ -228,7 +226,7 @@ static int macb_mii_probe(struct net_device *dev) static int macb_mii_init(struct macb *bp) { - struct eth_platform_data *pdata; + struct macb_platform_data *pdata; int err = -ENXIO, i; /* Enable management port */ @@ -1119,7 +1117,7 @@ static const struct net_device_ops macb_netdev_ops = { static int __init macb_probe(struct platform_device *pdev) { - struct eth_platform_data *pdata; + struct macb_platform_data *pdata; struct resource *regs; struct net_device *dev; struct macb *bp; diff --git a/include/linux/platform_data/macb.h b/include/linux/platform_data/macb.h new file mode 100644 index 000000000000..e7c748fb6053 --- /dev/null +++ b/include/linux/platform_data/macb.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2004-2006 Atmel 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. + */ +#ifndef __MACB_PDATA_H__ +#define __MACB_PDATA_H__ + +struct macb_platform_data { + u32 phy_mask; + u8 phy_irq_pin; /* PHY IRQ */ + u8 is_rmii; /* using RMII interface? */ +}; + +#endif /* __MACB_PDATA_H__ */ -- cgit v1.2.3 From 4673ca8eb3690832e76371371955a8b02e1f59d4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 14:54:28 +0200 Subject: lib: move GENERIC_IOMAP to lib/Kconfig define GENERIC_IOMAP in a central location instead of all architectures. This will be helpful for the follow-up patch which makes it select other configs. Code is also a bit shorter this way. Signed-off-by: Michael S. Tsirkin --- arch/alpha/Kconfig | 4 ---- arch/cris/Kconfig | 5 +---- arch/hexagon/Kconfig | 4 +--- arch/ia64/Kconfig | 5 +---- arch/m68k/Kconfig | 4 +--- arch/openrisc/Kconfig | 3 --- arch/powerpc/platforms/Kconfig | 3 --- arch/score/Kconfig | 4 +--- arch/sh/Kconfig | 3 --- arch/unicore32/Kconfig | 4 +--- arch/x86/Kconfig | 4 +--- lib/Kconfig | 3 +++ 12 files changed, 10 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 3d74801a4015..3636b11ddff0 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -70,10 +70,6 @@ config GENERIC_ISA_DMA bool default y -config GENERIC_IOMAP - bool - default n - source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 408b055c585f..b3abfb08aa5c 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -19,10 +19,6 @@ config GENERIC_CMOS_UPDATE config ARCH_USES_GETTIMEOFFSET def_bool n -config GENERIC_IOMAP - bool - default y - config ARCH_HAS_ILOG2_U32 bool default n @@ -52,6 +48,7 @@ config CRIS select HAVE_IDE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW + select GENERIC_IOMAP config HZ int diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 02513c2dd5ec..9059e3905887 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -26,6 +26,7 @@ config HEXAGON select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK select NO_IOPORT + select GENERIC_IOMAP # mostly generic routines, with some accelerated ones ---help--- Qualcomm Hexagon is a processor architecture designed for high @@ -73,9 +74,6 @@ config GENERIC_CSUM config GENERIC_IRQ_PROBE def_bool y -config GENERIC_IOMAP - def_bool y - #config ZONE_DMA # bool # default y diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 27489b6dd533..2732e1b0aa3d 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -29,6 +29,7 @@ config IA64 select GENERIC_IRQ_SHOW select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_HAVE_NMI_SAFE_CMPXCHG + select GENERIC_IOMAP default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -102,10 +103,6 @@ config EFI bool default y -config GENERIC_IOMAP - bool - default y - config ARCH_CLOCKSOURCE_DATA def_bool y diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 361d54019bb0..973e68614f28 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -38,9 +38,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_IOMAP - def_bool MMU - config TIME_LOW_RES bool default y @@ -73,6 +70,7 @@ source "kernel/Kconfig.freezer" config MMU bool "MMU-based Paged Memory Management Support" default y + select GENERIC_IOMAP help Select if you want MMU-based virtualised addressing space support by paged memory management. If unsure, say 'Y'. diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index e518a5a4cf4c..081a54f1a93d 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -38,9 +38,6 @@ config RWSEM_XCHGADD_ALGORITHM config GENERIC_HWEIGHT def_bool y -config GENERIC_IOMAP - def_bool y - config NO_IOPORT def_bool y diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 3fe6d927ad70..100feed97940 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -175,9 +175,6 @@ config PPC_INDIRECT_MMIO config PPC_IO_WORKAROUNDS bool -config GENERIC_IOMAP - bool - source "drivers/cpufreq/Kconfig" menu "CPU Frequency drivers" diff --git a/arch/score/Kconfig b/arch/score/Kconfig index df169e84db4e..455ce2d76823 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig @@ -4,6 +4,7 @@ config SCORE def_bool y select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW + select GENERIC_IOMAP choice prompt "System type" @@ -33,9 +34,6 @@ endmenu config CPU_SCORE7 bool -config GENERIC_IOMAP - def_bool y - config NO_DMA bool default y diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5629e2099130..5aeab58ac8be 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -84,9 +84,6 @@ config GENERIC_GPIO config GENERIC_CALIBRATE_DELAY bool -config GENERIC_IOMAP - bool - config GENERIC_CLOCKEVENTS def_bool y diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 942ed6174f1d..eeb8054c7cd8 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -12,6 +12,7 @@ config UNICORE32 select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select ARCH_WANT_FRAME_POINTERS + select GENERIC_IOMAP help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip @@ -30,9 +31,6 @@ config GENERIC_CLOCKEVENTS config GENERIC_CSUM def_bool y -config GENERIC_IOMAP - def_bool y - config NO_IOPORT bool diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cb9a1044a771..08af6457de72 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -75,6 +75,7 @@ config X86 select HAVE_BPF_JIT if (X86_64 && NET) select CLKEVT_I8253 select ARCH_HAVE_NMI_SAFE_CMPXCHG + select GENERIC_IOMAP config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) @@ -140,9 +141,6 @@ config NEED_SG_DMA_LENGTH config GENERIC_ISA_DMA def_bool ISA_DMA_API -config GENERIC_IOMAP - def_bool y - config GENERIC_BUG def_bool y depends on BUG diff --git a/lib/Kconfig b/lib/Kconfig index 32f3e5ae2be5..005892723a52 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -19,6 +19,9 @@ config RATIONAL config GENERIC_FIND_FIRST_BIT bool +config GENERIC_IOMAP + bool + config CRC_CCITT tristate "CRC-CCITT functions" help -- cgit v1.2.3 From 2f5893cf42ca10a1eb73bc527e2198847f4d0a79 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 16 Oct 2011 18:17:09 +0800 Subject: ARM: at91: define CLOCK_TICK_RATE to bogus value except A91X40 We have a clocksource which renders CLOCK_TICK_RATE useless. Define it to a bogus value to get rid of some ifdeffery. use local LATCH for at91rm9200 timer but keep it for A91X40 as we do not use a clocksource Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_time.c | 8 ++-- arch/arm/mach-at91/include/mach/timex.h | 65 +++------------------------------ 2 files changed, 10 insertions(+), 63 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 1dd69c85dfec..a028cdf8f974 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -32,6 +32,8 @@ static unsigned long last_crtr; static u32 irqmask; static struct clock_event_device clkevt; +#define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) + /* * The ST_CRTR is updated asynchronously to the master clock ... but * the updates as seen by the CPU don't seem to be strictly monotonic. @@ -74,8 +76,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) if (sr & AT91_ST_PITS) { u32 crtr = read_CRTR(); - while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) { - last_crtr += LATCH; + while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) { + last_crtr += RM9200_TIMER_LATCH; clkevt.event_handler(&clkevt); } return IRQ_HANDLED; @@ -116,7 +118,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; - at91_sys_write(AT91_ST_PIMR, LATCH); + at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h index 85820ad801cc..5e917a66edd7 100644 --- a/arch/arm/mach-at91/include/mach/timex.h +++ b/arch/arm/mach-at91/include/mach/timex.h @@ -23,70 +23,15 @@ #include -#if defined(CONFIG_ARCH_AT91RM9200) +#ifdef CONFIG_ARCH_AT91X40 -#define CLOCK_TICK_RATE (AT91_SLOW_CLOCK) - -#elif defined(CONFIG_ARCH_AT91SAM9260) - -#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260) -#define AT91SAM9_MASTER_CLOCK 90000000 -#else -#define AT91SAM9_MASTER_CLOCK 99300000 -#endif - -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9261) - -#define AT91SAM9_MASTER_CLOCK 99300000 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9G10) - -#define AT91SAM9_MASTER_CLOCK 133000000 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9263) - -#if defined(CONFIG_MACH_USB_A9263) -#define AT91SAM9_MASTER_CLOCK 90000000 -#else -#define AT91SAM9_MASTER_CLOCK 99959500 -#endif - -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9RL) - -#define AT91SAM9_MASTER_CLOCK 100000000 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9G20) +#define AT91X40_MASTER_CLOCK 40000000 +#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) -#if defined(CONFIG_MACH_USB_A9G20) -#define AT91SAM9_MASTER_CLOCK 133000000 #else -#define AT91SAM9_MASTER_CLOCK 132096000 -#endif - -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9G45) -#define AT91SAM9_MASTER_CLOCK 133333333 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91CAP9) - -#define AT91CAP9_MASTER_CLOCK 100000000 -#define CLOCK_TICK_RATE (AT91CAP9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91X40) - -#define AT91X40_MASTER_CLOCK 40000000 -#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) +#define CLOCK_TICK_RATE 12345678 #endif -#endif +#endif /* __ASM_ARCH_TIMEX_H */ -- cgit v1.2.3 From 80e91cb8023fbc07b2410c4ce5a2da12fbcebca4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 16 Sep 2011 23:37:50 +0800 Subject: ARM: at91: make gpio register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre Reviewed-by: Ryan Mallon --- arch/arm/mach-at91/at91cap9.c | 8 ++++---- arch/arm/mach-at91/at91rm9200.c | 8 ++++---- arch/arm/mach-at91/at91sam9260.c | 6 +++--- arch/arm/mach-at91/at91sam9261.c | 6 +++--- arch/arm/mach-at91/at91sam9263.c | 10 +++++----- arch/arm/mach-at91/at91sam9g45.c | 10 +++++----- arch/arm/mach-at91/at91sam9rl.c | 8 ++++---- arch/arm/mach-at91/generic.h | 2 +- arch/arm/mach-at91/gpio.c | 8 ++++++-- arch/arm/mach-at91/include/mach/at91cap9.h | 9 +++++---- arch/arm/mach-at91/include/mach/at91rm9200.h | 9 +++++---- arch/arm/mach-at91/include/mach/at91sam9260.h | 7 ++++--- arch/arm/mach-at91/include/mach/at91sam9261.h | 7 ++++--- arch/arm/mach-at91/include/mach/at91sam9263.h | 11 ++++++----- arch/arm/mach-at91/include/mach/at91sam9g45.h | 11 ++++++----- arch/arm/mach-at91/include/mach/at91sam9rl.h | 9 +++++---- 16 files changed, 70 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index ecdd54dd68c6..fe00dceba0af 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -296,19 +296,19 @@ void __init at91cap9_set_console_clock(int id) static struct at91_gpio_bank at91cap9_gpio[] = { { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOA, + .regbase = AT91CAP9_BASE_PIOA, .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOB, + .regbase = AT91CAP9_BASE_PIOB, .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOC, + .regbase = AT91CAP9_BASE_PIOC, .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOD, + .regbase = AT91CAP9_BASE_PIOD, .clock = &pioABCD_clk, } }; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 713d3bdbd284..8ce86751c2e2 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -271,19 +271,19 @@ void __init at91rm9200_set_console_clock(int id) static struct at91_gpio_bank at91rm9200_gpio[] = { { .id = AT91RM9200_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91RM9200_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91RM9200_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91RM9200_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91RM9200_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91RM9200_BASE_PIOC, .clock = &pioC_clk, }, { .id = AT91RM9200_ID_PIOD, - .offset = AT91_PIOD, + .regbase = AT91RM9200_BASE_PIOD, .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b84a9f642f59..1e9c79f5a6ed 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -273,15 +273,15 @@ void __init at91sam9260_set_console_clock(int id) static struct at91_gpio_bank at91sam9260_gpio[] = { { .id = AT91SAM9260_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9260_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9260_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9260_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9260_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9260_BASE_PIOC, .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 658a5185abfd..574aa6b6a78b 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -254,15 +254,15 @@ void __init at91sam9261_set_console_clock(int id) static struct at91_gpio_bank at91sam9261_gpio[] = { { .id = AT91SAM9261_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9261_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9261_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9261_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9261_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9261_BASE_PIOC, .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index f83fbb0ee0c5..dee0ed7d88e4 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -266,23 +266,23 @@ void __init at91sam9263_set_console_clock(int id) static struct at91_gpio_bank at91sam9263_gpio[] = { { .id = AT91SAM9263_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9263_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9263_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9263_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9263_ID_PIOCDE, - .offset = AT91_PIOC, + .regbase = AT91SAM9263_BASE_PIOC, .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, - .offset = AT91_PIOD, + .regbase = AT91SAM9263_BASE_PIOD, .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, - .offset = AT91_PIOE, + .regbase = AT91SAM9263_BASE_PIOE, .clock = &pioCDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 318b0407ea04..404d70cececb 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -296,23 +296,23 @@ void __init at91sam9g45_set_console_clock(int id) static struct at91_gpio_bank at91sam9g45_gpio[] = { { .id = AT91SAM9G45_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9G45_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9G45_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9G45_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9G45_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9G45_BASE_PIOC, .clock = &pioC_clk, }, { .id = AT91SAM9G45_ID_PIODE, - .offset = AT91_PIOD, + .regbase = AT91SAM9G45_BASE_PIOD, .clock = &pioDE_clk, }, { .id = AT91SAM9G45_ID_PIODE, - .offset = AT91_PIOE, + .regbase = AT91SAM9G45_BASE_PIOE, .clock = &pioDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index a238105d2c11..c4004e21d805 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -246,19 +246,19 @@ void __init at91sam9rl_set_console_clock(int id) static struct at91_gpio_bank at91sam9rl_gpio[] = { { .id = AT91SAM9RL_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9RL_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9RL_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9RL_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9RL_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9RL_BASE_PIOC, .clock = &pioC_clk, }, { .id = AT91SAM9RL_ID_PIOD, - .offset = AT91_PIOD, + .regbase = AT91SAM9RL_BASE_PIOD, .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 938b34f57741..11d7297eee22 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -65,7 +65,7 @@ extern void at91sam9_alt_reset(void); struct at91_gpio_bank { unsigned short id; /* peripheral ID */ - unsigned long offset; /* offset from system peripheral base */ + unsigned long regbase; /* offset from system peripheral base */ struct clk *clock; /* associated clock */ }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 224e9e2f8674..cedb753f4cad 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -614,8 +614,12 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) at91_gpio->bank = &data[i]; at91_gpio->chip.base = PIN_BASE + i * 32; - at91_gpio->regbase = at91_gpio->bank->offset + - (void __iomem *)AT91_VA_BASE_SYS; + + at91_gpio->regbase = ioremap(at91_gpio->bank->regbase, 512); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); + continue; + } /* enable PIO controller's clock */ clk_enable(at91_gpio->bank->clock); diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index c5df1e8f1955..f65d0834eee7 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -88,10 +88,6 @@ #define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -102,6 +98,11 @@ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) +#define AT91CAP9_BASE_PIOA 0xfffff200 +#define AT91CAP9_BASE_PIOB 0xfffff400 +#define AT91CAP9_BASE_PIOC 0xfffff600 +#define AT91CAP9_BASE_PIOD 0xfffff800 + #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 #define AT91_USART2 AT91CAP9_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index e4037b500302..57409549585f 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -81,15 +81,16 @@ */ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */ -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */ -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */ -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */ -#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ #define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ +#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 AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART1 AT91RM9200_BASE_US1 #define AT91_USART2 AT91RM9200_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 9a791165913f..1bea3dcae7bc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -87,9 +87,6 @@ #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -98,6 +95,10 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9260_BASE_PIOA 0xfffff400 +#define AT91SAM9260_BASE_PIOB 0xfffff600 +#define AT91SAM9260_BASE_PIOC 0xfffff800 + #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 #define AT91_USART2 AT91SAM9260_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index ce596204cefa..17ae9c73be5e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -70,9 +70,6 @@ #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -81,6 +78,10 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9261_BASE_PIOA 0xfffff400 +#define AT91SAM9261_BASE_PIOB 0xfffff600 +#define AT91SAM9261_BASE_PIOC 0xfffff800 + #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 #define AT91_USART2 AT91SAM9261_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index f1b92961a2b1..dd54079c5671 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -84,11 +84,6 @@ #define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) -#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -98,6 +93,12 @@ #define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) +#define AT91SAM9263_BASE_PIOA 0xfffff200 +#define AT91SAM9263_BASE_PIOB 0xfffff400 +#define AT91SAM9263_BASE_PIOC 0xfffff600 +#define AT91SAM9263_BASE_PIOD 0xfffff800 +#define AT91SAM9263_BASE_PIOE 0xfffffa00 + #define AT91_USART0 AT91SAM9263_BASE_US0 #define AT91_USART1 AT91SAM9263_BASE_US1 #define AT91_USART2 AT91SAM9263_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 406bb6496805..a487af5a2237 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -94,11 +94,6 @@ #define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) -#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -108,6 +103,12 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) +#define AT91SAM9G45_BASE_PIOA 0xfffff200 +#define AT91SAM9G45_BASE_PIOB 0xfffff400 +#define AT91SAM9G45_BASE_PIOC 0xfffff600 +#define AT91SAM9G45_BASE_PIOD 0xfffff800 +#define AT91SAM9G45_BASE_PIOE 0xfffffa00 + #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 #define AT91_USART2 AT91SAM9G45_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 1aabacd315d4..d3ef11ad04df 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -77,10 +77,6 @@ #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -91,6 +87,11 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) +#define AT91SAM9RL_BASE_PIOA 0xfffff400 +#define AT91SAM9RL_BASE_PIOB 0xfffff600 +#define AT91SAM9RL_BASE_PIOC 0xfffff800 +#define AT91SAM9RL_BASE_PIOD 0xfffffa00 + #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 #define AT91_USART2 AT91SAM9RL_BASE_US2 -- cgit v1.2.3 From d28edd1bc4d1cd92f0ab129ac71892eead47d8a2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 09:31:56 +0800 Subject: ARM: at91: make ecc register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9260_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9263_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9g45_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9rl_devices.c | 4 ++-- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 4 ++-- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index adad70db70eb..fb525f4e6fab 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -398,8 +398,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91CAP9_BASE_ECC, + .end = AT91CAP9_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 25e3464fb07f..067c1685fdaa 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -399,8 +399,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91SAM9260_BASE_ECC, + .end = AT91SAM9260_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ad017eb1f8df..0b1a28e47f48 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -473,8 +473,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC0, - .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1, + .start = AT91SAM9263_BASE_ECC0, + .end = AT91SAM9263_BASE_ECC0 + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 09a16d6bd5cd..d19d72085cb4 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -529,8 +529,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91SAM9G45_BASE_ECC, + .end = AT91SAM9G45_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 628eb566d60c..e63ab90e8e80 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -248,8 +248,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91SAM9RL_BASE_ECC, + .end = AT91SAM9RL_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index f65d0834eee7..5fd105dd1f1a 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -79,7 +79,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC (0xffffe200 - AT91_BASE_SYS) #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) +#define AT91CAP9_BASE_ECC 0xffffe200 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 1bea3dcae7bc..697465660955 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -80,7 +80,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC (0xffffe800 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) @@ -95,6 +94,7 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9260_BASE_ECC 0xffffe800 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index dd54079c5671..a668538340b9 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -74,10 +74,8 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS) -#define AT91_ECC1 (0xffffe600 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) @@ -93,6 +91,8 @@ #define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) +#define AT91SAM9263_BASE_ECC0 0xffffe000 +#define AT91SAM9263_BASE_ECC1 0xffffe600 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 #define AT91SAM9263_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index a487af5a2237..3c0b7c16d090 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -86,7 +86,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC (0xffffe200 - AT91_BASE_SYS) #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) @@ -103,6 +102,7 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) +#define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index d3ef11ad04df..d9efe5ac93f0 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -70,7 +70,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_DMA (0xffffe600 - AT91_BASE_SYS) -#define AT91_ECC (0xffffe800 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) @@ -87,6 +86,7 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) +#define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 -- cgit v1.2.3 From 9627b200eddb7755d62c4c5638c40e476cf61647 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 15 Oct 2011 15:47:51 +0800 Subject: ARM: at91: make dma register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91sam9g45_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9rl_devices.c | 4 ++-- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index d19d72085cb4..42bf77049541 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -44,8 +44,8 @@ static struct at_dma_platform_data atdma_pdata = { static struct resource hdmac_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DMA, - .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, + .start = AT91SAM9G45_BASE_DMA, + .end = AT91SAM9G45_BASE_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index e63ab90e8e80..34fe5dd78194 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -39,8 +39,8 @@ static struct at_dma_platform_data atdma_pdata = { static struct resource hdmac_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DMA, - .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, + .start = AT91SAM9RL_BASE_DMA, + .end = AT91SAM9RL_BASE_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [2] = { diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 5fd105dd1f1a..a2eccb9ad3f5 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -84,7 +84,6 @@ #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) -#define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ (0xfffffd60 - AT91_BASE_SYS)) #define AT91CAP9_BASE_ECC 0xffffe200 +#define AT91CAP9_BASE_DMA 0xffffec00 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 3c0b7c16d090..29e577f13c06 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -90,7 +90,6 @@ #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) @@ -103,6 +102,7 @@ #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) #define AT91SAM9G45_BASE_ECC 0xffffe200 +#define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index d9efe5ac93f0..e56465037253 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -69,7 +69,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_DMA (0xffffe600 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) @@ -86,6 +85,7 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) +#define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 -- cgit v1.2.3 From eab5fd67d6d144ae9877a3de307714836bd1fbf0 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 10:12:00 +0800 Subject: ARM: at91: make rtt register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9260_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9261_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9263_devices.c | 8 ++++---- arch/arm/mach-at91/at91sam9g45_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9rl_devices.c | 4 ++-- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9261.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 4 ++-- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index fb525f4e6fab..3262a7edc9c7 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -670,8 +670,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91CAP9_BASE_RTT, + .end = AT91CAP9_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 067c1685fdaa..63cbfb887fbf 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -714,8 +714,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9260_BASE_RTT, + .end = AT91SAM9260_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index ae78f4d03b73..d5bd1e704421 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -600,8 +600,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9261_BASE_RTT, + .end = AT91SAM9261_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 0b1a28e47f48..5d2b061fcc64 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -956,8 +956,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt0_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT0, - .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1, + .start = AT91SAM9263_BASE_RTT0, + .end = AT91SAM9263_BASE_RTT0 + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; @@ -971,8 +971,8 @@ static struct platform_device at91sam9263_rtt0_device = { static struct resource rtt1_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT1, - .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1, + .start = AT91SAM9263_BASE_RTT1, + .end = AT91SAM9263_BASE_RTT1 + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 42bf77049541..bb2ba0c1d0ee 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1081,8 +1081,8 @@ void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9G45_BASE_RTT, + .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 34fe5dd78194..f9b423b7d7ae 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -685,8 +685,8 @@ static void __init at91_add_device_rtc(void) {} static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9RL_BASE_RTT, + .end = AT91SAM9RL_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index a2eccb9ad3f5..1cb42a63c822 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ @@ -102,6 +101,7 @@ #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 +#define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 697465660955..6aa7ca979e4d 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 +#define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 17ae9c73be5e..f84b7132cb79 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -73,7 +73,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -81,6 +80,7 @@ #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 +#define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index a668538340b9..938965ebe775 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -85,10 +85,8 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT0 (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) -#define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 @@ -98,6 +96,8 @@ #define AT91SAM9263_BASE_PIOC 0xfffff600 #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 +#define AT91SAM9263_BASE_RTT0 0xfffffd20 +#define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91_USART0 AT91SAM9263_BASE_US0 #define AT91_USART1 AT91SAM9263_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 29e577f13c06..00638c6a65fd 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -95,7 +95,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -108,6 +107,7 @@ #define AT91SAM9G45_BASE_PIOC 0xfffff600 #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 +#define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index e56465037253..099cefc20bf0 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -78,7 +78,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) @@ -91,6 +90,7 @@ #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 +#define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 -- cgit v1.2.3 From cfa5a1fe7e65bacdee59d5df60a9f44b0c030532 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 14 Oct 2011 01:17:18 +0800 Subject: ARM: at91: add ioremap_registers entry point to soc setup this will allow to ioremap the register of the PIT, PMC and others and make the code soc independent Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9.c | 5 +++++ arch/arm/mach-at91/at91rm9200.c | 5 +++++ arch/arm/mach-at91/at91sam9260.c | 5 +++++ arch/arm/mach-at91/at91sam9261.c | 5 +++++ arch/arm/mach-at91/at91sam9263.c | 5 +++++ arch/arm/mach-at91/at91sam9g45.c | 5 +++++ arch/arm/mach-at91/at91sam9rl.c | 5 +++++ arch/arm/mach-at91/setup.c | 2 ++ arch/arm/mach-at91/soc.h | 1 + 9 files changed, 38 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index fe00dceba0af..36872070afef 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -333,6 +333,10 @@ static void __init at91cap9_map_io(void) at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); } +static void __init at91cap9_ioremap_registers(void) +{ +} + static void __init at91cap9_initialize(void) { at91_arch_reset = at91cap9_reset; @@ -394,6 +398,7 @@ static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { 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/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 8ce86751c2e2..c67d50c9ea20 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -307,6 +307,10 @@ static void __init at91rm9200_map_io(void) iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); } +static void __init at91rm9200_ioremap_registers(void) +{ +} + static void __init at91rm9200_initialize(void) { at91_arch_reset = at91rm9200_reset; @@ -366,6 +370,7 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91rm9200_soc = { .map_io = at91rm9200_map_io, .default_irq_priority = at91rm9200_default_irq_priority, + .ioremap_registers = at91rm9200_ioremap_registers, .register_clocks = at91rm9200_register_clocks, .init = at91rm9200_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 1e9c79f5a6ed..0e549284b127 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -325,6 +325,10 @@ static void __init at91sam9260_map_io(void) } } +static void __init at91sam9260_ioremap_registers(void) +{ +} + static void __init at91sam9260_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -381,6 +385,7 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9260_soc = { .map_io = at91sam9260_map_io, .default_irq_priority = at91sam9260_default_irq_priority, + .ioremap_registers = at91sam9260_ioremap_registers, .register_clocks = at91sam9260_register_clocks, .init = at91sam9260_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 574aa6b6a78b..dde831814737 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -285,6 +285,10 @@ static void __init at91sam9261_map_io(void) at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE); } +static void __init at91sam9261_ioremap_registers(void) +{ +} + static void __init at91sam9261_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -341,6 +345,7 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9261_soc = { .map_io = at91sam9261_map_io, .default_irq_priority = at91sam9261_default_irq_priority, + .ioremap_registers = at91sam9261_ioremap_registers, .register_clocks = at91sam9261_register_clocks, .init = at91sam9261_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index dee0ed7d88e4..fc442dd0753c 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -303,6 +303,10 @@ static void __init at91sam9263_map_io(void) at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE); } +static void __init at91sam9263_ioremap_registers(void) +{ +} + static void __init at91sam9263_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -358,6 +362,7 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9263_soc = { .map_io = at91sam9263_map_io, .default_irq_priority = at91sam9263_default_irq_priority, + .ioremap_registers = at91sam9263_ioremap_registers, .register_clocks = at91sam9263_register_clocks, .init = at91sam9263_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 404d70cececb..56282b26a5a2 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -338,6 +338,10 @@ static void __init at91sam9g45_map_io(void) init_consistent_dma_size(SZ_4M); } +static void __init at91sam9g45_ioremap_registers(void) +{ +} + static void __init at91sam9g45_initialize(void) { at91_arch_reset = at91sam9g45_reset; @@ -393,6 +397,7 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9g45_soc = { .map_io = at91sam9g45_map_io, .default_irq_priority = at91sam9g45_default_irq_priority, + .ioremap_registers = at91sam9g45_ioremap_registers, .register_clocks = at91sam9g45_register_clocks, .init = at91sam9g45_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index c4004e21d805..29dae9b275b0 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -290,6 +290,10 @@ static void __init at91sam9rl_map_io(void) at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size); } +static void __init at91sam9rl_ioremap_registers(void) +{ +} + static void __init at91sam9rl_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -345,6 +349,7 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9rl_soc = { .map_io = at91sam9rl_map_io, .default_irq_priority = at91sam9rl_default_irq_priority, + .ioremap_registers = at91sam9rl_ioremap_registers, .register_clocks = at91sam9rl_register_clocks, .init = at91sam9rl_initialize, }; diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index aa64294c7db3..63b3ac2595b7 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -287,6 +287,8 @@ void __init at91_map_io(void) void __init at91_initialize(unsigned long main_clock) { + at91_boot_soc.ioremap_registers(); + /* Init clock subsystem */ at91_clock_init(main_clock); diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index 21ed8816e6f7..4588ae6f7acd 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -7,6 +7,7 @@ struct at91_init_soc { unsigned int *default_irq_priority; void (*map_io)(void); + void (*ioremap_registers)(void); void (*register_clocks)(void); void (*init)(void); }; -- cgit v1.2.3 From 4ab0c5998d327cba5b7e0dc8ce67f45859997669 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 22:29:50 +0800 Subject: ARM: at91: make pit register base soc independent Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9.c | 1 + arch/arm/mach-at91/at91sam9260.c | 1 + arch/arm/mach-at91/at91sam9261.c | 1 + arch/arm/mach-at91/at91sam9263.c | 1 + arch/arm/mach-at91/at91sam926x_time.c | 38 ++++++++++++++++++++------- arch/arm/mach-at91/at91sam9g45.c | 1 + arch/arm/mach-at91/at91sam9rl.c | 1 + arch/arm/mach-at91/generic.h | 1 + arch/arm/mach-at91/include/mach/at91_pit.h | 8 +++--- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9261.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- 15 files changed, 45 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 36872070afef..abfe36858a01 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -335,6 +335,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); } static void __init at91cap9_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 0e549284b127..0030d5f16ed8 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -327,6 +327,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); } static void __init at91sam9260_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index dde831814737..348d5ae4dee2 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -287,6 +287,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); } static void __init at91sam9261_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index fc442dd0753c..09ccf734c7d7 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -305,6 +305,7 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); } static void __init at91sam9263_initialize(void) diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index 4ba85499fa97..d89ead740a99 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -25,7 +25,17 @@ static u32 pit_cycle; /* write-once */ static u32 pit_cnt; /* access only w/system irq blocked */ +static void __iomem *pit_base_addr __read_mostly; +static inline unsigned int pit_read(unsigned int reg_offset) +{ + return __raw_readl(pit_base_addr + reg_offset); +} + +static inline void pit_write(unsigned int reg_offset, unsigned long value) +{ + __raw_writel(value, pit_base_addr + reg_offset); +} /* * Clocksource: just a monotonic counter of MCK/16 cycles. @@ -39,7 +49,7 @@ static cycle_t read_pit_clk(struct clocksource *cs) raw_local_irq_save(flags); elapsed = pit_cnt; - t = at91_sys_read(AT91_PIT_PIIR); + t = pit_read(AT91_PIT_PIIR); raw_local_irq_restore(flags); elapsed += PIT_PICNT(t) * pit_cycle; @@ -64,8 +74,8 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* update clocksource counter */ - pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); - at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN + pit_cnt += pit_cycle * PIT_PICNT(pit_read(AT91_PIT_PIVR)); + pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN | AT91_PIT_PITIEN); break; case CLOCK_EVT_MODE_ONESHOT: @@ -74,7 +84,7 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: /* disable irq, leaving the clocksource active */ - at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); + pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); break; case CLOCK_EVT_MODE_RESUME: break; @@ -103,11 +113,11 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) /* The PIT interrupt may be disabled, and is shared */ if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC) - && (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS)) { + && (pit_read(AT91_PIT_SR) & AT91_PIT_PITS)) { unsigned nr_ticks; /* Get number of ticks performed before irq, and ack it */ - nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); + nr_ticks = PIT_PICNT(pit_read(AT91_PIT_PIVR)); do { pit_cnt += pit_cycle; pit_clkevt.event_handler(&pit_clkevt); @@ -129,14 +139,14 @@ static struct irqaction at91sam926x_pit_irq = { static void at91sam926x_pit_reset(void) { /* Disable timer and irqs */ - at91_sys_write(AT91_PIT_MR, 0); + pit_write(AT91_PIT_MR, 0); /* Clear any pending interrupts, wait for PIT to stop counting */ - while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0) + while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0) cpu_relax(); /* Start PIT but don't enable IRQ */ - at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); + pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); } /* @@ -178,7 +188,15 @@ static void __init at91sam926x_pit_init(void) static void at91sam926x_pit_suspend(void) { /* Disable timer */ - at91_sys_write(AT91_PIT_MR, 0); + pit_write(AT91_PIT_MR, 0); +} + +void __init at91sam926x_ioremap_pit(u32 addr) +{ + pit_base_addr = ioremap(addr, 16); + + if (!pit_base_addr) + panic("Impossible to ioremap PIT\n"); } struct sys_timer at91sam926x_timer = { diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 56282b26a5a2..aa8b4414f3ed 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -340,6 +340,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); } static void __init at91sam9g45_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 29dae9b275b0..291fc9983cc3 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -292,6 +292,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); } static void __init at91sam9rl_initialize(void) diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 11d7297eee22..8196ecc37ed2 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -29,6 +29,7 @@ extern void __init at91_aic_init(unsigned int priority[]); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; +extern void at91sam926x_ioremap_pit(u32 addr); extern struct sys_timer at91sam926x_timer; extern struct sys_timer at91x40_timer; diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h index 974d0bd05b5b..d1f80ad7f4d4 100644 --- a/arch/arm/mach-at91/include/mach/at91_pit.h +++ b/arch/arm/mach-at91/include/mach/at91_pit.h @@ -16,16 +16,16 @@ #ifndef AT91_PIT_H #define AT91_PIT_H -#define AT91_PIT_MR (AT91_PIT + 0x00) /* Mode Register */ +#define AT91_PIT_MR 0x00 /* Mode Register */ #define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */ #define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */ #define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */ -#define AT91_PIT_SR (AT91_PIT + 0x04) /* Status Register */ +#define AT91_PIT_SR 0x04 /* Status Register */ #define AT91_PIT_PITS (1 << 0) /* Timer Status */ -#define AT91_PIT_PIVR (AT91_PIT + 0x08) /* Periodic Interval Value Register */ -#define AT91_PIT_PIIR (AT91_PIT + 0x0c) /* Periodic Interval Image Register */ +#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */ +#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */ #define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */ #define AT91_PIT_CPIV (0xfffff) /* Inverval Value */ diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 1cb42a63c822..ad8d298cf8ba 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ @@ -102,6 +101,7 @@ #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 #define AT91CAP9_BASE_RTT 0xfffffd20 +#define AT91CAP9_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 6aa7ca979e4d..b8c85dc4abce 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 #define AT91SAM9260_BASE_RTT 0xfffffd20 +#define AT91SAM9260_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index f84b7132cb79..0dccaff5212e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -73,7 +73,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -81,6 +80,7 @@ #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 #define AT91SAM9261_BASE_RTT 0xfffffd20 +#define AT91SAM9261_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 938965ebe775..735408e6d2e6 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -85,7 +85,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -97,6 +96,7 @@ #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 #define AT91SAM9263_BASE_RTT0 0xfffffd20 +#define AT91SAM9263_BASE_PIT 0xfffffd30 #define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91_USART0 AT91SAM9263_BASE_US0 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 00638c6a65fd..ba609f3872fd 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -95,7 +95,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) @@ -108,6 +107,7 @@ #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 #define AT91SAM9G45_BASE_RTT 0xfffffd20 +#define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 099cefc20bf0..bab09a745d2b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -78,7 +78,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -91,6 +90,7 @@ #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 #define AT91SAM9RL_BASE_RTT 0xfffffd20 +#define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 -- cgit v1.2.3 From faee0cc33c3df3b63314926eecef77d384ae9cd4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 14 Oct 2011 01:37:09 +0800 Subject: ARM: at91: make smc register base soc independent now sam9_smc_configure will take as first parameter is the SMC id Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9.c | 2 + arch/arm/mach-at91/at91rm9200.c | 1 + arch/arm/mach-at91/at91sam9260.c | 2 + arch/arm/mach-at91/at91sam9261.c | 2 + arch/arm/mach-at91/at91sam9263.c | 3 ++ arch/arm/mach-at91/at91sam9g45.c | 2 + arch/arm/mach-at91/at91sam9rl.c | 2 + arch/arm/mach-at91/board-cam60.c | 2 +- arch/arm/mach-at91/board-cap9adk.c | 4 +- arch/arm/mach-at91/board-cpu9krea.c | 4 +- arch/arm/mach-at91/board-dt.c | 2 +- arch/arm/mach-at91/board-neocore926.c | 2 +- arch/arm/mach-at91/board-pcontrol-g20.c | 4 +- arch/arm/mach-at91/board-qil-a9260.c | 2 +- arch/arm/mach-at91/board-sam9-l9260.c | 2 +- arch/arm/mach-at91/board-sam9260ek.c | 2 +- arch/arm/mach-at91/board-sam9261ek.c | 4 +- arch/arm/mach-at91/board-sam9263ek.c | 2 +- arch/arm/mach-at91/board-sam9g20ek.c | 2 +- arch/arm/mach-at91/board-sam9m10g45ek.c | 2 +- arch/arm/mach-at91/board-sam9rlek.c | 2 +- arch/arm/mach-at91/board-snapper9260.c | 2 +- arch/arm/mach-at91/board-stamp9g20.c | 2 +- arch/arm/mach-at91/board-usb-a926x.c | 4 +- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9261.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 4 +- arch/arm/mach-at91/include/mach/at91sam9_smc.h | 17 +++---- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- arch/arm/mach-at91/sam9_smc.c | 62 +++++++++++++++++--------- arch/arm/mach-at91/sam9_smc.h | 3 +- 33 files changed, 92 insertions(+), 62 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index abfe36858a01..1ea931274bac 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -28,6 +28,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -336,6 +337,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); + at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); } static void __init at91cap9_initialize(void) diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index c67d50c9ea20..c06c14fecba4 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -23,6 +23,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" static struct map_desc at91rm9200_io_desc[] __initdata = { { diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 0030d5f16ed8..fc1f734b80ce 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -26,6 +26,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -328,6 +329,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); } static void __init at91sam9260_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 348d5ae4dee2..804181aedd9e 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -25,6 +25,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -288,6 +289,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); } static void __init at91sam9261_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 09ccf734c7d7..b8f49962e87f 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -24,6 +24,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -306,6 +307,8 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); + at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); } static void __init at91sam9263_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index aa8b4414f3ed..ce3233f22ed1 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -26,6 +26,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -341,6 +342,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); } static void __init at91sam9g45_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 291fc9983cc3..1bcccd705296 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -25,6 +25,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -293,6 +294,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); } static void __init at91sam9rl_initialize(void) diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index f90cfb32bad2..02ded92de5b7 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -163,7 +163,7 @@ static struct sam9_smc_config __initdata cam60_nand_smc_config = { static void __init cam60_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &cam60_nand_smc_config); + sam9_smc_configure(0, 3, &cam60_nand_smc_config); at91_add_device_nand(&cam60_nand_data); } diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 5dffd3be62d2..da2616f20e10 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -212,7 +212,7 @@ static void __init cap9adk_add_device_nand(void) cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &cap9adk_nand_smc_config); + sam9_smc_configure(0, 3, &cap9adk_nand_smc_config); at91_add_device_nand(&cap9adk_nand_data); } @@ -282,7 +282,7 @@ static __init void cap9adk_add_device_nor(void) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, &cap9adk_nor_smc_config); + sam9_smc_configure(0, 0, &cap9adk_nor_smc_config); platform_device_register(&cap9adk_nor_flash); } diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index fc885a4ce243..7dd752e32e2a 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -156,7 +156,7 @@ static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { static void __init cpu9krea_add_device_nand(void) { - sam9_smc_configure(3, &cpu9krea_nand_smc_config); + sam9_smc_configure(0, 3, &cpu9krea_nand_smc_config); at91_add_device_nand(&cpu9krea_nand_data); } @@ -238,7 +238,7 @@ static __init void cpu9krea_add_device_nor(void) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, &cpu9krea_nor_smc_config); + sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config); platform_device_register(&cpu9krea_nor_flash); } diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index 0b7d32778210..41d84d9a2316 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -82,7 +82,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index ef816c17dc61..a9b9adc78c1d 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -213,7 +213,7 @@ static struct sam9_smc_config __initdata neocore926_nand_smc_config = { static void __init neocore926_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &neocore926_nand_smc_config); + sam9_smc_configure(0, 3, &neocore926_nand_smc_config); at91_add_device_nand(&neocore926_nand_data); } diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 49e3f699b48e..0e3c632d30eb 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -96,9 +96,9 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { static void __init add_device_pcontrol(void) { /* configure chip-select 4 (IO compatible to 8051 X4 ) */ - sam9_smc_configure(4, &pcontrol_smc_config[0]); + sam9_smc_configure(0, 4, &pcontrol_smc_config[0]); /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */ - sam9_smc_configure(7, &pcontrol_smc_config[1]); + sam9_smc_configure(0, 7, &pcontrol_smc_config[1]); } diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 07421bdb88ea..89d44c037291 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -161,7 +161,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { static void __init ek_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 072d53af98d9..e0283c57f467 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -162,7 +162,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { static void __init ek_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 4f10181a0782..00db0f8e34b6 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -211,7 +211,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index b005b738e8ff..a879b3398f38 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -131,7 +131,7 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init ek_add_device_dm9000(void) { /* Configure chip-select 2 (DM9000) */ - sam9_smc_configure(2, &dm9000_smc_config); + sam9_smc_configure(0, 2, &dm9000_smc_config); /* Configure Reset signal as output */ at91_set_gpio_output(AT91_PIN_PC10, 0); @@ -217,7 +217,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index bccdcf23caa1..7b25ca10d9d5 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -218,7 +218,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 64fc75c9d0ac..0579f069d97b 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -195,7 +195,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 92de9127923a..3e0d5a91f782 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -175,7 +175,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index b2b748239f36..c561edac25b9 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -119,7 +119,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { static void __init ek_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 0df01c6e2d0c..645d8336468e 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -149,7 +149,7 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { static void __init snapper9260_add_device_nand(void) { at91_set_A_periph(AT91_PIN_PC14, 0); - sam9_smc_configure(3, &snapper9260_nand_smc_config); + sam9_smc_configure(0, 3, &snapper9260_nand_smc_config); at91_add_device_nand(&snapper9260_nand_data); } diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 936e5fd7f406..f94ac865da53 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -108,7 +108,7 @@ static struct sam9_smc_config __initdata nand_smc_config = { static void __init add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &nand_smc_config); + sam9_smc_configure(0, 3, &nand_smc_config); at91_add_device_nand(&nand_data); } diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 0a20bab21f99..6f893cf4d336 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -245,9 +245,9 @@ static void __init ek_add_device_nand(void) /* configure chip-select 3 (NAND) */ if (machine_is_usb_a9g20()) - sam9_smc_configure(3, &usb_a9g20_nand_smc_config); + sam9_smc_configure(0, 3, &usb_a9g20_nand_smc_config); else - sam9_smc_configure(3, &usb_a9260_nand_smc_config); + sam9_smc_configure(0, 3, &usb_a9260_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index ad8d298cf8ba..d7d0b685668f 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -81,7 +81,6 @@ */ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) @@ -96,6 +95,7 @@ #define AT91CAP9_BASE_ECC 0xffffe200 #define AT91CAP9_BASE_DMA 0xffffec00 +#define AT91CAP9_BASE_SMC 0xffffe800 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index b8c85dc4abce..e55ab6abcdbf 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -81,7 +81,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) @@ -93,6 +92,7 @@ #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 +#define AT91SAM9260_BASE_SMC 0xffffec00 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 0dccaff5212e..1ea2d6b06c81 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -66,7 +66,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) @@ -76,6 +75,7 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9261_BASE_SMC 0xffffec00 #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 735408e6d2e6..b827ff7974b2 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -75,9 +75,7 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) -#define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) -#define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) @@ -89,7 +87,9 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 +#define AT91SAM9263_BASE_SMC0 0xffffe400 #define AT91SAM9263_BASE_ECC1 0xffffe600 +#define AT91SAM9263_BASE_SMC1 0xffffea00 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 #define AT91SAM9263_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h index 57de6207e57e..eb18a70fa647 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_smc.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h @@ -16,7 +16,9 @@ #ifndef AT91SAM9_SMC_H #define AT91SAM9_SMC_H -#define AT91_SMC_SETUP(n) (AT91_SMC + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ +#include + +#define AT91_SMC_SETUP 0x00 /* Setup Register for CS n */ #define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */ #define AT91_SMC_NWESETUP_(x) ((x) << 0) #define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */ @@ -26,7 +28,7 @@ #define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */ #define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24) -#define AT91_SMC_PULSE(n) (AT91_SMC + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ +#define AT91_SMC_PULSE 0x04 /* Pulse Register for CS n */ #define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */ #define AT91_SMC_NWEPULSE_(x) ((x) << 0) #define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */ @@ -36,13 +38,13 @@ #define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */ #define AT91_SMC_NCS_RDPULSE_(x)((x) << 24) -#define AT91_SMC_CYCLE(n) (AT91_SMC + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ +#define AT91_SMC_CYCLE 0x08 /* Cycle Register for CS n */ #define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */ #define AT91_SMC_NWECYCLE_(x) ((x) << 0) #define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */ #define AT91_SMC_NRDCYCLE_(x) ((x) << 16) -#define AT91_SMC_MODE(n) (AT91_SMC + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ +#define AT91_SMC_MODE 0x0c /* Mode Register for CS n */ #define AT91_SMC_READMODE (1 << 0) /* Read Mode */ #define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */ #define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */ @@ -66,11 +68,4 @@ #define AT91_SMC_PS_16 (2 << 28) #define AT91_SMC_PS_32 (3 << 28) -#if defined(AT91_SMC1) /* The AT91SAM9263 has 2 Static Memory contollers */ -#define AT91_SMC1_SETUP(n) (AT91_SMC1 + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ -#define AT91_SMC1_PULSE(n) (AT91_SMC1 + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ -#define AT91_SMC1_CYCLE(n) (AT91_SMC1 + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ -#define AT91_SMC1_MODE(n) (AT91_SMC1 + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ -#endif - #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index ba609f3872fd..ac051d427e6b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -88,7 +88,6 @@ */ #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) @@ -101,6 +100,7 @@ #define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_DMA 0xffffec00 +#define AT91SAM9G45_BASE_SMC 0xffffe800 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index bab09a745d2b..846139ddf06a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -70,7 +70,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) @@ -85,6 +84,7 @@ #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 +#define AT91SAM9RL_BASE_SMC 0xffffec00 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c index 5eab6aa621d0..8294783b679d 100644 --- a/arch/arm/mach-at91/sam9_smc.c +++ b/arch/arm/mach-at91/sam9_smc.c @@ -10,38 +10,58 @@ #include #include +#include +#include #include #include "sam9_smc.h" -void __init sam9_smc_configure(int cs, struct sam9_smc_config* config) + +#define AT91_SMC_CS(id, n) (smc_base_addr[id] + ((n) * 0x10)) + +static void __iomem *smc_base_addr[2]; + +static void __init sam9_smc_cs_configure(void __iomem *base, struct sam9_smc_config* config) { + /* Setup register */ - at91_sys_write(AT91_SMC_SETUP(cs), - AT91_SMC_NWESETUP_(config->nwe_setup) - | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup) - | AT91_SMC_NRDSETUP_(config->nrd_setup) - | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup) - ); + __raw_writel(AT91_SMC_NWESETUP_(config->nwe_setup) + | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup) + | AT91_SMC_NRDSETUP_(config->nrd_setup) + | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup), + base + AT91_SMC_SETUP); /* Pulse register */ - at91_sys_write(AT91_SMC_PULSE(cs), - AT91_SMC_NWEPULSE_(config->nwe_pulse) - | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse) - | AT91_SMC_NRDPULSE_(config->nrd_pulse) - | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse) - ); + __raw_writel(AT91_SMC_NWEPULSE_(config->nwe_pulse) + | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse) + | AT91_SMC_NRDPULSE_(config->nrd_pulse) + | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse), + base + AT91_SMC_PULSE); /* Cycle register */ - at91_sys_write(AT91_SMC_CYCLE(cs), - AT91_SMC_NWECYCLE_(config->write_cycle) - | AT91_SMC_NRDCYCLE_(config->read_cycle) - ); + __raw_writel(AT91_SMC_NWECYCLE_(config->write_cycle) + | AT91_SMC_NRDCYCLE_(config->read_cycle), + base + AT91_SMC_CYCLE); /* Mode register */ - at91_sys_write(AT91_SMC_MODE(cs), - config->mode - | AT91_SMC_TDF_(config->tdf_cycles) - ); + __raw_writel(config->mode + | AT91_SMC_TDF_(config->tdf_cycles), + base + AT91_SMC_MODE); +} + +void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config) +{ + sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config); +} + +void __init at91sam9_ioremap_smc(int id, u32 addr) +{ + if (id > 1) { + pr_warn("%s: id > 2\n", __func__); + return; + } + smc_base_addr[id] = ioremap(addr, 512); + if (!smc_base_addr[id]) + pr_warn("Impossible to ioremap smc.%d 0x%x\n", id, addr); } diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h index bf72cfb3455b..039c5ce17aec 100644 --- a/arch/arm/mach-at91/sam9_smc.h +++ b/arch/arm/mach-at91/sam9_smc.h @@ -30,4 +30,5 @@ struct sam9_smc_config { u8 tdf_cycles:4; }; -extern void __init sam9_smc_configure(int cs, struct sam9_smc_config* config); +extern void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config); +extern void __init at91sam9_ioremap_smc(int id, u32 addr); -- cgit v1.2.3 From f466f3bc92eb6857181bb033d14b1e9b1dd52140 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 1 Nov 2011 01:55:11 +0800 Subject: ARM: at91: drop CCFG never used in the kernel Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/include/mach/at91cap9.h | 1 - arch/arm/mach-at91/include/mach/at91sam9260.h | 1 - arch/arm/mach-at91/include/mach/at91sam9263.h | 1 - arch/arm/mach-at91/include/mach/at91sam9rl.h | 1 - 4 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index d7d0b685668f..cd19f0500cd2 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -82,7 +82,6 @@ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index e55ab6abcdbf..f964cfaca379 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -82,7 +82,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index b827ff7974b2..a62a3a8d9087 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -77,7 +77,6 @@ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 846139ddf06a..c945d4d5de3f 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -71,7 +71,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -- cgit v1.2.3 From f22deee523e0ff49c3be01dd6f979d374230725a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 1 Nov 2011 01:23:20 +0800 Subject: ARM: at91: make shutdown controler soc independent Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9.c | 10 +--------- arch/arm/mach-at91/at91sam9260.c | 10 +--------- arch/arm/mach-at91/at91sam9261.c | 10 +--------- arch/arm/mach-at91/at91sam9263.c | 10 +--------- arch/arm/mach-at91/at91sam9g45.c | 10 +--------- arch/arm/mach-at91/at91sam9rl.c | 10 +--------- arch/arm/mach-at91/board-qil-a9260.c | 2 +- arch/arm/mach-at91/board-usb-a926x.c | 2 +- arch/arm/mach-at91/generic.h | 3 +++ arch/arm/mach-at91/include/mach/at91_shdwc.h | 16 +++++++++++++--- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9261.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- arch/arm/mach-at91/pm.c | 7 +++++-- arch/arm/mach-at91/setup.c | 17 +++++++++++++++++ 18 files changed, 52 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 1ea931274bac..652dbe1c9cef 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -13,7 +13,6 @@ */ #include -#include #include #include @@ -23,7 +22,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -319,12 +317,6 @@ static void at91cap9_reset(void) at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); } -static void at91cap9_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91CAP9 processor initialization * -------------------------------------------------------------------- */ @@ -336,6 +328,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { + at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); } @@ -343,7 +336,6 @@ static void __init at91cap9_ioremap_registers(void) static void __init at91cap9_initialize(void) { at91_arch_reset = at91cap9_reset; - pm_power_off = at91cap9_poweroff; at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index fc1f734b80ce..5a17a23724c2 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -287,12 +285,6 @@ static struct at91_gpio_bank at91sam9260_gpio[] = { } }; -static void at91sam9260_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9260 processor initialization * -------------------------------------------------------------------- */ @@ -328,6 +320,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); } @@ -335,7 +328,6 @@ static void __init at91sam9260_ioremap_registers(void) static void __init at91sam9260_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9260_poweroff; at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | (1 << AT91SAM9260_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 804181aedd9e..80e3e0fac6b1 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -268,12 +266,6 @@ static struct at91_gpio_bank at91sam9261_gpio[] = { } }; -static void at91sam9261_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9261 processor initialization * -------------------------------------------------------------------- */ @@ -288,6 +280,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); } @@ -295,7 +288,6 @@ static void __init at91sam9261_ioremap_registers(void) static void __init at91sam9261_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | (1 << AT91SAM9261_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index b8f49962e87f..2a42b99d99d1 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -19,7 +18,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -288,12 +286,6 @@ static struct at91_gpio_bank at91sam9263_gpio[] = { } }; -static void at91sam9263_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9263 processor initialization * -------------------------------------------------------------------- */ @@ -306,6 +298,7 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); @@ -314,7 +307,6 @@ static void __init at91sam9263_ioremap_registers(void) static void __init at91sam9263_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9263_poweroff; at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index ce3233f22ed1..7fdf964f6c3a 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include #include "soc.h" @@ -323,12 +321,6 @@ static void at91sam9g45_reset(void) at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); } -static void at91sam9g45_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9G45 processor initialization * -------------------------------------------------------------------- */ @@ -341,6 +333,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); } @@ -348,7 +341,6 @@ static void __init at91sam9g45_ioremap_registers(void) static void __init at91sam9g45_initialize(void) { at91_arch_reset = at91sam9g45_reset; - pm_power_off = at91sam9g45_poweroff; at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 1bcccd705296..6856badc518b 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -10,7 +10,6 @@ */ #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -264,12 +262,6 @@ static struct at91_gpio_bank at91sam9rl_gpio[] = { } }; -static void at91sam9rl_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9RL processor initialization * -------------------------------------------------------------------- */ @@ -293,6 +285,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); } @@ -300,7 +293,6 @@ static void __init at91sam9rl_ioremap_registers(void) static void __init at91sam9rl_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9rl_poweroff; at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 89d44c037291..6eb0c9359866 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -251,7 +251,7 @@ static void __init ek_board_init(void) /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); /* shutdown controller, wakeup button (5 msec low) */ - at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW | AT91_SHDW_RTTWKEN); } diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 6f893cf4d336..dbc2609fa7fe 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -344,7 +344,7 @@ static void __init ek_board_init(void) /* I2C */ at91_add_device_i2c(NULL, 0); /* shutdown controller, wakeup button (5 msec low) */ - at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) + at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW | AT91_SHDW_RTTWKEN); } diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 8196ecc37ed2..bc1776406f42 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -60,6 +60,9 @@ extern void at91_irq_resume(void); /* reset */ extern void at91sam9_alt_reset(void); +/* shutdown */ +extern void at91_ioremap_shdwc(u32 base_addr); + /* GPIO */ #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h index c4ce07e8a8fa..1d4fe822c77a 100644 --- a/arch/arm/mach-at91/include/mach/at91_shdwc.h +++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h @@ -16,11 +16,21 @@ #ifndef AT91_SHDWC_H #define AT91_SHDWC_H -#define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_shdwc_base; + +#define at91_shdwc_read(field) \ + __raw_readl(at91_shdwc_base + field) + +#define at91_shdwc_write(field, value) \ + __raw_writel(value, at91_shdwc_base + field); +#endif + +#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */ #define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */ #define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */ +#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */ #define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ #define AT91_SHDW_WKMODE0_NONE 0 #define AT91_SHDW_WKMODE0_HIGH 1 @@ -30,7 +40,7 @@ #define AT91_SHDW_CPTWK0_(x) ((x) << 4) #define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ -#define AT91_SHDW_SR (AT91_SHDWC + 0x08) /* Shut Down Status Register */ +#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */ #define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ #define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */ #define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */ diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index cd19f0500cd2..5ac468c219af 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -86,7 +86,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ @@ -99,6 +98,7 @@ #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 +#define AT91CAP9_BASE_SHDWC 0xfffffd10 #define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91CAP9_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index f964cfaca379..e3c819ab3435 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -86,7 +86,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -95,6 +94,7 @@ #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 +#define AT91SAM9260_BASE_SHDWC 0xfffffd10 #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 1ea2d6b06c81..f9b516368f96 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -71,7 +71,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -79,6 +78,7 @@ #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 +#define AT91SAM9261_BASE_SHDWC 0xfffffd10 #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index a62a3a8d9087..28d52d588e90 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -81,7 +81,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -94,6 +93,7 @@ #define AT91SAM9263_BASE_PIOC 0xfffff600 #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 +#define AT91SAM9263_BASE_SHDWC 0xfffffd10 #define AT91SAM9263_BASE_RTT0 0xfffffd20 #define AT91SAM9263_BASE_PIT 0xfffffd30 #define AT91SAM9263_BASE_RTT1 0xfffffd50 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index ac051d427e6b..5f3453ef5866 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -93,7 +93,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) @@ -106,6 +105,7 @@ #define AT91SAM9G45_BASE_PIOC 0xfffff600 #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 +#define AT91SAM9G45_BASE_SHDWC 0xfffffd10 #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index c945d4d5de3f..6f3a4eeb7394 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -75,7 +75,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -88,6 +87,7 @@ #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 +#define AT91SAM9RL_BASE_SHDWC 0xfffffd10 #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 7046158109d7..3a5b7b4279e7 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -34,7 +34,7 @@ /* * Show the reason for the previous system reset. */ -#if defined(AT91_SHDWC) +#if defined(AT91_RSTC) #include #include @@ -58,8 +58,11 @@ static void __init show_reset_status(void) char *reason, *r2 = reset; u32 reset_type, wake_type; + if (!at91_shdwc_base) + return; + reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; - wake_type = at91_sys_read(AT91_SHDW_SR); + wake_type = at91_shdwc_read(AT91_SHDW_SR); switch (reset_type) { case AT91_RSTC_RSTTYP_GENERAL: diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 63b3ac2595b7..053c36993154 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include "soc.h" #include "generic.h" @@ -285,6 +287,21 @@ void __init at91_map_io(void) at91_boot_soc.map_io(); } +void __iomem *at91_shdwc_base = NULL; + +static void at91sam9_poweroff(void) +{ + at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + +void __init at91_ioremap_shdwc(u32 base_addr) +{ + at91_shdwc_base = ioremap(base_addr, 16); + if (!at91_shdwc_base) + panic("Impossible to ioremap at91_shdwc_base\n"); + pm_power_off = at91sam9_poweroff; +} + void __init at91_initialize(unsigned long main_clock) { at91_boot_soc.ioremap_registers(); -- cgit v1.2.3 From c1c30a29df7e47310caa979dc48f715ae478de5f Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 2 Nov 2011 01:43:31 +0800 Subject: ARM: at91: make watchdog drivers soc independent switch the watchdog drivers to resource and pass it via platform_device Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre Signed-off-by: Wim Van Sebroeck --- arch/arm/mach-at91/at91cap9_devices.c | 11 ++++++++++- arch/arm/mach-at91/at91sam9260_devices.c | 11 ++++++++++- arch/arm/mach-at91/at91sam9261_devices.c | 11 ++++++++++- arch/arm/mach-at91/at91sam9263_devices.c | 11 ++++++++++- arch/arm/mach-at91/at91sam9g45_devices.c | 11 ++++++++++- arch/arm/mach-at91/at91sam9rl_devices.c | 11 ++++++++++- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9261.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- drivers/watchdog/at91sam9_wdt.c | 22 +++++++++++++++++++--- drivers/watchdog/at91sam9_wdt.h | 6 +++--- 14 files changed, 88 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 3262a7edc9c7..019dac047b91 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -694,10 +694,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #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, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 63cbfb887fbf..9cdaffa0d6b1 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -738,10 +738,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9260_BASE_WDT, + .end = AT91SAM9260_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9260_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index d5bd1e704421..c59e1e9a4f5c 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -624,10 +624,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9261_BASE_WDT, + .end = AT91SAM9261_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9261_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 5d2b061fcc64..b5f4e2532fdb 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -996,10 +996,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9263_BASE_WDT, + .end = AT91SAM9263_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9263_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index bb2ba0c1d0ee..3b91706e4f7d 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1133,10 +1133,19 @@ static void __init at91_add_device_trng(void) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9G45_BASE_WDT, + .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9g45_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index f9b423b7d7ae..c7961b446dd8 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -709,10 +709,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9RL_BASE_WDT, + .end = AT91SAM9RL_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9rl_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 5ac468c219af..750ba85614ca 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -86,7 +86,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) @@ -101,6 +100,7 @@ #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 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index e3c819ab3435..05860c5eb548 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -86,7 +86,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 @@ -97,6 +96,7 @@ #define AT91SAM9260_BASE_SHDWC 0xfffffd10 #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 +#define AT91SAM9260_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index f9b516368f96..df2ddfd2d22e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -71,7 +71,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9261_BASE_SMC 0xffffec00 @@ -81,6 +80,7 @@ #define AT91SAM9261_BASE_SHDWC 0xfffffd10 #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 +#define AT91SAM9261_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 28d52d588e90..0eb614eb2fa6 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -81,7 +81,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 @@ -96,6 +95,7 @@ #define AT91SAM9263_BASE_SHDWC 0xfffffd10 #define AT91SAM9263_BASE_RTT0 0xfffffd20 #define AT91SAM9263_BASE_PIT 0xfffffd30 +#define AT91SAM9263_BASE_WDT 0xfffffd40 #define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91_USART0 AT91SAM9263_BASE_US0 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 5f3453ef5866..65098c323101 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -93,7 +93,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) @@ -108,6 +107,7 @@ #define AT91SAM9G45_BASE_SHDWC 0xfffffd10 #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 +#define AT91SAM9G45_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 6f3a4eeb7394..46e136d3ef3f 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -75,7 +75,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) @@ -90,6 +89,7 @@ #define AT91SAM9RL_BASE_SHDWC 0xfffffd10 #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 +#define AT91SAM9RL_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 87445b2d72a7..00562566ef5f 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -35,6 +35,11 @@ #define DRV_NAME "AT91SAM9 Watchdog" +#define wdt_read(field) \ + __raw_readl(at91wdt_private.base + field) +#define wdt_write(field, val) \ + __raw_writel((val), at91wdt_private.base + field) + /* AT91SAM9 watchdog runs a 12bit counter @ 256Hz, * use this to convert a watchdog * value from/to milliseconds. @@ -63,6 +68,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " static void at91_ping(unsigned long data); static struct { + void __iomem *base; unsigned long next_heartbeat; /* the next_heartbeat for the timer */ unsigned long open; char expect_close; @@ -77,7 +83,7 @@ static struct { */ static inline void at91_wdt_reset(void) { - at91_sys_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); + wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); } /* @@ -132,7 +138,7 @@ static int at91_wdt_settimeout(unsigned int timeout) unsigned int mr; /* Check if disabled */ - mr = at91_sys_read(AT91_WDT_MR); + mr = wdt_read(AT91_WDT_MR); if (mr & AT91_WDT_WDDIS) { printk(KERN_ERR DRV_NAME": sorry, watchdog is disabled\n"); return -EIO; @@ -149,7 +155,7 @@ static int at91_wdt_settimeout(unsigned int timeout) | AT91_WDT_WDDBGHLT /* disabled in debug mode */ | AT91_WDT_WDD /* restart at any time */ | (timeout & AT91_WDT_WDV); /* timer value */ - at91_sys_write(AT91_WDT_MR, reg); + wdt_write(AT91_WDT_MR, reg); return 0; } @@ -248,12 +254,22 @@ static struct miscdevice at91wdt_miscdev = { static int __init at91wdt_probe(struct platform_device *pdev) { + struct resource *r; int res; if (at91wdt_miscdev.parent) return -EBUSY; at91wdt_miscdev.parent = &pdev->dev; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + at91wdt_private.base = ioremap(r->start, resource_size(r)); + if (!at91wdt_private.base) { + dev_err(&pdev->dev, "failed to map registers, aborting.\n"); + return -ENOMEM; + } + /* Set watchdog */ res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); if (res) diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h index 757f9cab5c82..c6fbb2e6c41b 100644 --- a/drivers/watchdog/at91sam9_wdt.h +++ b/drivers/watchdog/at91sam9_wdt.h @@ -16,11 +16,11 @@ #ifndef AT91_WDT_H #define AT91_WDT_H -#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ +#define AT91_WDT_CR 0x00 /* Watchdog Control Register */ #define AT91_WDT_WDRSTT (1 << 0) /* Restart */ #define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ +#define AT91_WDT_MR 0x04 /* Watchdog Mode Register */ #define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ #define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */ #define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */ @@ -30,7 +30,7 @@ #define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */ #define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */ -#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */ +#define AT91_WDT_SR 0x08 /* Watchdog Status Register */ #define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */ #define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */ -- cgit v1.2.3 From 13079a733313c00ca92fc6716383dd126caa7276 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 2 Nov 2011 01:43:31 +0800 Subject: ARM: at91: make DBGU soc independent we will select now the DBGU used by the soc at Kconfig level For the DEBUG_LL and early_printk this will allow to select which DBGU to use this will also allow to select them when multiple SOC are enabled Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/Kconfig.debug | 8 ++++++++ arch/arm/mach-at91/Kconfig | 24 ++++++++++++++++++++++-- arch/arm/mach-at91/at91cap9_devices.c | 4 ++-- arch/arm/mach-at91/at91rm9200_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9260_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9261_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9263_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9g45_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9rl_devices.c | 4 ++-- arch/arm/mach-at91/include/mach/at91_dbgu.h | 2 +- arch/arm/mach-at91/include/mach/at91cap9.h | 2 +- arch/arm/mach-at91/include/mach/at91rm9200.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9261.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9263.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- arch/arm/mach-at91/include/mach/debug-macro.S | 10 ++++++++-- arch/arm/mach-at91/include/mach/hardware.h | 6 ++++++ arch/arm/mach-at91/include/mach/uncompress.h | 6 ++++-- arch/arm/mach-at91/setup.c | 7 ++----- 21 files changed, 72 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c5213e78606b..0608c0ba94e6 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -100,6 +100,14 @@ choice 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" + depends on HAVE_AT91_DBGU1 + config DEBUG_FOOTBRIDGE_COM1 bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" depends on FOOTBRIDGE diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index d111c3e99249..4f991f295284 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -3,6 +3,12 @@ if ARCH_AT91 config HAVE_AT91_DATAFLASH_CARD bool +config HAVE_AT91_DBGU0 + bool + +config HAVE_AT91_DBGU1 + bool + config HAVE_AT91_USART3 bool @@ -21,12 +27,14 @@ config ARCH_AT91RM9200 bool "AT91RM9200" select CPU_ARM920T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_AT91_USART3 config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE" select CPU_ARM926T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_AT91_USART3 select HAVE_AT91_USART4 select HAVE_AT91_USART5 @@ -37,11 +45,13 @@ config ARCH_AT91SAM9261 select CPU_ARM926T select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL + select HAVE_AT91_DBGU0 config ARCH_AT91SAM9G10 bool "AT91SAM9G10" select CPU_ARM926T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL config ARCH_AT91SAM9263 @@ -50,6 +60,7 @@ config ARCH_AT91SAM9263 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91SAM9RL bool "AT91SAM9RL" @@ -57,11 +68,13 @@ config ARCH_AT91SAM9RL select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_FB_ATMEL + select HAVE_AT91_DBGU0 config ARCH_AT91SAM9G20 bool "AT91SAM9G20" select CPU_ARM926T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_AT91_USART3 select HAVE_AT91_USART4 select HAVE_AT91_USART5 @@ -74,6 +87,7 @@ config ARCH_AT91SAM9G45 select HAVE_AT91_USART3 select HAVE_FB_ATMEL select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91CAP9 bool "AT91CAP9" @@ -81,6 +95,7 @@ config ARCH_AT91CAP9 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91X40 bool "AT91x40" @@ -510,8 +525,13 @@ config AT91_TIMER_HZ choice prompt "Select a UART for early kernel messages" -config AT91_EARLY_DBGU - bool "DBGU" +config AT91_EARLY_DBGU0 + bool "DBGU on rm9200, 9260/9g20, 9261/9g10 and 9rl" + depends on HAVE_AT91_DBGU0 + +config AT91_EARLY_DBGU1 + bool "DBGU on 9263, 9g45 and cap9" + depends on HAVE_AT91_DBGU1 config AT91_EARLY_USART0 bool "USART0" diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 019dac047b91..19975cfb00cd 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -1030,8 +1030,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91CAP9_BASE_DBGU, + .end = AT91CAP9_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 66591fa53e05..1007ba8ec131 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -877,8 +877,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91RM9200_BASE_DBGU, + .end = AT91RM9200_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 9cdaffa0d6b1..5b424fcc9c8c 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -846,8 +846,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9260_BASE_DBGU, + .end = AT91SAM9260_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index c59e1e9a4f5c..e5cff1d902d0 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -825,8 +825,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9261_BASE_DBGU, + .end = AT91SAM9261_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b5f4e2532fdb..20e681c6b404 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -1205,8 +1205,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9263_BASE_DBGU, + .end = AT91SAM9263_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 3b91706e4f7d..153dad0642c6 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1341,8 +1341,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9G45_BASE_DBGU, + .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index c7961b446dd8..366c1cfd4f77 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -917,8 +917,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9RL_BASE_DBGU, + .end = AT91SAM9RL_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h index dbfe455a4c41..2aa0c5e13495 100644 --- a/arch/arm/mach-at91/include/mach/at91_dbgu.h +++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h @@ -19,7 +19,7 @@ #define dbgu_readl(dbgu, field) \ __raw_readl(AT91_VA_BASE_SYS + dbgu + AT91_DBGU_ ## field) -#ifdef AT91_DBGU +#if !defined(CONFIG_ARCH_AT91X40) #define AT91_DBGU_CR (0x00) /* Control Register */ #define AT91_DBGU_MR (0x04) /* Mode Register */ #define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */ diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 750ba85614ca..bca2b54de73e 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -82,7 +82,6 @@ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) @@ -93,6 +92,7 @@ #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 diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 57409549585f..1f767e28ea50 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -80,12 +80,12 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ #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 */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 05860c5eb548..e360d6665437 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -83,13 +83,13 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 #define AT91SAM9260_BASE_SMC 0xffffec00 +#define AT91SAM9260_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index df2ddfd2d22e..2ccc8a53985b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -68,12 +68,12 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9261_BASE_SMC 0xffffec00 +#define AT91SAM9261_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 0eb614eb2fa6..aee137ba5bcf 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -77,7 +77,6 @@ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) @@ -87,6 +86,7 @@ #define AT91SAM9263_BASE_SMC0 0xffffe400 #define AT91SAM9263_BASE_ECC1 0xffffe600 #define AT91SAM9263_BASE_SMC1 0xffffea00 +#define AT91SAM9263_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 #define AT91SAM9263_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 65098c323101..211721b790a7 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -89,7 +89,6 @@ #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) @@ -99,6 +98,7 @@ #define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_SMC 0xffffe800 +#define AT91SAM9G45_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 46e136d3ef3f..4f7367a53f04 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -72,7 +72,6 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) @@ -82,6 +81,7 @@ #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_SMC 0xffffec00 +#define AT91SAM9RL_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S index 0ed8648c6452..c6bb9e2d9baa 100644 --- a/arch/arm/mach-at91/include/mach/debug-macro.S +++ b/arch/arm/mach-at91/include/mach/debug-macro.S @@ -14,9 +14,15 @@ #include #include +#if defined(CONFIG_AT91_DEBUG_LL_DBGU0) +#define AT91_DBGU AT91_BASE_DBGU0 +#else +#define AT91_DBGU AT91_BASE_DBGU1 +#endif + .macro addruart, rp, rv, tmp - ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address) - ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address) + ldr \rp, =AT91_DBGU @ System peripherals (phys address) + ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address) .endm .macro senduart,rd,rx diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 483478d8be6b..435764ee8490 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -16,6 +16,12 @@ #include +/* DBGU base */ +/* rm9200, 9260/9g20, 9261/9g10, 9rl */ +#define AT91_BASE_DBGU0 0xfffff200 +/* 9263, 9g45, cap9 */ +#define AT91_BASE_DBGU1 0xffffee00 + #if defined(CONFIG_ARCH_AT91RM9200) #include #elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h index 18bdcdeb474f..0234fd9d20d6 100644 --- a/arch/arm/mach-at91/include/mach/uncompress.h +++ b/arch/arm/mach-at91/include/mach/uncompress.h @@ -24,8 +24,10 @@ #include #include -#if defined(CONFIG_AT91_EARLY_DBGU) -#define UART_OFFSET (AT91_DBGU + AT91_BASE_SYS) +#if defined(CONFIG_AT91_EARLY_DBGU0) +#define UART_OFFSET AT91_BASE_DBGU0 +#elif defined(CONFIG_AT91_EARLY_DBGU1) +#define UART_OFFSET AT91_BASE_DBGU1 #elif defined(CONFIG_AT91_EARLY_USART0) #define UART_OFFSET AT91_USART0 #elif defined(CONFIG_AT91_EARLY_USART1) diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 053c36993154..242c26b2368d 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -93,9 +93,6 @@ void at91_iounmap(volatile void __iomem *addr) } EXPORT_SYMBOL(at91_iounmap); -#define AT91_DBGU0 0xfffff200 -#define AT91_DBGU1 0xffffee00 - static void __init soc_detect(u32 dbgu_base) { u32 cidr, socid; @@ -268,9 +265,9 @@ void __init at91_map_io(void) at91_soc_initdata.type = AT91_SOC_NONE; at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; - soc_detect(AT91_DBGU0); + soc_detect(AT91_BASE_DBGU0); if (!at91_soc_is_detected()) - soc_detect(AT91_DBGU1); + soc_detect(AT91_BASE_DBGU1); if (!at91_soc_is_detected()) panic("AT91: Impossible to detect the SOC type"); -- cgit v1.2.3 From be6d4321720cd56623c1d5be311bde65c2c91229 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 3 Nov 2011 01:12:50 +0800 Subject: ARM: at91: make aic soc independent on all at91 have the Advanced Interrupt Controller starts at address 0xfffff000 Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/include/mach/at91_aic.h | 48 +++++++++++++++++---------- arch/arm/mach-at91/include/mach/at91cap9.h | 1 - arch/arm/mach-at91/include/mach/at91rm9200.h | 1 - arch/arm/mach-at91/include/mach/at91sam9260.h | 1 - arch/arm/mach-at91/include/mach/at91sam9261.h | 1 - arch/arm/mach-at91/include/mach/at91sam9263.h | 1 - arch/arm/mach-at91/include/mach/at91sam9g45.h | 1 - arch/arm/mach-at91/include/mach/at91sam9rl.h | 1 - arch/arm/mach-at91/include/mach/at91x40.h | 1 - arch/arm/mach-at91/include/mach/entry-macro.S | 11 +++--- arch/arm/mach-at91/include/mach/hardware.h | 6 ++++ arch/arm/mach-at91/include/mach/irqs.h | 2 +- arch/arm/mach-at91/irq.c | 38 ++++++++++++--------- arch/arm/mach-at91/pm.c | 4 +-- 14 files changed, 67 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/include/mach/at91_aic.h b/arch/arm/mach-at91/include/mach/at91_aic.h index 03566799d3be..3045781c473f 100644 --- a/arch/arm/mach-at91/include/mach/at91_aic.h +++ b/arch/arm/mach-at91/include/mach/at91_aic.h @@ -16,7 +16,19 @@ #ifndef AT91_AIC_H #define AT91_AIC_H -#define AT91_AIC_SMR(n) (AT91_AIC + ((n) * 4)) /* Source Mode Registers 0-31 */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_aic_base; + +#define at91_aic_read(field) \ + __raw_readl(at91_aic_base + field) + +#define at91_aic_write(field, value) \ + __raw_writel(value, at91_aic_base + field); +#else +.extern at91_aic_base +#endif + +#define AT91_AIC_SMR(n) ((n) * 4) /* Source Mode Registers 0-31 */ #define AT91_AIC_PRIOR (7 << 0) /* Priority Level */ #define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */ #define AT91_AIC_SRCTYPE_LOW (0 << 5) @@ -24,30 +36,30 @@ #define AT91_AIC_SRCTYPE_HIGH (2 << 5) #define AT91_AIC_SRCTYPE_RISING (3 << 5) -#define AT91_AIC_SVR(n) (AT91_AIC + 0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ -#define AT91_AIC_IVR (AT91_AIC + 0x100) /* Interrupt Vector Register */ -#define AT91_AIC_FVR (AT91_AIC + 0x104) /* Fast Interrupt Vector Register */ -#define AT91_AIC_ISR (AT91_AIC + 0x108) /* Interrupt Status Register */ +#define AT91_AIC_SVR(n) (0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ +#define AT91_AIC_IVR 0x100 /* Interrupt Vector Register */ +#define AT91_AIC_FVR 0x104 /* Fast Interrupt Vector Register */ +#define AT91_AIC_ISR 0x108 /* Interrupt Status Register */ #define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */ -#define AT91_AIC_IPR (AT91_AIC + 0x10c) /* Interrupt Pending Register */ -#define AT91_AIC_IMR (AT91_AIC + 0x110) /* Interrupt Mask Register */ -#define AT91_AIC_CISR (AT91_AIC + 0x114) /* Core Interrupt Status Register */ +#define AT91_AIC_IPR 0x10c /* Interrupt Pending Register */ +#define AT91_AIC_IMR 0x110 /* Interrupt Mask Register */ +#define AT91_AIC_CISR 0x114 /* Core Interrupt Status Register */ #define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */ #define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */ -#define AT91_AIC_IECR (AT91_AIC + 0x120) /* Interrupt Enable Command Register */ -#define AT91_AIC_IDCR (AT91_AIC + 0x124) /* Interrupt Disable Command Register */ -#define AT91_AIC_ICCR (AT91_AIC + 0x128) /* Interrupt Clear Command Register */ -#define AT91_AIC_ISCR (AT91_AIC + 0x12c) /* Interrupt Set Command Register */ -#define AT91_AIC_EOICR (AT91_AIC + 0x130) /* End of Interrupt Command Register */ -#define AT91_AIC_SPU (AT91_AIC + 0x134) /* Spurious Interrupt Vector Register */ -#define AT91_AIC_DCR (AT91_AIC + 0x138) /* Debug Control Register */ +#define AT91_AIC_IECR 0x120 /* Interrupt Enable Command Register */ +#define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */ +#define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */ +#define AT91_AIC_ISCR 0x12c /* Interrupt Set Command Register */ +#define AT91_AIC_EOICR 0x130 /* End of Interrupt Command Register */ +#define AT91_AIC_SPU 0x134 /* Spurious Interrupt Vector Register */ +#define AT91_AIC_DCR 0x138 /* Debug Control Register */ #define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */ #define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */ -#define AT91_AIC_FFER (AT91_AIC + 0x140) /* Fast Forcing Enable Register [SAM9 only] */ -#define AT91_AIC_FFDR (AT91_AIC + 0x144) /* Fast Forcing Disable Register [SAM9 only] */ -#define AT91_AIC_FFSR (AT91_AIC + 0x148) /* Fast Forcing Status Register [SAM9 only] */ +#define AT91_AIC_FFER 0x140 /* Fast Forcing Enable Register [SAM9 only] */ +#define AT91_AIC_FFDR 0x144 /* Fast Forcing Disable Register [SAM9 only] */ +#define AT91_AIC_FFSR 0x148 /* Fast Forcing Status Register [SAM9 only] */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index bca2b54de73e..4c0e2f6011d7 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -82,7 +82,6 @@ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 1f767e28ea50..90e92a8b3cb5 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -79,7 +79,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index e360d6665437..f937c476bb67 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -82,7 +82,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 2ccc8a53985b..175604e261be 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -67,7 +67,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index aee137ba5bcf..80c915002d83 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -77,7 +77,6 @@ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 211721b790a7..ac5c471635dc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -89,7 +89,6 @@ #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 4f7367a53f04..c466e8c898ad 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -71,7 +71,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h index a152ff87e688..a57829f4fd18 100644 --- a/arch/arm/mach-at91/include/mach/at91x40.h +++ b/arch/arm/mach-at91/include/mach/at91x40.h @@ -40,7 +40,6 @@ #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_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ /* * The AT91x40 series doesn't have a debug unit like the other AT91 parts. diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S index 7ab68f972227..423eea0ed74c 100644 --- a/arch/arm/mach-at91/include/mach/entry-macro.S +++ b/arch/arm/mach-at91/include/mach/entry-macro.S @@ -17,16 +17,17 @@ .endm .macro get_irqnr_preamble, base, tmp - ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral + 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 - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) - ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number - teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt - streq \tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)] @ not going to be handled further, then ACK it now. + 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 + teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt + streq \tmp, [\base, #AT91_AIC_EOICR] @ not going to be handled further, then ACK it now. .endm diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 435764ee8490..2d0e4e998566 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -57,6 +57,12 @@ #define AT91_BASE_SYS 0xffffc000 #endif +/* + * On all at91 have the Advanced Interrupt Controller starts at address + * 0xfffff000 + */ +#define AT91_AIC 0xfffff000 + /* * Peripheral identifiers/interrupts. */ diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h index 36bd55f3fc6e..ac8b7dfc85ef 100644 --- a/arch/arm/mach-at91/include/mach/irqs.h +++ b/arch/arm/mach-at91/include/mach/irqs.h @@ -31,7 +31,7 @@ * Acknowledge interrupt with AIC after interrupt has been handled. * (by kernel/irq.c) */ -#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0) +#define irq_finish(irq) do { at91_aic_write(AT91_AIC_EOICR, 0); } while (0) /* diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index 9665265ec757..be6b639ecd7b 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -33,17 +33,18 @@ #include #include +void __iomem *at91_aic_base; static void at91_aic_mask_irq(struct irq_data *d) { /* Disable interrupt on AIC */ - at91_sys_write(AT91_AIC_IDCR, 1 << d->irq); + at91_aic_write(AT91_AIC_IDCR, 1 << d->irq); } static void at91_aic_unmask_irq(struct irq_data *d) { /* Enable interrupt on AIC */ - at91_sys_write(AT91_AIC_IECR, 1 << d->irq); + at91_aic_write(AT91_AIC_IECR, 1 << d->irq); } unsigned int at91_extern_irq; @@ -77,8 +78,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) return -EINVAL; } - smr = at91_sys_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; - at91_sys_write(AT91_AIC_SMR(d->irq), smr | srctype); + smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; + at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype); return 0; } @@ -102,15 +103,15 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value) void at91_irq_suspend(void) { - backups = at91_sys_read(AT91_AIC_IMR); - at91_sys_write(AT91_AIC_IDCR, backups); - at91_sys_write(AT91_AIC_IECR, wakeups); + backups = at91_aic_read(AT91_AIC_IMR); + at91_aic_write(AT91_AIC_IDCR, backups); + at91_aic_write(AT91_AIC_IECR, wakeups); } void at91_irq_resume(void) { - at91_sys_write(AT91_AIC_IDCR, wakeups); - at91_sys_write(AT91_AIC_IECR, backups); + at91_aic_write(AT91_AIC_IDCR, wakeups); + at91_aic_write(AT91_AIC_IECR, backups); } #else @@ -133,34 +134,39 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) { unsigned int i; + at91_aic_base = ioremap(AT91_AIC, 512); + + if (!at91_aic_base) + panic("Impossible to ioremap AT91_AIC\n"); + /* * 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: */ - at91_sys_write(AT91_AIC_SVR(i), i); + at91_aic_write(AT91_AIC_SVR(i), i); /* Active Low interrupt, with the specified priority */ - at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); + 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_sys_write(AT91_AIC_EOICR, 0); + 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_sys_write(AT91_AIC_SPU, NR_AIC_IRQS); + at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS); /* No debugging in AIC: Debug (Protect) Control Register */ - at91_sys_write(AT91_AIC_DCR, 0); + at91_aic_write(AT91_AIC_DCR, 0); /* Disable and clear all interrupts initially */ - at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); + at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); } diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 3a5b7b4279e7..62ad95556c36 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -218,7 +218,7 @@ static int at91_pm_enter(suspend_state_t state) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_extern_irq)) - & at91_sys_read(AT91_AIC_IMR), + & at91_aic_read(AT91_AIC_IMR), state); switch (state) { @@ -286,7 +286,7 @@ static int at91_pm_enter(suspend_state_t state) } pr_debug("AT91: PM - wakeup %08x\n", - at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); + at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; -- cgit v1.2.3 From d28bdfc5c80fb64bf50824920bf9b554732dec74 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 14 Nov 2011 14:24:53 +0800 Subject: ARM: at91: make rm9200 rtc drivers soc independent switch the rtc drivers to resource and pass it via platform_device Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_devices.c | 16 +++- arch/arm/mach-at91/at91sam9g45_devices.c | 16 +++- arch/arm/mach-at91/include/mach/at91_rtc.h | 24 +++--- arch/arm/mach-at91/include/mach/at91rm9200.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9g45.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9rl.h | 2 +- drivers/rtc/rtc-at91rm9200.c | 101 ++++++++++++++++---------- 7 files changed, 108 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 1007ba8ec131..ba4fefe60f62 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -665,10 +665,24 @@ static void __init at91_add_device_tc(void) { } * -------------------------------------------------------------------- */ #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct resource rtc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_RTC, + .end = AT91RM9200_BASE_RTC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device at91rm9200_rtc_device = { .name = "at91_rtc", .id = -1, - .num_resources = 0, + .resource = rtc_resources, + .num_resources = ARRAY_SIZE(rtc_resources), }; static void __init at91_add_device_rtc(void) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 153dad0642c6..2c64e01bbd13 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1009,10 +1009,24 @@ static void __init at91_add_device_tc(void) { } * -------------------------------------------------------------------- */ #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct resource rtc_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_RTC, + .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device at91sam9g45_rtc_device = { .name = "at91_rtc", .id = -1, - .num_resources = 0, + .resource = rtc_resources, + .num_resources = ARRAY_SIZE(rtc_resources), }; static void __init at91_add_device_rtc(void) diff --git a/arch/arm/mach-at91/include/mach/at91_rtc.h b/arch/arm/mach-at91/include/mach/at91_rtc.h index e56f4701a3e5..da1945e5f714 100644 --- a/arch/arm/mach-at91/include/mach/at91_rtc.h +++ b/arch/arm/mach-at91/include/mach/at91_rtc.h @@ -16,7 +16,7 @@ #ifndef AT91_RTC_H #define AT91_RTC_H -#define AT91_RTC_CR (AT91_RTC + 0x00) /* Control Register */ +#define AT91_RTC_CR 0x00 /* Control Register */ #define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ #define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ #define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ @@ -29,44 +29,44 @@ #define AT91_RTC_CALEVSEL_MONTH (1 << 16) #define AT91_RTC_CALEVSEL_YEAR (2 << 16) -#define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */ +#define AT91_RTC_MR 0x04 /* Mode Register */ #define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ -#define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */ +#define AT91_RTC_TIMR 0x08 /* Time Register */ #define AT91_RTC_SEC (0x7f << 0) /* Current Second */ #define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ #define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ #define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ -#define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */ +#define AT91_RTC_CALR 0x0c /* Calendar Register */ #define AT91_RTC_CENT (0x7f << 0) /* Current Century */ #define AT91_RTC_YEAR (0xff << 8) /* Current Year */ #define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ #define AT91_RTC_DAY (7 << 21) /* Current Day */ #define AT91_RTC_DATE (0x3f << 24) /* Current Date */ -#define AT91_RTC_TIMALR (AT91_RTC + 0x10) /* Time Alarm Register */ +#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */ #define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ #define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ #define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ -#define AT91_RTC_CALALR (AT91_RTC + 0x14) /* Calendar Alarm Register */ +#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */ #define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ #define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ -#define AT91_RTC_SR (AT91_RTC + 0x18) /* Status Register */ +#define AT91_RTC_SR 0x18 /* Status Register */ #define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ #define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ #define AT91_RTC_SECEV (1 << 2) /* Second Event */ #define AT91_RTC_TIMEV (1 << 3) /* Time Event */ #define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ -#define AT91_RTC_SCCR (AT91_RTC + 0x1c) /* Status Clear Command Register */ -#define AT91_RTC_IER (AT91_RTC + 0x20) /* Interrupt Enable Register */ -#define AT91_RTC_IDR (AT91_RTC + 0x24) /* Interrupt Disable Register */ -#define AT91_RTC_IMR (AT91_RTC + 0x28) /* Interrupt Mask Register */ +#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */ +#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */ +#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ +#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ -#define AT91_RTC_VER (AT91_RTC + 0x2c) /* Valid Entry Register */ +#define AT91_RTC_VER 0x2c /* Valid Entry Register */ #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ #define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ #define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 90e92a8b3cb5..bacb51141819 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -81,7 +81,6 @@ */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ -#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ #define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ #define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */ @@ -89,6 +88,7 @@ #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_RTC 0xfffffe00 /* Real-Time Clock */ #define AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART1 AT91RM9200_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index ac5c471635dc..f0c23c960dec 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -92,7 +92,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) -#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) #define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_DMA 0xffffec00 @@ -107,6 +106,7 @@ #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91SAM9G45_BASE_WDT 0xfffffd40 +#define AT91SAM9G45_BASE_RTC 0xfffffdb0 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index c466e8c898ad..2bb359e60b97 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -75,7 +75,6 @@ #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) -#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 @@ -89,6 +88,7 @@ #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91SAM9RL_BASE_WDT 0xfffffd40 +#define AT91SAM9RL_BASE_RTC 0xfffffe00 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index e39b77a4609a..dc474bc6522d 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -32,11 +32,17 @@ #include +#define at91_rtc_read(field) \ + __raw_readl(at91_rtc_regs + field) +#define at91_rtc_write(field, val) \ + __raw_writel((val), at91_rtc_regs + field) #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ static DECLARE_COMPLETION(at91_rtc_updated); static unsigned int at91_alarm_year = AT91_RTC_EPOCH; +static void __iomem *at91_rtc_regs; +static int irq; /* * Decode time/date into rtc_time structure @@ -48,10 +54,10 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, /* must read twice in case it changes */ do { - time = at91_sys_read(timereg); - date = at91_sys_read(calreg); - } while ((time != at91_sys_read(timereg)) || - (date != at91_sys_read(calreg))); + time = at91_rtc_read(timereg); + date = at91_rtc_read(calreg); + } while ((time != at91_rtc_read(timereg)) || + (date != at91_rtc_read(calreg))); tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0); tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8); @@ -98,19 +104,19 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) tm->tm_hour, tm->tm_min, tm->tm_sec); /* Stop Time/Calendar from counting */ - cr = at91_sys_read(AT91_RTC_CR); - at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); + cr = at91_rtc_read(AT91_RTC_CR); + at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ACKUPD); + at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD); wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); - at91_sys_write(AT91_RTC_TIMR, + at91_rtc_write(AT91_RTC_TIMR, bin2bcd(tm->tm_sec) << 0 | bin2bcd(tm->tm_min) << 8 | bin2bcd(tm->tm_hour) << 16); - at91_sys_write(AT91_RTC_CALR, + at91_rtc_write(AT91_RTC_CALR, bin2bcd((tm->tm_year + 1900) / 100) /* century */ | bin2bcd(tm->tm_year % 100) << 8 /* year */ | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ @@ -118,8 +124,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | bin2bcd(tm->tm_mday) << 24); /* Restart Time/Calendar */ - cr = at91_sys_read(AT91_RTC_CR); - at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); + cr = at91_rtc_read(AT91_RTC_CR); + at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); return 0; } @@ -135,7 +141,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_year = at91_alarm_year - 1900; - alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM) + alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) ? 1 : 0; pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -160,20 +166,20 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) tm.tm_min = alrm->time.tm_min; tm.tm_sec = alrm->time.tm_sec; - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_TIMALR, + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_TIMALR, bin2bcd(tm.tm_sec) << 0 | bin2bcd(tm.tm_min) << 8 | bin2bcd(tm.tm_hour) << 16 | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); - at91_sys_write(AT91_RTC_CALALR, + at91_rtc_write(AT91_RTC_CALALR, bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ | bin2bcd(tm.tm_mday) << 24 | AT91_RTC_DATEEN | AT91_RTC_MTHEN); if (alrm->enabled) { - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); } pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -188,10 +194,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) pr_debug("%s(): cmd=%08x\n", __func__, enabled); if (enabled) { - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); } else - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); return 0; } @@ -200,7 +206,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) */ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned long imr = at91_sys_read(AT91_RTC_IMR); + unsigned long imr = at91_rtc_read(AT91_RTC_IMR); seq_printf(seq, "update_IRQ\t: %s\n", (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); @@ -220,7 +226,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) unsigned int rtsr; unsigned long events = 0; - rtsr = at91_sys_read(AT91_RTC_SR) & at91_sys_read(AT91_RTC_IMR); + rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR); if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) events |= (RTC_AF | RTC_IRQF); @@ -229,7 +235,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) if (rtsr & AT91_RTC_ACKUPD) complete(&at91_rtc_updated); - at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ + at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ rtc_update_irq(rtc, 1, events); @@ -256,22 +262,41 @@ static const struct rtc_class_ops at91_rtc_ops = { static int __init at91_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - int ret; + struct resource *regs; + int ret = 0; - at91_sys_write(AT91_RTC_CR, 0); - at91_sys_write(AT91_RTC_MR, 0); /* 24 hour mode */ + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "no mmio resource defined\n"); + return -ENXIO; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource defined\n"); + return -ENXIO; + } + + at91_rtc_regs = ioremap(regs->start, resource_size(regs)); + if (!at91_rtc_regs) { + dev_err(&pdev->dev, "failed to map registers, aborting.\n"); + return -ENOMEM; + } + + at91_rtc_write(AT91_RTC_CR, 0); + at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */ /* Disable all interrupts */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); - ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, + ret = request_irq(irq, at91_rtc_interrupt, IRQF_SHARED, "at91_rtc", pdev); if (ret) { printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", - AT91_ID_SYS); + irq); return ret; } @@ -284,7 +309,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) rtc = rtc_device_register(pdev->name, &pdev->dev, &at91_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - free_irq(AT91_ID_SYS, pdev); + free_irq(irq, pdev); return PTR_ERR(rtc); } platform_set_drvdata(pdev, rtc); @@ -301,10 +326,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) struct rtc_device *rtc = platform_get_drvdata(pdev); /* Disable all interrupts */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); - free_irq(AT91_ID_SYS, pdev); + free_irq(irq, pdev); rtc_device_unregister(rtc); platform_set_drvdata(pdev, NULL); @@ -323,13 +348,13 @@ static int at91_rtc_suspend(struct device *dev) /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... */ - at91_rtc_imr = at91_sys_read(AT91_RTC_IMR) + at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR) & (AT91_RTC_ALARM|AT91_RTC_SECEV); if (at91_rtc_imr) { if (device_may_wakeup(dev)) - enable_irq_wake(AT91_ID_SYS); + enable_irq_wake(irq); else - at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); + at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr); } return 0; } @@ -338,9 +363,9 @@ static int at91_rtc_resume(struct device *dev) { if (at91_rtc_imr) { if (device_may_wakeup(dev)) - disable_irq_wake(AT91_ID_SYS); + disable_irq_wake(irq); else - at91_sys_write(AT91_RTC_IER, at91_rtc_imr); + at91_rtc_write(AT91_RTC_IER, at91_rtc_imr); } return 0; } -- cgit v1.2.3 From f2971c4c3197935f409bff202b9ab67416981dd7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 20:48:56 +0200 Subject: alpha: switch to GENERIC_PCI_IOMAP alpha copied pci_iomap from generic code to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. The only difference is handling of nocache flag, that turns out to be done correctly by the generic code since arch/alpha/include/asm/io.h defines ioremap_nocache same as ioremap. Signed-off-by: Michael S. Tsirkin --- arch/alpha/Kconfig | 1 + arch/alpha/kernel/pci.c | 26 +------------------------- 2 files changed, 2 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 3636b11ddff0..56a4df952fb0 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -315,6 +315,7 @@ config ISA_DMA_API config PCI bool depends on !ALPHA_JENSEN + select GENERIC_PCI_IOMAP default y help Find out whether you have a PCI motherboard. PCI is the name of a diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index c9ab94ee1ca8..f3cae275d3f5 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -508,30 +508,7 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn) return -EOPNOTSUPP; } -/* Create an __iomem token from a PCI BAR. Copied from lib/iomap.c with - no changes, since we don't want the other things in that object file. */ - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - /* Not checking IORESOURCE_CACHEABLE because alpha does - not distinguish between ioremap and ioremap_nocache. */ - return ioremap(start, len); - } - return NULL; -} - -/* Destroy that token. Not copied from lib/iomap.c. */ +/* Destroy an __iomem token. Not copied from lib/iomap.c. */ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { @@ -539,7 +516,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) iounmap(addr); } -EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); /* FIXME: Some boxes have multiple ISA bridges! */ -- cgit v1.2.3 From e5bfb72ce2ce558b5a5a46cc5694001f0479c7f2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 20:57:23 +0200 Subject: arm: switch to GENERIC_PCI_IOMAP arm copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. Signed-off-by: Michael S. Tsirkin --- arch/arm/Kconfig | 1 + arch/arm/include/asm/io.h | 2 +- arch/arm/mm/iomap.c | 21 --------------------- 3 files changed, 2 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 44789eff983f..2ebf66b8008f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -30,6 +30,7 @@ config ARM select HAVE_SPARSE_IRQ select GENERIC_IRQ_SHOW select CPU_PM if (SUSPEND || CPU_IDLE) + select GENERIC_PCI_IOMAP help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 065d100fa63e..9275828feb3d 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -27,6 +27,7 @@ #include #include #include +#include /* * ISA I/O bus memory addresses are 1:1 with the physical address. @@ -306,7 +307,6 @@ extern void ioport_unmap(void __iomem *addr); struct pci_dev; -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen); extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); /* diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index 430df1a5978d..e62956e12030 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c @@ -35,27 +35,6 @@ EXPORT_SYMBOL(pcibios_min_mem); unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; EXPORT_SYMBOL(pci_flags); -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { if ((unsigned long)addr >= VMALLOC_START && -- cgit v1.2.3 From 1b34d16073430671513b5231fb81cbe725b1a0de Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 21:06:41 +0200 Subject: microblaze: switch to GENERIC_PCI_IOMAP microblaze copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. The only difference is handling of nocache flag, that turns out to be done correctly by the generic code since arch/microblaze/include/asm/io.h defines ioremap_nocache same as ioremap. Signed-off-by: Michael S. Tsirkin --- arch/microblaze/Kconfig | 1 + arch/microblaze/pci/iomap.c | 19 ------------------- 2 files changed, 1 insertion(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index e446bab2427b..f0eead74fff6 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -17,6 +17,7 @@ config MICROBLAZE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP config SWAP def_bool n diff --git a/arch/microblaze/pci/iomap.c b/arch/microblaze/pci/iomap.c index 57acda852f5a..b07abbac0319 100644 --- a/arch/microblaze/pci/iomap.c +++ b/arch/microblaze/pci/iomap.c @@ -10,25 +10,6 @@ #include #include -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len) - return NULL; - if (max && len > max) - len = max; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - /* What? */ - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { if (isa_vaddr_is_ioport(addr)) -- cgit v1.2.3 From eab90291d35438bcebf7c3dc85be66d0f24e3002 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 21:10:12 +0200 Subject: mips: switch to GENERIC_PCI_IOMAP mips copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. Signed-off-by: Michael S. Tsirkin --- arch/mips/Kconfig | 1 + arch/mips/lib/iomap-pci.c | 26 -------------------------- 2 files changed, 1 insertion(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d46f1da18a3c..b70c96f4417e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2317,6 +2317,7 @@ config PCI bool "Support for PCI controller" depends on HW_HAS_PCI select PCI_DOMAINS + select GENERIC_PCI_IOMAP help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c index 2ab899c4b4ce..2635b1a96333 100644 --- a/arch/mips/lib/iomap-pci.c +++ b/arch/mips/lib/iomap-pci.c @@ -40,32 +40,6 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev, return (void __iomem *) (ctrl->io_map_base + port); } -/* - * Create a virtual mapping cookie for a PCI BAR (memory or IO) - */ -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map_pci(dev, start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - /* What? */ - return NULL; -} - -EXPORT_SYMBOL(pci_iomap); - void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { iounmap(addr); -- cgit v1.2.3 From 629a858160751b670e1376dab4788f0c84138cc6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 21:11:16 +0200 Subject: parisc: switch to GENERIC_PCI_IOMAP parisc copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. Signed-off-by: Michael S. Tsirkin --- arch/parisc/Kconfig | 1 + arch/parisc/lib/iomap.c | 23 ----------------------- 2 files changed, 1 insertion(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index fdfd8be29e95..242a1b7ac759 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -14,6 +14,7 @@ config PARISC select GENERIC_ATOMIC64 if !64BIT select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE + select GENERIC_PCI_IOMAP select IRQ_PER_CPU select ARCH_HAVE_NMI_SAFE_CMPXCHG diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c index 8f470c93b16d..fb8e10a4fb39 100644 --- a/arch/parisc/lib/iomap.c +++ b/arch/parisc/lib/iomap.c @@ -436,28 +436,6 @@ void ioport_unmap(void __iomem *addr) } } -/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - /* What? */ - return NULL; -} - void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { if (!INDIRECT_ADDR(addr)) { @@ -483,5 +461,4 @@ EXPORT_SYMBOL(iowrite16_rep); EXPORT_SYMBOL(iowrite32_rep); EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); -EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); -- cgit v1.2.3 From 335b8cf7c383c5589d29addd7c4149741a4014b9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 21:06:41 +0200 Subject: powerpc: switch to GENERIC_PCI_IOMAP powerpc copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. The only difference is handling of nocache flag, that turns out to be done correctly by the generic code since arch/powerpc/include/asm/io.h defines ioremap_nocache same as ioremap. Signed-off-by: Michael S. Tsirkin --- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/iomap.c | 19 ------------------- 2 files changed, 1 insertion(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 951e18f5335b..6ffe3df3e57c 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -710,6 +710,7 @@ config PCI default PCI_PERMEDIA if !4xx && !CPM2 && !8xx default PCI_QSPAN if !4xx && !CPM2 && 8xx select ARCH_SUPPORTS_MSI + select GENERIC_PCI_IOMAP help Find out whether your system includes a PCI bus. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c index 262791807397..97a3715ac8bd 100644 --- a/arch/powerpc/kernel/iomap.c +++ b/arch/powerpc/kernel/iomap.c @@ -119,24 +119,6 @@ EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); #ifdef CONFIG_PCI -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len) - return NULL; - if (max && len > max) - len = max; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - /* What? */ - return NULL; -} - void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { if (isa_vaddr_is_ioport(addr)) @@ -146,6 +128,5 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr) iounmap(addr); } -EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); #endif /* CONFIG_PCI */ -- cgit v1.2.3 From 43db595e8b5d78ce5ad2feab719814a76e3ad2e5 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 21:10:12 +0200 Subject: sh: switch to GENERIC_PCI_IOMAP sh copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. Signed-off-by: Michael S. Tsirkin --- arch/sh/Kconfig | 1 + arch/sh/drivers/pci/pci.c | 23 ----------------------- 2 files changed, 1 insertion(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5aeab58ac8be..ead164080cf5 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -857,6 +857,7 @@ config PCI bool "PCI support" depends on SYS_SUPPORTS_PCI select PCI_DOMAINS + select GENERIC_PCI_IOMAP help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c2691afe8f79..11aaf2fdec84 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -393,29 +393,6 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev, return (void __iomem *)(chan->io_map_base + port); } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (unlikely(!len || !start)) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - - if (flags & IORESOURCE_IO) - return ioport_map_pci(dev, start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { iounmap(addr); -- cgit v1.2.3 From 619d4a4b40f44c1b45263a0e0c9598e3139a1fec Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 13 Nov 2011 13:00:58 +0800 Subject: ARM: at91: switch gpio clock to clkdev Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre --- arch/arm/mach-at91/at91cap9.c | 8 ++++---- arch/arm/mach-at91/at91rm9200.c | 8 ++++---- arch/arm/mach-at91/at91sam9260.c | 6 +++--- arch/arm/mach-at91/at91sam9261.c | 6 +++--- arch/arm/mach-at91/at91sam9263.c | 10 +++++----- arch/arm/mach-at91/at91sam9g45.c | 10 +++++----- arch/arm/mach-at91/at91sam9rl.c | 8 ++++---- arch/arm/mach-at91/generic.h | 1 - arch/arm/mach-at91/gpio.c | 23 +++++++++++++++-------- 9 files changed, 43 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index dcfa8af845ab..f7f7e1ea2d1f 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -222,6 +222,10 @@ static struct clk_lookup periph_clocks_lookups[] = { 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[] = { @@ -298,19 +302,15 @@ static struct at91_gpio_bank at91cap9_gpio[] = { { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOA, - .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOB, - .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOC, - .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOD, - .clock = &pioABCD_clk, } }; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index c06c14fecba4..7470f6381752 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -196,6 +196,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_ID("pioD", &pioD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -273,19 +277,15 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { { .id = AT91RM9200_ID_PIOA, .regbase = AT91RM9200_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91RM9200_ID_PIOB, .regbase = AT91RM9200_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91RM9200_ID_PIOC, .regbase = AT91RM9200_BASE_PIOC, - .clock = &pioC_clk, }, { .id = AT91RM9200_ID_PIOD, .regbase = AT91RM9200_BASE_PIOD, - .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index e94cc2268461..943da2100cdc 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -210,6 +210,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -275,15 +278,12 @@ static struct at91_gpio_bank at91sam9260_gpio[] = { { .id = AT91SAM9260_ID_PIOA, .regbase = AT91SAM9260_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9260_ID_PIOB, .regbase = AT91SAM9260_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9260_ID_PIOC, .regbase = AT91SAM9260_BASE_PIOC, - .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 80e3e0fac6b1..dd7924c996fc 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -175,6 +175,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -254,15 +257,12 @@ static struct at91_gpio_bank at91sam9261_gpio[] = { { .id = AT91SAM9261_ID_PIOA, .regbase = AT91SAM9261_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9261_ID_PIOB, .regbase = AT91SAM9261_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9261_ID_PIOC, .regbase = AT91SAM9261_BASE_PIOC, - .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 5c14b22928a8..5a7474174593 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -192,6 +192,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioCDE_clk), + CLKDEV_CON_ID("pioD", &pioCDE_clk), + CLKDEV_CON_ID("pioE", &pioCDE_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -268,23 +273,18 @@ static struct at91_gpio_bank at91sam9263_gpio[] = { { .id = AT91SAM9263_ID_PIOA, .regbase = AT91SAM9263_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9263_ID_PIOB, .regbase = AT91SAM9263_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9263_ID_PIOCDE, .regbase = AT91SAM9263_BASE_PIOC, - .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, .regbase = AT91SAM9263_BASE_PIOD, - .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, .regbase = AT91SAM9263_BASE_PIOE, - .clock = &pioCDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index c0c9fa7b73f0..4bb0bf00b3a4 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -232,6 +232,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_ID("pioD", &pioDE_clk), + CLKDEV_CON_ID("pioE", &pioDE_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -298,23 +303,18 @@ static struct at91_gpio_bank at91sam9g45_gpio[] = { { .id = AT91SAM9G45_ID_PIOA, .regbase = AT91SAM9G45_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9G45_ID_PIOB, .regbase = AT91SAM9G45_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9G45_ID_PIOC, .regbase = AT91SAM9G45_BASE_PIOC, - .clock = &pioC_clk, }, { .id = AT91SAM9G45_ID_PIODE, .regbase = AT91SAM9G45_BASE_PIOD, - .clock = &pioDE_clk, }, { .id = AT91SAM9G45_ID_PIODE, .regbase = AT91SAM9G45_BASE_PIOE, - .clock = &pioDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 6856badc518b..60555d4738f8 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -183,6 +183,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_ID("pioD", &pioD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -246,19 +250,15 @@ static struct at91_gpio_bank at91sam9rl_gpio[] = { { .id = AT91SAM9RL_ID_PIOA, .regbase = AT91SAM9RL_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9RL_ID_PIOB, .regbase = AT91SAM9RL_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9RL_ID_PIOC, .regbase = AT91SAM9RL_BASE_PIOC, - .clock = &pioC_clk, }, { .id = AT91SAM9RL_ID_PIOD, .regbase = AT91SAM9RL_BASE_PIOD, - .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index bc1776406f42..40309588f360 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -70,7 +70,6 @@ extern void at91_ioremap_shdwc(u32 base_addr); struct at91_gpio_bank { unsigned short id; /* peripheral ID */ unsigned long regbase; /* offset from system peripheral base */ - struct clk *clock; /* associated clock */ }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index cedb753f4cad..4059f07eb955 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -31,6 +31,7 @@ struct at91_gpio_chip { struct at91_gpio_chip *next; /* Bank sharing same clock */ struct at91_gpio_bank *bank; /* Bank definition */ void __iomem *regbase; /* Base of register bank */ + struct clk *clock; /* associated clock */ }; #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) @@ -58,11 +59,11 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32), - AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32), - AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32), - AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32), - AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioA", 0x00 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioB", 0x20 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioC", 0x40 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioD", 0x60 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioE", 0x80 + PIN_BASE, 32), }; static int gpio_banks; @@ -302,7 +303,7 @@ void at91_gpio_suspend(void) __raw_writel(wakeups[i], pio + PIO_IER); if (!wakeups[i]) - clk_disable(gpio_chip[i].bank->clock); + clk_disable(gpio_chip[i].clock); else { #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); @@ -319,7 +320,7 @@ void at91_gpio_resume(void) void __iomem *pio = gpio_chip[i].regbase; if (!wakeups[i]) - clk_enable(gpio_chip[i].bank->clock); + clk_enable(gpio_chip[i].clock); __raw_writel(wakeups[i], pio + PIO_IDR); __raw_writel(backups[i], pio + PIO_IER); @@ -621,8 +622,14 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) 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->bank->clock); + clk_enable(at91_gpio->clock); /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ if (last && last->bank->id == at91_gpio->bank->id) -- cgit v1.2.3 From 1a2d9156b5fc92b40aa2ffbc2fdf6d88bbf74f3a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 17 Oct 2011 14:28:38 +0800 Subject: ARM: at91: gpio make struct at91_gpio_bank an initdata this will simplify the switch to the DT and later to the platform_device Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91cap9.c | 2 +- arch/arm/mach-at91/at91rm9200.c | 2 +- arch/arm/mach-at91/at91sam9260.c | 2 +- arch/arm/mach-at91/at91sam9261.c | 2 +- arch/arm/mach-at91/at91sam9263.c | 2 +- arch/arm/mach-at91/at91sam9g45.c | 2 +- arch/arm/mach-at91/at91sam9rl.c | 2 +- arch/arm/mach-at91/gpio.c | 12 ++++++------ 8 files changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index f7f7e1ea2d1f..506a26c3fff6 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -298,7 +298,7 @@ void __init at91cap9_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91cap9_gpio[] = { +static struct at91_gpio_bank at91cap9_gpio[] __initdata = { { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 7470f6381752..9163d7d5f76e 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -273,7 +273,7 @@ void __init at91rm9200_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91rm9200_gpio[] = { +static struct at91_gpio_bank at91rm9200_gpio[] __initdata = { { .id = AT91RM9200_ID_PIOA, .regbase = AT91RM9200_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 943da2100cdc..3f6c6a12480d 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -274,7 +274,7 @@ void __init at91sam9260_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9260_gpio[] = { +static struct at91_gpio_bank at91sam9260_gpio[] __initdata = { { .id = AT91SAM9260_ID_PIOA, .regbase = AT91SAM9260_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index dd7924c996fc..a0538c5c2520 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -253,7 +253,7 @@ void __init at91sam9261_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9261_gpio[] = { +static struct at91_gpio_bank at91sam9261_gpio[] __initdata = { { .id = AT91SAM9261_ID_PIOA, .regbase = AT91SAM9261_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 5a7474174593..5ffbbb024c1e 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -269,7 +269,7 @@ void __init at91sam9263_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9263_gpio[] = { +static struct at91_gpio_bank at91sam9263_gpio[] __initdata = { { .id = AT91SAM9263_ID_PIOA, .regbase = AT91SAM9263_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 4bb0bf00b3a4..f61eb64e6b39 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -299,7 +299,7 @@ void __init at91sam9g45_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9g45_gpio[] = { +static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = { { .id = AT91SAM9G45_ID_PIOA, .regbase = AT91SAM9G45_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 60555d4738f8..96247f68b9d2 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -246,7 +246,7 @@ void __init at91sam9rl_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9rl_gpio[] = { +static struct at91_gpio_bank at91sam9rl_gpio[] __initdata = { { .id = AT91SAM9RL_ID_PIOA, .regbase = AT91SAM9RL_BASE_PIOA, diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 4059f07eb955..163c724882c2 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -29,7 +29,7 @@ struct at91_gpio_chip { struct gpio_chip chip; struct at91_gpio_chip *next; /* Bank sharing same clock */ - struct at91_gpio_bank *bank; /* Bank definition */ + int id; /* ID of register bank */ void __iomem *regbase; /* Base of register bank */ struct clk *clock; /* associated clock */ }; @@ -286,7 +286,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state) else wakeups[bank] &= ~mask; - irq_set_irq_wake(gpio_chip[bank].bank->id, state); + irq_set_irq_wake(gpio_chip[bank].id, state); return 0; } @@ -498,7 +498,7 @@ void __init at91_gpio_irq_setup(void) for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL; pioc++ < gpio_banks; prev = this, this++) { - unsigned id = this->bank->id; + unsigned id = this->id; unsigned i; __raw_writel(~0, this->regbase + PIO_IDR); @@ -613,10 +613,10 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) for (i = 0; i < nr_banks; i++) { at91_gpio = &gpio_chip[i]; - at91_gpio->bank = &data[i]; + at91_gpio->id = data[i].id; at91_gpio->chip.base = PIN_BASE + i * 32; - at91_gpio->regbase = ioremap(at91_gpio->bank->regbase, 512); + 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; @@ -632,7 +632,7 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) clk_enable(at91_gpio->clock); /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ - if (last && last->bank->id == at91_gpio->bank->id) + if (last && last->id == at91_gpio->id) last->next = at91_gpio; last = at91_gpio; -- cgit v1.2.3 From 63b4c2967850033de0a488d2ba7cd09052199d99 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 25 Nov 2011 01:51:06 +0800 Subject: ARM: at91/boards: use -EINVAL for invalid gpio this will allow to use gpio_is_valid Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre --- arch/arm/mach-at91/board-1arm.c | 2 ++ arch/arm/mach-at91/board-afeb-9260v1.c | 8 +++++++- arch/arm/mach-at91/board-cam60.c | 4 +++- arch/arm/mach-at91/board-cap9adk.c | 15 +++++++++------ arch/arm/mach-at91/board-carmeva.c | 7 +++++-- arch/arm/mach-at91/board-cpu9krea.c | 8 +++++++- arch/arm/mach-at91/board-cpuat91.c | 5 +++++ arch/arm/mach-at91/board-csb337.c | 5 ++++- arch/arm/mach-at91/board-csb637.c | 2 ++ arch/arm/mach-at91/board-dt.c | 1 + arch/arm/mach-at91/board-eb9200.c | 9 +++++++-- arch/arm/mach-at91/board-ecbat91.c | 5 +++++ arch/arm/mach-at91/board-eco920.c | 5 +++++ arch/arm/mach-at91/board-flexibity.c | 5 ++++- arch/arm/mach-at91/board-foxg20.c | 7 ++++++- arch/arm/mach-at91/board-gsia18s.c | 5 ++++- arch/arm/mach-at91/board-kafa.c | 2 ++ arch/arm/mach-at91/board-kb9202.c | 6 +++++- arch/arm/mach-at91/board-neocore926.c | 5 ++++- arch/arm/mach-at91/board-pcontrol-g20.c | 2 ++ arch/arm/mach-at91/board-picotux200.c | 3 +++ arch/arm/mach-at91/board-qil-a9260.c | 12 +++++++----- arch/arm/mach-at91/board-rm9200dk.c | 11 ++++++++--- arch/arm/mach-at91/board-rm9200ek.c | 3 +++ arch/arm/mach-at91/board-rsi-ews.c | 2 ++ arch/arm/mach-at91/board-sam9-l9260.c | 8 +++++--- arch/arm/mach-at91/board-sam9260ek.c | 12 +++++++----- arch/arm/mach-at91/board-sam9261ek.c | 9 +++++++-- arch/arm/mach-at91/board-sam9263ek.c | 8 +++++--- arch/arm/mach-at91/board-sam9g20ek.c | 9 ++++++++- arch/arm/mach-at91/board-sam9m10g45ek.c | 4 ++++ arch/arm/mach-at91/board-sam9rlek.c | 7 ++++--- arch/arm/mach-at91/board-snapper9260.c | 6 ++++++ arch/arm/mach-at91/board-stamp9g20.c | 12 ++++++++++-- arch/arm/mach-at91/board-usb-a926x.c | 6 ++++-- arch/arm/mach-at91/board-yl-9200.c | 7 +++++-- arch/arm/mach-at91/include/mach/board.h | 28 ++++++++++++++-------------- include/linux/platform_data/macb.h | 2 +- 38 files changed, 192 insertions(+), 65 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index a60d98d7c3e2..2628384aaae1 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c @@ -70,6 +70,8 @@ static struct macb_platform_data __initdata onearm_eth_data = { static struct at91_usbh_data __initdata onearm_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata onearm_udc_data = { diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 17fc77925707..3bb40694b02d 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -75,6 +75,8 @@ static void __init afeb9260_init_early(void) */ static struct at91_usbh_data __initdata afeb9260_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -82,7 +84,7 @@ static struct at91_usbh_data __initdata afeb9260_usbh_data = { */ static struct at91_udc_data __initdata afeb9260_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -138,6 +140,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = { .bus_width_16 = 0, .parts = afeb9260_nand_partition, .num_parts = ARRAY_SIZE(afeb9260_nand_partition), + .det_pin = -EINVAL, }; @@ -149,6 +152,7 @@ static struct at91_mmc_data __initdata afeb9260_mmc_data = { .wp_pin = AT91_PIN_PC4, .slot_b = 1, .wire4 = 1, + .vcc_pin = -EINVAL, }; @@ -169,6 +173,8 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = { static struct at91_cf_data afeb9260_cf_data = { .chipselect = 4, .irq_pin = AT91_PIN_PA6, + .det_pin = -EINVAL, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PA7, .flags = AT91_CF_TRUE_IDE, }; diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index 18c90c454079..8510e9e54988 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -62,6 +62,8 @@ static void __init cam60_init_early(void) */ static struct at91_usbh_data __initdata cam60_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -135,7 +137,7 @@ static struct mtd_partition __initdata cam60_nand_partition[] = { static struct atmel_nand_data __initdata cam60_nand_data = { .ale = 21, .cle = 22, - // .det_pin = ... not there + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA9, .enable_pin = AT91_PIN_PA7, .parts = cam60_nand_partition, diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 14d1d0556638..ac3de4f7c31d 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -70,6 +70,8 @@ static void __init cap9adk_init_early(void) */ static struct at91_usbh_data __initdata cap9adk_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -144,9 +146,9 @@ static struct spi_board_info cap9adk_spi_devices[] = { */ static struct at91_mmc_data __initdata cap9adk_mmc_data = { .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; @@ -154,6 +156,7 @@ static struct at91_mmc_data __initdata cap9adk_mmc_data = { * MACB Ethernet device */ static struct macb_platform_data __initdata cap9adk_macb_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; @@ -172,8 +175,8 @@ static struct mtd_partition __initdata cap9adk_nand_partitions[] = { static struct atmel_nand_data __initdata cap9adk_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected -// .rdy_pin = ... not connected + .det_pin = -EINVAL, + .rdy_pin = -EINVAL, .enable_pin = AT91_PIN_PD15, .parts = cap9adk_nand_partitions, .num_parts = ARRAY_SIZE(cap9adk_nand_partitions), @@ -351,7 +354,7 @@ static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data; * AC97 */ static struct ac97c_platform_data cap9adk_ac97_data = { -// .reset_pin = ... not connected + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index 529b356cdb7d..59d9cf997537 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -64,6 +64,8 @@ static struct macb_platform_data __initdata carmeva_eth_data = { static struct at91_usbh_data __initdata carmeva_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata carmeva_udc_data = { @@ -75,8 +77,8 @@ static struct at91_udc_data __initdata carmeva_udc_data = { // static struct at91_cf_data __initdata carmeva_cf_data = { // .det_pin = AT91_PIN_PB0, // .rst_pin = AT91_PIN_PC5, - // .irq_pin = ... not connected - // .vcc_pin = ... always powered + // .irq_pin = -EINVAL, + // .vcc_pin = -EINVAL, // }; static struct at91_mmc_data __initdata carmeva_mmc_data = { @@ -84,6 +86,7 @@ static struct at91_mmc_data __initdata carmeva_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PB10, .wp_pin = AT91_PIN_PC14, + .vcc_pin = -EINVAL, }; static struct spi_board_info carmeva_spi_devices[] = { diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 5b55525e2966..9ab3d1ea326d 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -86,6 +86,8 @@ static void __init cpu9krea_init_early(void) */ static struct at91_usbh_data __initdata cpu9krea_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -93,13 +95,14 @@ static struct at91_usbh_data __initdata cpu9krea_usbh_data = { */ static struct at91_udc_data __initdata cpu9krea_udc_data = { .vbus_pin = AT91_PIN_PC8, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* * MACB Ethernet device */ static struct macb_platform_data __initdata cpu9krea_macb_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; @@ -112,6 +115,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = { .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, + .det_pin = -EINVAL, }; #ifdef CONFIG_MACH_CPU9260 @@ -337,6 +341,8 @@ static struct at91_mmc_data __initdata cpu9krea_mmc_data = { .slot_b = 0, .wire4 = 1, .det_pin = AT91_PIN_PA29, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static void __init cpu9krea_board_init(void) diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index 7a4c82e8da51..368e1427ad99 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -83,11 +83,14 @@ static void __init cpuat91_init_early(void) } static struct macb_platform_data __initdata cpuat91_eth_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; static struct at91_usbh_data __initdata cpuat91_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata cpuat91_udc_data = { @@ -98,6 +101,8 @@ static struct at91_udc_data __initdata cpuat91_udc_data = { static struct at91_mmc_data __initdata cpuat91_mmc_data = { .det_pin = AT91_PIN_PC2, .wire4 = 1, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct physmap_flash_data cpuat91_flash_data = { diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index b004b20b8e42..1a1547b1ce4e 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c @@ -65,11 +65,13 @@ static struct macb_platform_data __initdata csb337_eth_data = { static struct at91_usbh_data __initdata csb337_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata csb337_udc_data = { - // this has no VBUS sensing pin .pullup_pin = AT91_PIN_PA24, + .vbus_pin = -EINVAL, }; static struct i2c_board_info __initdata csb337_i2c_devices[] = { @@ -98,6 +100,7 @@ static struct at91_mmc_data __initdata csb337_mmc_data = { .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PD6, + .vcc_pin = -EINVAL, }; static struct spi_board_info csb337_spi_devices[] = { diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index e966de5219c7..f650bf39455d 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c @@ -59,6 +59,8 @@ static struct macb_platform_data __initdata csb637_eth_data = { static struct at91_usbh_data __initdata csb637_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata csb637_udc_data = { diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index 41d84d9a2316..bb6b434ec0c1 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -50,6 +50,7 @@ static void __init ek_init_early(void) 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, }; diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c index 3788fa527121..d302ca3eeb64 100644 --- a/arch/arm/mach-at91/board-eb9200.c +++ b/arch/arm/mach-at91/board-eb9200.c @@ -67,6 +67,8 @@ static struct macb_platform_data __initdata eb9200_eth_data = { static struct at91_usbh_data __initdata eb9200_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata eb9200_udc_data = { @@ -75,15 +77,18 @@ static struct at91_udc_data __initdata eb9200_udc_data = { }; static struct at91_cf_data __initdata eb9200_cf_data = { + .irq_pin = -EINVAL, .det_pin = AT91_PIN_PB0, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PC5, - // .irq_pin = ... not connected - // .vcc_pin = ... always powered }; static struct at91_mmc_data __initdata eb9200_mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct i2c_board_info __initdata eb9200_i2c_devices[] = { diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index af7622eae1a9..69966ce4d776 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -71,11 +71,16 @@ static struct macb_platform_data __initdata ecb_at91eth_data = { static struct at91_usbh_data __initdata ecb_at91usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_mmc_data __initdata ecb_at91mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index 8e75867d1d18..07ef35b0ec2c 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -54,6 +54,8 @@ static struct macb_platform_data __initdata eco920_eth_data = { static struct at91_usbh_data __initdata eco920_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata eco920_udc_data = { @@ -64,6 +66,9 @@ static struct at91_udc_data __initdata eco920_udc_data = { static struct at91_mmc_data __initdata eco920_mmc_data = { .slot_b = 0, .wire4 = 0, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct physmap_flash_data eco920_flash_data = { diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index 4c3f65d9c59b..eec02cd57ced 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c @@ -52,12 +52,14 @@ static void __init flexibity_init_early(void) /* USB Host port */ static struct at91_usbh_data __initdata flexibity_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* USB Device port */ static struct at91_udc_data __initdata flexibity_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* SPI devices */ @@ -76,6 +78,7 @@ static struct at91_mmc_data __initdata flexibity_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PC9, .wp_pin = AT91_PIN_PC4, + .vcc_pin = -EINVAL, }; /* LEDs */ diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index de8e09642f4e..caf017f0f4ee 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c @@ -106,6 +106,8 @@ static void __init foxg20_init_early(void) */ static struct at91_usbh_data __initdata foxg20_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -113,7 +115,7 @@ static struct at91_usbh_data __initdata foxg20_usbh_data = { */ static struct at91_udc_data __initdata foxg20_udc_data = { .vbus_pin = AT91_PIN_PC6, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -147,6 +149,9 @@ static struct macb_platform_data __initdata foxg20_macb_data = { static struct at91_mmc_data __initdata foxg20_mmc_data = { .slot_b = 1, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index 51c82f151119..230e71969fb7 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -80,6 +80,8 @@ static void __init gsia18s_init_early(void) */ static struct at91_usbh_data __initdata usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -87,7 +89,7 @@ static struct at91_usbh_data __initdata usbh_data = { */ static struct at91_udc_data __initdata udc_data = { .vbus_pin = AT91_PIN_PA22, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* @@ -530,6 +532,7 @@ static struct i2c_board_info __initdata gsia18s_i2c_devices[] = { static struct at91_cf_data __initdata gsia18s_cf1_data = { .irq_pin = AT91_PIN_PA27, .det_pin = AT91_PIN_PB30, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PB31, .chipselect = 5, .flags = AT91_CF_TRUE_IDE, diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c index 9628a3defcf4..efde1b2327c8 100644 --- a/arch/arm/mach-at91/board-kafa.c +++ b/arch/arm/mach-at91/board-kafa.c @@ -68,6 +68,8 @@ static struct macb_platform_data __initdata kafa_eth_data = { static struct at91_usbh_data __initdata kafa_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata kafa_udc_data = { diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index 5ba5244cb632..d75a4a2ad9c2 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -76,6 +76,8 @@ static struct macb_platform_data __initdata kb9202_eth_data = { static struct at91_usbh_data __initdata kb9202_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata kb9202_udc_data = { @@ -87,6 +89,8 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = { .det_pin = AT91_PIN_PB2, .slot_b = 0, .wire4 = 1, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct mtd_partition __initdata kb9202_nand_partition[] = { @@ -100,7 +104,7 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = { static struct atmel_nand_data __initdata kb9202_nand_data = { .ale = 22, .cle = 21, - // .det_pin = ... not there + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC29, .enable_pin = AT91_PIN_PC28, .parts = kb9202_nand_partition, diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index 7d24d84f5d50..3f8617c0e04e 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -72,6 +72,7 @@ static void __init neocore926_init_early(void) static struct at91_usbh_data __initdata neocore926_usbh_data = { .ports = 2, .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -79,7 +80,7 @@ static struct at91_usbh_data __initdata neocore926_usbh_data = { */ static struct at91_udc_data __initdata neocore926_udc_data = { .vbus_pin = AT91_PIN_PA25, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -149,6 +150,7 @@ static struct at91_mmc_data __initdata neocore926_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PE18, .wp_pin = AT91_PIN_PE19, + .vcc_pin = -EINVAL, }; @@ -190,6 +192,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = { .enable_pin = AT91_PIN_PD15, .parts = neocore926_nand_partition, .num_parts = ARRAY_SIZE(neocore926_nand_partition), + .det_pin = -EINVAL, }; static struct sam9_smc_config __initdata neocore926_nand_smc_config = { diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 9a6e02163950..b4a12fc184c8 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -107,6 +107,8 @@ static void __init add_device_pcontrol(void) */ static struct at91_usbh_data __initdata usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index dc18759a24b4..ab024fa11d5c 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -67,6 +67,8 @@ static struct macb_platform_data __initdata picotux200_eth_data = { static struct at91_usbh_data __initdata picotux200_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_mmc_data __initdata picotux200_mmc_data = { @@ -74,6 +76,7 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = { .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PA17, + .vcc_pin = -EINVAL, }; #define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 04be42798128..e029d220cb84 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -77,6 +77,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -84,7 +86,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* @@ -133,7 +135,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -172,9 +174,9 @@ static void __init ek_add_device_nand(void) static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 0, .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; /* diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 022d0cebda9d..782f37946af5 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -72,6 +72,8 @@ static struct macb_platform_data __initdata dk_eth_data = { static struct at91_usbh_data __initdata dk_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata dk_udc_data = { @@ -80,16 +82,19 @@ static struct at91_udc_data __initdata dk_udc_data = { }; static struct at91_cf_data __initdata dk_cf_data = { + .irq_pin = -EINVAL, .det_pin = AT91_PIN_PB0, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PC5, - // .irq_pin = ... not connected - // .vcc_pin = ... always powered }; #ifndef CONFIG_MTD_AT91_DATAFLASH_CARD static struct at91_mmc_data __initdata dk_mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif @@ -143,7 +148,7 @@ static struct atmel_nand_data __initdata dk_nand_data = { .cle = 21, .det_pin = AT91_PIN_PB1, .rdy_pin = AT91_PIN_PC2, - // .enable_pin = ... not there + .enable_pin = -EINVAL, .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 ed275861adef..ef7c12a92246 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -72,6 +72,8 @@ static struct macb_platform_data __initdata ek_eth_data = { static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata ek_udc_data = { @@ -85,6 +87,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PA17, + .vcc_pin = -EINVAL, }; #endif diff --git a/arch/arm/mach-at91/board-rsi-ews.c b/arch/arm/mach-at91/board-rsi-ews.c index ed3b21f77674..af0750fafa29 100644 --- a/arch/arm/mach-at91/board-rsi-ews.c +++ b/arch/arm/mach-at91/board-rsi-ews.c @@ -70,6 +70,8 @@ static struct macb_platform_data rsi_ews_eth_data __initdata = { */ static struct at91_usbh_data rsi_ews_usbh_data __initdata = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 1e1834b2b4c3..84bce587735f 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -72,6 +72,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -79,7 +81,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -134,7 +136,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -176,7 +178,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PC8, .wp_pin = AT91_PIN_PC4, -// .vcc_pin = ... not connected + .vcc_pin = -EINVAL, }; static void __init ek_board_init(void) diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index e1b250ed0ca8..be8233bcabdc 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -75,6 +75,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -82,7 +84,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -176,7 +178,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -223,9 +225,9 @@ static void __init ek_add_device_nand(void) static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 1, .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index a879b3398f38..40895072a1a7 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -151,6 +151,8 @@ static void __init ek_add_device_dm9000(void) {} */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -159,7 +161,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PB29, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -182,7 +184,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 22, .cle = 21, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC15, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -345,6 +347,9 @@ static struct spi_board_info ek_spi_devices[] = { */ static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif /* CONFIG_SPI_ATMEL_* */ diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 3ce0b17bd9ed..29f66052fe63 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 }, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -81,7 +82,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PA25, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -151,7 +152,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PE18, .wp_pin = AT91_PIN_PE19, -// .vcc_pin = ... not connected + .vcc_pin = -EINVAL, }; @@ -183,7 +184,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, .parts = ek_nand_partition, @@ -353,6 +354,7 @@ static void __init ek_add_device_buttons(void) {} * reset_pin is not connected: NRST */ static struct ac97c_platform_data ek_ac97_data = { + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index a67b269a2fce..843d6286c6f4 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -86,6 +86,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -93,7 +95,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -163,6 +165,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { .cle = 22, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, + .det_pin = -EINVAL, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; @@ -210,6 +213,7 @@ static struct mci_platform_data __initdata ek_mmc_data = { .slot[1] = { .bus_width = 4, .detect_pin = AT91_PIN_PC9, + .wp_pin = -EINVAL, }, }; @@ -218,6 +222,8 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 1, /* Only one slot so use slot B */ .wire4 = 1, .det_pin = AT91_PIN_PC9, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif @@ -227,6 +233,7 @@ static void __init ek_add_device_mmc(void) if (ek_have_2mmc()) { ek_mmc_data.slot[0].bus_width = 4; ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2; + ek_mmc_data.slot[0].wp_pin = -1; } at91_add_device_mci(0, &ek_mmc_data); #else diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 061465daa1f8..ea0d1b9c2b7b 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -69,6 +69,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}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -100,6 +101,7 @@ static struct mci_platform_data __initdata mci0_data = { .slot[0] = { .bus_width = 4, .detect_pin = AT91_PIN_PD10, + .wp_pin = -EINVAL, }, }; @@ -143,6 +145,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { .cle = 22, .rdy_pin = AT91_PIN_PC8, .enable_pin = AT91_PIN_PC14, + .det_pin = -EINVAL, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; @@ -330,6 +333,7 @@ static void __init ek_add_device_buttons(void) {} * reset_pin is not connected: NRST */ static struct ac97c_platform_data ek_ac97_data = { + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index c561edac25b9..c1366d0032bf 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -67,8 +67,8 @@ static struct usba_platform_data __initdata ek_usba_udc_data = { static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PA15, -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; @@ -91,7 +91,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PD17, .enable_pin = AT91_PIN_PB6, .parts = ek_nand_partition, @@ -204,6 +204,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data; * reset_pin is not connected: NRST */ static struct ac97c_platform_data ek_ac97_data = { + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 73ed8c746085..4770db08e5a6 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -57,15 +57,19 @@ static void __init snapper9260_init_early(void) static struct at91_usbh_data __initdata snapper9260_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata snapper9260_udc_data = { .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5), .vbus_active_low = 1, .vbus_polled = 1, + .pullup_pin = -EINVAL, }; static struct macb_platform_data snapper9260_macb_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; @@ -104,6 +108,8 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = { .parts = snapper9260_nand_partitions, .num_parts = ARRAY_SIZE(snapper9260_nand_partitions), .bus_width_16 = 0, + .enable_pin = -EINVAL, + .det_pin = -EINVAL, }; static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index f4b9b6f2b594..e8d3d5b88244 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -85,6 +85,7 @@ static struct atmel_nand_data __initdata nand_data = { .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, + .det_pin = -EINVAL, }; static struct sam9_smc_config __initdata nand_smc_config = { @@ -122,12 +123,17 @@ static void __init add_device_nand(void) static struct mci_platform_data __initdata mmc_data = { .slot[0] = { .bus_width = 4, + .detect_pin = -1; + .wp_pin = -1; }, }; #else static struct at91_mmc_data __initdata mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif @@ -137,6 +143,8 @@ static struct at91_mmc_data __initdata mmc_data = { */ static struct at91_usbh_data __initdata usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -145,12 +153,12 @@ static struct at91_usbh_data __initdata usbh_data = { */ static struct at91_udc_data __initdata portuxg20_udc_data = { .vbus_pin = AT91_PIN_PC7, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; static struct at91_udc_data __initdata stamp9g20evb_udc_data = { .vbus_pin = AT91_PIN_PA22, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 2ffb2c84c7ce..26c36fc2d1e5 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -66,6 +66,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -73,7 +75,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PB11, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; static void __init ek_add_device_udc(void) @@ -193,7 +195,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, .parts = ek_nand_partition, diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index 2c40a21b2794..bbd553e1cd93 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -120,6 +120,8 @@ static struct macb_platform_data __initdata yl9200_eth_data = { */ static struct at91_usbh_data __initdata yl9200_usbh_data = { .ports = 1, /* PQFP version of AT91RM9200 */ + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -137,8 +139,9 @@ static struct at91_udc_data __initdata yl9200_udc_data = { */ static struct at91_mmc_data __initdata yl9200_mmc_data = { .det_pin = AT91_PIN_PB9, - // .wp_pin = ... not connected .wire4 = 1, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; /* @@ -175,7 +178,7 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = { static struct atmel_nand_data __initdata yl9200_nand_data = { .ale = 6, .cle = 7, - // .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ .parts = yl9200_nand_partition, diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index e209a2992245..d0b377b21bd7 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -44,10 +44,10 @@ /* USB Device */ struct at91_udc_data { - u8 vbus_pin; /* high == host powering us */ + int vbus_pin; /* high == host powering us */ u8 vbus_active_low; /* vbus polarity */ u8 vbus_polled; /* Use polling, not interrupt */ - u8 pullup_pin; /* active == D+ pulled up */ + int pullup_pin; /* active == D+ pulled up */ u8 pullup_active_low; /* true == pullup_pin is active low */ }; extern void __init at91_add_device_udc(struct at91_udc_data *data); @@ -57,10 +57,10 @@ extern void __init at91_add_device_usba(struct usba_platform_data *data); /* Compact Flash */ struct at91_cf_data { - u8 irq_pin; /* I/O IRQ */ - u8 det_pin; /* Card detect */ - u8 vcc_pin; /* power switching */ - u8 rst_pin; /* card reset */ + int irq_pin; /* I/O IRQ */ + int det_pin; /* Card detect */ + int vcc_pin; /* power switching */ + int rst_pin; /* card reset */ u8 chipselect; /* EBI Chip Select number */ u8 flags; #define AT91_CF_TRUE_IDE 0x01 @@ -71,11 +71,11 @@ extern void __init at91_add_device_cf(struct at91_cf_data *data); /* MMC / SD */ /* at91_mci platform config */ struct at91_mmc_data { - u8 det_pin; /* card detect IRQ */ + int det_pin; /* card detect IRQ */ unsigned slot_b:1; /* uses Slot B */ unsigned wire4:1; /* (SD) supports DAT0..DAT3 */ - u8 wp_pin; /* (SD) writeprotect detect */ - u8 vcc_pin; /* power switching (high == on) */ + int wp_pin; /* (SD) writeprotect detect */ + int vcc_pin; /* power switching (high == on) */ }; extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); @@ -87,10 +87,10 @@ extern void __init at91_add_device_eth(struct macb_platform_data *data); /* USB Host */ struct at91_usbh_data { u8 ports; /* number of ports on root hub */ - u8 vbus_pin[2]; /* port power-control pin */ + int vbus_pin[2]; /* port power-control pin */ u8 vbus_pin_inverted; u8 overcurrent_supported; - u8 overcurrent_pin[2]; + int overcurrent_pin[2]; u8 overcurrent_status[2]; u8 overcurrent_changed[2]; }; @@ -100,9 +100,9 @@ extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); /* NAND / SmartMedia */ struct atmel_nand_data { - u8 enable_pin; /* chip enable */ - u8 det_pin; /* card detect */ - u8 rdy_pin; /* ready/busy */ + 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 */ diff --git a/include/linux/platform_data/macb.h b/include/linux/platform_data/macb.h index e7c748fb6053..b081c7245ec8 100644 --- a/include/linux/platform_data/macb.h +++ b/include/linux/platform_data/macb.h @@ -10,7 +10,7 @@ struct macb_platform_data { u32 phy_mask; - u8 phy_irq_pin; /* PHY IRQ */ + int phy_irq_pin; /* PHY IRQ */ u8 is_rmii; /* using RMII interface? */ }; -- cgit v1.2.3 From cc9f9aef6ad3ebdda911e25b38222c215f7634f9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:28:25 +0800 Subject: ARM: at91/soc: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91cap9_devices.c | 20 ++++++++++---------- arch/arm/mach-at91/at91rm9200_devices.c | 22 +++++++++++----------- arch/arm/mach-at91/at91sam9260_devices.c | 26 +++++++++++++------------- arch/arm/mach-at91/at91sam9261_devices.c | 14 +++++++------- arch/arm/mach-at91/at91sam9263_devices.c | 26 +++++++++++++------------- arch/arm/mach-at91/at91sam9g45_devices.c | 20 ++++++++++---------- arch/arm/mach-at91/at91sam9rl_devices.c | 16 ++++++++-------- 7 files changed, 72 insertions(+), 72 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 3f54eca3fca6..d298fb7cb210 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -76,7 +76,7 @@ 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 (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -179,7 +179,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) 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 && data->vbus_pin > 0) { + 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; @@ -232,7 +232,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + 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); } @@ -332,13 +332,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); if (mmc_id == 0) { /* MCI0 */ @@ -425,15 +425,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -816,7 +816,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index cb2244086113..064bbae65e5b 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -114,11 +114,11 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } - if (data->pullup_pin) + if (gpio_is_valid(data->pullup_pin)) at91_set_gpio_output(data->pullup_pin, 0); udc_data = *data; @@ -167,7 +167,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + 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); } @@ -260,7 +260,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) ); /* input/irq */ - if (data->irq_pin) { + if (gpio_is_valid(data->irq_pin)) { at91_set_gpio_input(data->irq_pin, 1); at91_set_deglitch(data->irq_pin, 1); } @@ -268,7 +268,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_set_deglitch(data->det_pin, 1); /* outputs, initially off */ - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); at91_set_gpio_output(data->rst_pin, 0); @@ -328,13 +328,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -419,15 +419,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) ); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index f6d8ccf42a8d..f9bcb251e338 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -115,7 +115,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } @@ -168,7 +168,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + 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); } @@ -243,13 +243,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -330,11 +330,11 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { if (data->slot[i].bus_width) { /* input/irq */ - if (data->slot[i].detect_pin) { + if (gpio_is_valid(data->slot[i].detect_pin)) { at91_set_gpio_input(data->slot[i].detect_pin, 1); at91_set_deglitch(data->slot[i].detect_pin, 1); } - if (data->slot[i].wp_pin) + if (gpio_is_valid(data->slot[i].wp_pin)) at91_set_gpio_input(data->slot[i].wp_pin, 1); switch (i) { @@ -426,15 +426,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -1290,17 +1290,17 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa); - if (data->rst_pin) { + if (gpio_is_valid(data->rst_pin)) { at91_set_multi_drive(data->rst_pin, 0); at91_set_gpio_output(data->rst_pin, 1); } - if (data->irq_pin) { + if (gpio_is_valid(data->irq_pin)) { at91_set_gpio_input(data->irq_pin, 0); at91_set_deglitch(data->irq_pin, 1); } - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 0); at91_set_deglitch(data->det_pin, 1); } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index e5cff1d902d0..dff4c2de20c7 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -118,7 +118,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } @@ -171,13 +171,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -240,15 +240,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b344ec8a9af2..a1d452b22514 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -70,7 +70,7 @@ 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 (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -123,7 +123,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } @@ -176,7 +176,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + 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); } @@ -276,13 +276,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); if (mmc_id == 0) { /* MCI0 */ @@ -430,17 +430,17 @@ void __init at91_add_device_cf(struct at91_cf_data *data) } at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->irq_pin) { + if (gpio_is_valid(data->irq_pin)) { at91_set_gpio_input(data->irq_pin, 1); at91_set_deglitch(data->irq_pin, 1); } - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) /* initially off */ at91_set_gpio_output(data->vcc_pin, 0); @@ -500,15 +500,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -749,7 +749,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index fc3eb4d9c5c9..b7582dd10dc3 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -120,7 +120,7 @@ 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 (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -181,7 +181,7 @@ 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 (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -263,7 +263,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) 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 && data->vbus_pin > 0) { + 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; @@ -316,7 +316,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + 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); } @@ -449,11 +449,11 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) /* input/irq */ - if (data->slot[0].detect_pin) { + if (gpio_is_valid(data->slot[0].detect_pin)) { at91_set_gpio_input(data->slot[0].detect_pin, 1); at91_set_deglitch(data->slot[0].detect_pin, 1); } - if (data->slot[0].wp_pin) + if (gpio_is_valid(data->slot[0].wp_pin)) at91_set_gpio_input(data->slot[0].wp_pin, 1); if (mmc_id == 0) { /* MCI0 */ @@ -556,15 +556,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -859,7 +859,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 366c1cfd4f77..61908dce9784 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -147,7 +147,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) 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 && data->vbus_pin > 0) { + 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; @@ -201,13 +201,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -275,15 +275,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */ @@ -483,7 +483,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; -- cgit v1.2.3 From d0fbda9add3281c97205649150fc99fc26148792 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 17 Sep 2011 21:49:36 +0800 Subject: ARM: at91/gpio: drop PIN_BASE Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/gpio.c | 54 +++--- arch/arm/mach-at91/include/mach/gpio.h | 336 ++++++++++++++++----------------- 2 files changed, 195 insertions(+), 195 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 163c724882c2..d000448b11ac 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -59,18 +59,17 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA", 0x00 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioB", 0x20 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioC", 0x40 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioD", 0x60 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioE", 0x80 + PIN_BASE, 32), + 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), }; static int gpio_banks; static inline void __iomem *pin_to_controller(unsigned pin) { - pin -= PIN_BASE; pin /= 32; if (likely(pin < gpio_banks)) return gpio_chip[pin].regbase; @@ -80,7 +79,6 @@ static inline void __iomem *pin_to_controller(unsigned pin) static inline unsigned pin_to_mask(unsigned pin) { - pin -= PIN_BASE; return 1 << (pin % 32); } @@ -275,8 +273,9 @@ static u32 backups[MAX_GPIO_BANKS]; static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { - unsigned mask = pin_to_mask(d->irq); - unsigned bank = (d->irq - PIN_BASE) / 32; + unsigned pin = irq_to_gpio(d->irq); + unsigned mask = pin_to_mask(pin); + unsigned bank = pin / 32; if (unlikely(bank >= MAX_GPIO_BANKS)) return -EINVAL; @@ -345,8 +344,9 @@ void at91_gpio_resume(void) static void gpio_irq_mask(struct irq_data *d) { - void __iomem *pio = pin_to_controller(d->irq); - unsigned mask = pin_to_mask(d->irq); + unsigned pin = irq_to_gpio(d->irq); + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); if (pio) __raw_writel(mask, pio + PIO_IDR); @@ -354,8 +354,9 @@ static void gpio_irq_mask(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d) { - void __iomem *pio = pin_to_controller(d->irq); - unsigned mask = pin_to_mask(d->irq); + unsigned pin = irq_to_gpio(d->irq); + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); if (pio) __raw_writel(mask, pio + PIO_IER); @@ -383,7 +384,7 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - unsigned pin; + 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); @@ -406,12 +407,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) continue; } - pin = at91_gpio->chip.base; + irq_pin = gpio_to_irq(at91_gpio->chip.base); while (isr) { if (isr & 1) - generic_handle_irq(pin); - pin++; + generic_handle_irq(irq_pin); + irq_pin++; isr >>= 1; } } @@ -439,7 +440,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused) seq_printf(s, "%i:\t", j); for (bank = 0; bank < gpio_banks; bank++) { - unsigned pin = PIN_BASE + (32 * bank) + j; + unsigned pin = (32 * bank) + j; void __iomem *pio = pin_to_controller(pin); unsigned mask = pin_to_mask(pin); @@ -492,10 +493,10 @@ static struct lock_class_key gpio_lock_class; */ void __init at91_gpio_irq_setup(void) { - unsigned pioc, pin; + unsigned pioc, irq = gpio_to_irq(0); struct at91_gpio_chip *this, *prev; - for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL; + for (pioc = 0, this = gpio_chip, prev = NULL; pioc++ < gpio_banks; prev = this, this++) { unsigned id = this->id; @@ -503,16 +504,17 @@ void __init at91_gpio_irq_setup(void) __raw_writel(~0, this->regbase + PIO_IDR); - for (i = 0, pin = this->chip.base; i < 32; i++, pin++) { - irq_set_lockdep_class(pin, &gpio_lock_class); + for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32; + i++, irq++) { + irq_set_lockdep_class(irq, &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(pin, &gpio_irqchip, + irq_set_chip_and_handler(irq, &gpio_irqchip, handle_simple_irq); - set_irq_flags(pin, IRQF_VALID); + set_irq_flags(irq, IRQF_VALID); } /* The toplevel handler handles one bank of GPIOs, except @@ -525,7 +527,7 @@ void __init at91_gpio_irq_setup(void) irq_set_chip_data(id, this); irq_set_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); + pr_info("AT91: %d gpio irqs in %d banks\n", irq, gpio_banks); } /* gpiolib support */ @@ -614,7 +616,7 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) at91_gpio = &gpio_chip[i]; at91_gpio->id = data[i].id; - at91_gpio->chip.base = PIN_BASE + i * 32; + at91_gpio->chip.base = i * 32; at91_gpio->regbase = ioremap(data[i].regbase, 512); if (!at91_gpio->regbase) { diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index 2b9a1f51210f..e3fd225121c7 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -16,177 +16,175 @@ #include #include -#define PIN_BASE NR_AIC_IRQS - #define MAX_GPIO_BANKS 5 -#define NR_BUILTIN_GPIO (PIN_BASE + (MAX_GPIO_BANKS * 32)) +#define NR_BUILTIN_GPIO (MAX_GPIO_BANKS * 32) /* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ -#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) -#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) -#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) -#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) -#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) -#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) -#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) -#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) -#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) -#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) -#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) -#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) -#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) -#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) -#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) -#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) -#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) -#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) -#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) -#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) -#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) -#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) -#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) -#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) -#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) -#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) -#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) -#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) -#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) -#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) -#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) -#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) - -#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) -#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) -#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) -#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) -#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) -#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) -#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) -#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) -#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) -#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) -#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) -#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) -#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) -#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) -#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) -#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) -#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) -#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) -#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) -#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) -#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) -#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) -#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) -#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) -#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) -#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) -#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) -#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) -#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) -#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) -#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) -#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) - -#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) -#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) -#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) -#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) -#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) -#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) -#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) -#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) -#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) -#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) -#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) -#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) -#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) -#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) -#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) -#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) -#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) -#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) -#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) -#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) -#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) -#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) -#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) -#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) -#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) -#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) -#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) -#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) -#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) -#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) -#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) -#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) - -#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) -#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) -#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) -#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) -#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) -#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) -#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) -#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) -#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) -#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) -#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) -#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) -#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) -#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) -#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) -#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) -#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) -#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) -#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) -#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) -#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) -#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) -#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) -#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) -#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) -#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) -#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) -#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) -#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) -#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) -#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) -#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) - -#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) -#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) -#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) -#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) -#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) -#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) -#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) -#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) -#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) -#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) -#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) -#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) -#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) -#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) -#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) -#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) -#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) -#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) -#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) -#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) -#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) -#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) -#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) -#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) -#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) -#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) -#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) -#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) -#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) -#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) -#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) -#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) +#define AT91_PIN_PA0 (0x00 + 0) +#define AT91_PIN_PA1 (0x00 + 1) +#define AT91_PIN_PA2 (0x00 + 2) +#define AT91_PIN_PA3 (0x00 + 3) +#define AT91_PIN_PA4 (0x00 + 4) +#define AT91_PIN_PA5 (0x00 + 5) +#define AT91_PIN_PA6 (0x00 + 6) +#define AT91_PIN_PA7 (0x00 + 7) +#define AT91_PIN_PA8 (0x00 + 8) +#define AT91_PIN_PA9 (0x00 + 9) +#define AT91_PIN_PA10 (0x00 + 10) +#define AT91_PIN_PA11 (0x00 + 11) +#define AT91_PIN_PA12 (0x00 + 12) +#define AT91_PIN_PA13 (0x00 + 13) +#define AT91_PIN_PA14 (0x00 + 14) +#define AT91_PIN_PA15 (0x00 + 15) +#define AT91_PIN_PA16 (0x00 + 16) +#define AT91_PIN_PA17 (0x00 + 17) +#define AT91_PIN_PA18 (0x00 + 18) +#define AT91_PIN_PA19 (0x00 + 19) +#define AT91_PIN_PA20 (0x00 + 20) +#define AT91_PIN_PA21 (0x00 + 21) +#define AT91_PIN_PA22 (0x00 + 22) +#define AT91_PIN_PA23 (0x00 + 23) +#define AT91_PIN_PA24 (0x00 + 24) +#define AT91_PIN_PA25 (0x00 + 25) +#define AT91_PIN_PA26 (0x00 + 26) +#define AT91_PIN_PA27 (0x00 + 27) +#define AT91_PIN_PA28 (0x00 + 28) +#define AT91_PIN_PA29 (0x00 + 29) +#define AT91_PIN_PA30 (0x00 + 30) +#define AT91_PIN_PA31 (0x00 + 31) + +#define AT91_PIN_PB0 (0x20 + 0) +#define AT91_PIN_PB1 (0x20 + 1) +#define AT91_PIN_PB2 (0x20 + 2) +#define AT91_PIN_PB3 (0x20 + 3) +#define AT91_PIN_PB4 (0x20 + 4) +#define AT91_PIN_PB5 (0x20 + 5) +#define AT91_PIN_PB6 (0x20 + 6) +#define AT91_PIN_PB7 (0x20 + 7) +#define AT91_PIN_PB8 (0x20 + 8) +#define AT91_PIN_PB9 (0x20 + 9) +#define AT91_PIN_PB10 (0x20 + 10) +#define AT91_PIN_PB11 (0x20 + 11) +#define AT91_PIN_PB12 (0x20 + 12) +#define AT91_PIN_PB13 (0x20 + 13) +#define AT91_PIN_PB14 (0x20 + 14) +#define AT91_PIN_PB15 (0x20 + 15) +#define AT91_PIN_PB16 (0x20 + 16) +#define AT91_PIN_PB17 (0x20 + 17) +#define AT91_PIN_PB18 (0x20 + 18) +#define AT91_PIN_PB19 (0x20 + 19) +#define AT91_PIN_PB20 (0x20 + 20) +#define AT91_PIN_PB21 (0x20 + 21) +#define AT91_PIN_PB22 (0x20 + 22) +#define AT91_PIN_PB23 (0x20 + 23) +#define AT91_PIN_PB24 (0x20 + 24) +#define AT91_PIN_PB25 (0x20 + 25) +#define AT91_PIN_PB26 (0x20 + 26) +#define AT91_PIN_PB27 (0x20 + 27) +#define AT91_PIN_PB28 (0x20 + 28) +#define AT91_PIN_PB29 (0x20 + 29) +#define AT91_PIN_PB30 (0x20 + 30) +#define AT91_PIN_PB31 (0x20 + 31) + +#define AT91_PIN_PC0 (0x40 + 0) +#define AT91_PIN_PC1 (0x40 + 1) +#define AT91_PIN_PC2 (0x40 + 2) +#define AT91_PIN_PC3 (0x40 + 3) +#define AT91_PIN_PC4 (0x40 + 4) +#define AT91_PIN_PC5 (0x40 + 5) +#define AT91_PIN_PC6 (0x40 + 6) +#define AT91_PIN_PC7 (0x40 + 7) +#define AT91_PIN_PC8 (0x40 + 8) +#define AT91_PIN_PC9 (0x40 + 9) +#define AT91_PIN_PC10 (0x40 + 10) +#define AT91_PIN_PC11 (0x40 + 11) +#define AT91_PIN_PC12 (0x40 + 12) +#define AT91_PIN_PC13 (0x40 + 13) +#define AT91_PIN_PC14 (0x40 + 14) +#define AT91_PIN_PC15 (0x40 + 15) +#define AT91_PIN_PC16 (0x40 + 16) +#define AT91_PIN_PC17 (0x40 + 17) +#define AT91_PIN_PC18 (0x40 + 18) +#define AT91_PIN_PC19 (0x40 + 19) +#define AT91_PIN_PC20 (0x40 + 20) +#define AT91_PIN_PC21 (0x40 + 21) +#define AT91_PIN_PC22 (0x40 + 22) +#define AT91_PIN_PC23 (0x40 + 23) +#define AT91_PIN_PC24 (0x40 + 24) +#define AT91_PIN_PC25 (0x40 + 25) +#define AT91_PIN_PC26 (0x40 + 26) +#define AT91_PIN_PC27 (0x40 + 27) +#define AT91_PIN_PC28 (0x40 + 28) +#define AT91_PIN_PC29 (0x40 + 29) +#define AT91_PIN_PC30 (0x40 + 30) +#define AT91_PIN_PC31 (0x40 + 31) + +#define AT91_PIN_PD0 (0x60 + 0) +#define AT91_PIN_PD1 (0x60 + 1) +#define AT91_PIN_PD2 (0x60 + 2) +#define AT91_PIN_PD3 (0x60 + 3) +#define AT91_PIN_PD4 (0x60 + 4) +#define AT91_PIN_PD5 (0x60 + 5) +#define AT91_PIN_PD6 (0x60 + 6) +#define AT91_PIN_PD7 (0x60 + 7) +#define AT91_PIN_PD8 (0x60 + 8) +#define AT91_PIN_PD9 (0x60 + 9) +#define AT91_PIN_PD10 (0x60 + 10) +#define AT91_PIN_PD11 (0x60 + 11) +#define AT91_PIN_PD12 (0x60 + 12) +#define AT91_PIN_PD13 (0x60 + 13) +#define AT91_PIN_PD14 (0x60 + 14) +#define AT91_PIN_PD15 (0x60 + 15) +#define AT91_PIN_PD16 (0x60 + 16) +#define AT91_PIN_PD17 (0x60 + 17) +#define AT91_PIN_PD18 (0x60 + 18) +#define AT91_PIN_PD19 (0x60 + 19) +#define AT91_PIN_PD20 (0x60 + 20) +#define AT91_PIN_PD21 (0x60 + 21) +#define AT91_PIN_PD22 (0x60 + 22) +#define AT91_PIN_PD23 (0x60 + 23) +#define AT91_PIN_PD24 (0x60 + 24) +#define AT91_PIN_PD25 (0x60 + 25) +#define AT91_PIN_PD26 (0x60 + 26) +#define AT91_PIN_PD27 (0x60 + 27) +#define AT91_PIN_PD28 (0x60 + 28) +#define AT91_PIN_PD29 (0x60 + 29) +#define AT91_PIN_PD30 (0x60 + 30) +#define AT91_PIN_PD31 (0x60 + 31) + +#define AT91_PIN_PE0 (0x80 + 0) +#define AT91_PIN_PE1 (0x80 + 1) +#define AT91_PIN_PE2 (0x80 + 2) +#define AT91_PIN_PE3 (0x80 + 3) +#define AT91_PIN_PE4 (0x80 + 4) +#define AT91_PIN_PE5 (0x80 + 5) +#define AT91_PIN_PE6 (0x80 + 6) +#define AT91_PIN_PE7 (0x80 + 7) +#define AT91_PIN_PE8 (0x80 + 8) +#define AT91_PIN_PE9 (0x80 + 9) +#define AT91_PIN_PE10 (0x80 + 10) +#define AT91_PIN_PE11 (0x80 + 11) +#define AT91_PIN_PE12 (0x80 + 12) +#define AT91_PIN_PE13 (0x80 + 13) +#define AT91_PIN_PE14 (0x80 + 14) +#define AT91_PIN_PE15 (0x80 + 15) +#define AT91_PIN_PE16 (0x80 + 16) +#define AT91_PIN_PE17 (0x80 + 17) +#define AT91_PIN_PE18 (0x80 + 18) +#define AT91_PIN_PE19 (0x80 + 19) +#define AT91_PIN_PE20 (0x80 + 20) +#define AT91_PIN_PE21 (0x80 + 21) +#define AT91_PIN_PE22 (0x80 + 22) +#define AT91_PIN_PE23 (0x80 + 23) +#define AT91_PIN_PE24 (0x80 + 24) +#define AT91_PIN_PE25 (0x80 + 25) +#define AT91_PIN_PE26 (0x80 + 26) +#define AT91_PIN_PE27 (0x80 + 27) +#define AT91_PIN_PE28 (0x80 + 28) +#define AT91_PIN_PE29 (0x80 + 29) +#define AT91_PIN_PE30 (0x80 + 30) +#define AT91_PIN_PE31 (0x80 + 31) #ifndef __ASSEMBLY__ /* setup setup routines, called from board init or driver probe() */ @@ -215,8 +213,8 @@ extern void at91_gpio_resume(void); #include -#define gpio_to_irq(gpio) (gpio) -#define irq_to_gpio(irq) (irq) +#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS) +#define irq_to_gpio(irq) (irq - NR_AIC_IRQS) #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From 1e81799bd62d42bb6d5ec5c74e9b022e7d44f11c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 03:04:30 +0800 Subject: ARM: at91/gpio: fix display of number of irq setuped Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index d000448b11ac..74d6783eeabb 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -527,7 +527,7 @@ void __init at91_gpio_irq_setup(void) irq_set_chip_data(id, this); irq_set_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", irq, gpio_banks); + pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks); } /* gpiolib support */ -- cgit v1.2.3 From 4313d88c93df8c096adde516b08f1fb2f2e8b844 Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Wed, 30 Nov 2011 10:22:37 -0800 Subject: xen/ia64: fix build breakage because of conflicting u64 guest handles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit include/xen/interface/xen.h:526: error: conflicting types for ‘__guest_handle_u64’ arch/ia64/include/asm/xen/interface.h:74: error: previous declaration of ‘__guest_handle_u64’ was here Problem introduced by "xen/granttable: Introducing grant table V2 stucture" which added a new definition to include/xen/interface/xen.h for "u64". Fix: delete the ia64 arch specific definition. Signed-off-by: Tony Luck Signed-off-by: Konrad Rzeszutek Wilk --- arch/ia64/include/asm/xen/interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h index 1d2427d116e3..fbb519828aa1 100644 --- a/arch/ia64/include/asm/xen/interface.h +++ b/arch/ia64/include/asm/xen/interface.h @@ -71,7 +71,7 @@ __DEFINE_GUEST_HANDLE(uchar, unsigned char); __DEFINE_GUEST_HANDLE(uint, unsigned int); __DEFINE_GUEST_HANDLE(ulong, unsigned long); -__DEFINE_GUEST_HANDLE(u64, unsigned long); + DEFINE_GUEST_HANDLE(char); DEFINE_GUEST_HANDLE(int); DEFINE_GUEST_HANDLE(long); -- cgit v1.2.3 From 8351c7aad45c15647903f70e30a5884258d25b95 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:29:07 +0900 Subject: ARM: S3C64XX: Raise the frequency of the second I2C bus on Cragganmore The S3C I2C driver defaults to a rather low 66kHz, ask for 400kHz for a bit of a speed boost. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 8b04a46e9f6d..d7245ccb99ac 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -634,6 +634,11 @@ static struct i2c_board_info i2c_devs1[] __initdata = { { I2C_BOARD_INFO("wm1250-ev1", 0x27) }, }; +static struct s3c2410_platform_i2c i2c1_pdata = { + .frequency = 400000, + .bus_num = 1, +}; + static void __init crag6410_map_io(void) { s3c64xx_init_io(NULL, 0); @@ -692,7 +697,7 @@ static void __init crag6410_machine_init(void) s3c_sdhci2_set_platdata(&crag6410_hsmmc2_pdata); s3c_i2c0_set_platdata(&i2c0_pdata); - s3c_i2c1_set_platdata(NULL); + s3c_i2c1_set_platdata(&i2c1_pdata); s3c_fb_set_platdata(&crag6410_lcd_pdata); i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); -- cgit v1.2.3 From dcf3580a554757920c799364369a44bf0e6dc6f8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:29:07 +0900 Subject: ARM: S3C64XX: Use software initiated powerdown for Cragganmore Since the two PMICs are independent we initiate a shutdown on each. Signed-off-by: Mark Brown [kgene.kim@samsung.com: fix up conflict] Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index d7245ccb99ac..bb81a9fc8221 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -501,6 +501,7 @@ static struct wm831x_pdata crag_pmic_pdata __initdata = { .wm831x_num = 1, .irq_base = BANFF_PMIC_IRQ_BASE, .gpio_base = BANFF_PMIC_GPIO_BASE, + .soft_shutdown = true, .backup = &banff_backup_pdata, @@ -605,6 +606,7 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = { .wm831x_num = 2, .irq_base = GLENFARCLAS_PMIC_IRQ_BASE, .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE, + .soft_shutdown = true, .gpio_defaults = { /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */ -- cgit v1.2.3 From 8504a3cb5cbc43dbbec457105d9cead3fc20cd85 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:29:07 +0900 Subject: ARM: S3C64XX: Configure WM1250 EV1 GPIOs on Cragganmore Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index bb81a9fc8221..2b91c877de69 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -37,6 +37,8 @@ #include #include +#include + #include #include @@ -624,6 +626,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = { .disable_touch = true, }; +static struct wm1250_ev1_pdata wm1250_ev1_pdata = { + .gpios = { + [WM1250_EV1_GPIO_CLK_ENA] = S3C64XX_GPN(12), + [WM1250_EV1_GPIO_CLK_SEL0] = S3C64XX_GPL(12), + [WM1250_EV1_GPIO_CLK_SEL1] = S3C64XX_GPL(13), + [WM1250_EV1_GPIO_OSR] = S3C64XX_GPL(14), + [WM1250_EV1_GPIO_MASTER] = S3C64XX_GPL(8), + }, +}; + static struct i2c_board_info i2c_devs1[] __initdata = { { I2C_BOARD_INFO("wm8311", 0x34), .irq = S3C_EINT(0), @@ -633,7 +645,8 @@ static struct i2c_board_info i2c_devs1[] __initdata = { { I2C_BOARD_INFO("wlf-gf-module", 0x25) }, { I2C_BOARD_INFO("wlf-gf-module", 0x26) }, - { I2C_BOARD_INFO("wm1250-ev1", 0x27) }, + { I2C_BOARD_INFO("wm1250-ev1", 0x27), + .platform_data = &wm1250_ev1_pdata }, }; static struct s3c2410_platform_i2c i2c1_pdata = { -- cgit v1.2.3 From fc716894ac25e81a094adb964b78fde2387411a9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:29:08 +0900 Subject: ARM: S3C64XX: Improve logging of unknown Cragganmore module types As our ID table is populated with hexidecimal values it makes sense to log unknown module IDs in hexidecimal. It's also helpful to display board revisions as 1 based rather than 0 based as that's the numbering system used for the hardware (and what we do when announcing known modules). Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 66668565ee75..003c171ea275 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -154,8 +154,8 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, "Failed to register dev: %d\n", ret); } } else { - dev_warn(&i2c->dev, "Unknown module ID %d revision %d\n", - id, rev); + dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n", + id, rev + 1); } return 0; -- cgit v1.2.3 From 3153389b3b923f0e54f01e61d782da022b5e6206 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:29:08 +0900 Subject: ARM: S3C64XX: Run Tobermory interrupts in the default mode No need not to now that generic emulation is provided for the PMIC IRQ controller. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 003c171ea275..6387ced230c9 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -72,7 +72,6 @@ static struct wm8962_pdata wm8962_pdata __initdata = { 0x8000 | WM8962_GPIO_FN_DMICDAT, WM8962_GPIO_FN_IRQ, /* Open drain mode */ }, - .irq_active_low = true, }; static struct wm9081_pdata wm9081_pdata __initdata = { -- cgit v1.2.3 From 3d19f1cd25cfcfba685ef9df7d926c7264b0f8c9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:29:08 +0900 Subject: ARM: S3C64XX: Hook up platform data for Kilchomin module on Cragganmore Now that the WM5100 driver is merged add some initial platform data for the WM5100 on Kilchomin. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 6387ced230c9..c492f75a6b32 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -15,12 +15,41 @@ #include #include +#include #include #include #include #include +static struct wm5100_pdata wm5100_pdata = { + .ldo_ena = S3C64XX_GPN(7), + .irq_flags = IRQF_TRIGGER_HIGH, + .gpio_base = CODEC_GPIO_BASE, + + .in_mode = { + WM5100_IN_DIFF, + WM5100_IN_DIFF, + WM5100_IN_DIFF, + WM5100_IN_SE, + }, + + .hp_pol = CODEC_GPIO_BASE + 3, + .jack_modes = { + { WM5100_MICDET_MICBIAS3, 0, 0 }, + { WM5100_MICDET_MICBIAS2, 1, 1 }, + }, + + .gpio_defaults = { + 0, + 0, + 0, + 0, + 0x2, /* IRQ: CMOS output */ + 0x3, /* CLKOUT: CMOS output */ + }, +}; + static struct wm8996_retune_mobile_config wm8996_retune[] = { { .name = "Sub LPF", @@ -90,6 +119,7 @@ static const struct i2c_board_info wm1254_devs[] = { static const struct i2c_board_info wm1255_devs[] = { { I2C_BOARD_INFO("wm5100", 0x1a), + .platform_data = &wm5100_pdata, .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, }, { I2C_BOARD_INFO("wm9081", 0x6c), -- cgit v1.2.3 From c5c32c965dad8456dd2f6e7c1b05183258593e75 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Dec 2011 14:32:32 +0900 Subject: ARM: S3C64XX: Hook up Littlemill audio card on Cragganmore The Littlemill audio card is an adaptor card which can take any 6220-EV1 CODEC daughtercard. Provide standard support for the use of WM8994 class devices on the Littlemill card, configuring the MFD for WM8958 usage as this part is a superset of all others and the driver will use runtime detection to identify the actually fitted part given the configuration for the superset. Signed-off-by: Mark Brown [kgene.kim@samsung.com: fix up conflict] Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/include/mach/crag6410.h | 5 +++-- arch/arm/mach-s3c64xx/include/mach/irqs.h | 2 +- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 21 +++++++++++++++++++++ arch/arm/mach-s3c64xx/mach-crag6410.c | 6 ++++++ 4 files changed, 31 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h index 1cc1cc82e754..5d55ab018b6b 100644 --- a/arch/arm/mach-s3c64xx/include/mach/crag6410.h +++ b/arch/arm/mach-s3c64xx/include/mach/crag6410.h @@ -15,10 +15,11 @@ #define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START #define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) +#define CODEC_IRQ_BASE (IRQ_BOARD_START + 128) #define PCA935X_GPIO_BASE GPIO_BOARD_START #define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) -#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 16) -#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 32) +#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 32) +#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 64) #endif diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h index 443f85b3c203..96d60e0d9372 100644 --- a/arch/arm/mach-s3c64xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h @@ -169,7 +169,7 @@ #define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1) #ifdef CONFIG_MACH_WLF_CRAGG_6410 -#define IRQ_BOARD_NR 128 +#define IRQ_BOARD_NR 160 #elif defined(CONFIG_SMDK6410_WM1190_EV1) #define IRQ_BOARD_NR 64 #elif defined(CONFIG_SMDK6410_WM1192_EV1) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index c492f75a6b32..3fa7ebc83a31 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -133,6 +134,24 @@ static const struct i2c_board_info wm1259_devs[] = { }, }; +static struct wm8994_pdata wm8994_pdata = { + .gpio_base = CODEC_GPIO_BASE, + .gpio_defaults = { + 0x3, /* IRQ out, active high, CMOS */ + }, + .irq_base = CODEC_IRQ_BASE, + .ldo = { + { .supply = "WALLVDD" }, + { .supply = "WALLVDD" }, + }, +}; + +static const struct i2c_board_info wm1277_devs[] = { + { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */ + .platform_data = &wm8994_pdata, + .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, + }, +}; static __devinitdata const struct { u8 id; @@ -154,6 +173,8 @@ static __devinitdata const struct { { .id = 0x3b, .name = "1255-EV1 Kilchoman", .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) }, { .id = 0x3c, .name = "1273-EV1 Longmorn" }, + { .id = 0x3d, .name = "1277-EV1 Littlemill", + .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) }, }; static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 2b91c877de69..b2381c1bb3ba 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -289,6 +289,11 @@ static struct platform_device speyside_wm8962_device = { .id = -1, }; +static struct platform_device littlemill_device = { + .name = "littlemill", + .id = -1, +}; + static struct regulator_consumer_supply wallvdd_consumers[] = { REGULATOR_SUPPLY("SPKVDD1", "1-001a"), REGULATOR_SUPPLY("SPKVDD2", "1-001a"), @@ -341,6 +346,7 @@ static struct platform_device *crag6410_devices[] __initdata = { &crag6410_backlight_device, &speyside_device, &speyside_wm8962_device, + &littlemill_device, &lowland_device, &wallvdd_device, }; -- cgit v1.2.3 From 4e1b4ecaa23108a8422c84c602b308d21948d642 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 22 Nov 2011 23:54:23 +0800 Subject: ARM: mxs: add saif clkmux functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dong Aisheng Acked-by: Marek Vasut Cc: Sascha Hauer Cc: Wolfram Sang Cc: Uwe Kleine-König Cc: Mark Brown Cc: Liam Girdwood Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/clock-mx28.c | 29 +++++++++++++++++++++++++++++ arch/arm/mach-mxs/include/mach/common.h | 1 + arch/arm/mach-mxs/include/mach/digctl.h | 21 +++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 arch/arm/mach-mxs/include/mach/digctl.h (limited to 'arch') diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index da6e4aad177c..60c189a441b7 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include "regs-clkctrl-mx28.h" @@ -43,6 +45,33 @@ static struct clk emi_clk; static struct clk saif0_clk; static struct clk saif1_clk; static struct clk clk32k_clk; +static DEFINE_SPINLOCK(clkmux_lock); + +/* + * HW_SAIF_CLKMUX_SEL: + * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1 + * clock pins selected for SAIF1 input clocks. + * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and + * SAIF0 clock inputs selected for SAIF1 input clocks. + * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input + * clocks. + * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input + * clocks. + */ +int mxs_saif_clkmux_select(unsigned int clkmux) +{ + if (clkmux > 0x3) + return -EINVAL; + + spin_lock(&clkmux_lock); + __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX, + DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR); + __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX, + DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR); + spin_unlock(&clkmux_lock); + + return 0; +} static int _raw_clk_enable(struct clk *clk) { diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h index 635bb5d9a20a..3bbb94f4bbe1 100644 --- a/arch/arm/mach-mxs/include/mach/common.h +++ b/arch/arm/mach-mxs/include/mach/common.h @@ -16,6 +16,7 @@ struct clk; extern const u32 *mxs_get_ocotp(void); extern int mxs_reset_block(void __iomem *); extern void mxs_timer_init(struct clk *, int); +extern int mxs_saif_clkmux_select(unsigned int clkmux); extern int mx23_register_gpios(void); extern int mx23_clocks_init(void); diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h new file mode 100644 index 000000000000..49a888c65d6d --- /dev/null +++ b/arch/arm/mach-mxs/include/mach/digctl.h @@ -0,0 +1,21 @@ +/* + * 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_DIGCTL_H__ +#define __MACH_DIGCTL_H__ + +/* MXS DIGCTL SAIF CLKMUX */ +#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0 +#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1 +#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2 +#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3 + +#define HW_DIGCTL_CTRL 0x0 +#define BP_DIGCTL_CTRL_SAIF_CLKMUX 10 +#define BM_DIGCTL_CTRL_SAIF_CLKMUX (0x3 << 10) +#endif -- cgit v1.2.3 From 4c0174c52010435e6e0158500033868dc404f014 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 22 Nov 2011 23:54:24 +0800 Subject: ARM: mx28evk: add platform data for saif MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is for supporting saif record function. Signed-off-by: Dong Aisheng Acked-by: Marek Vasut Cc: Sascha Hauer Cc: Wolfram Sang Cc: Uwe Kleine-König Cc: Mark Brown Cc: Liam Girdwood Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/devices-mx28.h | 3 ++- arch/arm/mach-mxs/devices/platform-mxs-saif.c | 5 +++-- arch/arm/mach-mxs/include/mach/devices-common.h | 4 +++- arch/arm/mach-mxs/mach-mx28evk.c | 18 ++++++++++++++++-- 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h index c8887103f0e3..4f50094e293d 100644 --- a/arch/arm/mach-mxs/devices-mx28.h +++ b/arch/arm/mach-mxs/devices-mx28.h @@ -47,6 +47,7 @@ struct platform_device *__init mx28_add_mxsfb( const struct mxsfb_platform_data *pdata); extern const struct mxs_saif_data mx28_saif_data[] __initconst; -#define mx28_add_saif(id) mxs_add_saif(&mx28_saif_data[id]) +#define mx28_add_saif(id, pdata) \ + mxs_add_saif(&mx28_saif_data[id], pdata) struct platform_device *__init mx28_add_rtc_stmp3xxx(void); diff --git a/arch/arm/mach-mxs/devices/platform-mxs-saif.c b/arch/arm/mach-mxs/devices/platform-mxs-saif.c index 1ec965e9fe92..f6e3a60b4201 100644 --- a/arch/arm/mach-mxs/devices/platform-mxs-saif.c +++ b/arch/arm/mach-mxs/devices/platform-mxs-saif.c @@ -32,7 +32,8 @@ const struct mxs_saif_data mx28_saif_data[] __initconst = { }; #endif -struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data) +struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data, + const struct mxs_saif_platform_data *pdata) { struct resource res[] = { { @@ -56,5 +57,5 @@ struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data) }; return mxs_add_platform_device("mxs-saif", data->id, res, - ARRAY_SIZE(res), NULL, 0); + ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index a8080f44c03d..dc369c1239fc 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h @@ -94,6 +94,7 @@ struct platform_device *__init mxs_add_mxs_pwm( resource_size_t iobase, int id); /* saif */ +#include struct mxs_saif_data { int id; resource_size_t iobase; @@ -103,4 +104,5 @@ struct mxs_saif_data { }; struct platform_device *__init mxs_add_saif( - const struct mxs_saif_data *data); + const struct mxs_saif_data *data, + const struct mxs_saif_platform_data *pdata); diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index 064ec5abaa55..ac84a10baa14 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -27,6 +27,7 @@ #include #include +#include #include "devices-mx28.h" @@ -421,6 +422,18 @@ static struct gpio mx28evk_lcd_gpios[] = { { MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" }, }; +static const struct mxs_saif_platform_data + mx28evk_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 void __init mx28evk_init(void) { int ret; @@ -454,8 +467,9 @@ static void __init mx28evk_init(void) else mx28_add_mxsfb(&mx28evk_mxsfb_pdata); - mx28_add_saif(0); - mx28_add_saif(1); + mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); + mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]); + mx28_add_saif(1, &mx28evk_mxs_saif_pdata[1]); mx28_add_mxs_i2c(0); i2c_register_board_info(0, mxs_i2c0_board_info, -- cgit v1.2.3 From b07fed455c883f07f8e847f5b0d79975b4dc8e7a Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 22 Nov 2011 23:54:25 +0800 Subject: ARM: mx28evk: set a initial clock rate for saif MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dong Aisheng Acked-by: Marek Vasut Cc: Sascha Hauer Cc: Wolfram Sang Cc: Uwe Kleine-König Cc: Mark Brown Cc: Liam Girdwood Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/clock-mx28.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index 60c189a441b7..df0ad3ce234b 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -814,6 +814,15 @@ int __init mx28_clocks_init(void) clk_set_parent(&saif0_clk, &pll0_clk); clk_set_parent(&saif1_clk, &pll0_clk); + /* + * Set an initial clock rate for the saif internal logic to work + * properly. This is important when working in EXTMASTER mode that + * uses the other saif's BITCLK&LRCLK but it still needs a basic + * clock which should be fast enough for the internal logic. + */ + clk_set_rate(&saif0_clk, 24000000); + clk_set_rate(&saif1_clk, 24000000); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0); -- cgit v1.2.3 From e13c692b1f97a6a4f753695b4f28b7f10e5d79ae Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Sat, 12 Nov 2011 20:36:02 +0530 Subject: ARM: davinci: vpif: move code to driver core header from platform Move vpif related definitions for capture and display drivers from dm646x platform header file to vpif_types.h inside the driver as these definitions are related to driver code rather than the platform or board. This enables reusing this IP across platforms. Signed-off-by: Manjunath Hadli Acked-by: Mauro Carvalho Chehab Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/include/mach/dm646x.h | 53 +-------------------- drivers/media/video/davinci/vpif.h | 1 + drivers/media/video/davinci/vpif_capture.h | 2 +- drivers/media/video/davinci/vpif_display.h | 1 + include/media/davinci/vpif_types.h | 71 +++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 include/media/davinci/vpif_types.h (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index 2a00fe5ac253..a8ee6c9f0bb0 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -16,6 +16,7 @@ #include #include #include +#include #define DM646X_EMAC_BASE (0x01C80000) #define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) @@ -34,58 +35,6 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv); void dm646x_video_init(void); -enum vpif_if_type { - VPIF_IF_BT656, - VPIF_IF_BT1120, - VPIF_IF_RAW_BAYER -}; - -struct vpif_interface { - enum vpif_if_type if_type; - unsigned hd_pol:1; - unsigned vd_pol:1; - unsigned fid_pol:1; -}; - -struct vpif_subdev_info { - const char *name; - struct i2c_board_info board_info; - u32 input; - u32 output; - unsigned can_route:1; - struct vpif_interface vpif_if; -}; - -struct vpif_display_config { - int (*set_clock)(int, int); - struct vpif_subdev_info *subdevinfo; - int subdev_count; - const char **output; - int output_count; - const char *card_name; -}; - -struct vpif_input { - struct v4l2_input input; - const char *subdev_name; -}; - -#define VPIF_CAPTURE_MAX_CHANNELS 2 - -struct vpif_capture_chan_config { - const struct vpif_input *inputs; - int input_count; -}; - -struct vpif_capture_config { - int (*setup_input_channel_mode)(int); - int (*setup_input_path)(int, const char *); - struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS]; - struct vpif_subdev_info *subdev_info; - int subdev_count; - const char *card_name; -}; - void dm646x_setup_vpif(struct vpif_display_config *, struct vpif_capture_config *); diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index 10550bd93b06..25036cb11bea 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h @@ -20,6 +20,7 @@ #include #include #include +#include /* Maximum channel allowed */ #define VPIF_NUM_CHANNELS (4) diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h index 064550f5ce4a..a693d4ebda55 100644 --- a/drivers/media/video/davinci/vpif_capture.h +++ b/drivers/media/video/davinci/vpif_capture.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "vpif.h" diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h index 5d1936dafed2..56879d1a0684 100644 --- a/drivers/media/video/davinci/vpif_display.h +++ b/drivers/media/video/davinci/vpif_display.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "vpif.h" diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h new file mode 100644 index 000000000000..9929b05cff3a --- /dev/null +++ b/include/media/davinci/vpif_types.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011 Texas Instruments 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 version 2. + * + * 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 _VPIF_TYPES_H +#define _VPIF_TYPES_H + +#define VPIF_CAPTURE_MAX_CHANNELS 2 + +enum vpif_if_type { + VPIF_IF_BT656, + VPIF_IF_BT1120, + VPIF_IF_RAW_BAYER +}; + +struct vpif_interface { + enum vpif_if_type if_type; + unsigned hd_pol:1; + unsigned vd_pol:1; + unsigned fid_pol:1; +}; + +struct vpif_subdev_info { + const char *name; + struct i2c_board_info board_info; + u32 input; + u32 output; + unsigned can_route:1; + struct vpif_interface vpif_if; +}; + +struct vpif_display_config { + int (*set_clock)(int, int); + struct vpif_subdev_info *subdevinfo; + int subdev_count; + const char **output; + int output_count; + const char *card_name; +}; + +struct vpif_input { + struct v4l2_input input; + const char *subdev_name; +}; + +struct vpif_capture_chan_config { + const struct vpif_input *inputs; + int input_count; +}; + +struct vpif_capture_config { + int (*setup_input_channel_mode)(int); + int (*setup_input_path)(int, const char *); + struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS]; + struct vpif_subdev_info *subdev_info; + int subdev_count; + const char *card_name; +}; +#endif /* _VPIF_TYPES_H */ -- cgit v1.2.3 From 12221d434eb60e3bf0851d747b17395b7083a76d Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Tue, 15 Nov 2011 01:42:09 +0530 Subject: ARM: davinci: add support for multiple power domains On a new SoC based on DaVinci, there are multiple power domains similar to that in C6670 (c6x). Currently the clock module assumes that there are only two power domains (0 and 1). This patch removes this restriction to allow porting on to the new SoC. Reviewed-by :Sergei Shtylyov Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/clock.c | 13 +++---------- arch/arm/mach-davinci/clock.h | 10 +++++----- arch/arm/mach-davinci/dm644x.c | 4 ++-- 3 files changed, 10 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 00861139101d..008772e3b843 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -31,19 +31,12 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clockfw_lock); -static unsigned psc_domain(struct clk *clk) -{ - return (clk->flags & PSC_DSP) - ? DAVINCI_GPSC_DSPDOMAIN - : DAVINCI_GPSC_ARMDOMAIN; -} - static void __clk_enable(struct clk *clk) { if (clk->parent) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, true, clk->flags); } @@ -53,7 +46,7 @@ static void __clk_disable(struct clk *clk) return; if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, false, clk->flags); if (clk->parent) __clk_disable(clk->parent); @@ -237,7 +230,7 @@ static int __init clk_disable_unused(void) pr_debug("Clocks: disable unused %s\n", ck->name); - davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, + davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc, false, ck->flags); } spin_unlock_irq(&clockfw_lock); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index a705f367a84d..46f0f1bf1a4c 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -93,6 +93,7 @@ struct clk { u8 usecount; u8 lpsc; u8 gpsc; + u8 domain; u32 flags; struct clk *parent; struct list_head children; /* list of children */ @@ -107,11 +108,10 @@ struct clk { /* Clock flags: SoC-specific flags start at BIT(16) */ #define ALWAYS_ENABLED BIT(1) #define CLK_PSC BIT(2) -#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ -#define CLK_PLL BIT(4) /* PLL-derived clock */ -#define PRE_PLL BIT(5) /* source is before PLL mult/div */ -#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ -#define PSC_FORCE BIT(7) /* Force module state transtition */ +#define CLK_PLL BIT(3) /* PLL-derived clock */ +#define PRE_PLL BIT(4) /* source is before PLL mult/div */ +#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(6) /* Force module state transtition */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 3470983aa343..b95097dbdfed 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -130,7 +130,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DAVINCI_LPSC_GEM, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; @@ -145,7 +145,7 @@ static struct clk vicp_clk = { .name = "vicp", .parent = &pll1_sysclk2, .lpsc = DAVINCI_LPSC_IMCOP, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; -- cgit v1.2.3 From 51ccd81d9b1220ac1729434ac1ed5b0142001097 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 3 Dec 2011 19:49:26 +0900 Subject: ARM: S3C64XX: Power gate unused domains The S3C64xx CPUs have power gating support with a series of software controllable power domains in the SoC. To take full advantage of these we should implement runtime PM support but since several of the IP blocks have no in tree drivers (and at this point aren't likely to acquire such drivers) we can get some benefit from the hardware much more easily if we just turn those blocks off unconditionally. This will cut down on the leakage these domains generate without interfering with active usage. Do this for: - Domain G: 3D acceleration - Domain V: MFC - Domain I: JPEG and camera interface - Domain P: 2D acceleration, TV encoder and scaler This is easy to reverse if any of these devices do acquire drivers in the future or as part of out of tree patches for them. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/pm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index b375cd5c47cb..0868d1331912 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -89,6 +89,8 @@ static struct sleep_save misc_save[] = { SAVE_ITEM(S3C64XX_SDMA_SEL), SAVE_ITEM(S3C64XX_MODEM_MIFPCON), + + SAVE_ITEM(S3C64XX_NORMAL_CFG), }; void s3c_pm_configure_extint(void) @@ -181,10 +183,23 @@ static void s3c64xx_pm_prepare(void) static int s3c64xx_pm_init(void) { + u32 val; + pm_cpu_prep = s3c64xx_pm_prepare; pm_cpu_sleep = s3c64xx_cpu_suspend; pm_uart_udivslot = 1; + /* + * Unconditionally disable power domains that contain only + * blocks which have no mainline driver support. + */ + val = __raw_readl(S3C64XX_NORMAL_CFG); + val &= ~(S3C64XX_NORMALCFG_DOMAIN_G_ON | + S3C64XX_NORMALCFG_DOMAIN_V_ON | + S3C64XX_NORMALCFG_DOMAIN_I_ON | + S3C64XX_NORMALCFG_DOMAIN_P_ON); + __raw_writel(val, S3C64XX_NORMAL_CFG); + #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK gpio_request(S3C64XX_GPN(12), "DEBUG_LED0"); gpio_request(S3C64XX_GPN(13), "DEBUG_LED1"); -- cgit v1.2.3 From a21a2fd4036f9a572415a7543896a1163c211ee5 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 Nov 2011 21:10:12 +0200 Subject: sparc: switch to GENERIC_PCI_IOMAP sparc copied pci_iomap from generic code, probably to avoid pulling the rest of iomap.c in. Since that's in a separate file now, we can reuse the common implementation. Signed-off-by: Michael S. Tsirkin --- arch/sparc/Kconfig | 1 + arch/sparc/include/asm/io_32.h | 2 +- arch/sparc/include/asm/io_64.h | 2 +- arch/sparc/lib/iomap.c | 23 ----------------------- 4 files changed, 3 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index f92602e86607..a4644f5ea98c 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -28,6 +28,7 @@ config SPARC select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW select USE_GENERIC_SMP_HELPERS if SMP + select GENERIC_PCI_IOMAP config SPARC32 def_bool !64BIT diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index c2ced21c9dc1..2006e5d359df 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h @@ -7,6 +7,7 @@ #include /* IO address mapping routines need this */ #include +#include #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) @@ -324,7 +325,6 @@ extern void ioport_unmap(void __iomem *); /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); extern void pci_iounmap(struct pci_dev *dev, void __iomem *); /* diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 9c8965415f0a..9481e5a6fa90 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h @@ -8,6 +8,7 @@ #include /* IO address mapping routines need this */ #include #include +#include /* PC crapola... */ #define __SLOW_DOWN_IO do { } while (0) @@ -514,7 +515,6 @@ extern void ioport_unmap(void __iomem *); /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); extern void pci_iounmap(struct pci_dev *dev, void __iomem *); static inline int sbus_can_dma_64bit(void) diff --git a/arch/sparc/lib/iomap.c b/arch/sparc/lib/iomap.c index 9ef37e13a920..c4d42a50ebc0 100644 --- a/arch/sparc/lib/iomap.c +++ b/arch/sparc/lib/iomap.c @@ -18,31 +18,8 @@ void ioport_unmap(void __iomem *addr) EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); -/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - /* What? */ - return NULL; -} - void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { /* nothing to do */ } -EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); -- cgit v1.2.3 From 8593dd375ad10045e69b7b43fc1d885929aebbd5 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 29 Nov 2011 20:40:42 +0200 Subject: tile: don't panic on iomap I think panic on iomap is there just for debugging. If we return NULL instead, the generic pci_iomap will DTRT so we don't need to roll our own. Signed-off-by: Michael S. Tsirkin --- arch/tile/include/asm/io.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index c9ea1652af03..d2152deb1f3c 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h @@ -204,7 +204,8 @@ static inline long ioport_panic(void) static inline void __iomem *ioport_map(unsigned long port, unsigned int len) { - return (void __iomem *) ioport_panic(); + pr_info("ioport_map: mapping IO resources is unsupported on tile.\n"); + return NULL; } static inline void ioport_unmap(void __iomem *addr) -- cgit v1.2.3 From 845501213033d0058945776349f15502823359d8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 29 Nov 2011 20:42:56 +0200 Subject: tile: switch to GENERIC_PCI_IOMAP tile now has working stubs for ioport_map and ioremap such that the generic pci_iomap will DTRT: cast to pointer on memory and return NULL and log message on IO map. Switch it over to GENERIC_PCI_IOMAP. Signed-off-by: Michael S. Tsirkin --- arch/tile/Kconfig | 1 + arch/tile/include/asm/pci.h | 2 +- arch/tile/kernel/pci.c | 21 --------------------- 3 files changed, 2 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 70a0de46cd1b..11270ca22c0a 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -321,6 +321,7 @@ config PCI bool "PCI support" default y select PCI_DOMAINS + select GENERIC_PCI_IOMAP ---help--- Enable PCI root complex support, so PCIe endpoint devices can be attached to the Tile chip. Many, but not all, PCI devices diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h index 7f03cefed1b9..1d25fea42e54 100644 --- a/arch/tile/include/asm/pci.h +++ b/arch/tile/include/asm/pci.h @@ -16,6 +16,7 @@ #define _ASM_TILE_PCI_H #include +#include /* * Structure of a PCI controller (host bridge) @@ -49,7 +50,6 @@ struct pci_controller { int __devinit tile_pci_init(void); int __devinit pcibios_init(void); -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} void __devinit pcibios_fixup_bus(struct pci_bus *bus); diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 2a8014cb1ff5..1b6244e69de4 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -465,27 +465,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return 0; } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len) - return NULL; - if (max && len > max) - len = max; - - if (!(flags & IORESOURCE_MEM)) { - pr_info("PCI: Trying to map invalid resource %#lx\n", flags); - start = 0; - } - - return (void __iomem *)start; -} -EXPORT_SYMBOL(pci_iomap); - - /**************************************************************** * * Tile PCI config space read/write routines -- cgit v1.2.3 From 5322418502be4696ebdef2ed164bbd0a348d4816 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 29 Nov 2011 21:20:06 +0200 Subject: frv: switch to GENERIC_PCI_IOMAP frv uses a version of pci_iomap that simply casts and returns back the start address. Looking closely, both ioremap and ioport_map seem to do this on this platform, so the generic pci_iomap will DTRT automatically. Signed-off-by: Michael S. Tsirkin --- arch/frv/Kconfig | 1 + arch/frv/include/asm/io.h | 2 +- arch/frv/mb93090-mb00/Makefile | 2 +- arch/frv/mb93090-mb00/pci-iomap.c | 29 ----------------------------- 4 files changed, 3 insertions(+), 31 deletions(-) delete mode 100644 arch/frv/mb93090-mb00/pci-iomap.c (limited to 'arch') diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index bad27a6ff407..dfde78b09322 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -317,6 +317,7 @@ config PCI bool "Use PCI" depends on MB93090_MB00 default y + select GENERIC_PCI_IOMAP help Some FR-V systems (such as the MB93090-MB00 VDK) have PCI onboard. If you have one of these boards and you wish to use the PCI diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h index ca7475e73b5e..8cb50a2fbcb2 100644 --- a/arch/frv/include/asm/io.h +++ b/arch/frv/include/asm/io.h @@ -21,6 +21,7 @@ #include #include #include +#include #include /* @@ -370,7 +371,6 @@ static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) { } diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile index b73b542f8f48..21f1df1b378a 100644 --- a/arch/frv/mb93090-mb00/Makefile +++ b/arch/frv/mb93090-mb00/Makefile @@ -3,7 +3,7 @@ # ifeq "$(CONFIG_PCI)" "y" -obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o +obj-y := pci-frv.o pci-irq.o pci-vdk.o ifeq "$(CONFIG_MMU)" "y" obj-y += pci-dma.o diff --git a/arch/frv/mb93090-mb00/pci-iomap.c b/arch/frv/mb93090-mb00/pci-iomap.c deleted file mode 100644 index 35f6df28351e..000000000000 --- a/arch/frv/mb93090-mb00/pci-iomap.c +++ /dev/null @@ -1,29 +0,0 @@ -/* pci-iomap.c: description - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.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 -#include - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - - if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM)) - return (void __iomem *) start; - - return NULL; -} - -EXPORT_SYMBOL(pci_iomap); -- cgit v1.2.3 From 2ebf5d0d79087005e1042df2cd0f7594782746d8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 1 Dec 2011 13:12:22 +0200 Subject: mn10300: add missing __iomap markers MN10300's *ioremap*() collection lacks __iomem markers. Fix that. Signed-off-by: Michael S. Tsirkin --- arch/mn10300/include/asm/io.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h index 787255da744e..0d6d54f09f17 100644 --- a/arch/mn10300/include/asm/io.h +++ b/arch/mn10300/include/asm/io.h @@ -251,15 +251,15 @@ static inline void *phys_to_virt(unsigned long address) /* * Change "struct page" to physical address. */ -static inline void *__ioremap(unsigned long offset, unsigned long size, - unsigned long flags) +static inline void __iomem *__ioremap(unsigned long offset, unsigned long size, + unsigned long flags) { - return (void *) offset; + return (void __iomem *) offset; } -static inline void *ioremap(unsigned long offset, unsigned long size) +static inline void __iomem *ioremap(unsigned long offset, unsigned long size) { - return (void *) offset; + return (void __iomem *) offset; } /* @@ -267,14 +267,14 @@ static inline void *ioremap(unsigned long offset, unsigned long size) * area. it's useful if some control registers are in such an area and write * combining or read caching is not desirable: */ -static inline void *ioremap_nocache(unsigned long offset, unsigned long size) +static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size) { - return (void *) (offset | 0x20000000); + return (void __iomem *) (offset | 0x20000000); } #define ioremap_wc ioremap_nocache -static inline void iounmap(void *addr) +static inline void iounmap(void __iomem *addr) { } -- cgit v1.2.3 From 34f1bdee1910f7efe3c32e1a891dba4fd21cb3b6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 1 Dec 2011 12:41:36 +0200 Subject: mn10300: switch to GENERIC_PCI_IOMAP The pci_iomap variant that arch/mn10300/unit-asb2305/pci-iomap.c uses differs from the generic one in that it does not use ioremap_nocache for PCI addresses. However, it turns out that PCI addresses are automatically noncached, so switching to ioremap_nocache and to the generic implementation is safe. Signed-off-by: Michael S. Tsirkin --- arch/mn10300/Kconfig | 1 + arch/mn10300/include/asm/io.h | 1 - arch/mn10300/unit-asb2305/Makefile | 2 +- arch/mn10300/unit-asb2305/pci-iomap.c | 31 ------------------------------- 4 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 arch/mn10300/unit-asb2305/pci-iomap.c (limited to 'arch') diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 438db84a1f7c..8f1c40d5817e 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -252,6 +252,7 @@ config PCI bool "Use PCI" depends on MN10300_UNIT_ASB2305 default y + select GENERIC_PCI_IOMAP help Some systems (such as the ASB2305) have PCI onboard. If you have one of these boards and you wish to use the PCI facilities, say Y here. diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h index 0d6d54f09f17..139df8c53de8 100644 --- a/arch/mn10300/include/asm/io.h +++ b/arch/mn10300/include/asm/io.h @@ -229,7 +229,6 @@ static inline void outsl(unsigned long addr, const void *buffer, int count) /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) { } diff --git a/arch/mn10300/unit-asb2305/Makefile b/arch/mn10300/unit-asb2305/Makefile index 0551022225b3..cbc5abaa939a 100644 --- a/arch/mn10300/unit-asb2305/Makefile +++ b/arch/mn10300/unit-asb2305/Makefile @@ -5,4 +5,4 @@ ############################################################################### obj-y := unit-init.o leds.o -obj-$(CONFIG_PCI) += pci.o pci-asb2305.o pci-irq.o pci-iomap.o +obj-$(CONFIG_PCI) += pci.o pci-asb2305.o pci-irq.o diff --git a/arch/mn10300/unit-asb2305/pci-iomap.c b/arch/mn10300/unit-asb2305/pci-iomap.c deleted file mode 100644 index c1a8d8f941fd..000000000000 --- a/arch/mn10300/unit-asb2305/pci-iomap.c +++ /dev/null @@ -1,31 +0,0 @@ -/* ASB2305 PCI I/O mapping handler - * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ -#include -#include - -/* - * Create a virtual mapping cookie for a PCI BAR (memory or IO) - */ -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - - if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM)) - return (void __iomem *) start; - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); -- cgit v1.2.3 From 193a667fba76b3df482cbf865228e26ee246e889 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 4 Dec 2011 15:05:55 +0200 Subject: alpha: drop pci_iomap/pci_iounmap from pci-noop.c Jenkins disables PCI so asm-generic provides inline stubs for these, we don't need offline stubs as well. Signed-off-by: Michael S. Tsirkin --- arch/alpha/kernel/pci-noop.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 246100ef07c2..04eea4894ef3 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -185,15 +185,3 @@ struct dma_map_ops alpha_noop_ops = { struct dma_map_ops *dma_ops = &alpha_noop_ops; EXPORT_SYMBOL(dma_ops); - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - return NULL; -} - -void pci_iounmap(struct pci_dev *dev, void __iomem * addr) -{ -} - -EXPORT_SYMBOL(pci_iomap); -EXPORT_SYMBOL(pci_iounmap); -- cgit v1.2.3 From 1fa02ac9536c9a5278e999e40e274bba62c23a4d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Fri, 23 Sep 2011 16:37:27 +0300 Subject: ARM: OMAP: iommu: declare a private iommu binding struct Declare an omap iommu private struct, which binds an iommu user to its iommu device. This struct should be placed at the iommu user's dev_archdata so generic IOMMU API can be used without having to utilize omap-specific plumbing anymore. While at it, provide an accessor method to ease the retrieval of the omap_iommu handle from a user device. Signed-off-by: Ohad Ben-Cohen Acked-by: Tony Lindgren Cc: Hiroshi Doyu --- arch/arm/plat-omap/include/plat/iommu.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index a1d79ee19250..fa11ee26aca9 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -111,6 +111,32 @@ struct iommu_platform_data { u32 da_end; }; +/** + * struct iommu_arch_data - omap iommu private data + * @name: name of the iommu device + * @iommu_dev: handle of the iommu device + * + * This is an omap iommu private data object, which binds an iommu user + * to its iommu device. This object should be placed at the iommu user's + * dev_archdata so generic IOMMU API can be used without having to + * utilize omap-specific plumbing anymore. + */ +struct omap_iommu_arch_data { + const char *name; + struct omap_iommu *iommu_dev; +}; + +/** + * dev_to_omap_iommu() - retrieves an omap iommu object from a user device + * @dev: iommu client device + */ +static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) +{ + struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; + + return arch_data->iommu_dev; +} + /* IOMMU errors */ #define OMAP_IOMMU_ERR_TLB_MISS (1 << 0) #define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1) -- cgit v1.2.3 From c8eaab3b74f1326c989e1db8d7c0c14981556e4e Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Fri, 23 Sep 2011 16:44:57 +0300 Subject: ARM: OMAP3: bind omap3isp_device to its iommu device Bind OMAP3's isp device to the isp's dedicated iommu, by setting the device's archdata iommu member. This way omap3isp will be able to use the generic IOMMU API without having to call any omap-specific binding method. Signed-off-by: Ohad Ben-Cohen Acked-by: Laurent Pinchart Acked-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index c15cfada5f13..9ceabf02eeb7 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -211,9 +212,15 @@ static struct platform_device omap3isp_device = { .resource = omap3isp_resources, }; +static struct omap_iommu_arch_data omap3_isp_iommu = { + .name = "isp", +}; + int omap3_init_camera(struct isp_platform_data *pdata) { omap3isp_device.dev.platform_data = pdata; + omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu; + return platform_device_register(&omap3isp_device); } -- cgit v1.2.3 From fabdbca8c991dfa0ea1ff26214ae7d18e5740cc3 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 11 Oct 2011 00:18:33 +0200 Subject: iommu/omap: eliminate the public omap_find_iommu_device() method Eliminate the public omap_find_iommu_device() method, and don't expect clients to provide the omap_iommu handle anymore. Instead, OMAP's iommu driver now utilizes dev_archdata's private iommu extension to be able to access the required iommu information. This way OMAP IOMMU users are now able to use the generic IOMMU API without having to call any omap-specific binding method. Update omap3isp appropriately. Signed-off-by: Ohad Ben-Cohen Acked-by: Laurent Pinchart Acked-by: Tony Lindgren Cc: Hiroshi Doyu --- arch/arm/plat-omap/include/plat/iommu.h | 5 ++- arch/arm/plat-omap/include/plat/iovmm.h | 12 +++---- drivers/iommu/omap-iommu.c | 58 +++++++++++++++------------------ drivers/iommu/omap-iovmm.c | 31 +++++++++++------- drivers/media/video/omap3isp/isp.c | 30 +++-------------- drivers/media/video/omap3isp/isp.h | 2 -- drivers/media/video/omap3isp/ispccdc.c | 18 +++++----- drivers/media/video/omap3isp/ispstat.c | 8 ++--- drivers/media/video/omap3isp/ispvideo.c | 4 +-- 9 files changed, 74 insertions(+), 94 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index fa11ee26aca9..88be3e628b33 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -189,8 +189,8 @@ extern int omap_iommu_set_isr(const char *name, void *priv), void *isr_priv); -extern void omap_iommu_save_ctx(struct omap_iommu *obj); -extern void omap_iommu_restore_ctx(struct omap_iommu *obj); +extern void omap_iommu_save_ctx(struct device *dev); +extern void omap_iommu_restore_ctx(struct device *dev); extern int omap_install_iommu_arch(const struct iommu_functions *ops); extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops); @@ -202,6 +202,5 @@ extern ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); extern size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len); -struct device *omap_find_iommu_device(const char *name); #endif /* __MACH_IOMMU_H */ diff --git a/arch/arm/plat-omap/include/plat/iovmm.h b/arch/arm/plat-omap/include/plat/iovmm.h index 6af1a91c0f36..498e57cda6cd 100644 --- a/arch/arm/plat-omap/include/plat/iovmm.h +++ b/arch/arm/plat-omap/include/plat/iovmm.h @@ -72,18 +72,18 @@ struct iovm_struct { #define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT)) -extern struct iovm_struct *omap_find_iovm_area(struct omap_iommu *obj, u32 da); +extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da); extern u32 -omap_iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da, +omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da, const struct sg_table *sgt, u32 flags); extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain, - struct omap_iommu *obj, u32 da); + struct device *dev, u32 da); extern u32 -omap_iommu_vmalloc(struct iommu_domain *domain, struct omap_iommu *obj, +omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev, u32 da, size_t bytes, u32 flags); extern void -omap_iommu_vfree(struct iommu_domain *domain, struct omap_iommu *obj, +omap_iommu_vfree(struct iommu_domain *domain, struct device *dev, const u32 da); -extern void *omap_da_to_va(struct omap_iommu *obj, u32 da); +extern void *omap_da_to_va(struct device *dev, u32 da); #endif /* __IOMMU_MMAP_H */ diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 8f32b2bf7587..b7f863d72c08 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -86,20 +86,24 @@ EXPORT_SYMBOL_GPL(omap_uninstall_iommu_arch); /** * omap_iommu_save_ctx - Save registers for pm off-mode support - * @obj: target iommu + * @dev: client device **/ -void omap_iommu_save_ctx(struct omap_iommu *obj) +void omap_iommu_save_ctx(struct device *dev) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); + arch_iommu->save_ctx(obj); } EXPORT_SYMBOL_GPL(omap_iommu_save_ctx); /** * omap_iommu_restore_ctx - Restore registers for pm off-mode support - * @obj: target iommu + * @dev: client device **/ -void omap_iommu_restore_ctx(struct omap_iommu *obj) +void omap_iommu_restore_ctx(struct device *dev) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); + arch_iommu->restore_ctx(obj); } EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); @@ -819,36 +823,24 @@ static int device_match_by_alias(struct device *dev, void *data) return strcmp(obj->name, name) == 0; } -/** - * omap_find_iommu_device() - find an omap iommu device by name - * @name: name of the iommu device - * - * The generic iommu API requires the caller to provide the device - * he wishes to attach to a certain iommu domain. - * - * Drivers generally should not bother with this as it should just - * be taken care of by the DMA-API using dev_archdata. - * - * This function is provided as an interim solution until the latter - * materializes, and omap3isp is fully migrated to the DMA-API. - */ -struct device *omap_find_iommu_device(const char *name) -{ - return driver_find_device(&omap_iommu_driver.driver, NULL, - (void *)name, - device_match_by_alias); -} -EXPORT_SYMBOL_GPL(omap_find_iommu_device); - /** * omap_iommu_attach() - attach iommu device to an iommu domain - * @dev: target omap iommu device + * @name: name of target omap iommu device * @iopgd: page table **/ -static struct omap_iommu *omap_iommu_attach(struct device *dev, u32 *iopgd) +static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd) { int err = -ENOMEM; - struct omap_iommu *obj = to_iommu(dev); + struct device *dev; + struct omap_iommu *obj; + + dev = driver_find_device(&omap_iommu_driver.driver, NULL, + (void *)name, + device_match_by_alias); + if (!dev) + return NULL; + + obj = to_iommu(dev); spin_lock(&obj->iommu_lock); @@ -1069,6 +1061,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) { struct omap_iommu_domain *omap_domain = domain->priv; struct omap_iommu *oiommu; + struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; int ret = 0; spin_lock(&omap_domain->lock); @@ -1081,14 +1074,14 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) } /* get a handle to and enable the omap iommu */ - oiommu = omap_iommu_attach(dev, omap_domain->pgtable); + oiommu = omap_iommu_attach(arch_data->name, omap_domain->pgtable); if (IS_ERR(oiommu)) { ret = PTR_ERR(oiommu); dev_err(dev, "can't get omap iommu: %d\n", ret); goto out; } - omap_domain->iommu_dev = oiommu; + omap_domain->iommu_dev = arch_data->iommu_dev = oiommu; oiommu->domain = domain; out: @@ -1100,7 +1093,8 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain, struct device *dev) { struct omap_iommu_domain *omap_domain = domain->priv; - struct omap_iommu *oiommu = to_iommu(dev); + struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; + struct omap_iommu *oiommu = dev_to_omap_iommu(dev); spin_lock(&omap_domain->lock); @@ -1114,7 +1108,7 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain, omap_iommu_detach(oiommu); - omap_domain->iommu_dev = NULL; + omap_domain->iommu_dev = arch_data->iommu_dev = NULL; out: spin_unlock(&omap_domain->lock); diff --git a/drivers/iommu/omap-iovmm.c b/drivers/iommu/omap-iovmm.c index 46be456fcc00..23655945e30c 100644 --- a/drivers/iommu/omap-iovmm.c +++ b/drivers/iommu/omap-iovmm.c @@ -231,12 +231,14 @@ static struct iovm_struct *__find_iovm_area(struct omap_iommu *obj, /** * omap_find_iovm_area - find iovma which includes @da + * @dev: client device * @da: iommu device virtual address * * Find the existing iovma starting at @da */ -struct iovm_struct *omap_find_iovm_area(struct omap_iommu *obj, u32 da) +struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); struct iovm_struct *area; mutex_lock(&obj->mmap_lock); @@ -343,14 +345,15 @@ static void free_iovm_area(struct omap_iommu *obj, struct iovm_struct *area) /** * omap_da_to_va - convert (d) to (v) - * @obj: objective iommu + * @dev: client device * @da: iommu device virtual address * @va: mpu virtual address * * Returns mpu virtual addr which corresponds to a given device virtual addr */ -void *omap_da_to_va(struct omap_iommu *obj, u32 da) +void *omap_da_to_va(struct device *dev, u32 da) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); void *va = NULL; struct iovm_struct *area; @@ -582,16 +585,18 @@ __iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, /** * omap_iommu_vmap - (d)-(p)-(v) address mapper - * @obj: objective iommu + * @domain: iommu domain + * @dev: client device * @sgt: address of scatter gather table * @flags: iovma and page property * * Creates 1-n-1 mapping with given @sgt and returns @da. * All @sgt element must be io page size aligned. */ -u32 omap_iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da, +u32 omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da, const struct sg_table *sgt, u32 flags) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); size_t bytes; void *va = NULL; @@ -622,15 +627,17 @@ EXPORT_SYMBOL_GPL(omap_iommu_vmap); /** * omap_iommu_vunmap - release virtual mapping obtained by 'omap_iommu_vmap()' - * @obj: objective iommu + * @domain: iommu domain + * @dev: client device * @da: iommu device virtual address * * Free the iommu virtually contiguous memory area starting at * @da, which was returned by 'omap_iommu_vmap()'. */ struct sg_table * -omap_iommu_vunmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da) +omap_iommu_vunmap(struct iommu_domain *domain, struct device *dev, u32 da) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); struct sg_table *sgt; /* * 'sgt' is allocated before 'omap_iommu_vmalloc()' is called. @@ -647,7 +654,7 @@ EXPORT_SYMBOL_GPL(omap_iommu_vunmap); /** * omap_iommu_vmalloc - (d)-(p)-(v) address allocator and mapper - * @obj: objective iommu + * @dev: client device * @da: contiguous iommu virtual memory * @bytes: allocation size * @flags: iovma and page property @@ -656,9 +663,10 @@ EXPORT_SYMBOL_GPL(omap_iommu_vunmap); * @da again, which might be adjusted if 'IOVMF_DA_FIXED' is not set. */ u32 -omap_iommu_vmalloc(struct iommu_domain *domain, struct omap_iommu *obj, u32 da, +omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev, u32 da, size_t bytes, u32 flags) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); void *va; struct sg_table *sgt; @@ -698,15 +706,16 @@ EXPORT_SYMBOL_GPL(omap_iommu_vmalloc); /** * omap_iommu_vfree - release memory allocated by 'omap_iommu_vmalloc()' - * @obj: objective iommu + * @dev: client device * @da: iommu device virtual address * * Frees the iommu virtually continuous memory area starting at * @da, as obtained from 'omap_iommu_vmalloc()'. */ -void omap_iommu_vfree(struct iommu_domain *domain, struct omap_iommu *obj, +void omap_iommu_vfree(struct iommu_domain *domain, struct device *dev, const u32 da) { + struct omap_iommu *obj = dev_to_omap_iommu(dev); struct sg_table *sgt; sgt = unmap_vm_area(domain, obj, da, vfree, diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index b818cacf420f..d4c48ef227fb 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c @@ -80,13 +80,6 @@ #include "isph3a.h" #include "isphist.h" -/* - * this is provided as an interim solution until omap3isp doesn't need - * any omap-specific iommu API - */ -#define to_iommu(dev) \ - (struct omap_iommu *)platform_get_drvdata(to_platform_device(dev)) - static unsigned int autoidle; module_param(autoidle, int, 0444); MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support"); @@ -1114,8 +1107,7 @@ isp_restore_context(struct isp_device *isp, struct isp_reg *reg_list) static void isp_save_ctx(struct isp_device *isp) { isp_save_context(isp, isp_reg_list); - if (isp->iommu) - omap_iommu_save_ctx(isp->iommu); + omap_iommu_save_ctx(isp->dev); } /* @@ -1128,8 +1120,7 @@ static void isp_save_ctx(struct isp_device *isp) static void isp_restore_ctx(struct isp_device *isp) { isp_restore_context(isp, isp_reg_list); - if (isp->iommu) - omap_iommu_restore_ctx(isp->iommu); + omap_iommu_restore_ctx(isp->dev); omap3isp_ccdc_restore_context(isp); omap3isp_preview_restore_context(isp); } @@ -1983,7 +1974,7 @@ static int isp_remove(struct platform_device *pdev) isp_cleanup_modules(isp); omap3isp_get(isp); - iommu_detach_device(isp->domain, isp->iommu_dev); + iommu_detach_device(isp->domain, &pdev->dev); iommu_domain_free(isp->domain); omap3isp_put(isp); @@ -2131,17 +2122,6 @@ static int isp_probe(struct platform_device *pdev) } } - /* IOMMU */ - isp->iommu_dev = omap_find_iommu_device("isp"); - if (!isp->iommu_dev) { - dev_err(isp->dev, "omap_find_iommu_device failed\n"); - ret = -ENODEV; - goto error_isp; - } - - /* to be removed once iommu migration is complete */ - isp->iommu = to_iommu(isp->iommu_dev); - isp->domain = iommu_domain_alloc(pdev->dev.bus); if (!isp->domain) { dev_err(isp->dev, "can't alloc iommu domain\n"); @@ -2149,7 +2129,7 @@ static int isp_probe(struct platform_device *pdev) goto error_isp; } - ret = iommu_attach_device(isp->domain, isp->iommu_dev); + ret = iommu_attach_device(isp->domain, &pdev->dev); if (ret) { dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret); goto free_domain; @@ -2188,7 +2168,7 @@ error_modules: error_irq: free_irq(isp->irq_num, isp); detach_dev: - iommu_detach_device(isp->domain, isp->iommu_dev); + iommu_detach_device(isp->domain, &pdev->dev); free_domain: iommu_domain_free(isp->domain); error_isp: diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h index 705946ef4d60..d96603eb0d17 100644 --- a/drivers/media/video/omap3isp/isp.h +++ b/drivers/media/video/omap3isp/isp.h @@ -212,9 +212,7 @@ struct isp_device { unsigned int sbl_resources; unsigned int subclk_resources; - struct omap_iommu *iommu; struct iommu_domain *domain; - struct device *iommu_dev; struct isp_platform_callback platform_cb; }; diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index b0b0fa5a3572..8748e0855c61 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c @@ -366,7 +366,7 @@ static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc, dma_unmap_sg(isp->dev, req->iovm->sgt->sgl, req->iovm->sgt->nents, DMA_TO_DEVICE); if (req->table) - omap_iommu_vfree(isp->domain, isp->iommu, req->table); + omap_iommu_vfree(isp->domain, isp->dev, req->table); kfree(req); } @@ -438,7 +438,7 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, req->enable = 1; - req->table = omap_iommu_vmalloc(isp->domain, isp->iommu, 0, + req->table = omap_iommu_vmalloc(isp->domain, isp->dev, 0, req->config.size, IOMMU_FLAG); if (IS_ERR_VALUE(req->table)) { req->table = 0; @@ -446,7 +446,7 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, goto done; } - req->iovm = omap_find_iovm_area(isp->iommu, req->table); + req->iovm = omap_find_iovm_area(isp->dev, req->table); if (req->iovm == NULL) { ret = -ENOMEM; goto done; @@ -462,7 +462,7 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl, req->iovm->sgt->nents, DMA_TO_DEVICE); - table = omap_da_to_va(isp->iommu, req->table); + table = omap_da_to_va(isp->dev, req->table); if (copy_from_user(table, config->lsc, req->config.size)) { ret = -EFAULT; goto done; @@ -734,15 +734,15 @@ static int ccdc_config(struct isp_ccdc_device *ccdc, * already done by omap_iommu_vmalloc(). */ size = ccdc->fpc.fpnum * 4; - table_new = omap_iommu_vmalloc(isp->domain, isp->iommu, + table_new = omap_iommu_vmalloc(isp->domain, isp->dev, 0, size, IOMMU_FLAG); if (IS_ERR_VALUE(table_new)) return -ENOMEM; - if (copy_from_user(omap_da_to_va(isp->iommu, table_new), + if (copy_from_user(omap_da_to_va(isp->dev, table_new), (__force void __user *) ccdc->fpc.fpcaddr, size)) { - omap_iommu_vfree(isp->domain, isp->iommu, + omap_iommu_vfree(isp->domain, isp->dev, table_new); return -EFAULT; } @@ -753,7 +753,7 @@ static int ccdc_config(struct isp_ccdc_device *ccdc, ccdc_configure_fpc(ccdc); if (table_old != 0) - omap_iommu_vfree(isp->domain, isp->iommu, table_old); + omap_iommu_vfree(isp->domain, isp->dev, table_old); } return ccdc_lsc_config(ccdc, ccdc_struct); @@ -2309,7 +2309,7 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp) ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue); if (ccdc->fpc.fpcaddr != 0) - omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr); + omap_iommu_vfree(isp->domain, isp->dev, ccdc->fpc.fpcaddr); mutex_destroy(&ccdc->ioctl_lock); } diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c index 68d539456c55..9f41aa3d00a5 100644 --- a/drivers/media/video/omap3isp/ispstat.c +++ b/drivers/media/video/omap3isp/ispstat.c @@ -366,7 +366,7 @@ static void isp_stat_bufs_free(struct ispstat *stat) dma_unmap_sg(isp->dev, buf->iovm->sgt->sgl, buf->iovm->sgt->nents, DMA_FROM_DEVICE); - omap_iommu_vfree(isp->domain, isp->iommu, + omap_iommu_vfree(isp->domain, isp->dev, buf->iommu_addr); } else { if (!buf->virt_addr) @@ -400,7 +400,7 @@ static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size) struct iovm_struct *iovm; WARN_ON(buf->dma_addr); - buf->iommu_addr = omap_iommu_vmalloc(isp->domain, isp->iommu, 0, + buf->iommu_addr = omap_iommu_vmalloc(isp->domain, isp->dev, 0, size, IOMMU_FLAG); if (IS_ERR((void *)buf->iommu_addr)) { dev_err(stat->isp->dev, @@ -410,7 +410,7 @@ static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size) return -ENOMEM; } - iovm = omap_find_iovm_area(isp->iommu, buf->iommu_addr); + iovm = omap_find_iovm_area(isp->dev, buf->iommu_addr); if (!iovm || !dma_map_sg(isp->dev, iovm->sgt->sgl, iovm->sgt->nents, DMA_FROM_DEVICE)) { @@ -419,7 +419,7 @@ static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size) } buf->iovm = iovm; - buf->virt_addr = omap_da_to_va(stat->isp->iommu, + buf->virt_addr = omap_da_to_va(stat->isp->dev, (u32)buf->iommu_addr); buf->empty = 1; dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated." diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index d1000723c5ae..9974cfc09090 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c @@ -452,7 +452,7 @@ ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen) sgt->nents = sglen; sgt->orig_nents = sglen; - da = omap_iommu_vmap(isp->domain, isp->iommu, 0, sgt, IOMMU_FLAG); + da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG); if (IS_ERR_VALUE(da)) kfree(sgt); @@ -468,7 +468,7 @@ static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da) { struct sg_table *sgt; - sgt = omap_iommu_vunmap(isp->domain, isp->iommu, (u32)da); + sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da); kfree(sgt); } -- cgit v1.2.3 From bd0552ed05e019995a6fd2b1064919d7c6e14554 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 5 Dec 2011 08:35:55 -0600 Subject: ARM: highbank: add xgmac ethernet devices to dts Add device nodes for xgmac ethernet block in Calxeda Highbank. Signed-off-by: Rob Herring --- arch/arm/boot/dts/highbank.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index aeb1a7578fad..305635bd45c0 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -194,5 +194,17 @@ reg = <0xfff3d000 0x1000>; interrupts = <0 92 4>; }; + + ethernet@fff50000 { + compatible = "calxeda,hb-xgmac"; + reg = <0xfff50000 0x1000>; + interrupts = <0 77 4 0 78 4 0 79 4>; + }; + + ethernet@fff51000 { + compatible = "calxeda,hb-xgmac"; + reg = <0xfff51000 0x1000>; + interrupts = <0 80 4 0 81 4 0 82 4>; + }; }; }; -- cgit v1.2.3 From 8e146f547a5d12498cbbb0190e1b70cca63c1b87 Mon Sep 17 00:00:00 2001 From: Denis Kuzmenko Date: Tue, 6 Dec 2011 20:21:54 +0900 Subject: ARM: S3C2440: Add new LCD (W35i) support for Mini2440 board Signed-off-by: Denis Kuzmenko Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2440/mach-mini2440.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index 91fe0b4c95f1..937eb7818c1a 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c @@ -167,6 +167,24 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { .lcdcon5 = (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_HWSWP), }, + /* mini2440 + 3.5" TFT (LCD-W35i, LQ035Q1DG06 type) + touchscreen*/ + [3] = { + _LCD_DECLARE( + /* clock */ + 7, + /* xres, margin_right, margin_left, hsync */ + 320, 68, 66, 4, + /* yres, margin_top, margin_bottom, vsync */ + 240, 4, 4, 9, + /* refresh rate */ + 60), + .lcdcon5 = (S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVDEN | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVCLK | + S3C2410_LCDCON5_HWSWP), + }, }; /* todo - put into gpio header */ -- cgit v1.2.3 From 7803c7aa8ef262a63e91ee0b04470715a7dc2eb0 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 8 Dec 2011 10:05:52 +0900 Subject: ARM: SAMSUNG: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Kukjin Kim --- arch/arm/plat-s3c24xx/dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 53754bcf15a7..9fe35348e03b 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1437,11 +1437,10 @@ int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel) size_t map_sz = sizeof(*nmap) * sel->map_size; int ptr; - nmap = kmalloc(map_sz, GFP_KERNEL); + nmap = kmemdup(sel->map, map_sz, GFP_KERNEL); if (nmap == NULL) return -ENOMEM; - memcpy(nmap, sel->map, map_sz); memcpy(&dma_sel, sel, sizeof(*sel)); dma_sel.map = nmap; -- cgit v1.2.3 From 39cb263eccc974765eed1100d48ac6f0986ef257 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 8 Dec 2011 10:52:19 +0900 Subject: ARM: S3C64XX: Hook up VDDINT on Cragganmore Basic hookup, we do have a GPIO to use to control the voltage but we don't currently use it. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index b2381c1bb3ba..42d3d64947b0 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -380,6 +380,10 @@ static struct regulator_init_data vddarm __initdata = { .driver_data = &vddarm_pdata, }; +static struct regulator_consumer_supply vddint_consumers[] __initdata = { + REGULATOR_SUPPLY("vddint", NULL), +}; + static struct regulator_init_data vddint __initdata = { .constraints = { .name = "VDDINT", @@ -388,6 +392,9 @@ static struct regulator_init_data vddint __initdata = { .always_on = 1, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, }, + .num_consumer_supplies = ARRAY_SIZE(vddint_consumers), + .consumer_supplies = vddint_consumers, + .supply_regulator = "WALLVDD", }; static struct regulator_init_data vddmem __initdata = { -- cgit v1.2.3 From 317d5330aea392c032a5f8c87df74444fd514910 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 9 Nov 2011 10:33:23 -0800 Subject: arm/tegra: fix variable formatting in makefile For some reason it started out using {} instead of (), and it's proliferated from there. Switch back to (). Signed-off-by: Olof Johansson Acked-by: Colin Cross --- arch/arm/mach-tegra/Makefile | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 91a07e187208..5be8e9eefc95 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -18,20 +18,20 @@ obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o obj-$(CONFIG_TEGRA_PCI) += pcie.o obj-$(CONFIG_USB_SUPPORT) += usb_phy.o -obj-${CONFIG_MACH_HARMONY} += board-harmony.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-pinmux.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-pcie.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-power.o -obj-${CONFIG_MACH_PAZ00} += board-paz00.o -obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o +obj-$(CONFIG_MACH_PAZ00) += board-paz00.o +obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o -obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o -obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_SEABOARD) += board-seaboard.o +obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o -obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o -obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o -obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o -obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o -obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o +obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o +obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o -- cgit v1.2.3 From c27317c0ed114152d02b2ed40056f232e5732b9d Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 4 Nov 2011 09:12:39 +0000 Subject: arm/dt: add basic usb nodes to tegra device trees For now they are a minimal binding. It needs to be amended with vendor-specific settings for phy setup and link tuning, etc. v2: Added bindings specification and phy_type properties Signed-off-by: Olof Johansson Acked-by: Grant Likely Acked-by: Stephen Warren --- Documentation/devicetree/bindings/usb/tegra-usb.txt | 13 +++++++++++++ arch/arm/boot/dts/tegra-seaboard.dts | 4 ++++ arch/arm/boot/dts/tegra20.dtsi | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/tegra-usb.txt (limited to 'arch') diff --git a/Documentation/devicetree/bindings/usb/tegra-usb.txt b/Documentation/devicetree/bindings/usb/tegra-usb.txt new file mode 100644 index 000000000000..035d63d5646d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/tegra-usb.txt @@ -0,0 +1,13 @@ +Tegra SOC USB controllers + +The device node for a USB controller that is part of a Tegra +SOC is as described in the document "Open Firmware Recommended +Practice : Universal Serial Bus" with the following modifications +and additions : + +Required properties : + - compatible : Should be "nvidia,tegra20-ehci" for USB controllers + used in host mode. + - phy_type : Should be one of "ulpi" or "utmi". + - nvidia,vbus-gpio : If present, specifies a gpio that needs to be + activated for the bus to be powered. diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index a72299b8e668..88c682a26cb2 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -29,4 +29,8 @@ sdhci@c8000600 { support-8bit; }; + + usb@c5000000 { + nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */ + }; }; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 65d7e6a333eb..795b921d92fc 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -143,5 +143,26 @@ reg = <0xc8000600 0x200>; interrupts = < 63 >; }; + + usb@c5000000 { + compatible = "nvidia,tegra20-ehci", "usb-ehci"; + reg = <0xc5000000 0x4000>; + interrupts = < 52 >; + phy_type = "utmi"; + }; + + usb@c5004000 { + compatible = "nvidia,tegra20-ehci", "usb-ehci"; + reg = <0xc5004000 0x4000>; + interrupts = < 53 >; + phy_type = "ulpi"; + }; + + usb@c5008000 { + compatible = "nvidia,tegra20-ehci", "usb-ehci"; + reg = <0xc5008000 0x4000>; + interrupts = < 129 >; + phy_type = "utmi"; + }; }; -- cgit v1.2.3 From 4a53f4e692c5df8a4bf9bf059b8007d575b0204a Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 4 Nov 2011 09:12:40 +0000 Subject: USB: ehci-tegra: add probing through device tree Rely on platform_data being passed through auxdata for now; more elaborate bindings for phy config and tunings to be added. v2: moved vbus-gpio check to the helper function, added check for !of_node, added usb2 clock to board-dt table. Signed-off-by: Olof Johansson Cc: Greg Kroah-Hartman Acked-by: Grant Likely --- arch/arm/mach-tegra/board-dt.c | 9 ++++++ drivers/usb/host/ehci-tegra.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index 74743ad3d2d3..7f287a86941e 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -61,12 +61,21 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_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), + OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1", + &tegra_ehci2_device.dev.platform_data), + OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", + &tegra_ehci3_device.dev.platform_data), {} }; static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { /* name parent rate enabled */ { "uartd", "pll_p", 216000000, true }, + { "usbd", "clk_m", 12000000, false }, + { "usb2", "clk_m", 12000000, false }, + { "usb3", "clk_m", 12000000, false }, { NULL, NULL, 0, 0}, }; diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index db9d1b4bfbdc..dbc7fe8ca9e7 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -21,7 +21,12 @@ #include #include #include +#include +#include +#include + #include +#include #define TEGRA_USB_DMA_ALIGN 32 @@ -574,6 +579,35 @@ static const struct hc_driver tegra_ehci_hc_driver = { .port_handed_over = ehci_port_handed_over, }; +static int setup_vbus_gpio(struct platform_device *pdev) +{ + int err = 0; + int gpio; + + if (!pdev->dev.of_node) + return 0; + + gpio = of_get_named_gpio(pdev->dev.of_node, "nvidia,vbus-gpio", 0); + if (!gpio_is_valid(gpio)) + return 0; + + err = gpio_request(gpio, "vbus_gpio"); + if (err) { + dev_err(&pdev->dev, "can't request vbus gpio %d", gpio); + return err; + } + err = gpio_direction_output(gpio, 1); + if (err) { + dev_err(&pdev->dev, "can't enable vbus\n"); + return err; + } + gpio_set_value(gpio, 1); + + return err; +} + +static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); + static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; @@ -590,6 +624,15 @@ static int tegra_ehci_probe(struct platform_device *pdev) return -EINVAL; } + /* Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &tegra_ehci_dma_mask; + + setup_vbus_gpio(pdev); + tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); if (!tegra) return -ENOMEM; @@ -640,6 +683,28 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail_io; } + /* This is pretty ugly and needs to be fixed when we do only + * device-tree probing. Old code relies on the platform_device + * numbering that we lack for device-tree-instantiated devices. + */ + if (instance < 0) { + switch (res->start) { + case TEGRA_USB_BASE: + instance = 0; + break; + case TEGRA_USB2_BASE: + instance = 1; + break; + case TEGRA_USB3_BASE: + instance = 2; + break; + default: + err = -ENODEV; + dev_err(&pdev->dev, "unknown usb instance\n"); + goto fail_phy; + } + } + tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, TEGRA_USB_PHY_MODE_HOST); if (IS_ERR(tegra->phy)) { @@ -773,6 +838,11 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) hcd->driver->shutdown(hcd); } +static struct of_device_id tegra_ehci_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra20-ehci", }, + { }, +}; + static struct platform_driver tegra_ehci_driver = { .probe = tegra_ehci_probe, .remove = tegra_ehci_remove, @@ -783,5 +853,6 @@ static struct platform_driver tegra_ehci_driver = { .shutdown = tegra_ehci_hcd_shutdown, .driver = { .name = "tegra-ehci", + .of_match_table = tegra_ehci_of_match, } }; -- cgit v1.2.3 From 64f88ec3957b8e448e377231d177260ebfda71a2 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 7 Dec 2011 15:13:48 -0700 Subject: arm/dt: tegra: Clean up I2S and DAS nodes The I2S and DAS nodes don't have children, and hence don't need to set address/size cells. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra20.dtsi | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 795b921d92fc..04068dd49286 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -45,8 +45,6 @@ }; i2s@70002800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; interrupts = < 45 >; @@ -54,8 +52,6 @@ }; i2s@70002a00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; interrupts = < 35 >; @@ -63,8 +59,6 @@ }; das@70000c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "nvidia,tegra20-das"; reg = <0x70000c00 0x80>; }; -- cgit v1.2.3 From a7db2c15938668999d4ceb1caec3723d88e38c80 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 25 Oct 2011 02:01:28 +0000 Subject: arm/tegra: Add device-tree support for TrimSlice board * Add device-tree file for TrimSlice * Add that to the list of .dts files to build * Update board-dt.c to recognize TrimSlice board name v2: Makefile: Add board-trimslice-pinmux.c to obj-$(CONFIG_MACH_TEGRA_DT). v3: Makefile: Use brackets not braces around var names Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-trimslice.dts | 38 +++++++++++++++++++++++++++++++++++ arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/Makefile.boot | 1 + arch/arm/mach-tegra/board-dt.c | 3 +++ 4 files changed, 43 insertions(+) create mode 100644 arch/arm/boot/dts/tegra-trimslice.dts (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts new file mode 100644 index 000000000000..d3d0d205a474 --- /dev/null +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -0,0 +1,38 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ "tegra20.dtsi" + +/ { + model = "Compulab TrimSlice board"; + compatible = "compulab,trimslice", "nvidia,tegra20"; + + chosen { + bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p1 rw rootwait"; + }; + + memory@0 { + reg = < 0x00000000 0x40000000 >; + }; + + i2c@7000c000 { + clock-frequency = <400000>; + }; + + i2c@7000c400 { + clock-frequency = <400000>; + }; + + i2c@7000c500 { + clock-frequency = <400000>; + }; + + serial@70006000 { + clock-frequency = < 216000000 >; + }; + + sdhci@c8000600 { + cd-gpios = <&gpio 121 0>; + wp-gpios = <&gpio 122 0>; + }; +}; diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 5be8e9eefc95..565bb2253529 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-trimslice-pinmux.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index bd12c9fb81e8..9f177a466b83 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot @@ -4,4 +4,5 @@ initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb +dtb-$(CONFIG_MACH_TRIMSLICE) += tegra-trimslice.dtb dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index 7f287a86941e..e6b3953a62b9 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -47,6 +47,7 @@ void harmony_pinmux_init(void); void seaboard_pinmux_init(void); +void trimslice_pinmux_init(void); void ventana_pinmux_init(void); struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { @@ -93,6 +94,7 @@ static struct { char *machine; void (*init)(void); } pinmux_configs[] = { + { "compulab,trimslice", trimslice_pinmux_init }, { "nvidia,harmony", harmony_pinmux_init }, { "nvidia,seaboard", seaboard_pinmux_init }, { "nvidia,ventana", ventana_pinmux_init }, @@ -129,6 +131,7 @@ static void __init tegra_dt_init(void) } static const char * tegra_dt_board_compat[] = { + "compulab,trimslice", "nvidia,harmony", "nvidia,seaboard", "nvidia,ventana", -- cgit v1.2.3 From cc2afa43d43cd07d5a34516262d7489e183311a1 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Tue, 1 Nov 2011 10:37:05 +0000 Subject: arm/dt: tegra: add dts file for paz00 This adds a dts file for paz00. As a side effect, this also enables the embedded controller which controls the keyboard, touchpad, power, leds, and some other functions. Cc: Grant Likely Signed-off-by: Marc Dietrich Acked-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-paz00.dts | 82 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/Makefile.boot | 1 + arch/arm/mach-tegra/board-dt.c | 3 ++ 4 files changed, 87 insertions(+) create mode 100644 arch/arm/boot/dts/tegra-paz00.dts (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts new file mode 100644 index 000000000000..15a949f192ff --- /dev/null +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -0,0 +1,82 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ "tegra20.dtsi" + +/ { + model = "Toshiba AC100 / Dynabook AZ"; + compatible = "compal,paz00", "nvidia,tegra20"; + + chosen { + bootargs = "console=ttyS0,115200n8 root=/dev/mmcblk0p1"; + }; + + memory@0 { + reg = <0x00000000 0x20000000>; + }; + + i2c@7000c000 { + clock-frequency = <400000>; + }; + + i2c@7000c400 { + clock-frequency = <400000>; + }; + + i2c@7000c500 { + status = "disable"; + }; + + nvec@7000c500 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,nvec"; + reg = <0x7000C500 0x100>; + interrupts = <124>; + clock-frequency = <80000>; + request-gpios = <&gpio 170 0>; + slave-addr = <138>; + }; + + i2c@7000d000 { + clock-frequency = <400000>; + }; + + serial@70006000 { + clock-frequency = <216000000>; + }; + + serial@70006040 { + status = "disable"; + }; + + serial@70006200 { + status = "disable"; + }; + + serial@70006300 { + clock-frequency = <216000000>; + }; + + serial@70006400 { + status = "disable"; + }; + + sdhci@c8000000 { + cd-gpios = <&gpio 173 0>; /* gpio PV5 */ + wp-gpios = <&gpio 57 0>; /* gpio PH1 */ + power-gpios = <&gpio 155 0>; /* gpio PT3 */ + }; + + sdhci@c8000200 { + status = "disable"; + }; + + sdhci@c8000400 { + status = "disable"; + }; + + sdhci@c8000600 { + support-8bit; + }; +}; diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 565bb2253529..c9ec38e82991 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-paz00-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-trimslice-pinmux.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index 9f177a466b83..cf51a000d400 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot @@ -3,6 +3,7 @@ params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb +dtb-$(CONFIG_MACH_PAZ00) += tegra-paz00.dtb dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb dtb-$(CONFIG_MACH_TRIMSLICE) += tegra-trimslice.dtb dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index e6b3953a62b9..03ccaf1380c1 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -46,6 +46,7 @@ #include "devices.h" void harmony_pinmux_init(void); +void paz00_pinmux_init(void); void seaboard_pinmux_init(void); void trimslice_pinmux_init(void); void ventana_pinmux_init(void); @@ -96,6 +97,7 @@ static struct { } pinmux_configs[] = { { "compulab,trimslice", trimslice_pinmux_init }, { "nvidia,harmony", harmony_pinmux_init }, + { "compal,paz00", paz00_pinmux_init }, { "nvidia,seaboard", seaboard_pinmux_init }, { "nvidia,ventana", ventana_pinmux_init }, }; @@ -133,6 +135,7 @@ static void __init tegra_dt_init(void) static const char * tegra_dt_board_compat[] = { "compulab,trimslice", "nvidia,harmony", + "compal,paz00", "nvidia,seaboard", "nvidia,ventana", NULL -- cgit v1.2.3 From f110164ed68e0a039aff0378d66de157c3816aba Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 7 Dec 2011 15:13:40 -0700 Subject: arm/tegra: board-dt: Fix AUXDATA typo Fix the address of the I2S2 controller in the AUXDATA table. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/board-dt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index 03ccaf1380c1..574e2e7ac930 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -61,7 +61,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_DVC_BASE, "tegra-i2c.3", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL), - OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.1", NULL), + 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), -- cgit v1.2.3 From 586187e22ddc87e95f8ac93f1a1b2a629c983aaf Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 7 Dec 2011 15:13:42 -0700 Subject: arm/tegra: board-dt: Enable audio-related clocks Certain clocks are required for core audio functionality. Set up the appropriate parenting relationships, and enable clocks that must be on permanently. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/board-dt.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index 574e2e7ac930..ba27c13e44e0 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -78,6 +78,11 @@ static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { { "usbd", "clk_m", 12000000, false }, { "usb2", "clk_m", 12000000, false }, { "usb3", "clk_m", 12000000, false }, + { "pll_a", "pll_p_out1", 56448000, true }, + { "pll_a_out0", "pll_a", 11289600, true }, + { "cdev1", NULL, 0, true }, + { "i2s1", "pll_a_out0", 11289600, false}, + { "i2s2", "pll_a_out0", 11289600, false}, { NULL, NULL, 0, 0}, }; -- cgit v1.2.3 From 5a85426506d7593695380dddd92f01f79b2bca4e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 Nov 2011 14:44:07 -0700 Subject: arm/dt: tegra: Remove /memreserve/ from device-tree files There are no drivers in the kernel at present which can make use of the memory reserved by /memreserve/, so there is no point reserving it. Remove /memreserve/ to allow the user more memory. It's also unclear whether any future driver would actually require /memreserve/, or allocate memory through some other mechanism. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-harmony.dts | 1 - arch/arm/boot/dts/tegra-paz00.dts | 1 - arch/arm/boot/dts/tegra-seaboard.dts | 1 - arch/arm/boot/dts/tegra-trimslice.dts | 1 - arch/arm/boot/dts/tegra-ventana.dts | 1 - 5 files changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index 0e225b86b652..a80232443b7f 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -1,6 +1,5 @@ /dts-v1/; -/memreserve/ 0x1c000000 0x04000000; /include/ "tegra20.dtsi" / { diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index 15a949f192ff..1cd0cfe9e3d0 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -1,6 +1,5 @@ /dts-v1/; -/memreserve/ 0x1c000000 0x04000000; /include/ "tegra20.dtsi" / { diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index 88c682a26cb2..60724e4183b4 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -1,6 +1,5 @@ /dts-v1/; -/memreserve/ 0x1c000000 0x04000000; /include/ "tegra20.dtsi" / { diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index d3d0d205a474..95117d31fee3 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -1,6 +1,5 @@ /dts-v1/; -/memreserve/ 0x1c000000 0x04000000; /include/ "tegra20.dtsi" / { diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index 3f9abd6b6964..2af12fa76eef 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -1,6 +1,5 @@ /dts-v1/; -/memreserve/ 0x1c000000 0x04000000; /include/ "tegra20.dtsi" / { -- cgit v1.2.3 From 492f204da87ccfef508d5fff63873bda37d4363b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 Nov 2011 14:44:08 -0700 Subject: arm/dt: tegra: Remove /chosen node The command-lines present in the existing /chosen node are not necessarily correct for all users. Ideally, we should simply use the command-line supplied by the boot-loader. In fact, using the boot-loader's cmdline is quite easy; either the bootloader fully supports DT, in which case it can modify the DT passed to the kernel to include its command-line, or CONFIG_APPENDED_DTB can be used in conjunction with CONFIG_ARM_ATAG_DTB_COMPAT, and the kernel will substitute the bootloader's command-line into the DT. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-harmony.dts | 4 ---- arch/arm/boot/dts/tegra-paz00.dts | 4 ---- arch/arm/boot/dts/tegra-seaboard.dts | 4 ---- arch/arm/boot/dts/tegra-trimslice.dts | 4 ---- arch/arm/boot/dts/tegra-ventana.dts | 4 ---- 5 files changed, 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index a80232443b7f..ca6fa1084c9d 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -6,10 +6,6 @@ model = "NVIDIA Tegra2 Harmony evaluation board"; compatible = "nvidia,harmony", "nvidia,tegra20"; - chosen { - bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait"; - }; - memory@0 { reg = < 0x00000000 0x40000000 >; }; diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index 1cd0cfe9e3d0..4f6a8aa0a757 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -6,10 +6,6 @@ model = "Toshiba AC100 / Dynabook AZ"; compatible = "compal,paz00", "nvidia,tegra20"; - chosen { - bootargs = "console=ttyS0,115200n8 root=/dev/mmcblk0p1"; - }; - memory@0 { reg = <0x00000000 0x20000000>; }; diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index 60724e4183b4..d1ada26b7b90 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -6,10 +6,6 @@ model = "NVIDIA Seaboard"; compatible = "nvidia,seaboard", "nvidia,tegra20"; - chosen { - bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk1p3 rw rootwait"; - }; - memory { device_type = "memory"; reg = < 0x00000000 0x40000000 >; diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index 95117d31fee3..cf8e5617f3bd 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -6,10 +6,6 @@ model = "Compulab TrimSlice board"; compatible = "compulab,trimslice", "nvidia,tegra20"; - chosen { - bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p1 rw rootwait"; - }; - memory@0 { reg = < 0x00000000 0x40000000 >; }; diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index 2af12fa76eef..1c0948541806 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -6,10 +6,6 @@ model = "NVIDIA Tegra2 Ventana evaluation board"; compatible = "nvidia,ventana", "nvidia,tegra20"; - chosen { - bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/ram rdinit=/sbin/init"; - }; - memory { reg = < 0x00000000 0x40000000 >; }; -- cgit v1.2.3 From 88950f3b6d0f49b6b5a2f68bd1f67406c2c73922 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 Nov 2011 14:44:09 -0700 Subject: arm/dt: tegra: Fix I2C nodes to match board files With board files, all I2C busses run at 400KHz. Fix the device-tree to be consistent with this. It's possible this is incorrect, but at least it keeps the board files and device-tree consistent. Also, disable any I2C controllers that the board files don't register, also for consistency. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-seaboard.dts | 16 ++++++++++++++++ arch/arm/boot/dts/tegra-trimslice.dts | 4 ++++ arch/arm/boot/dts/tegra-ventana.dts | 16 ++++++++++++++++ 3 files changed, 36 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index d1ada26b7b90..92da1f1ed3a3 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -11,6 +11,22 @@ reg = < 0x00000000 0x40000000 >; }; + i2c@7000c000 { + clock-frequency = <400000>; + }; + + i2c@7000c400 { + clock-frequency = <400000>; + }; + + i2c@7000c500 { + clock-frequency = <400000>; + }; + + i2c@7000d000 { + clock-frequency = <400000>; + }; + serial@70006300 { clock-frequency = < 216000000 >; }; diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index cf8e5617f3bd..b1aaa45407d4 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -22,6 +22,10 @@ clock-frequency = <400000>; }; + i2c@7000d000 { + 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 1c0948541806..0f14ee373e76 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -10,6 +10,22 @@ reg = < 0x00000000 0x40000000 >; }; + i2c@7000c000 { + clock-frequency = <400000>; + }; + + i2c@7000c400 { + clock-frequency = <400000>; + }; + + i2c@7000c500 { + clock-frequency = <400000>; + }; + + i2c@7000d000 { + clock-frequency = <400000>; + }; + serial@70006300 { clock-frequency = < 216000000 >; }; -- cgit v1.2.3 From 31c1ec9282d28f4eecb5f2e431f67accdf420ac2 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 Nov 2011 14:44:10 -0700 Subject: arm/dt: tegra: Fix serial nodes to match board files Mark any serial ports that aren't registered by the board files as disabled in the device-tree files. In practice, none of the now-disabled ports ended up succeeding device probing because of the missing clock-frequency property. However, explicitly marking the devices disabled has the advantage of squashing the dev_warn() the failed probe causes, and documenting that we intend the port not to be used, rather than accidentally left out the property. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-harmony.dts | 16 ++++++++++++++++ arch/arm/boot/dts/tegra-seaboard.dts | 16 ++++++++++++++++ arch/arm/boot/dts/tegra-trimslice.dts | 16 ++++++++++++++++ arch/arm/boot/dts/tegra-ventana.dts | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index ca6fa1084c9d..ac179a05cfe3 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -47,10 +47,26 @@ ext-mic-en-gpios = <&gpio 185 0>; }; + serial@70006000 { + status = "disable"; + }; + + serial@70006040 { + status = "disable"; + }; + + serial@70006200 { + status = "disable"; + }; + serial@70006300 { clock-frequency = < 216000000 >; }; + serial@70006400 { + status = "disable"; + }; + sdhci@c8000200 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index 92da1f1ed3a3..cbb2f085ac23 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -27,10 +27,26 @@ clock-frequency = <400000>; }; + serial@70006000 { + status = "disable"; + }; + + serial@70006040 { + status = "disable"; + }; + + serial@70006200 { + status = "disable"; + }; + serial@70006300 { clock-frequency = < 216000000 >; }; + serial@70006400 { + status = "disable"; + }; + sdhci@c8000400 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index b1aaa45407d4..6060ce0ae77c 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -30,6 +30,22 @@ clock-frequency = < 216000000 >; }; + serial@70006040 { + status = "disable"; + }; + + serial@70006200 { + status = "disable"; + }; + + serial@70006300 { + status = "disable"; + }; + + serial@70006400 { + status = "disable"; + }; + sdhci@c8000600 { cd-gpios = <&gpio 121 0>; wp-gpios = <&gpio 122 0>; diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index 0f14ee373e76..5ac0aa300fe0 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -26,10 +26,26 @@ clock-frequency = <400000>; }; + serial@70006000 { + status = "disable"; + }; + + serial@70006040 { + status = "disable"; + }; + + serial@70006200 { + status = "disable"; + }; + serial@70006300 { clock-frequency = < 216000000 >; }; + serial@70006400 { + status = "disable"; + }; + sdhci@c8000400 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ -- cgit v1.2.3 From 1292c129597ce42a75d9e97cd312c3242e10a6f3 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 Nov 2011 14:44:11 -0700 Subject: arm/dt: tegra: Fix SDHCI nodes to match board files Mark any SDHCI controllers that aren't registered by the board files as disabled in the device-tree files. In practice, these controllers: * Have nothing hooked up to them at all, or * For ports intended for SDIO usage, the drivers for anything that might be attached are not in the device-tree yet. If/when drivers appear, the SD/MMC port can be re-enabled. The only possible exception is TrimSlice's mico SD slot, but that wasn't enabled in the board files before anyway, and doesn't work when all the SDHCI controllers are enabled anyway. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-harmony.dts | 8 ++++++++ arch/arm/boot/dts/tegra-seaboard.dts | 8 ++++++++ arch/arm/boot/dts/tegra-trimslice.dts | 12 ++++++++++++ arch/arm/boot/dts/tegra-ventana.dts | 8 ++++++++ 4 files changed, 36 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index ac179a05cfe3..80afa1b70b80 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -67,12 +67,20 @@ status = "disable"; }; + sdhci@c8000000 { + status = "disable"; + }; + sdhci@c8000200 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ power-gpios = <&gpio 155 0>; /* gpio PT3 */ }; + sdhci@c8000400 { + status = "disable"; + }; + sdhci@c8000600 { cd-gpios = <&gpio 58 0>; /* gpio PH2 */ wp-gpios = <&gpio 59 0>; /* gpio PH3 */ diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index cbb2f085ac23..f552bcc04412 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -47,6 +47,14 @@ status = "disable"; }; + sdhci@c8000000 { + status = "disable"; + }; + + sdhci@c8000200 { + status = "disable"; + }; + sdhci@c8000400 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index 6060ce0ae77c..3b3ee7db99f3 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -46,6 +46,18 @@ status = "disable"; }; + sdhci@c8000000 { + status = "disable"; + }; + + sdhci@c8000200 { + status = "disable"; + }; + + sdhci@c8000400 { + status = "disable"; + }; + sdhci@c8000600 { cd-gpios = <&gpio 121 0>; wp-gpios = <&gpio 122 0>; diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index 5ac0aa300fe0..c7d3b87f29df 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -46,6 +46,14 @@ status = "disable"; }; + sdhci@c8000000 { + status = "disable"; + }; + + sdhci@c8000200 { + status = "disable"; + }; + sdhci@c8000400 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ -- cgit v1.2.3 From c1c374d58c5678fd2364c767f4281342e5362b29 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Tue, 1 Nov 2011 10:37:03 +0000 Subject: ARM: tegra: paz00: add support for wakeup gpio key This adds support for a wakeup gpio which is connected to the embedded controller. This will be used later on for wakeup from suspend. Acked-by: Stephen Warren Signed-off-by: Marc Dietrich Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/board-paz00.c | 27 +++++++++++++++++++++++++++ arch/arm/mach-tegra/board-paz00.h | 3 +++ 2 files changed, 30 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 55c55ba89f1e..799e4201ecf3 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -23,8 +23,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -114,12 +116,37 @@ static struct platform_device leds_gpio = { }, }; +static struct gpio_keys_button paz00_gpio_keys_buttons[] = { + { + .code = KEY_POWER, + .gpio = TEGRA_GPIO_POWERKEY, + .active_low = 1, + .desc = "Power", + .type = EV_KEY, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data paz00_gpio_keys = { + .buttons = paz00_gpio_keys_buttons, + .nbuttons = ARRAY_SIZE(paz00_gpio_keys_buttons), +}; + +static struct platform_device gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &paz00_gpio_keys, + }, +}; + static struct platform_device *paz00_devices[] __initdata = { &debug_uart, &tegra_sdhci_device4, &tegra_sdhci_device1, &wifi_rfkill_device, &leds_gpio, + &gpio_keys_device, }; static void paz00_i2c_init(void) diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h index 8aff06eb58c3..ffa83f580db6 100644 --- a/arch/arm/mach-tegra/board-paz00.h +++ b/arch/arm/mach-tegra/board-paz00.h @@ -32,6 +32,9 @@ #define TEGRA_WIFI_RST TEGRA_GPIO_PD1 #define TEGRA_WIFI_LED TEGRA_GPIO_PD0 +/* WakeUp */ +#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PJ7 + void paz00_pinmux_init(void); #endif -- cgit v1.2.3 From 50ca0d911b1eb0d5bb10e0638d09456e713120c8 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Sat, 15 Oct 2011 17:18:33 +0200 Subject: ARM: tegra: paz00: Fix board pinmux table. This fix updates the CDEV1 pinmux for the paz00 board to be as in the Harmony board. Paz00 board is originally based on Harmony design. Signed-off-by: Leon Romanovsky Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/board-paz00-pinmux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c index be30e215f4b7..126892cfddce 100644 --- a/arch/arm/mach-tegra/board-paz00-pinmux.c +++ b/arch/arm/mach-tegra/board-paz00-pinmux.c @@ -30,7 +30,7 @@ static struct tegra_pingroup_config paz00_pinmux[] = { {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, -- cgit v1.2.3 From 584634e327bc34cfcddae38b604a10b901263970 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 9 Nov 2011 10:33:23 -0800 Subject: arm/tegra: fix variable formatting in makefile For some reason it started out using {} instead of (), and it's proliferated from there. Switch back to (). Signed-off-by: Olof Johansson Acked-by: Colin Cross --- arch/arm/mach-tegra/Makefile | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 91a07e187208..5be8e9eefc95 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -18,20 +18,20 @@ obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o obj-$(CONFIG_TEGRA_PCI) += pcie.o obj-$(CONFIG_USB_SUPPORT) += usb_phy.o -obj-${CONFIG_MACH_HARMONY} += board-harmony.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-pinmux.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-pcie.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-power.o -obj-${CONFIG_MACH_PAZ00} += board-paz00.o -obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o +obj-$(CONFIG_MACH_PAZ00) += board-paz00.o +obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o -obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o -obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_SEABOARD) += board-seaboard.o +obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o -obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o -obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o -obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o -obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o -obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o +obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o +obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o -- cgit v1.2.3 From 103c43a2c6aaf7fc4932513e2991cdec60411b18 Mon Sep 17 00:00:00 2001 From: "pdeschrijver@nvidia.com" Date: Wed, 2 Nov 2011 05:25:23 +0000 Subject: arm/tegra: remove unused defines PPI_NR is never used in arch/arm/mach-tegra/irq.c. Remove it. Signed-off-by: Peter De Schrijver Acked-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/irq.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4956c3cea731..8ad82af6a293 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -28,10 +28,6 @@ #include "board.h" -#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) -#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) -#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) - #define ICTLR_CPU_IEP_VFIQ 0x08 #define ICTLR_CPU_IEP_FIR 0x14 #define ICTLR_CPU_IEP_FIR_SET 0x18 -- cgit v1.2.3 From 0d4f74792e2946cb2ef40a1673851eda1041358c Mon Sep 17 00:00:00 2001 From: "pdeschrijver@nvidia.com" Date: Tue, 29 Nov 2011 18:29:19 -0700 Subject: arm/tegra: convert tegra20 to GIC devicetree binding Convert tegra20 IRQ intialization to the GIC devicetree binding. Modify the interrupt definitions in the dts files according to Documentation/devicetree/bindings/arm/gic.txt v3 (swarren): * Moved of_irq_init() call into board-dt.c to avoid ifdef'ing it. - Even with a dummy replacement if !CONFIG_OF, the reference from tegra_dt_irq_match[] to gic_of_init() would still have to be ifdef'd - It's plausible that tegra_dt_irq_match[] may need to contain more entries in the future, and defining what they are seems more suitable for board-dt.c than irq.c v2 (swarren): * Removed some stale GIC init code from board-dt.c * Undid some accidental 0x -> 0x0 search/replace. Signed-off-by: Peter De Schrijver Acked-by: Rob Herring Signed-off-by: Stephen Warren [olof: added include of for compile to pass] Signed-off-by: Olof Johansson --- arch/arm/boot/dts/tegra-paz00.dts | 2 +- arch/arm/boot/dts/tegra20.dtsi | 48 ++++++++++++++++++++++----------------- arch/arm/mach-tegra/board-dt.c | 25 ++++++++++---------- arch/arm/mach-tegra/irq.c | 10 ++++++-- 4 files changed, 49 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index 4f6a8aa0a757..1a1d7023b69b 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -27,7 +27,7 @@ #size-cells = <0>; compatible = "nvidia,nvec"; reg = <0x7000C500 0x100>; - interrupts = <124>; + interrupts = <0 92 0x04>; clock-frequency = <80000>; request-gpios = <&gpio 170 0>; slave-addr = <138>; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 04068dd49286..660c8ad537c0 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -5,9 +5,9 @@ interrupt-parent = <&intc>; intc: interrupt-controller@50041000 { - compatible = "nvidia,tegra20-gic"; + compatible = "arm,cortex-a9-gic"; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <3>; reg = < 0x50041000 0x1000 >, < 0x50040100 0x0100 >; }; @@ -17,7 +17,7 @@ #size-cells = <0>; compatible = "nvidia,tegra20-i2c"; reg = <0x7000C000 0x100>; - interrupts = < 70 >; + interrupts = < 0 38 0x04 >; }; i2c@7000c400 { @@ -25,7 +25,7 @@ #size-cells = <0>; compatible = "nvidia,tegra20-i2c"; reg = <0x7000C400 0x100>; - interrupts = < 116 >; + interrupts = < 0 84 0x04 >; }; i2c@7000c500 { @@ -33,7 +33,7 @@ #size-cells = <0>; compatible = "nvidia,tegra20-i2c"; reg = <0x7000C500 0x100>; - interrupts = < 124 >; + interrupts = < 0 92 0x04 >; }; i2c@7000d000 { @@ -41,20 +41,20 @@ #size-cells = <0>; compatible = "nvidia,tegra20-i2c"; reg = <0x7000D000 0x200>; - interrupts = < 85 >; + interrupts = < 0 53 0x04 >; }; i2s@70002800 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; - interrupts = < 45 >; + interrupts = < 0 13 0x04 >; dma-channel = < 2 >; }; i2s@70002a00 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; - interrupts = < 35 >; + interrupts = < 0 3 0x04 >; dma-channel = < 1 >; }; @@ -66,7 +66,13 @@ gpio: gpio@6000d000 { compatible = "nvidia,tegra20-gpio"; reg = < 0x6000d000 0x1000 >; - interrupts = < 64 65 66 67 87 119 121 >; + interrupts = < 0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04 >; #gpio-cells = <2>; gpio-controller; }; @@ -83,79 +89,79 @@ compatible = "nvidia,tegra20-uart"; reg = <0x70006000 0x40>; reg-shift = <2>; - interrupts = < 68 >; + interrupts = < 0 36 0x04 >; }; serial@70006040 { compatible = "nvidia,tegra20-uart"; reg = <0x70006040 0x40>; reg-shift = <2>; - interrupts = < 69 >; + interrupts = < 0 37 0x04 >; }; serial@70006200 { compatible = "nvidia,tegra20-uart"; reg = <0x70006200 0x100>; reg-shift = <2>; - interrupts = < 78 >; + interrupts = < 0 46 0x04 >; }; serial@70006300 { compatible = "nvidia,tegra20-uart"; reg = <0x70006300 0x100>; reg-shift = <2>; - interrupts = < 122 >; + interrupts = < 0 90 0x04 >; }; serial@70006400 { compatible = "nvidia,tegra20-uart"; reg = <0x70006400 0x100>; reg-shift = <2>; - interrupts = < 123 >; + interrupts = < 0 91 0x04 >; }; sdhci@c8000000 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000000 0x200>; - interrupts = < 46 >; + interrupts = < 0 14 0x04 >; }; sdhci@c8000200 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000200 0x200>; - interrupts = < 47 >; + interrupts = < 0 15 0x04 >; }; sdhci@c8000400 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000400 0x200>; - interrupts = < 51 >; + interrupts = < 0 19 0x04 >; }; sdhci@c8000600 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000600 0x200>; - interrupts = < 63 >; + interrupts = < 0 31 0x04 >; }; usb@c5000000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5000000 0x4000>; - interrupts = < 52 >; + interrupts = < 0 20 0x04 >; phy_type = "utmi"; }; usb@c5004000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5004000 0x4000>; - interrupts = < 53 >; + interrupts = < 0 21 0x04 >; phy_type = "ulpi"; }; usb@c5008000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5008000 0x4000>; - interrupts = < 129 >; + interrupts = < 0 97 0x04 >; phy_type = "utmi"; }; }; diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index ba27c13e44e0..2fa599da7deb 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,17 @@ void seaboard_pinmux_init(void); void trimslice_pinmux_init(void); void ventana_pinmux_init(void); +static const struct of_device_id tegra_dt_irq_match[] __initconst = { + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init }, + { } +}; + +void __init tegra_dt_init_irq(void) +{ + tegra_init_irq(); + of_irq_init(tegra_dt_irq_match); +} + struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), @@ -91,11 +103,6 @@ static struct of_device_id tegra_dt_match_table[] __initdata = { {} }; -static struct of_device_id tegra_dt_gic_match[] __initdata = { - { .compatible = "nvidia,tegra20-gic", }, - {} -}; - static struct { char *machine; void (*init)(void); @@ -109,14 +116,8 @@ static struct { static void __init tegra_dt_init(void) { - struct device_node *node; int i; - node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match, - TEGRA_ARM_INT_DIST_BASE); - if (node) - irq_domain_add_simple(node, INT_GIC_BASE); - tegra_clk_init_from_table(tegra_dt_clk_init_table); /* @@ -149,7 +150,7 @@ static const char * tegra_dt_board_compat[] = { DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)") .map_io = tegra_map_common_io, .init_early = tegra_init_early, - .init_irq = tegra_init_irq, + .init_irq = tegra_dt_init_irq, .timer = &tegra_timer, .init_machine = tegra_dt_init, .dt_compat = tegra_dt_board_compat, diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4956c3cea731..004b0fdf0d76 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -129,6 +130,11 @@ void __init tegra_init_irq(void) gic_arch_extn.irq_unmask = tegra_unmask; gic_arch_extn.irq_retrigger = tegra_retrigger; - gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), - IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); + /* + * Check if there is a devicetree present, since the GIC will be + * initialized elsewhere under DT. + */ + if (!of_have_populated_dt()) + gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), + IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); } -- cgit v1.2.3 From f5ce5e7e9cc3f69c3e6a0a4599262f740aff92c0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 2 Nov 2011 13:50:43 -0600 Subject: arm/tegra: Remove code that's ifndef CONFIG_ARM_GIC entry-macro.S contains some stale code for chips before Tegra20 that apparently didn't use an ARM GIC. All chips supported by mainline use an ARM GIC, so rip out the stale code. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/include/mach/entry-macro.S | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S index dd165c53889d..485a11eeaceb 100644 --- a/arch/arm/mach-tegra/include/mach/entry-macro.S +++ b/arch/arm/mach-tegra/include/mach/entry-macro.S @@ -15,7 +15,6 @@ #include #include -#if defined(CONFIG_ARM_GIC) #define HAVE_GET_IRQNR_PREAMBLE #include @@ -32,25 +31,3 @@ .macro arch_ret_to_user, tmp1, tmp2 .endm -#else - /* legacy interrupt controller for AP16 */ - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - @ enable imprecise aborts - cpsie a - @ EVP base at 0xf010f000 - mov \base, #0xf0000000 - orr \base, #0x00100000 - orr \base, #0x0000f000 - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS - cmp \irqnr, #0x80 - .endm -#endif -- cgit v1.2.3 From 6f7c047164631a474a544266355767d9edbac50c Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 8 Dec 2011 15:07:19 +0800 Subject: ARM: pxa: fix the build error because of missing gpio-pxa.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/arm/mach-pxa/corgi_pm.c: In function ‘corgi_should_wakeup’: arch/arm/mach-pxa/corgi_pm.c:102:2: error: implicit declaration of function ‘GPIO_bit’ make[1]: *** [arch/arm/mach-pxa/corgi_pm.o] Error 1 make: *** [arch/arm/mach-pxa] Error 2 Signed-off-by: Haojian Zhuang Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/corgi_pm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index eca862fb2cd5..39e265cfc86d 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From e0bf102e1df73182e98c5ff96711b04534bc7bd9 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 8 Dec 2011 15:07:18 +0800 Subject: ARM: pxa: fix build error for GPIO_bit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/arm/mach-pxa/spitz_pm.c: In function ‘spitz_presuspend’: arch/arm/mach-pxa/spitz_pm.c:112:2: error: implicit declaration of function ‘GPIO_bit’ make[1]: *** [arch/arm/mach-pxa/spitz_pm.o] Error 1 GPIO_bit() is moved into . Signed-off-by: Haojian Zhuang Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/spitz_pm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 5cc05d122d0c..34cbdac51525 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 0db1803e4ee459fd261915a2f1b2c39bb34767eb Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 3 Mar 2011 17:36:52 +0530 Subject: ARM: OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit OMAP4 L2X0 initialisation code uses BUG_ON() for the ioremap() failure scenarios. Use WARN_ON() instead and allow graceful function exits. This was suggsted by Kevin Hilman during OMAP4 PM code review. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap4-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index beecfdd56ea3..21d4821c9612 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -72,7 +72,8 @@ static int __init omap_l2_cache_init(void) /* Static mapping, never released */ l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); - BUG_ON(!l2cache_base); + if (WARN_ON(!l2cache_base)) + return -ENOMEM; /* * 16-way associativity, parity disabled -- cgit v1.2.3 From 02afe8a7f23d562cec76743ae34c4735d2819345 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 3 Mar 2011 18:03:25 +0530 Subject: ARM: OMAP4: Export omap4_get_base*() rather than global address pointers This patch exports APIs to get base address for GIC distributor, CPU interface, SCU and PL310 L2 Cache which are used in OMAP4 PM code. This was suggested by Kevin Hilman during OMAP4 PM code review. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 11 ++++++++++- arch/arm/mach-omap2/omap-smp.c | 5 +++++ arch/arm/mach-omap2/omap4-common.c | 7 ++++++- 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 012bac7d56a5..ca04152a9199 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -168,7 +168,16 @@ void omap3_intc_handle_irq(struct pt_regs *regs); #endif #ifdef CONFIG_CACHE_L2X0 -extern void __iomem *l2cache_base; +extern void __iomem *omap4_get_l2cache_base(void); +#endif + +#ifdef CONFIG_SMP +extern void __iomem *omap4_get_scu_base(void); +#else +static inline void __iomem *omap4_get_scu_base(void) +{ + return NULL; +} #endif extern void __init gic_init_irq(void); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index e99bc6cd4714..74e90b40a0c7 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -32,6 +32,11 @@ static void __iomem *scu_base; static DEFINE_SPINLOCK(boot_lock); +void __iomem *omap4_get_scu_base(void) +{ + return scu_base; +} + void __cpuinit platform_secondary_init(unsigned int cpu) { /* diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 21d4821c9612..4a3d2898543b 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -26,7 +26,7 @@ #include "common.h" #ifdef CONFIG_CACHE_L2X0 -void __iomem *l2cache_base; +static void __iomem *l2cache_base; #endif void __init gic_init_irq(void) @@ -47,6 +47,11 @@ void __init gic_init_irq(void) #ifdef CONFIG_CACHE_L2X0 +void __iomem *omap4_get_l2cache_base(void) +{ + return l2cache_base; +} + static void omap4_l2x0_disable(void) { /* Disable PL310 L2 Cache controller */ -- cgit v1.2.3 From 501f0c751de06d8484b4279131c26f58bd49a69d Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sat, 1 Jan 2011 19:56:04 +0530 Subject: ARM: OMAP4: PM: Add SAR RAM support This patch adds SAR RAM support on OMAP4430. SAR RAM used to save and restore the HW context in low power modes. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/omap4-common.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 22 ++++++++++++++++++++++ arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 4 files changed, 54 insertions(+) create mode 100644 arch/arm/mach-omap2/omap4-sar-layout.h (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index ca04152a9199..7ebcb6a9b73e 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -182,6 +182,7 @@ static inline void __iomem *omap4_get_scu_base(void) extern void __init gic_init_irq(void); extern void omap_smc1(u32 fn, u32 arg); +extern void __iomem *omap4_get_sar_ram_base(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 4a3d2898543b..2489f5b8b983 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -24,11 +24,14 @@ #include #include "common.h" +#include "omap4-sar-layout.h" #ifdef CONFIG_CACHE_L2X0 static void __iomem *l2cache_base; #endif +static void __iomem *sar_ram_base; + void __init gic_init_irq(void) { void __iomem *omap_irq_base; @@ -118,3 +121,30 @@ static int __init omap_l2_cache_init(void) } early_initcall(omap_l2_cache_init); #endif + +void __iomem *omap4_get_sar_ram_base(void) +{ + return sar_ram_base; +} + +/* + * SAR RAM used to save and restore the HW + * context in low power modes + */ +static int __init omap4_sar_ram_init(void) +{ + /* + * To avoid code running on other OMAPs in + * multi-omap builds + */ + if (!cpu_is_omap44xx()) + return -ENOMEM; + + /* Static mapping, never released */ + sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K); + if (WARN_ON(!sar_ram_base)) + return -ENOMEM; + + return 0; +} +early_initcall(omap4_sar_ram_init); diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h new file mode 100644 index 000000000000..7781ea4dacbc --- /dev/null +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -0,0 +1,22 @@ +/* + * omap4-sar-layout.h: OMAP4 SAR RAM layout header file + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * 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 OMAP_ARCH_OMAP4_SAR_LAYOUT_H +#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H + +/* + * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE + */ +#define SAR_BANK1_OFFSET 0x0000 +#define SAR_BANK2_OFFSET 0x1000 +#define SAR_BANK3_OFFSET 0x2000 +#define SAR_BANK4_OFFSET 0x3000 + +#endif diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index ea2b8a6306e7..c0d478e55c84 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -45,6 +45,7 @@ #define OMAP44XX_WKUPGEN_BASE 0x48281000 #define OMAP44XX_MCPDM_BASE 0x40132000 #define OMAP44XX_MCPDM_L3_BASE 0x49032000 +#define OMAP44XX_SAR_RAM_BASE 0x4a326000 #define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) #define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000) -- cgit v1.2.3 From 12f27826bdaf56b01cbdfc8bdeb577ebc106dee3 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Tue, 8 Mar 2011 18:24:30 +0530 Subject: ARM: OMAP4: PM: Keep static dep between MPUSS-EMIF and MPUSS-L3/L4 and DUCATI-L3 As per OMAP4430 TRM, the dynamic dependency between MPUSS -> EMIF and MPUSS -> L4PER/L3_* and DUCATI -> L3_* clockdomains is enable by default. Refer register CM_MPU_DYNAMICDEP description for details. But these dynamic dependencies doesn't work as expected. The hardware recommendation is to enable static dependencies for above clockdomains. Without this, system locks up or randomly crashes. Signed-off-by: Rajendra Nayak Signed-off-by: Santosh Shilimkar Acked-by: Paul Walmsley Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm44xx.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 8edb015f5618..715035d0512a 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -99,6 +99,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) static int __init omap4_pm_init(void) { int ret; + struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; + struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; if (!cpu_is_omap44xx()) return -ENODEV; @@ -111,6 +113,34 @@ static int __init omap4_pm_init(void) goto err2; } + /* + * The dynamic dependency between MPUSS -> MEMIF and + * 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. + */ + 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"); + ducati_clkdm = clkdm_lookup("ducati_clkdm"); + if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || + (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm)) + goto err2; + + ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); + 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(ducati_clkdm, l3_1_clkdm); + ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); + if (ret) { + pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 " + "wakeup dependency\n"); + goto err2; + } + #ifdef CONFIG_SUSPEND suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ -- cgit v1.2.3 From 361b02f3538bc5603a426ed3bb04129a8d7b9a67 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 11 Mar 2011 16:13:09 +0530 Subject: ARM: OMAP4: PM: Avoid omap4_pm_init() on OMAP4430 ES1.0 On OMAP4430 ES1.0, Power Management features are not supported. Avoid omap4_pm_init() on ES1.0 silicon so that we can continue to use same kernel binary to boot on all OMAP4 silicons. The ES1.0 boot failure with OMAP4 PM series was because of the clockdomain initialisation code. Hardware supervised clockdomain mode isn't functional for all clockdomains on OMAP4430 ES1.0 silicon so avoid the same. Signed-off-by: Santosh Shilimkar Reported-by: Kevin Hilman Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm44xx.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 715035d0512a..35d392abcaa4 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -105,6 +105,11 @@ static int __init omap4_pm_init(void) if (!cpu_is_omap44xx()) return -ENODEV; + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + pr_err("Power Management for TI OMAP4.\n"); ret = pwrdm_for_each(pwrdms_setup, NULL); -- cgit v1.2.3 From 3c50729b3fa1cd8ca1f347e6caf1081204cf1a7c Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 5 Jan 2011 22:03:17 +0530 Subject: ARM: OMAP4: PM: Initialise all the clockdomains to supported states Initialise hardware supervised mode for all clockdomains if it's supported. Initiate sleep transition for other clockdomains, if they are not being used. Signed-off-by: Santosh Shilimkar Signed-off-by: Rajendra Nayak Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm44xx.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 35d392abcaa4..c34139dc8d8c 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -17,6 +17,7 @@ #include #include "common.h" +#include "clockdomain.h" #include "powerdomain.h" struct power_state { @@ -73,6 +74,22 @@ static const struct platform_suspend_ops omap_pm_ops = { }; #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; @@ -146,6 +163,8 @@ static int __init omap4_pm_init(void) goto err2; } + (void) clkdm_for_each(clkdms_setup, NULL); + #ifdef CONFIG_SUSPEND suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ -- cgit v1.2.3 From ba9456ac9c72a7a5d4d59340aba4259351832521 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 6 Jun 2011 17:56:49 +0530 Subject: ARM: OMAP: Add Secure HAL and monitor mode API infrastructure. On OMAP secure/emulation devices, certain APIs are exported by secure code. Add an infrastructure so that relevant operations on secure devices can be implemented using it. While at this, rename omap44xx-smc.S to omap-smc.S since the common APIs can be used on other OMAP's too. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Makefile | 11 ++-- arch/arm/mach-omap2/include/mach/omap-secure.h | 40 +++++++++++++ arch/arm/mach-omap2/omap-secure.c | 52 +++++++++++++++++ arch/arm/mach-omap2/omap-smc.S | 80 ++++++++++++++++++++++++++ arch/arm/mach-omap2/omap44xx-smc.S | 57 ------------------ 5 files changed, 178 insertions(+), 62 deletions(-) create mode 100644 arch/arm/mach-omap2/include/mach/omap-secure.h create mode 100644 arch/arm/mach-omap2/omap-secure.c create mode 100644 arch/arm/mach-omap2/omap-smc.S delete mode 100644 arch/arm/mach-omap2/omap44xx-smc.S (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index b009f17dee56..bd3a224d1678 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -11,10 +11,11 @@ hwmod-common = omap_hwmod.o \ omap_hwmod_common_data.o clock-common = clock.o clock_common_data.o \ clkt_dpll.o clkt_clksel.o +secure-common = omap-smc.o omap-secure.o -obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) -obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) -obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) +obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common) +obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) +obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common) obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o @@ -24,11 +25,11 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o 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) += omap44xx-smc.o omap4-common.o +obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) -AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec) # Functions loaded to SRAM obj-$(CONFIG_SOC_OMAP2420) += sram242x.o diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h new file mode 100644 index 000000000000..26e7bcc49adc --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/omap-secure.h @@ -0,0 +1,40 @@ +/* + * omap-secure.h: OMAP Secure infrastructure header. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * 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 OMAP_ARCH_OMAP_SECURE_H +#define OMAP_ARCH_OMAP_SECURE_H + +/* Monitor error code */ +#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE +#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF + +/* HAL API error codes */ +#define API_HAL_RET_VALUE_OK 0x00 +#define API_HAL_RET_VALUE_FAIL 0x01 + +/* Secure HAL API flags */ +#define FLAG_START_CRITICAL 0x4 +#define FLAG_IRQFIQ_MASK 0x3 +#define FLAG_IRQ_ENABLE 0x2 +#define FLAG_FIQ_ENABLE 0x1 +#define NO_FLAG 0x0 + + +/* Secure low power HAL API index */ +#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a +#define OMAP4_HAL_SAVEHW_INDEX 0x1b +#define OMAP4_HAL_SAVEALL_INDEX 0x1c +#define OMAP4_HAL_SAVEGIC_INDEX 0x1d + +extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, + u32 arg1, u32 arg2, u32 arg3, u32 arg4); +extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); + +#endif /* OMAP_ARCH_OMAP_SECURE_H */ diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c new file mode 100644 index 000000000000..e5a606e59b1e --- /dev/null +++ b/arch/arm/mach-omap2/omap-secure.c @@ -0,0 +1,52 @@ +/* + * OMAP Secure API infrastructure. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * + * 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 +#include +#include + +#include + +#include + +/** + * omap_sec_dispatcher: Routine to dispatch low power secure + * service routines + * @idx: The HAL API index + * @flag: The flag indicating criticality of operation + * @nargs: Number of valid arguments out of four. + * @arg1, arg2, arg3 args4: Parameters passed to secure API + * + * Return the non-zero error value on failure. + */ +u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, + u32 arg3, u32 arg4) +{ + u32 ret; + u32 param[5]; + + param[0] = nargs; + param[1] = arg1; + param[2] = arg2; + param[3] = arg3; + param[4] = arg4; + + /* + * Secure API needs physical address + * pointer for the parameters + */ + flush_cache_all(); + outer_clean_range(__pa(param), __pa(param + 5)); + ret = omap_smc2(idx, flag, __pa(param)); + + return ret; +} diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S new file mode 100644 index 000000000000..f6441c13cd8c --- /dev/null +++ b/arch/arm/mach-omap2/omap-smc.S @@ -0,0 +1,80 @@ +/* + * OMAP44xx secure APIs file. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Written by Santosh Shilimkar + * + * + * 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 + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. It uses few CPU registers + * internally and hence they need be backed up including + * link register "lr". + * Function signature : void omap_smc1(u32 fn, u32 arg) + */ + +ENTRY(omap_smc1) + stmfd sp!, {r2-r12, lr} + mov r12, r0 + mov r0, r1 + dsb + smc #0 + ldmfd sp!, {r2-r12, pc} +ENDPROC(omap_smc1) + +/** + * u32 omap_smc2(u32 id, u32 falg, u32 pargs) + * Low level common routine for secure HAL and PPA APIs. + * @id: Application ID of HAL APIs + * @flag: Flag to indicate the criticality of operation + * @pargs: Physical address of parameter list starting + * with number of parametrs + */ +ENTRY(omap_smc2) + stmfd sp!, {r4-r12, lr} + mov r3, r2 + mov r2, r1 + mov r1, #0x0 @ Process ID + mov r6, #0xff + mov r12, #0x00 @ Secure Service ID + mov r7, #0 + mcr p15, 0, r7, c7, c5, 6 + dsb + dmb + smc #0 + ldmfd sp!, {r4-r12, pc} +ENDPROC(omap_smc2) + +ENTRY(omap_modify_auxcoreboot0) + stmfd sp!, {r1-r12, lr} + ldr r12, =0x104 + dsb + smc #0 + ldmfd sp!, {r1-r12, pc} +ENDPROC(omap_modify_auxcoreboot0) + +ENTRY(omap_auxcoreboot_addr) + stmfd sp!, {r2-r12, lr} + ldr r12, =0x105 + dsb + smc #0 + ldmfd sp!, {r2-r12, pc} +ENDPROC(omap_auxcoreboot_addr) + +ENTRY(omap_read_auxcoreboot0) + stmfd sp!, {r2-r12, lr} + ldr r12, =0x103 + dsb + smc #0 + mov r0, r0, lsr #9 + ldmfd sp!, {r2-r12, pc} +ENDPROC(omap_read_auxcoreboot0) diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S deleted file mode 100644 index e69d37d95204..000000000000 --- a/arch/arm/mach-omap2/omap44xx-smc.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * OMAP44xx secure APIs file. - * - * Copyright (C) 2010 Texas Instruments, Inc. - * Written by Santosh Shilimkar - * - * - * 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 - -/* - * This is common routine to manage secure monitor API - * used to modify the PL310 secure registers. - * 'r0' contains the value to be modified and 'r12' contains - * the monitor API number. It uses few CPU registers - * internally and hence they need be backed up including - * link register "lr". - * Function signature : void omap_smc1(u32 fn, u32 arg) - */ - -ENTRY(omap_smc1) - stmfd sp!, {r2-r12, lr} - mov r12, r0 - mov r0, r1 - dsb - smc #0 - ldmfd sp!, {r2-r12, pc} -ENDPROC(omap_smc1) - -ENTRY(omap_modify_auxcoreboot0) - stmfd sp!, {r1-r12, lr} - ldr r12, =0x104 - dsb - smc #0 - ldmfd sp!, {r1-r12, pc} -ENDPROC(omap_modify_auxcoreboot0) - -ENTRY(omap_auxcoreboot_addr) - stmfd sp!, {r2-r12, lr} - ldr r12, =0x105 - dsb - smc #0 - ldmfd sp!, {r2-r12, pc} -ENDPROC(omap_auxcoreboot_addr) - -ENTRY(omap_read_auxcoreboot0) - stmfd sp!, {r2-r12, lr} - ldr r12, =0x103 - dsb - smc #0 - mov r0, r0, lsr #9 - ldmfd sp!, {r2-r12, pc} -ENDPROC(omap_read_auxcoreboot0) -- cgit v1.2.3 From 259ee57a8cda5760dd3e803c5271a6327e1f38ac Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 6 Jun 2011 20:28:23 +0530 Subject: ARM: OMAP: PM: Add support to allocate the memory for secure RAM Allocate the memory to save secure ram context which needs to be done when MPU is hitting OFF mode. The ROM code expects a physical address to this memory and hence use memblock APIs to reserve this memory as part of .reserve() callback. Maximum size as per secure RAM requirements is allocated. To keep omap1 build working, omap-secure.h file is created under plat-omap directory. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/include/mach/omap-secure.h | 3 +++ arch/arm/mach-omap2/omap-secure.c | 29 ++++++++++++++++++++++++++ arch/arm/plat-omap/common.c | 3 +++ arch/arm/plat-omap/include/plat/omap-secure.h | 13 ++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 arch/arm/plat-omap/include/plat/omap-secure.h (limited to 'arch') diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h index 26e7bcc49adc..29f60cae45e9 100644 --- a/arch/arm/mach-omap2/include/mach/omap-secure.h +++ b/arch/arm/mach-omap2/include/mach/omap-secure.h @@ -26,6 +26,8 @@ #define FLAG_FIQ_ENABLE 0x1 #define NO_FLAG 0x0 +/* Maximum Secure memory storage size */ +#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K) /* Secure low power HAL API index */ #define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a @@ -36,5 +38,6 @@ extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, u32 arg3, u32 arg4); extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); +extern phys_addr_t omap_secure_ram_mempool_base(void); #endif /* OMAP_ARCH_OMAP_SECURE_H */ diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c index e5a606e59b1e..69f3c72d959b 100644 --- a/arch/arm/mach-omap2/omap-secure.c +++ b/arch/arm/mach-omap2/omap-secure.c @@ -13,11 +13,14 @@ #include #include #include +#include #include #include +static phys_addr_t omap_secure_memblock_base; + /** * omap_sec_dispatcher: Routine to dispatch low power secure * service routines @@ -50,3 +53,29 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, return ret; } + +/* Allocate the memory to save secure ram */ +int __init omap_secure_ram_reserve_memblock(void) +{ + phys_addr_t paddr; + u32 size = OMAP_SECURE_RAM_STORAGE; + + size = ALIGN(size, SZ_1M); + paddr = memblock_alloc(size, SZ_1M); + if (!paddr) { + pr_err("%s: failed to reserve %x bytes\n", + __func__, size); + return -ENOMEM; + } + memblock_free(paddr, size); + memblock_remove(paddr, size); + + omap_secure_memblock_base = paddr; + + return 0; +} + +phys_addr_t omap_secure_ram_mempool_base(void) +{ + return omap_secure_memblock_base; +} diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 2ee6341fffdb..06383b51e655 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -22,6 +22,8 @@ #include #include +#include + #define NO_LENGTH_CHECK 0xffffffff @@ -66,6 +68,7 @@ void __init omap_reserve(void) omapfb_reserve_sdram_memblock(); omap_vram_reserve_sdram_memblock(); omap_dsp_reserve_sdram_memblock(); + omap_secure_ram_reserve_memblock(); } void __init omap_init_consistent_dma_size(void) diff --git a/arch/arm/plat-omap/include/plat/omap-secure.h b/arch/arm/plat-omap/include/plat/omap-secure.h new file mode 100644 index 000000000000..64f9d1c7f1bb --- /dev/null +++ b/arch/arm/plat-omap/include/plat/omap-secure.h @@ -0,0 +1,13 @@ +#ifndef __OMAP_SECURE_H__ +#define __OMAP_SECURE_H__ + +#include + +#ifdef CONFIG_ARCH_OMAP2PLUS +extern int omap_secure_ram_reserve_memblock(void); +#else +static inline void omap_secure_ram_reserve_memblock(void) +{ } +#endif + +#endif /* __OMAP_SECURE_H__ */ -- cgit v1.2.3 From fcf6efa3ffbc3cc19e7abe39e0b90f497df2fc42 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 16 Jun 2010 22:19:47 +0530 Subject: ARM: OMAP4: PM: Add WakeupGen module as OMAP gic_arch_extn OMAP WakeupGen is the interrupt controller extension used along with ARM GIC to wake the CPU out from low power states on external interrupts. The WakeupGen unit is responsible for generating the wakeup event from the incoming interrupts and enable bits. It is implemented in the MPU always ON power domain. During normal operation, WakeupGen delivers the external interrupts directly to the GIC. WakeupGen specification has one restriction as per Veyron version 1.6. It is SW responsibility to program interrupt enabling/disabling coherently in the GIC and in the WakeupGen enable registers. That is, a given interrupt for a given CPU is either enable at both GIC and WakeupGen, or disable at both, but no mix. That's the reason the WakeupGen is implemented as an extension of GIC. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/include/mach/omap-wakeupgen.h | 39 ++++ arch/arm/mach-omap2/omap-wakeupgen.c | 226 ++++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 3 + 4 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/include/mach/omap-wakeupgen.h create mode 100644 arch/arm/mach-omap2/omap-wakeupgen.c (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index bd3a224d1678..19c29d569d82 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -25,7 +25,7 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o 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 +obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h new file mode 100644 index 000000000000..d79321b0f2a2 --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h @@ -0,0 +1,39 @@ +/* + * OMAP WakeupGen header file + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * 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 OMAP_ARCH_WAKEUPGEN_H +#define OMAP_ARCH_WAKEUPGEN_H + +#define OMAP_WKG_CONTROL_0 0x00 +#define OMAP_WKG_ENB_A_0 0x10 +#define OMAP_WKG_ENB_B_0 0x14 +#define OMAP_WKG_ENB_C_0 0x18 +#define OMAP_WKG_ENB_D_0 0x1c +#define OMAP_WKG_ENB_SECURE_A_0 0x20 +#define OMAP_WKG_ENB_SECURE_B_0 0x24 +#define OMAP_WKG_ENB_SECURE_C_0 0x28 +#define OMAP_WKG_ENB_SECURE_D_0 0x2c +#define OMAP_WKG_ENB_A_1 0x410 +#define OMAP_WKG_ENB_B_1 0x414 +#define OMAP_WKG_ENB_C_1 0x418 +#define OMAP_WKG_ENB_D_1 0x41c +#define OMAP_WKG_ENB_SECURE_A_1 0x420 +#define OMAP_WKG_ENB_SECURE_B_1 0x424 +#define OMAP_WKG_ENB_SECURE_C_1 0x428 +#define OMAP_WKG_ENB_SECURE_D_1 0x42c +#define OMAP_AUX_CORE_BOOT_0 0x800 +#define OMAP_AUX_CORE_BOOT_1 0x804 +#define OMAP_PTMSYNCREQ_MASK 0xc00 +#define OMAP_PTMSYNCREQ_EN 0xc04 +#define OMAP_TIMESTAMPCYCLELO 0xc08 +#define OMAP_TIMESTAMPCYCLEHI 0xc0c + +extern int __init omap_wakeupgen_init(void); +#endif diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c new file mode 100644 index 000000000000..a8a8d0efe350 --- /dev/null +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -0,0 +1,226 @@ +/* + * OMAP WakeupGen Source file + * + * OMAP WakeupGen is the interrupt controller extension used along + * with ARM GIC to wake the CPU out from low power states on + * external interrupts. It is responsible for generating wakeup + * event from the incoming interrupts and enable bits. It is + * implemented in MPU always ON power domain. During normal operation, + * WakeupGen delivers external interrupts directly to the GIC. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include + +#define NR_REG_BANKS 4 +#define MAX_IRQS 128 +#define WKG_MASK_ALL 0x00000000 +#define WKG_UNMASK_ALL 0xffffffff +#define CPU_ENA_OFFSET 0x400 +#define CPU0_ID 0x0 +#define CPU1_ID 0x1 + +static void __iomem *wakeupgen_base; +static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); +static DEFINE_SPINLOCK(wakeupgen_lock); +static unsigned int irq_target_cpu[NR_IRQS]; + +/* + * Static helper functions. + */ +static inline u32 wakeupgen_readl(u8 idx, u32 cpu) +{ + return __raw_readl(wakeupgen_base + OMAP_WKG_ENB_A_0 + + (cpu * CPU_ENA_OFFSET) + (idx * 4)); +} + +static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu) +{ + __raw_writel(val, wakeupgen_base + OMAP_WKG_ENB_A_0 + + (cpu * CPU_ENA_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; + + /* + * PPIs and SGIs are not supported. + */ + if (irq < OMAP44XX_IRQ_GIC_START) + return -EINVAL; + + /* + * Subtract the GIC offset. + */ + spi_irq = irq - OMAP44XX_IRQ_GIC_START; + if (spi_irq > MAX_IRQS) { + pr_err("omap wakeupGen: Invalid IRQ%d\n", irq); + return -EINVAL; + } + + /* + * Each WakeupGen register controls 32 interrupt. + * i.e. 1 bit per SPI IRQ + */ + *reg_index = spi_irq >> 5; + *bit_posn = spi_irq %= 32; + + return 0; +} + +static void _wakeupgen_clear(unsigned int irq, unsigned int cpu) +{ + u32 val, bit_number; + u8 i; + + if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) + return; + + val = wakeupgen_readl(i, cpu); + val &= ~BIT(bit_number); + wakeupgen_writel(val, i, cpu); +} + +static void _wakeupgen_set(unsigned int irq, unsigned int cpu) +{ + u32 val, bit_number; + u8 i; + + if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) + return; + + val = wakeupgen_readl(i, cpu); + val |= BIT(bit_number); + 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 + */ +static void wakeupgen_mask(struct irq_data *d) +{ + unsigned long flags; + + spin_lock_irqsave(&wakeupgen_lock, flags); + _wakeupgen_clear(d->irq, irq_target_cpu[d->irq]); + spin_unlock_irqrestore(&wakeupgen_lock, flags); +} + +/* + * Architecture specific Unmask extension + */ +static void wakeupgen_unmask(struct irq_data *d) +{ + unsigned long flags; + + spin_lock_irqsave(&wakeupgen_lock, flags); + _wakeupgen_set(d->irq, irq_target_cpu[d->irq]); + spin_unlock_irqrestore(&wakeupgen_lock, flags); +} + +/* + * Mask or unmask all interrupts on given CPU. + * 0 = Mask all interrupts on the 'cpu' + * 1 = Unmask all interrupts on the 'cpu' + * Ensure that the initial mask is maintained. This is faster than + * iterating through GIC registers to arrive at the correct masks. + */ +static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) +{ + unsigned long flags; + + spin_lock_irqsave(&wakeupgen_lock, flags); + if (set) { + _wakeupgen_save_masks(cpu); + _wakeupgen_set_all(cpu, WKG_MASK_ALL); + } else { + _wakeupgen_set_all(cpu, WKG_UNMASK_ALL); + _wakeupgen_restore_masks(cpu); + } + spin_unlock_irqrestore(&wakeupgen_lock, flags); +} + +/* + * Initialise the wakeupgen module. + */ +int __init omap_wakeupgen_init(void) +{ + int i; + unsigned int boot_cpu = smp_processor_id(); + + /* Not supported on OMAP4 ES1.0 silicon */ + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); + return -EPERM; + } + + /* Static mapping, never released */ + wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K); + if (WARN_ON(!wakeupgen_base)) + return -ENOMEM; + + /* Clear all IRQ bitmasks at wakeupGen level */ + for (i = 0; i < NR_REG_BANKS; i++) { + wakeupgen_writel(0, i, CPU0_ID); + wakeupgen_writel(0, i, CPU1_ID); + } + + /* + * Override GIC architecture specific functions to add + * OMAP WakeupGen interrupt controller along with GIC + */ + gic_arch_extn.irq_mask = wakeupgen_mask; + gic_arch_extn.irq_unmask = wakeupgen_unmask; + gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; + + /* + * FIXME: Add support to set_smp_affinity() once the core + * GIC code has necessary hooks in place. + */ + + /* Associate all the IRQs to boot CPU like GIC init does. */ + for (i = 0; i < NR_IRQS; i++) + irq_target_cpu[i] = boot_cpu; + + return 0; +} diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 2489f5b8b983..1b93d31fe8e9 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -22,6 +22,7 @@ #include #include +#include #include "common.h" #include "omap4-sar-layout.h" @@ -45,6 +46,8 @@ void __init gic_init_irq(void) omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); BUG_ON(!omap_irq_base); + omap_wakeupgen_init(); + gic_init(0, 29, gic_dist_base_addr, omap_irq_base); } -- cgit v1.2.3 From b2b9762f76981c16a8768255284efeae7f27e4f1 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 16 Jun 2010 22:19:48 +0530 Subject: ARM: OMAP4: PM: Add CPUX OFF mode support This patch adds the CPU0 and CPU1 off mode support. CPUX close switch retention (CSWR) is not supported by hardware design. The CPUx OFF mode isn't supported on OMAP4430 ES1.0 CPUx sleep code is common for hotplug, suspend and CPUilde. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Makefile | 6 +- arch/arm/mach-omap2/common.h | 30 +++ arch/arm/mach-omap2/include/mach/omap-secure.h | 9 + arch/arm/mach-omap2/omap-mpuss-lowpower.c | 248 ++++++++++++++++++++++ arch/arm/mach-omap2/omap-smp.c | 13 ++ arch/arm/mach-omap2/omap4-sar-layout.h | 9 + arch/arm/mach-omap2/pm44xx.c | 6 + arch/arm/mach-omap2/sleep44xx.S | 276 +++++++++++++++++++++++++ 8 files changed, 595 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-omap2/omap-mpuss-lowpower.c create mode 100644 arch/arm/mach-omap2/sleep44xx.S (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 19c29d569d82..58de1f6df27c 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -25,11 +25,13 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o 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 +obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ + sleep44xx.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec) # Functions loaded to SRAM obj-$(CONFIG_SOC_OMAP2420) += sram242x.o @@ -63,7 +65,7 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ cpuidle34xx.o -obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 7ebcb6a9b73e..36cdba7727f2 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -24,9 +24,11 @@ #ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H #define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H +#ifndef __ASSEMBLER__ #include #include +#include #ifdef CONFIG_SOC_OMAP2420 extern void omap242x_map_common_io(void); @@ -183,6 +185,7 @@ static inline void __iomem *omap4_get_scu_base(void) extern void __init gic_init_irq(void); extern void omap_smc1(u32 fn, u32 arg); extern void __iomem *omap4_get_sar_ram_base(void); +extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ @@ -192,4 +195,31 @@ extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); #endif +#if defined(CONFIG_SMP) && defined(CONFIG_PM) +extern int omap4_mpuss_init(void); +extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); +extern int omap4_finish_suspend(unsigned long cpu_state); +extern void omap4_cpu_resume(void); +#else +static inline int omap4_enter_lowpower(unsigned int cpu, + unsigned int power_state) +{ + cpu_do_idle(); + return 0; +} + +static inline int omap4_mpuss_init(void) +{ + return 0; +} + +static inline int omap4_finish_suspend(unsigned long cpu_state) +{ + return 0; +} + +static inline void omap4_cpu_resume(void) +{} +#endif +#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h index 29f60cae45e9..5f0763dd5664 100644 --- a/arch/arm/mach-omap2/include/mach/omap-secure.h +++ b/arch/arm/mach-omap2/include/mach/omap-secure.h @@ -35,9 +35,18 @@ #define OMAP4_HAL_SAVEALL_INDEX 0x1c #define OMAP4_HAL_SAVEGIC_INDEX 0x1d +/* Secure Monitor mode APIs */ +#define OMAP4_MON_SCU_PWR_INDEX 0x108 + +/* Secure PPA(Primary Protected Application) APIs */ +#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25 + +#ifndef __ASSEMBLER__ + extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, u32 arg3, u32 arg4); extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); extern phys_addr_t omap_secure_ram_mempool_base(void); +#endif /* __ASSEMBLER__ */ #endif /* OMAP_ARCH_OMAP_SECURE_H */ diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c new file mode 100644 index 000000000000..867fee51e42c --- /dev/null +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -0,0 +1,248 @@ +/* + * OMAP MPUSS low power code + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU + * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller, + * CPU0 and CPU1 LPRM modules. + * CPU0, CPU1 and MPUSS each have there own power domain and + * hence multiple low power combinations of MPUSS are possible. + * + * The CPU0 and CPU1 can't support Closed switch Retention (CSWR) + * because the mode is not supported by hw constraints of dormant + * mode. While waking up from the dormant mode, a reset signal + * to the Cortex-A9 processor must be asserted by the external + * power controller. + * + * With architectural inputs and hardware recommendations, only + * below modes are supported from power gain vs latency point of view. + * + * CPU0 CPU1 MPUSS + * ---------------------------------------------- + * ON ON ON + * ON(Inactive) OFF ON(Inactive) + * OFF OFF CSWR + * OFF OFF OSWR (*TBD) + * OFF OFF OFF* (*TBD) + * ---------------------------------------------- + * + * Note: CPU0 is the master core and it is the last CPU to go down + * and first to wake-up when MPUSS low power states are excercised + * + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "omap4-sar-layout.h" +#include "pm.h" +#include "powerdomain.h" + +#ifdef CONFIG_SMP + +struct omap4_cpu_pm_info { + struct powerdomain *pwrdm; + void __iomem *scu_sar_addr; + void __iomem *wkup_sar_addr; +}; + +static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); + +/* + * Program the wakeup routine address for the CPU0 and CPU1 + * used for OFF or DORMANT wakeup. + */ +static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + __raw_writel(addr, pm_info->wkup_sar_addr); +} + +/* + * Set the CPUx powerdomain's previous power state + */ +static inline void set_cpu_next_pwrst(unsigned int cpu_id, + unsigned int power_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); +} + +/* + * Read CPU's previous power state + */ +static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + return pwrdm_read_prev_pwrst(pm_info->pwrdm); +} + +/* + * Clear the CPUx powerdomain's previous power state + */ +static inline void clear_cpu_prev_pwrst(unsigned int cpu_id) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); +} + +/* + * Store the SCU power status value to scratchpad memory + */ +static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + u32 scu_pwr_st; + + switch (cpu_state) { + case PWRDM_POWER_RET: + scu_pwr_st = SCU_PM_DORMANT; + break; + case PWRDM_POWER_OFF: + scu_pwr_st = SCU_PM_POWEROFF; + break; + case PWRDM_POWER_ON: + case PWRDM_POWER_INACTIVE: + default: + scu_pwr_st = SCU_PM_NORMAL; + break; + } + + __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); +} + +/** + * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function + * The purpose of this function is to manage low power programming + * of OMAP4 MPUSS subsystem + * @cpu : CPU ID + * @power_state: Low power state. + */ +int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) +{ + unsigned int save_state = 0; + unsigned int wakeup_cpu; + + if (omap_rev() == OMAP4430_REV_ES1_0) + return -ENXIO; + + switch (power_state) { + case PWRDM_POWER_ON: + case PWRDM_POWER_INACTIVE: + save_state = 0; + break; + case PWRDM_POWER_OFF: + save_state = 1; + break; + case PWRDM_POWER_RET: + default: + /* + * CPUx CSWR is invalid hardware state. Also CPUx OSWR + * doesn't make much scense, since logic is lost and $L1 + * needs to be cleaned because of coherency. This makes + * CPUx OSWR equivalent to CPUX OFF and hence not supported + */ + WARN_ON(1); + return -ENXIO; + } + + clear_cpu_prev_pwrst(cpu); + set_cpu_next_pwrst(cpu, power_state); + set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); + scu_pwrst_prepare(cpu, power_state); + + /* + * Call low level function with targeted low power state. + */ + cpu_suspend(save_state, omap4_finish_suspend); + + /* + * Restore the CPUx power state to ON otherwise CPUx + * power domain can transitions to programmed low power + * state while doing WFI outside the low powe code. On + * secure devices, CPUx does WFI which can result in + * domain transition + */ + wakeup_cpu = smp_processor_id(); + set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); + + return 0; +} + +/* + * Initialise OMAP4 MPUSS + */ +int __init omap4_mpuss_init(void) +{ + struct omap4_cpu_pm_info *pm_info; + void __iomem *sar_base = omap4_get_sar_ram_base(); + + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + + /* Initilaise per CPU PM information */ + pm_info = &per_cpu(omap4_pm_info, 0x0); + pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; + pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm"); + if (!pm_info->pwrdm) { + pr_err("Lookup failed for CPU0 pwrdm\n"); + return -ENODEV; + } + + /* Clear CPU previous power domain state */ + pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + + /* Initialise CPU0 power domain state to ON */ + pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + + pm_info = &per_cpu(omap4_pm_info, 0x1); + pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; + pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); + if (!pm_info->pwrdm) { + pr_err("Lookup failed for CPU1 pwrdm\n"); + return -ENODEV; + } + + /* Clear CPU previous power domain state */ + pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + + /* Initialise CPU1 power domain state to ON */ + pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + + /* Save device type on scratchpad for low level code to use */ + if (omap_type() != OMAP2_DEVICE_TYPE_GP) + __raw_writel(1, sar_base + OMAP_TYPE_OFFSET); + else + __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); + + return 0; +} + +#endif diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 74e90b40a0c7..ee83808de0ff 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "common.h" @@ -39,6 +40,18 @@ void __iomem *omap4_get_scu_base(void) void __cpuinit platform_secondary_init(unsigned int cpu) { + /* + * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. + * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA + * init and for CPU1, a secure PPA API provided. CPU0 must be ON + * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. + * OMAP443X GP devices- SMP bit isn't accessible. + * OMAP446X GP devices - SMP bit access is enabled on both CPUs. + */ + if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) + omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, + 4, 0, 0, 0, 0, 0); + /* * If any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index 7781ea4dacbc..970a2eef3ab9 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -19,4 +19,13 @@ #define SAR_BANK3_OFFSET 0x2000 #define SAR_BANK4_OFFSET 0x3000 +/* Scratch pad memory offsets from SAR_BANK1 */ +#define SCU_OFFSET0 0xd00 +#define SCU_OFFSET1 0xd04 +#define OMAP_TYPE_OFFSET 0xd10 + +/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ +#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 +#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 + #endif diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index c34139dc8d8c..781aadf98e32 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -163,6 +163,12 @@ static int __init omap4_pm_init(void) goto err2; } + ret = omap4_mpuss_init(); + if (ret) { + pr_err("Failed to initialise OMAP4 MPUSS\n"); + goto err2; + } + (void) clkdm_for_each(clkdms_setup, NULL); #ifdef CONFIG_SUSPEND diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S new file mode 100644 index 000000000000..e5521945ba8e --- /dev/null +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -0,0 +1,276 @@ +/* + * OMAP44xx sleep code. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include "common.h" +#include "omap4-sar-layout.h" + +#if defined(CONFIG_SMP) && defined(CONFIG_PM) + +.macro DO_SMC + dsb + smc #0 + dsb +.endm + +ppa_zero_params: + .word 0x0 + +/* + * ============================= + * == CPU suspend finisher == + * ============================= + * + * void omap4_finish_suspend(unsigned long cpu_state) + * + * This function code saves the CPU context and performs the CPU + * power down sequence. Calling WFI effectively changes the CPU + * power domains states to the desired target power state. + * + * @cpu_state : contains context save state (r0) + * 0 - No context lost + * 1 - CPUx L1 and logic lost: MPUSS CSWR + * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR + * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF + * @return: This function never returns for CPU OFF and DORMANT power states. + * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up + * from this follows a full CPU reset path via ROM code to CPU restore code. + * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. + * It returns to the caller for CPU INACTIVE and ON power states or in case + * CPU failed to transition to targeted OFF/DORMANT state. + */ +ENTRY(omap4_finish_suspend) + stmfd sp!, {lr} + cmp r0, #0x0 + beq do_WFI @ No lowpower state, jump to WFI + + /* + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + bl omap4_get_sar_ram_base + ldr r9, [r0, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne skip_secure_l1_clean + mov r0, #SCU_PM_NORMAL + mov r1, #0xFF @ clean seucre L1 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} +skip_secure_l1_clean: + bl v7_flush_dcache_all + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* + * Invalidate L1 data cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. + */ + bl v7_flush_dcache_all + + /* + * Switch the CPU from Symmetric Multiprocessing (SMP) mode + * to AsymmetricMultiprocessing (AMP) mode by programming + * the SCU power status to DORMANT or OFF mode. + * This enables the CPU to be taken out of coherency by + * preventing the CPU from receiving cache, TLB, or BTB + * maintenance operations broadcast by other CPUs in the cluster. + */ + bl omap4_get_sar_ram_base + mov r8, r0 + ldr r9, [r8, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne scu_gp_set + mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR + ands r0, r0, #0x0f + ldreq r0, [r8, #SCU_OFFSET0] + ldrne r0, [r8, #SCU_OFFSET1] + mov r1, #0x00 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} + b skip_scu_gp_set +scu_gp_set: + mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR + ands r0, r0, #0x0f + ldreq r1, [r8, #SCU_OFFSET0] + ldrne r1, [r8, #SCU_OFFSET1] + bl omap4_get_scu_base + bl scu_power_mode +skip_scu_gp_set: + mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data + tst r0, #(1 << 18) + mrcne p15, 0, r0, c1, c0, 1 + bicne r0, r0, #(1 << 6) @ Disable SMP bit + mcrne p15, 0, r0, c1, c0, 1 + isb + dsb + +do_WFI: + bl omap_do_wfi + + /* + * CPU is here when it failed to enter OFF/DORMANT or + * no low power state was attempted. + */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit + mcreq p15, 0, r0, c1, c0, 0 + isb + + /* + * Ensure the CPU power state is set to NORMAL in + * SCU power state so that CPU is back in coherency. + * In non-coherent mode CPU can lock-up and lead to + * system deadlock. + */ + mrc p15, 0, r0, c1, c0, 1 + tst r0, #(1 << 6) @ Check SMP bit enabled? + orreq r0, r0, #(1 << 6) + mcreq p15, 0, r0, c1, c0, 1 + isb + bl omap4_get_sar_ram_base + mov r8, r0 + ldr r9, [r8, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne scu_gp_clear + mov r0, #SCU_PM_NORMAL + mov r1, #0x00 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} + b skip_scu_gp_clear +scu_gp_clear: + bl omap4_get_scu_base + mov r1, #SCU_PM_NORMAL + bl scu_power_mode +skip_scu_gp_clear: + isb + dsb + ldmfd sp!, {pc} +ENDPROC(omap4_finish_suspend) + +/* + * ============================ + * == CPU resume entry point == + * ============================ + * + * void omap4_cpu_resume(void) + * + * ROM code jumps to this function while waking up from CPU + * OFF or DORMANT state. Physical address of the function is + * stored in the SAR RAM while entering to OFF or DORMANT mode. + * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. + */ +ENTRY(omap4_cpu_resume) + /* + * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. + * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA + * init and for CPU1, a secure PPA API provided. CPU0 must be ON + * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. + * OMAP443X GP devices- SMP bit isn't accessible. + * OMAP446X GP devices - SMP bit access is enabled on both CPUs. + */ + ldr r8, =OMAP44XX_SAR_RAM_BASE + ldr r9, [r8, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Skip if GP device + bne skip_ns_smp_enable + mrc p15, 0, r0, c0, c0, 5 + ands r0, r0, #0x0f + beq skip_ns_smp_enable +ppa_actrl_retry: + mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX + adr r3, ppa_zero_params @ Pointer to parameters + mov r1, #0x0 @ Process ID + mov r2, #0x4 @ Flag + mov r6, #0xff + mov r12, #0x00 @ Secure Service ID + DO_SMC + cmp r0, #0x0 @ API returns 0 on success. + beq enable_smp_bit + b ppa_actrl_retry +enable_smp_bit: + mrc p15, 0, r0, c1, c0, 1 + tst r0, #(1 << 6) @ Check SMP bit enabled? + orreq r0, r0, #(1 << 6) + mcreq p15, 0, r0, c1, c0, 1 + isb +skip_ns_smp_enable: + + b cpu_resume @ Jump to generic resume +ENDPROC(omap4_cpu_resume) +#endif + +ENTRY(omap_do_wfi) + stmfd sp!, {lr} + + /* + * Execute an ISB instruction to ensure that all of the + * CP15 register changes have been committed. + */ + isb + + /* + * Execute a barrier instruction to ensure that all cache, + * TLB and branch predictor maintenance operations issued + * by any CPU in the cluster have completed. + */ + dsb + dmb + + /* + * Execute a WFI instruction and wait until the + * STANDBYWFI output is asserted to indicate that the + * CPU is in idle and low power state. CPU can specualatively + * prefetch the instructions so add NOPs after WFI. Sixteen + * NOPs as per Cortex-A9 pipeline. + */ + wfi @ Wait For Interrupt + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + ldmfd sp!, {pc} +ENDPROC(omap_do_wfi) -- cgit v1.2.3 From a6e48358d15fec2f3f9e86a6d6fc62422141a3a9 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 4 Sep 2011 13:10:32 +0530 Subject: ARM: OMAP4: Remove __INIT from omap_secondary_startup() to re-use it for hotplug. Remove the __INIT from omap_secondary_startup() so that it can be re-used for CPU hotplug. While at this, remove the un-used AUXBOOT register reference. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-headsmp.S | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 4ee6aeca885a..b13ef7ef5ef4 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -18,11 +18,6 @@ #include #include -/* Physical address needed since MMU not enabled yet on secondary core */ -#define OMAP4_AUX_CORE_BOOT1_PA 0x48281804 - - __INIT - /* * OMAP4 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which -- cgit v1.2.3 From b5b4f2881f619460fdb165111bac10a3dd8eebee Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 16 Jun 2010 22:19:48 +0530 Subject: ARM: OMAP4: PM: Program CPU1 to hit OFF when off-lined Program non-boot CPUs to hit lowest supported power state when it is off-lined using cpu hotplug framework. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 7 +++++++ arch/arm/mach-omap2/omap-hotplug.c | 14 +++++++++----- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 32 +++++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap-wakeupgen.c | 32 +++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 36cdba7727f2..c078db1b3de8 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -200,6 +200,7 @@ extern int omap4_mpuss_init(void); extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); extern int omap4_finish_suspend(unsigned long cpu_state); extern void omap4_cpu_resume(void); +extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); #else static inline int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) @@ -208,6 +209,12 @@ static inline int omap4_enter_lowpower(unsigned int cpu, return 0; } +static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) +{ + cpu_do_idle(); + return 0; +} + static inline int omap4_mpuss_init(void) { return 0; diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index e5a1c3f40a86..adbe4d8c7caf 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -22,6 +22,8 @@ #include "common.h" +#include "powerdomain.h" + int platform_cpu_kill(unsigned int cpu) { return 1; @@ -33,6 +35,8 @@ int platform_cpu_kill(unsigned int cpu) */ void platform_cpu_die(unsigned int cpu) { + unsigned int this_cpu; + flush_cache_all(); dsb(); @@ -40,15 +44,15 @@ void platform_cpu_die(unsigned int cpu) * we're ready for shutdown now, so do it */ if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) - printk(KERN_CRIT "Secure clear status failed\n"); + pr_err("Secure clear status failed\n"); for (;;) { /* - * Execute WFI + * Enter into low power state */ - do_wfi(); - - if (omap_read_auxcoreboot0() == cpu) { + omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); + this_cpu = smp_processor_id(); + if (omap_read_auxcoreboot0() == this_cpu) { /* * OK, proper wakeup, we're done */ diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 867fee51e42c..9c1c12b8c5e1 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -192,6 +192,38 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) return 0; } +/** + * omap4_hotplug_cpu: OMAP4 CPU hotplug entry + * @cpu : CPU ID + * @power_state: CPU low power state. + */ +int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) +{ + unsigned int cpu_state = 0; + + if (omap_rev() == OMAP4430_REV_ES1_0) + return -ENXIO; + + if (power_state == PWRDM_POWER_OFF) + cpu_state = 1; + + clear_cpu_prev_pwrst(cpu); + set_cpu_next_pwrst(cpu, power_state); + set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); + scu_pwrst_prepare(cpu, power_state); + + /* + * CPU never retuns back if targetted power state is OFF mode. + * CPU ONLINE follows normal CPU ONLINE ptah via + * omap_secondary_startup(). + */ + omap4_finish_suspend(cpu_state); + + set_cpu_next_pwrst(cpu, PWRDM_POWER_ON); + return 0; +} + + /* * Initialise OMAP4 MPUSS */ diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index a8a8d0efe350..701dfecad64b 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -180,6 +180,36 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) spin_unlock_irqrestore(&wakeupgen_lock, flags); } +#ifdef CONFIG_HOTPLUG_CPU +static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned int)hcpu; + + switch (action) { + case CPU_ONLINE: + wakeupgen_irqmask_all(cpu, 0); + break; + case CPU_DEAD: + wakeupgen_irqmask_all(cpu, 1); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __refdata irq_hotplug_notifier = { + .notifier_call = irq_cpu_hotplug_notify, +}; + +static void __init irq_hotplug_init(void) +{ + register_hotcpu_notifier(&irq_hotplug_notifier); +} +#else +static void __init irq_hotplug_init(void) +{} +#endif + /* * Initialise the wakeupgen module. */ @@ -222,5 +252,7 @@ int __init omap_wakeupgen_init(void) for (i = 0; i < NR_IRQS; i++) irq_target_cpu[i] = boot_cpu; + irq_hotplug_init(); + return 0; } -- cgit v1.2.3 From e97ca477e993da87769f967bd6f2602a7eab9715 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 16 Jun 2010 22:19:49 +0530 Subject: ARM: OMAP4: PM: CPU1 wakeup workaround from Low power modes The SGI(Software Generated Interrupts) are not wakeup capable from low power states. This is known limitation on OMAP4 and needs to be worked around by using software forced clockdomain wake-up. CPU0 forces the CPU1 clockdomain to software force wakeup. More details can be found in OMAP4430 TRM - Version J Section : 4.3.4.2 Power States of CPU0 and CPU1 Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-smp.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index ee83808de0ff..c1bf3ef0ba02 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -28,6 +28,8 @@ #include "common.h" +#include "clockdomain.h" + /* SCU base address */ static void __iomem *scu_base; @@ -68,6 +70,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu) int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { + static struct clockdomain *cpu1_clkdm; + static bool booted; /* * Set synchronisation state between this boot processor * and the secondary one @@ -83,6 +87,29 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) omap_modify_auxcoreboot0(0x200, 0xfffffdff); flush_cache_all(); smp_wmb(); + + if (!cpu1_clkdm) + cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); + + /* + * The SGI(Software Generated Interrupts) are not wakeup capable + * from low power states. This is known limitation on OMAP4 and + * needs to be worked around by using software forced clockdomain + * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to + * software force wakeup. The clockdomain is then put back to + * hardware supervised mode. + * More details can be found in OMAP4430 TRM - Version J + * Section : + * 4.3.4.2 Power States of CPU0 and CPU1 + */ + if (booted) { + clkdm_wakeup(cpu1_clkdm); + clkdm_allow_idle(cpu1_clkdm); + } else { + dsb_sev(); + booted = true; + } + gic_raise_softirq(cpumask_of(cpu), 1); /* -- cgit v1.2.3 From 72826b9f8892957156e3d390b74d8bd5e0835d51 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 18 Jul 2011 12:25:10 +0530 Subject: ARM: OMAP4: PM: Use custom omap_do_wfi() for default idle. Default arch_idle() isn't good enough for OMAP4 because of aync bridge errata and necessity of NOPs post WFI to avoid speculative prefetch aborts. Hence Use OMAP4 custom omap_do_wfi() hook for default idle. Later in the series, async bridge errata work-around patch updates the omap_do_wfi() with necessary interconnects barriers. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm44xx.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 781aadf98e32..72c745047514 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -107,6 +107,24 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); } +/** + * 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 + * 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(); +} + /** * omap4_pm_init - Init routine for OMAP4 PM * @@ -175,6 +193,9 @@ static int __init omap4_pm_init(void) suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ + /* Overwrite the default arch_idle() */ + pm_idle = omap_default_idle; + err2: return ret; } -- cgit v1.2.3 From e44f9a7744de8e39eda0f544171efc6e4b1ed91c Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 16 Jun 2010 22:19:49 +0530 Subject: ARM: OMAP4: suspend: Add MPUSS power domain RETENTION support This patch adds MPUSS(MPU Sub System) power domain CSWR(Close Switch Retention) support to system wide suspend. For MPUSS power domain to hit retention(CSWR or OSWR), both CPU0 and CPU1 power domains need to be in OFF or DORMANT state, since CPU power domain CSWR is not supported by hardware Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 16 ++++++++ arch/arm/mach-omap2/pm44xx.c | 66 +++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 9c1c12b8c5e1..f9bb2b3d977b 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -66,6 +66,7 @@ struct omap4_cpu_pm_info { }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); +static struct powerdomain *mpuss_pd; /* * Program the wakeup routine address for the CPU0 and CPU1 @@ -140,6 +141,13 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) * of OMAP4 MPUSS subsystem * @cpu : CPU ID * @power_state: Low power state. + * + * MPUSS states for the context save: + * save_state = + * 0 - Nothing lost and no need to save: MPUSS INACTIVE + * 1 - CPUx L1 and logic lost: MPUSS CSWR + * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR + * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF */ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) { @@ -169,6 +177,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) return -ENXIO; } + pwrdm_clear_all_prev_pwrst(mpuss_pd); clear_cpu_prev_pwrst(cpu); set_cpu_next_pwrst(cpu, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); @@ -268,6 +277,13 @@ int __init omap4_mpuss_init(void) /* Initialise CPU1 power domain state to ON */ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + mpuss_pd = pwrdm_lookup("mpu_pwrdm"); + if (!mpuss_pd) { + pr_err("Failed to lookup MPUSS power domain\n"); + return -ENODEV; + } + pwrdm_clear_all_prev_pwrst(mpuss_pd); + /* Save device type on scratchpad for low level code to use */ if (omap_type() != OMAP2_DEVICE_TYPE_GP) __raw_writel(1, sar_base + OMAP_TYPE_OFFSET); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 72c745047514..6dc9bbe0a4a8 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -1,8 +1,9 @@ /* * OMAP4 Power Management Routines * - * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2010-2011 Texas Instruments, Inc. * Rajendra Nayak + * Santosh Shilimkar * * 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 @@ -19,6 +20,7 @@ #include "common.h" #include "clockdomain.h" #include "powerdomain.h" +#include "pm.h" struct power_state { struct powerdomain *pwrdm; @@ -34,7 +36,47 @@ static LIST_HEAD(pwrst_list); #ifdef CONFIG_SUSPEND static int omap4_pm_suspend(void) { - do_wfi(); + struct power_state *pwrst; + int state, ret = 0; + u32 cpu_id = smp_processor_id(); + + /* Save current powerdomain state */ + list_for_each_entry(pwrst, &pwrst_list, node) { + pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); + } + + /* Set targeted power domain states by suspend */ + list_for_each_entry(pwrst, &pwrst_list, node) { + omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + } + + /* + * For MPUSS to hit power domain retention(CSWR or OSWR), + * CPU0 and CPU1 power domains need to be in OFF or DORMANT state, + * since CPU power domain CSWR is not supported by hardware + * Only master CPU follows suspend path. All other CPUs follow + * CPU hotplug path in system wide suspend. On OMAP4, CPU power + * domain CSWR is not supported by hardware. + * More details can be found in OMAP4430 TRM section 4.3.4.2. + */ + omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF); + + /* Restore next powerdomain state */ + list_for_each_entry(pwrst, &pwrst_list, node) { + state = pwrdm_read_prev_pwrst(pwrst->pwrdm); + if (state > pwrst->next_state) { + 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) + pr_crit("Could not enter target state in pm_suspend\n"); + else + pr_info("Successfully put all powerdomains to target state\n"); + return 0; } @@ -97,14 +139,30 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (!pwrdm->pwrsts) return 0; + /* + * Skip CPU0 and CPU1 power domains. CPU1 is programmed + * through hotplug path and CPU0 explicitly programmed + * further down in the code path + */ + if (!strncmp(pwrdm->name, "cpu", 3)) + return 0; + + /* + * FIXME: Remove this check when core retention is supported + * Only MPUSS power domain is added in the list. + */ + if (strcmp(pwrdm->name, "mpu_pwrdm")) + return 0; + pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); if (!pwrst) return -ENOMEM; + pwrst->pwrdm = pwrdm; - pwrst->next_state = PWRDM_POWER_ON; + pwrst->next_state = PWRDM_POWER_RET; list_add(&pwrst->node, &pwrst_list); - return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); + return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } /** -- cgit v1.2.3 From da82ce57a45ac2f295415ed487b9aec051db4f7f Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 25 Jul 2011 16:22:34 +0530 Subject: ARM: OMAP4: Remove un-used do_wfi() macro. With OMAP4 suspend, idle and hotplug series, we no longer need do_wfi() macro. Remove the same. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index c078db1b3de8..3312174d64ba 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -158,17 +158,6 @@ void omap3_intc_resume_idle(void); void omap2_intc_handle_irq(struct pt_regs *regs); void omap3_intc_handle_irq(struct pt_regs *regs); -/* - * wfi used in low power code. Directly opcode is used instead - * of instruction to avoid mulit-omap build break - */ -#ifdef CONFIG_THUMB2_KERNEL -#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory") -#else -#define do_wfi() \ - __asm__ __volatile__ (".word 0xe320f003" : : : "memory") -#endif - #ifdef CONFIG_CACHE_L2X0 extern void __iomem *omap4_get_l2cache_base(void); #endif -- cgit v1.2.3 From 0f3cf2ec81aeb4747624954bae2cc8decc48e12f Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 16 Jun 2010 23:29:31 +0530 Subject: ARM: OMAP4: PM: Add WakeupGen and secure GIC low power support Add WakeupGen and secure GIC low power support to save and restore it's registers. WakeupGen Registers are saved to pre-defined SAR RAM layout and the restore is automatically done by hardware(ROM code) while coming out of MPUSS OSWR or Device off state. Secure GIC is saved using secure API and restored by hardware like WakeupGen. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-wakeupgen.c | 131 +++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 15 ++++ 2 files changed, 146 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 701dfecad64b..d3d8971d7f30 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -22,10 +22,16 @@ #include #include #include +#include +#include #include #include +#include + +#include "omap4-sar-layout.h" +#include "common.h" #define NR_REG_BANKS 4 #define MAX_IRQS 128 @@ -36,6 +42,7 @@ #define CPU1_ID 0x1 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]; @@ -55,6 +62,11 @@ static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu) (cpu * CPU_ENA_OFFSET) + (idx * 4)); } +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; @@ -180,6 +192,93 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) spin_unlock_irqrestore(&wakeupgen_lock, flags); } +#ifdef CONFIG_CPU_PM +/* + * Save WakeupGen interrupt context in SAR BANK3. Restore is done by + * ROM code. WakeupGen IP is integrated along with GIC to manage the + * interrupt wakeups from CPU low power states. It manages + * masking/unmasking of Shared peripheral interrupts(SPI). So the + * interrupt enable/disable control should be in sync and consistent + * at WakeupGen and GIC so that interrupts are not lost. + */ +static void irq_save_context(void) +{ + u32 i, val; + + if (omap_rev() == OMAP4430_REV_ES1_0) + return; + + if (!sar_base) + sar_base = omap4_get_sar_ram_base(); + + for (i = 0; i < NR_REG_BANKS; i++) { + /* Save the CPUx interrupt mask for IRQ 0 to 127 */ + val = wakeupgen_readl(i, 0); + sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); + val = wakeupgen_readl(i, 1); + sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i); + + /* + * Disable the secure interrupts for CPUx. The restore + * code blindly restores secure and non-secure interrupt + * masks from SAR RAM. Secure interrupts are not suppose + * to be enabled from HLOS. So overwrite the SAR location + * so that the secure interrupt remains disabled. + */ + sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i); + sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i); + } + + /* Save AuxBoot* registers */ + val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET); + val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET); + + /* Save SyncReq generation logic */ + val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET); + val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET); + + /* Save SyncReq generation logic */ + val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK); + __raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET); + val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN); + __raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET); + + /* Set the Backup Bit Mask status */ + val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); + val |= SAR_BACKUP_STATUS_WAKEUPGEN; + __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); +} + +/* + * Clear WakeupGen SAR backup status. + */ +void irq_sar_clear(void) +{ + u32 val; + val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); + val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; + __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); +} + +/* + * Save GIC and Wakeupgen interrupt context using secure API + * for HS/EMU devices. + */ +static void irq_save_secure_context(void) +{ + u32 ret; + ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, + FLAG_START_CRITICAL, + 0, 0, 0, 0, 0); + if (ret != API_HAL_RET_VALUE_OK) + pr_err("GIC and Wakeupgen context save failed\n"); +} +#endif + #ifdef CONFIG_HOTPLUG_CPU static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self, unsigned long action, void *hcpu) @@ -210,6 +309,37 @@ static void __init irq_hotplug_init(void) {} #endif +#ifdef CONFIG_CPU_PM +static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) +{ + switch (cmd) { + case CPU_CLUSTER_PM_ENTER: + if (omap_type() == OMAP2_DEVICE_TYPE_GP) + irq_save_context(); + else + irq_save_secure_context(); + break; + case CPU_CLUSTER_PM_EXIT: + if (omap_type() == OMAP2_DEVICE_TYPE_GP) + irq_sar_clear(); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block irq_notifier_block = { + .notifier_call = irq_notifier, +}; + +static void __init irq_pm_init(void) +{ + cpu_pm_register_notifier(&irq_notifier_block); +} +#else +static void __init irq_pm_init(void) +{} +#endif + /* * Initialise the wakeupgen module. */ @@ -253,6 +383,7 @@ int __init omap_wakeupgen_init(void) irq_target_cpu[i] = boot_cpu; irq_hotplug_init(); + irq_pm_init(); return 0; } diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index 970a2eef3ab9..aa14a8dd2505 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -28,4 +28,19 @@ #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 +#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500) +#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504) +#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) + +/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ +#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684) +#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694) +#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4) +#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4) +#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4) +#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8) +#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc) +#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0) +#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10 + #endif -- cgit v1.2.3 From 5e94c6e33e7c4726ef09f46c267e9ca232c5148a Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 9 Jan 2011 02:59:09 +0530 Subject: ARM: OMAP4: PM: Add L2X0 cache lowpower support When MPUSS hits off-mode, L2 cache is lost. This patch adds L2X0 necessary maintenance operations and context restoration in the low power code. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/include/mach/omap-secure.h | 5 ++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 41 ++++++++++- arch/arm/mach-omap2/omap4-sar-layout.h | 4 ++ arch/arm/mach-omap2/sleep44xx.S | 95 ++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h index 5f0763dd5664..c90a43589abe 100644 --- a/arch/arm/mach-omap2/include/mach/omap-secure.h +++ b/arch/arm/mach-omap2/include/mach/omap-secure.h @@ -37,8 +37,13 @@ /* Secure Monitor mode APIs */ #define OMAP4_MON_SCU_PWR_INDEX 0x108 +#define OMAP4_MON_L2X0_DBG_CTRL_INDEX 0x100 +#define OMAP4_MON_L2X0_CTRL_INDEX 0x102 +#define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 +#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 /* Secure PPA(Primary Protected Application) APIs */ +#define OMAP4_PPA_L2_POR_INDEX 0x23 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25 #ifndef __ASSEMBLER__ diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index f9bb2b3d977b..907a048fe5e9 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -63,10 +64,12 @@ struct omap4_cpu_pm_info { struct powerdomain *pwrdm; void __iomem *scu_sar_addr; void __iomem *wkup_sar_addr; + void __iomem *l2x0_sar_addr; }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; +static void __iomem *sar_base; /* * Program the wakeup routine address for the CPU0 and CPU1 @@ -135,6 +138,36 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); } +/* + * Store the CPU cluster state for L2X0 low power operations. + */ +static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + __raw_writel(save_state, pm_info->l2x0_sar_addr); +} + +/* + * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to + * in every restore MPUSS OFF path. + */ +#ifdef CONFIG_CACHE_L2X0 +static void save_l2x0_context(void) +{ + u32 val; + void __iomem *l2x0_base = omap4_get_l2cache_base(); + + val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); + __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); + val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); + __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); +} +#else +static void save_l2x0_context(void) +{} +#endif + /** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming @@ -182,6 +215,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) set_cpu_next_pwrst(cpu, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); scu_pwrst_prepare(cpu, power_state); + l2x0_pwrst_prepare(cpu, save_state); /* * Call low level function with targeted low power state. @@ -239,17 +273,19 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) int __init omap4_mpuss_init(void) { struct omap4_cpu_pm_info *pm_info; - void __iomem *sar_base = omap4_get_sar_ram_base(); if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); return -ENODEV; } + sar_base = omap4_get_sar_ram_base(); + /* Initilaise per CPU PM information */ pm_info = &per_cpu(omap4_pm_info, 0x0); pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0; pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU0 pwrdm\n"); @@ -265,6 +301,7 @@ int __init omap4_mpuss_init(void) pm_info = &per_cpu(omap4_pm_info, 0x1); pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU1 pwrdm\n"); @@ -290,6 +327,8 @@ int __init omap4_mpuss_init(void) else __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); + save_l2x0_context(); + return 0; } diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index aa14a8dd2505..fe5b545ad443 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -23,6 +23,10 @@ #define SCU_OFFSET0 0xd00 #define SCU_OFFSET1 0xd04 #define OMAP_TYPE_OFFSET 0xd10 +#define L2X0_SAVE_OFFSET0 0xd14 +#define L2X0_SAVE_OFFSET1 0xd18 +#define L2X0_AUXCTRL_OFFSET 0xd1c +#define L2X0_PREFETCH_CTRL_OFFSET 0xd20 /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index e5521945ba8e..3154b63def35 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -32,6 +32,9 @@ ppa_zero_params: .word 0x0 +ppa_por_params: + .word 1, 0 + /* * ============================= * == CPU suspend finisher == @@ -132,6 +135,54 @@ skip_scu_gp_set: mcrne p15, 0, r0, c1, c0, 1 isb dsb +#ifdef CONFIG_CACHE_L2X0 + /* + * Clean and invalidate the L2 cache. + * Common cache-l2x0.c functions can't be used here since it + * uses spinlocks. We are out of coherency here with data cache + * disabled. The spinlock implementation uses exclusive load/store + * instruction which can fail without data cache being enabled. + * OMAP4 hardware doesn't support exclusive monitor which can + * overcome exclusive access issue. Because of this, CPU can + * lead to deadlock. + */ + bl omap4_get_sar_ram_base + mov r8, r0 + mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR + ands r5, r5, #0x0f + ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR + ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory. + cmp r0, #3 + bne do_WFI +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x03 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + DO_SMC +#endif + bl omap4_get_l2cache_base + mov r2, r0 + ldr r0, =0xffff + str r0, [r2, #L2X0_CLEAN_INV_WAY] +wait: + ldr r0, [r2, #L2X0_CLEAN_INV_WAY] + ldr r1, =0xffff + ands r0, r0, r1 + bne wait +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x00 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + DO_SMC +#endif +l2x_sync: + bl omap4_get_l2cache_base + mov r2, r0 + mov r0, #0x0 + str r0, [r2, #L2X0_CACHE_SYNC] +sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + ands r0, r0, #0x1 + bne sync +#endif do_WFI: bl omap_do_wfi @@ -225,6 +276,50 @@ enable_smp_bit: mcreq p15, 0, r0, c1, c0, 1 isb skip_ns_smp_enable: +#ifdef CONFIG_CACHE_L2X0 + /* + * Restore the L2 AUXCTRL and enable the L2 cache. + * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL + * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL + * register r0 contains value to be programmed. + * L2 cache is already invalidate by ROM code as part + * of MPUSS OFF wakeup path. + */ + ldr r2, =OMAP44XX_L2CACHE_BASE + ldr r0, [r2, #L2X0_CTRL] + and r0, #0x0f + cmp r0, #1 + beq skip_l2en @ Skip if already enabled + ldr r3, =OMAP44XX_SAR_RAM_BASE + ldr r1, [r3, #OMAP_TYPE_OFFSET] + cmp r1, #0x1 @ Check for HS device + bne set_gp_por + ldr r0, =OMAP4_PPA_L2_POR_INDEX + ldr r1, =OMAP44XX_SAR_RAM_BASE + ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET] + adr r3, ppa_por_params + str r4, [r3, #0x04] + mov r1, #0x0 @ Process ID + mov r2, #0x4 @ Flag + mov r6, #0xff + mov r12, #0x00 @ Secure Service ID + DO_SMC + b set_aux_ctrl +set_gp_por: + ldr r1, =OMAP44XX_SAR_RAM_BASE + ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET] + ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH + DO_SMC +set_aux_ctrl: + ldr r1, =OMAP44XX_SAR_RAM_BASE + ldr r0, [r1, #L2X0_AUXCTRL_OFFSET] + ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL + DO_SMC + mov r0, #0x1 + ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache + DO_SMC +skip_l2en: +#endif b cpu_resume @ Jump to generic resume ENDPROC(omap4_cpu_resume) -- cgit v1.2.3 From 3ba2a7393e6be48ad7f545a743cd6f46325ba8fd Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 6 Jun 2011 14:33:29 +0530 Subject: ARM: OMAP4: PM: Add MPUSS power domain OSWR support This patch adds the MPUSS OSWR (Open Switch Retention) support. The MPUSS OSWR configuration is as below. - CPUx L1 and logic lost, MPUSS logic lost, L2 memory is retained OMAP4460 onwards, MPUSS power domain doesn't support OFF state any more anymore just like CORE power domain. The deepest state supported is OSWR. On OMAP4430 secure devices too, MPUSS off mode can't be used because of a bug which alters Ducati and Tesla states. Hence MPUSS off mode as an independent state isn't supported on OMAP44XX devices. Ofcourse when MPUSS power domain transitions to OSWR along with device off mode, it eventually hits off state since memory contents are lost. Hence the MPUSS off mode independent state is not attempted without device off mode. All the necessary infrastructure code for MPUSS off mode is in place as part of this series. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 6 +++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 65 +++++++++++++++++++++++++++++-- arch/arm/mach-omap2/pm44xx.c | 4 ++ 3 files changed, 72 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 3312174d64ba..0911e843f079 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -190,6 +190,7 @@ extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); extern int omap4_finish_suspend(unsigned long cpu_state); extern void omap4_cpu_resume(void); extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); +extern u32 omap4_mpuss_read_prev_context_state(void); #else static inline int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) @@ -216,6 +217,11 @@ static inline int omap4_finish_suspend(unsigned long cpu_state) static inline void omap4_cpu_resume(void) {} + +static inline u32 omap4_mpuss_read_prev_context_state(void) +{ + return 0; +} #endif #endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 907a048fe5e9..549aff1bfecb 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -24,8 +24,8 @@ * ON ON ON * ON(Inactive) OFF ON(Inactive) * OFF OFF CSWR - * OFF OFF OSWR (*TBD) - * OFF OFF OFF* (*TBD) + * OFF OFF OSWR + * OFF OFF OFF(Device OFF *TBD) * ---------------------------------------------- * * Note: CPU0 is the master core and it is the last CPU to go down @@ -56,7 +56,11 @@ #include "common.h" #include "omap4-sar-layout.h" #include "pm.h" -#include "powerdomain.h" +#include "prcm_mpu44xx.h" +#include "prminst44xx.h" +#include "prcm44xx.h" +#include "prm44xx.h" +#include "prm-regbits-44xx.h" #ifdef CONFIG_SMP @@ -138,6 +142,48 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); } +/* Helper functions for MPUSS OSWR */ +static inline void mpuss_clear_prev_logic_pwrst(void) +{ + u32 reg; + + reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); + omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION, + OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); +} + +static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id) +{ + u32 reg; + + if (cpu_id) { + reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST, + OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); + omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST, + OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); + } else { + reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST, + OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); + omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST, + OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); + } +} + +/** + * omap4_mpuss_read_prev_context_state: + * Function returns the MPUSS previous context state + */ +u32 omap4_mpuss_read_prev_context_state(void) +{ + u32 reg; + + reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); + reg &= OMAP4430_LOSTCONTEXT_DFF_MASK; + return reg; +} + /* * Store the CPU cluster state for L2X0 low power operations. */ @@ -210,8 +256,18 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) return -ENXIO; } + /* + * Check MPUSS next state and save interrupt controller if needed. + * 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)); scu_pwrst_prepare(cpu, power_state); @@ -294,6 +350,7 @@ int __init omap4_mpuss_init(void) /* Clear CPU previous power domain state */ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + cpu_clear_prev_logic_pwrst(0); /* Initialise CPU0 power domain state to ON */ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); @@ -310,6 +367,7 @@ int __init omap4_mpuss_init(void) /* Clear CPU previous power domain state */ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + cpu_clear_prev_logic_pwrst(1); /* Initialise CPU1 power domain state to ON */ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); @@ -320,6 +378,7 @@ int __init omap4_mpuss_init(void) return -ENODEV; } pwrdm_clear_all_prev_pwrst(mpuss_pd); + mpuss_clear_prev_logic_pwrst(); /* Save device type on scratchpad for low level code to use */ if (omap_type() != OMAP2_DEVICE_TYPE_GP) diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 6dc9bbe0a4a8..92daae07d634 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -27,6 +27,7 @@ struct power_state { u32 next_state; #ifdef CONFIG_SUSPEND u32 saved_state; + u32 saved_logic_state; #endif struct list_head node; }; @@ -43,11 +44,13 @@ static int omap4_pm_suspend(void) /* Save current powerdomain state */ list_for_each_entry(pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); + pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm); } /* Set targeted power domain states by suspend */ list_for_each_entry(pwrst, &pwrst_list, node) { omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); } /* @@ -71,6 +74,7 @@ static int omap4_pm_suspend(void) ret = -1; } omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state); } if (ret) pr_crit("Could not enter target state in pm_suspend\n"); -- cgit v1.2.3 From 49404dd09f5dc78c247c6044c60d7be7768a71bc Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 10 Jan 2011 01:02:15 +0530 Subject: ARM: OMAP4: PM: Add power domain statistics support Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 549aff1bfecb..1d5d01056558 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -256,6 +256,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) return -ENXIO; } + pwrdm_pre_transition(); + /* * Check MPUSS next state and save interrupt controller if needed. * In MPUSS OSWR or device OFF, interrupt controller contest is lost. @@ -288,6 +290,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu = smp_processor_id(); set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); + pwrdm_post_transition(); + return 0; } -- cgit v1.2.3 From 137d105d50f6e6c373c1aa759f59045e6239cf66 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sat, 25 Jun 2011 18:04:31 -0700 Subject: ARM: OMAP4: Fix errata i688 with MPU interconnect barriers. On OMAP4 SOC, intecronnects has many write buffers in the async bridges and they need to be drained before CPU enters into standby state. Patch 'OMAP4: PM: Add CPUX OFF mode support' added CPU PM support but OMAP errata i688 (Async Bridge Corruption) needs to be taken care to avoid issues like system freeze, CPU deadlocks, random crashes with register accesses, synchronisation loss on initiators operating on both interconnect port simultaneously. As per the errata, if a data is stalled inside asynchronous bridge because of back pressure, it may be accepted multiple times, creating pointer misalignment that will corrupt next transfers on that data path until next reset of the system (No recovery procedure once the issue is hit, the path remains consistently broken). Async bridge can be found on path between MPU to EMIF and MPU to L3 interconnect. This situation can happen only when the idle is initiated by a Master Request Disconnection (which is trigged by software when executing WFI on CPU). The work-around for this errata needs all the initiators connected through async bridge must ensure that data path is properly drained before issuing WFI. This condition will be met if one Strongly ordered access is performed to the target right before executing the WFI. In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. IO barrier ensure that there is no synchronisation loss on initiators operating on both interconnect port simultaneously. Thanks to Russell for a tip to conver assembly function to C fuction there by reducing 40 odd lines of code from the patch. Signed-off-by: Santosh Shilimkar Signed-off-by: Richard Woodruff Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Kconfig | 21 ++++++++++++ arch/arm/mach-omap2/include/mach/barriers.h | 31 ++++++++++++++++++ arch/arm/mach-omap2/io.c | 9 +++++ arch/arm/mach-omap2/omap4-common.c | 51 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/sleep44xx.S | 8 +++++ arch/arm/plat-omap/include/plat/sram.h | 6 +++- arch/arm/plat-omap/sram.c | 8 +++++ 7 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/include/mach/barriers.h (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index b6625130831d..50f43942c1aa 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -353,6 +353,27 @@ config OMAP3_SDRC_AC_TIMING wish to say no. Selecting yes without understanding what is going on could result in system crashes; +config OMAP4_ERRATA_I688 + bool "OMAP4 errata: Async Bridge Corruption" + depends on ARCH_OMAP4 + select ARCH_HAS_BARRIERS + help + If a data is stalled inside asynchronous bridge because of back + pressure, it may be accepted multiple times, creating pointer + misalignment that will corrupt next transfers on that data path + until next reset of the system (No recovery procedure once the + issue is hit, the path remains consistently broken). Async bridge + can be found on path between MPU to EMIF and MPU to L3 interconnect. + This situation can happen only when the idle is initiated by a + Master Request Disconnection (which is trigged by software when + executing WFI on CPU). + The work-around for this errata needs all the initiators connected + through async bridge must ensure that data path is properly drained + before issuing WFI. This condition will be met if one Strongly ordered + access is performed to the target right before executing the WFI. + In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. + IO barrier ensure that there is no synchronisation loss on initiators + operating on both interconnect port simultaneously. endmenu endif diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h new file mode 100644 index 000000000000..4fa72c7cc7cd --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/barriers.h @@ -0,0 +1,31 @@ +/* + * OMAP memory barrier header. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * Richard Woodruff + * + * 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 __MACH_BARRIERS_H +#define __MACH_BARRIERS_H + +extern void omap_bus_sync(void); + +#define rmb() dsb() +#define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0) +#define mb() wmb() + +#endif /* __MACH_BARRIERS_H */ diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3f565dd2ea8d..65843390e7f0 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -237,6 +237,15 @@ static struct map_desc omap44xx_io_desc[] __initdata = { .length = L4_EMU_44XX_SIZE, .type = MT_DEVICE, }, +#ifdef CONFIG_OMAP4_ERRATA_I688 + { + .virtual = OMAP4_SRAM_VA, + .pfn = __phys_to_pfn(OMAP4_SRAM_PA), + .length = PAGE_SIZE, + .type = MT_MEMORY_SO, + }, +#endif + }; #endif diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 1b93d31fe8e9..bc16c818c6b7 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -15,11 +15,14 @@ #include #include #include +#include #include #include +#include #include +#include #include #include @@ -33,6 +36,54 @@ static void __iomem *l2cache_base; static void __iomem *sar_ram_base; +#ifdef CONFIG_OMAP4_ERRATA_I688 +/* Used to implement memory barrier on DRAM path */ +#define OMAP4_DRAM_BARRIER_VA 0xfe600000 + +void __iomem *dram_sync, *sram_sync; + +void omap_bus_sync(void) +{ + if (dram_sync && sram_sync) { + writel_relaxed(readl_relaxed(dram_sync), dram_sync); + writel_relaxed(readl_relaxed(sram_sync), sram_sync); + isb(); + } +} + +static int __init omap_barriers_init(void) +{ + struct map_desc dram_io_desc[1]; + phys_addr_t paddr; + u32 size; + + if (!cpu_is_omap44xx()) + return -ENODEV; + + size = ALIGN(PAGE_SIZE, SZ_1M); + paddr = memblock_alloc(size, SZ_1M); + if (!paddr) { + pr_err("%s: failed to reserve 4 Kbytes\n", __func__); + return -ENOMEM; + } + memblock_free(paddr, size); + memblock_remove(paddr, size); + dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; + dram_io_desc[0].pfn = __phys_to_pfn(paddr); + dram_io_desc[0].length = size; + dram_io_desc[0].type = MT_MEMORY_SO; + iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); + dram_sync = (void __iomem *) dram_io_desc[0].virtual; + sram_sync = (void __iomem *) OMAP4_SRAM_VA; + + pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n", + (long long) paddr, dram_io_desc[0].virtual); + + return 0; +} +core_initcall(omap_barriers_init); +#endif + void __init gic_init_irq(void) { void __iomem *omap_irq_base; diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 3154b63def35..abd283400490 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -325,8 +325,16 @@ skip_l2en: ENDPROC(omap4_cpu_resume) #endif +#ifndef CONFIG_OMAP4_ERRATA_I688 +ENTRY(omap_bus_sync) + mov pc, lr +ENDPROC(omap_bus_sync) +#endif + ENTRY(omap_do_wfi) stmfd sp!, {lr} + /* Drain interconnect write buffers. */ + bl omap_bus_sync /* * Execute an ISB instruction to ensure that all of the diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index f500fc34d065..75aa1b2bef51 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h @@ -95,6 +95,10 @@ static inline void omap_push_sram_idle(void) {} */ #define OMAP2_SRAM_PA 0x40200000 #define OMAP3_SRAM_PA 0x40200000 +#ifdef CONFIG_OMAP4_ERRATA_I688 +#define OMAP4_SRAM_PA 0x40304000 +#define OMAP4_SRAM_VA 0xfe404000 +#else #define OMAP4_SRAM_PA 0x40300000 - +#endif #endif diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 8b28664d1c62..ad6a71a00cef 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -40,7 +40,11 @@ #define OMAP1_SRAM_PA 0x20000000 #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) #define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) +#ifdef CONFIG_OMAP4_ERRATA_I688 +#define OMAP4_SRAM_PUB_PA OMAP4_SRAM_PA +#else #define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) +#endif #if defined(CONFIG_ARCH_OMAP2PLUS) #define SRAM_BOOTLOADER_SZ 0x00 @@ -163,6 +167,10 @@ static void __init omap_map_sram(void) if (omap_sram_size == 0) return; +#ifdef CONFIG_OMAP4_ERRATA_I688 + omap_sram_start += PAGE_SIZE; + omap_sram_size -= SZ_16K; +#endif if (cpu_is_omap34xx()) { /* * SRAM must be marked as non-cached on OMAP3 since the -- cgit v1.2.3 From 98272660970a71e21ad1992f695f75b780de833c Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Tue, 16 Aug 2011 17:31:40 +0530 Subject: ARM: OMAP4: PM: Add CPUidle support Add OMAP4 CPUIDLE support. CPU1 is left with defualt idle and the low power state for it is managed via cpu-hotplug. This patch adds MPUSS low power states in cpuidle. C1 - CPU0 ON + CPU1 ON + MPU ON C2 - CPU0 OFF + CPU1 OFF + MPU CSWR C3 - CPU0 OFF + CPU1 OFF + MPU OSWR OMAP4460 onwards, MPUSS power domain doesn't support OFF state any more anymore just like CORE power domain. The deepest state supported is OSWr. Ofcourse when MPUSS and CORE PD transitions to OSWR along with device off mode, even the memory contemts are lost which is as good as the PD off state. On OMAP4 because of hardware constraints, no low power states are targeted when both CPUs are online and in SMP mode. The low power states are attempted only when secondary CPU gets offline to OFF through hotplug infrastructure. Thanks to Nicole Chalhoub for doing exhaustive C-state latency profiling. Signed-off-by: Rajendra Nayak Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/cpuidle44xx.c | 237 ++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 2 + 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/cpuidle44xx.c (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 58de1f6df27c..9a6da52661ce 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -65,7 +65,8 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ cpuidle34xx.o -obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \ + cpuidle44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c new file mode 100644 index 000000000000..81386c6256eb --- /dev/null +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -0,0 +1,237 @@ +/* + * OMAP4 CPU idle Routines + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar + * Rajendra Nayak + * + * 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 +#include +#include +#include + +#include + +#include "common.h" +#include "pm.h" +#include "prm.h" + +#ifdef CONFIG_CPU_IDLE + +/* Machine specific information to be recorded in the C-state driver_data */ +struct omap4_idle_statedata { + u32 cpu_state; + u32 mpu_logic_state; + u32 mpu_state; + u8 valid; +}; + +static struct cpuidle_params cpuidle_params_table[] = { + /* C1 - CPU0 ON + CPU1 ON + MPU ON */ + {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, + /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ + {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, + /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ + {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, +}; + +#define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table) + +struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES]; +static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; + +/** + * omap4_enter_idle - Programs OMAP4 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 low power state selected by the governor. + * Returns the amount of time spent in the low power state. + */ +static int omap4_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + 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 new_state_idx; + + /* Used to keep track of the total time in idle */ + getnstimeofday(&ts_preidle); + + local_irq_disable(); + local_fiq_disable(); + + /* + * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state. + * This is necessary to honour hardware recommondation + * of triggeing all the possible low power modes once CPU1 is + * out of coherency and in OFF mode. + * Update dev->last_state so that governor stats reflects right + * data. + */ + cpu1_state = pwrdm_read_pwrst(cpu1_pd); + if (cpu1_state != PWRDM_POWER_OFF) { + new_state_idx = drv->safe_state_index; + cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]); + } + + /* + * Call idle CPU PM enter notifier chain so that + * VFP and per CPU interrupt context is saved. + */ + if (cx->cpu_state == PWRDM_POWER_OFF) + cpu_pm_enter(); + + pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); + omap_set_pwrdm_state(mpu_pd, cx->mpu_state); + + /* + * Call idle CPU cluster PM enter notifier chain + * to save GIC and wakeupgen context. + */ + if ((cx->mpu_state == PWRDM_POWER_RET) && + (cx->mpu_logic_state == PWRDM_POWER_OFF)) + cpu_cluster_pm_enter(); + + omap4_enter_lowpower(dev->cpu, cx->cpu_state); + + /* + * Call idle CPU PM exit notifier chain to restore + * VFP and per CPU IRQ context. Only CPU0 state is + * considered since CPU1 is managed by CPU hotplug. + */ + if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF) + cpu_pm_exit(); + + /* + * Call idle CPU cluster PM exit notifier chain + * to restore GIC and wakeupgen context. + */ + if (omap4_mpuss_read_prev_context_state()) + cpu_cluster_pm_exit(); + + 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, +}; + +static inline void _fill_cstate(struct cpuidle_driver *drv, + int idx, const char *descr) +{ + struct cpuidle_state *state = &drv->states[idx]; + + state->exit_latency = cpuidle_params_table[idx].exit_latency; + state->target_residency = cpuidle_params_table[idx].target_residency; + state->flags = CPUIDLE_FLAG_TIME_VALID; + state->enter = omap4_enter_idle; + sprintf(state->name, "C%d", idx + 1); + strncpy(state->desc, descr, CPUIDLE_DESC_LEN); +} + +static inline struct omap4_idle_statedata *_fill_cstate_usage( + struct cpuidle_device *dev, + int idx) +{ + struct omap4_idle_statedata *cx = &omap4_idle_data[idx]; + struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; + + cx->valid = cpuidle_params_table[idx].valid; + cpuidle_set_statedata(state_usage, cx); + + return cx; +} + + + +/** + * omap4_idle_init - Init routine for OMAP4 idle + * + * Registers the OMAP4 specific cpuidle driver to the cpuidle + * framework with the valid set of states. + */ +int __init omap4_idle_init(void) +{ + struct omap4_idle_statedata *cx; + struct cpuidle_device *dev; + struct cpuidle_driver *drv = &omap4_idle_driver; + unsigned int cpu_id = 0; + + mpu_pd = pwrdm_lookup("mpu_pwrdm"); + cpu0_pd = pwrdm_lookup("cpu0_pwrdm"); + cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); + if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) + return -ENODEV; + + + drv->safe_state_index = -1; + dev = &per_cpu(omap4_idle_dev, cpu_id); + dev->cpu = cpu_id; + + /* C1 - CPU0 ON + CPU1 ON + MPU ON */ + _fill_cstate(drv, 0, "MPUSS ON"); + drv->safe_state_index = 0; + cx = _fill_cstate_usage(dev, 0); + cx->valid = 1; /* C1 is always valid */ + cx->cpu_state = PWRDM_POWER_ON; + cx->mpu_state = PWRDM_POWER_ON; + cx->mpu_logic_state = PWRDM_POWER_RET; + + /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ + _fill_cstate(drv, 1, "MPUSS CSWR"); + cx = _fill_cstate_usage(dev, 1); + cx->cpu_state = PWRDM_POWER_OFF; + cx->mpu_state = PWRDM_POWER_RET; + cx->mpu_logic_state = PWRDM_POWER_RET; + + /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ + _fill_cstate(drv, 2, "MPUSS OSWR"); + cx = _fill_cstate_usage(dev, 2); + cx->cpu_state = PWRDM_POWER_OFF; + cx->mpu_state = PWRDM_POWER_RET; + cx->mpu_logic_state = PWRDM_POWER_OFF; + + drv->state_count = OMAP4_NUM_STATES; + cpuidle_register_driver(&omap4_idle_driver); + + dev->state_count = OMAP4_NUM_STATES; + if (cpuidle_register_device(dev)) { + pr_err("%s: CPUidle register device failed\n", __func__); + return -EIO; + } + + return 0; +} +#else +int __init omap4_idle_init(void) +{ + return 0; +} +#endif /* CONFIG_CPU_IDLE */ diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 4e166add2f35..b737b11e4499 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -21,6 +21,7 @@ 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); #if defined(CONFIG_PM_OPP) extern int omap3_opp_init(void); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 92daae07d634..c264ef7219c1 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -258,6 +258,8 @@ static int __init omap4_pm_init(void) /* Overwrite the default arch_idle() */ pm_idle = omap_default_idle; + omap4_idle_init(); + err2: return ret; } -- cgit v1.2.3 From 98be0dde1957a1e47d42cf2c220bf52bacf81d6e Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 16 Jan 2011 00:42:31 +0530 Subject: ARM: OMAP4: cpuidle: Switch to gptimer from twd in deeper C-states. CPU local timer(TWD) stops when the CPU is transitioning into deeper C-States. Since these timers are not wakeup capable, we need the wakeup capable global timer to program the wakeup time depending on the next timer expiry. It can be handled by registering a global wakeup capable timer along with local timers marked with (mis)feature flag CLOCK_EVT_FEAT_C3STOP. Then notify the clock events layer from idle code using CLOCK_EVT_NOTIFY_BROADCAST_ENTER/EXIT). ARM local timers are already marked with C3STOP feature. Add the notifiers to OMAP4 CPU idle code for the broadcast entry and exit. Signed-off-by: Santosh Shilimkar Acked-by: Jean Pihet Acked-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle44xx.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 81386c6256eb..cfdbb86bc84e 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -65,6 +66,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, u32 cpu1_state; int idle_time; int new_state_idx; + int cpu_id = smp_processor_id(); /* Used to keep track of the total time in idle */ getnstimeofday(&ts_preidle); @@ -86,6 +88,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev, cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]); } + if (index > 0) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); + /* * Call idle CPU PM enter notifier chain so that * VFP and per CPU interrupt context is saved. @@ -121,6 +126,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev, if (omap4_mpuss_read_prev_context_state()) cpu_cluster_pm_exit(); + if (index > 0) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); + getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); -- cgit v1.2.3 From ff819da44258ca12b9f60dfd589884106e5a3129 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sat, 3 Sep 2011 22:38:27 +0530 Subject: ARM: OMAP3: CPUidle: Make use of CPU PM notifiers Save VFP CPU context using CPU PM notifier chain. VFP context is lost when CPU hits OFF state. Signed-off-by: Santosh Shilimkar Reviewed-by: Kevin Hilman Tested-by: Vishwanath BS Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index e20332f4abdc..1f71ebb6c12c 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -124,9 +125,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev, pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); } + /* + * Call idle CPU PM enter notifier chain so that + * VFP context is saved. + */ + if (mpu_state == PWRDM_POWER_OFF) + cpu_pm_enter(); + /* Execute ARM wfi */ omap_sram_idle(); + /* + * Call idle CPU PM enter notifier chain to restore + * VFP context. + */ + if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) + cpu_pm_exit(); + /* Re-allow idle for C1 */ if (index == 0) { pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); -- cgit v1.2.3 From 6fdc75de7d0554134890d33a0a6f5e18c7503c01 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 22 Nov 2011 16:02:18 +0200 Subject: ARM: OMAP: hsmmc: add pm_caps field Add pm_caps field to omap2_hsmmc_info and omap_mmc_slot_data structs, so we will be able to indicate mmc pm capabilities in the board file. Signed-off-by: Eliad Peller Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 1 + arch/arm/mach-omap2/hsmmc.h | 1 + arch/arm/plat-omap/include/plat/mmc.h | 1 + drivers/mmc/host/omap_hsmmc.c | 2 ++ 4 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index f4a1020559a7..97dfedce084b 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -296,6 +296,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, mmc->slots[0].name = hc_name; mmc->nr_slots = 1; mmc->slots[0].caps = c->caps; + mmc->slots[0].pm_caps = c->pm_caps; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; if (cpu_is_omap44xx()) diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h index f757e78d4d4f..c4409730c4bb 100644 --- a/arch/arm/mach-omap2/hsmmc.h +++ b/arch/arm/mach-omap2/hsmmc.h @@ -12,6 +12,7 @@ struct omap2_hsmmc_info { u8 mmc; /* controller 1/2/3 */ u32 caps; /* 4/8 wires and any additional host * capabilities OR'd (ref. linux/mmc/host.h) */ + u32 pm_caps; /* PM capabilities */ bool transceiver; /* MMC-2 option */ bool ext_clock; /* use external pin for input clock */ bool cover_only; /* No card detect - just cover switch */ diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index 94cf70afb236..f75946c3293d 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -96,6 +96,7 @@ struct omap_mmc_platform_data { */ u8 wires; /* Used for the MMC driver on omap1 and 2420 */ u32 caps; /* Used for the MMC driver on 2430 and later */ + u32 pm_caps; /* PM capabilities of the mmc */ /* * nomux means "standard" muxing is wrong on this board, and diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6784fbbc337d..f0d792183b8e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1988,6 +1988,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) if (mmc_slot(host).nonremovable) mmc->caps |= MMC_CAP_NONREMOVABLE; + mmc->pm_caps = mmc_slot(host).pm_caps; + omap_hsmmc_conf_bus_power(host); /* Select DMA lines */ -- cgit v1.2.3 From ee62e93a3c135ae18f2fa18615ce065fe5487259 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 8 Dec 2011 14:58:38 -0800 Subject: ARM: OMAP1: Set the omap1623 sram size to 16K Now that we're always reprogramming the core clock we must make sure SRAM works. It seems that neither omap1621 or omap1623 has 256K of SRAM. Set the SRAM size to safe value of 16K. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/sram.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 8b28664d1c62..574351902c83 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -141,11 +141,9 @@ static void __init omap_detect_sram(void) omap_sram_size = 0x32000; /* 200K */ else if (cpu_is_omap15xx()) omap_sram_size = 0x30000; /* 192K */ - else if (cpu_is_omap1610() || cpu_is_omap1621() || - cpu_is_omap1710()) + else if (cpu_is_omap1610() || cpu_is_omap1611() || + cpu_is_omap1621() || cpu_is_omap1710()) omap_sram_size = 0x4000; /* 16K */ - else if (cpu_is_omap1611()) - omap_sram_size = SZ_256K; else { pr_err("Could not detect SRAM size\n"); omap_sram_size = 0x4000; -- cgit v1.2.3 From 24ce2705c2dd50e51f325c6e57dec378adc8c135 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 8 Dec 2011 18:01:41 -0800 Subject: ARM: OMAP1: Move dpll1 rates selection from config to runtime For still better multi-OMAP1 support, expand omap1_rate_table with flags for different SoC types and match them while selecting clock rates. The idea is stolen from current omap24xx clock rate selection algorithm. Since clkdev platform flag definitions are reused here, those had to be expanded with one extra entry for OMAP1710 subtype, as this is the only SoC for which we allow selection of the highest, 216 MHz rate. Once done, remove no longer needed clock rate configure time options. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/configs/omap1_defconfig | 1 - arch/arm/mach-omap1/Kconfig | 64 --------------------------- arch/arm/mach-omap1/clock.c | 6 +++ arch/arm/mach-omap1/clock.h | 3 ++ arch/arm/mach-omap1/clock_data.c | 6 ++- arch/arm/mach-omap1/opp.h | 1 + arch/arm/mach-omap1/opp_data.c | 63 ++++++++++++-------------- arch/arm/plat-omap/include/plat/clkdev_omap.h | 1 + 8 files changed, 45 insertions(+), 100 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 945a34f2a34d..dde2a1af7b39 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -48,7 +48,6 @@ CONFIG_MACH_SX1=y CONFIG_MACH_NOKIA770=y CONFIG_MACH_AMS_DELTA=y CONFIG_MACH_OMAP_GENERIC=y -CONFIG_OMAP_ARM_182MHZ=y # CONFIG_ARM_THUMB is not set CONFIG_PCCARD=y CONFIG_OMAP_CF=y diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 73f287d6429b..4f8d66f044e7 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -168,70 +168,6 @@ config MACH_OMAP_GENERIC custom OMAP boards. Say Y here if you have a custom board. -comment "OMAP CPU Speed" - depends on ARCH_OMAP1 - -config OMAP_ARM_216MHZ - bool "OMAP ARM 216 MHz CPU (1710 only)" - depends on ARCH_OMAP1 && ARCH_OMAP16XX - help - Enable 216 MHz clock for OMAP1710 CPU. If unsure, say N. - -config OMAP_ARM_195MHZ - bool "OMAP ARM 195 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 195MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_192MHZ - bool "OMAP ARM 192 MHz CPU" - depends on ARCH_OMAP1 && ARCH_OMAP16XX - help - Enable 192MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_182MHZ - bool "OMAP ARM 182 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 182MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_168MHZ - bool "OMAP ARM 168 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 168MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_150MHZ - bool "OMAP ARM 150 MHz CPU" - depends on ARCH_OMAP1 && ARCH_OMAP15XX - help - Enable 150MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_120MHZ - bool "OMAP ARM 120 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 120MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_96MHZ - bool "OMAP ARM 96 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 96MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_60MHZ - bool "OMAP ARM 60 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - default y - help - Enable 60MHz clock for OMAP CPU. If unsure, say Y. - -config OMAP_ARM_30MHZ - bool "OMAP ARM 30 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 30MHz clock for OMAP CPU. If unsure, say N. - endmenu endif diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 84ef70476b51..ff27dbdba3d6 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -197,6 +197,9 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) ref_rate = ck_ref_p->rate; for (ptr = omap1_rate_table; ptr->rate; ptr++) { + if (!(ptr->flags & cpu_mask)) + continue; + if (ptr->xtal != ref_rate) continue; @@ -290,6 +293,9 @@ long omap1_round_to_table_rate(struct clk *clk, unsigned long rate) highest_rate = -EINVAL; for (ptr = omap1_rate_table; ptr->rate; ptr++) { + if (!(ptr->flags & cpu_mask)) + continue; + if (ptr->xtal != ref_rate) continue; diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 16b1423b454a..3d04f4f67676 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -111,4 +111,7 @@ extern const struct clkops clkops_dummy; extern const struct clkops clkops_uart_16xx; extern const struct clkops clkops_generic; +/* used for passing SoC type to omap1_{select,round_to}_table_rate() */ +extern u32 cpu_mask; + #endif diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 9ff90a744a21..ff2d5248df23 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -778,12 +778,14 @@ static void __init omap1_show_rates(void) arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); } +u32 cpu_mask; + int __init omap1_clk_init(void) { struct omap_clk *c; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ - u32 reg, cpu_mask; + u32 reg; #ifdef CONFIG_DEBUG_LL /* @@ -808,6 +810,8 @@ int __init omap1_clk_init(void) clk_preinit(c->lk.clk); cpu_mask = 0; + if (cpu_is_omap1710()) + cpu_mask |= CK_1710; if (cpu_is_omap16xx()) cpu_mask |= CK_16XX; if (cpu_is_omap1510()) diff --git a/arch/arm/mach-omap1/opp.h b/arch/arm/mach-omap1/opp.h index 07074d79adce..79a683864a5c 100644 --- a/arch/arm/mach-omap1/opp.h +++ b/arch/arm/mach-omap1/opp.h @@ -21,6 +21,7 @@ struct mpu_rate { unsigned long pll_rate; __u16 ckctl_val; __u16 dpllctl_val; + u32 flags; }; extern struct mpu_rate omap1_rate_table[]; diff --git a/arch/arm/mach-omap1/opp_data.c b/arch/arm/mach-omap1/opp_data.c index 75a546514994..9cd4ddb51397 100644 --- a/arch/arm/mach-omap1/opp_data.c +++ b/arch/arm/mach-omap1/opp_data.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include "opp.h" /*------------------------------------------------------------------------- @@ -20,40 +21,34 @@ struct mpu_rate omap1_rate_table[] = { * NOTE: Comment order here is different from bits in CKCTL value: * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv */ -#if defined(CONFIG_OMAP_ARM_216MHZ) - { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_195MHZ) - { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_192MHZ) - { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ - { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ - { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ - { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */ - { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_182MHZ) - { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_168MHZ) - { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_150MHZ) - { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ -#endif -#if defined(CONFIG_OMAP_ARM_120MHZ) - { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ -#endif -#if defined(CONFIG_OMAP_ARM_96MHZ) - { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ -#endif -#if defined(CONFIG_OMAP_ARM_60MHZ) - { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ -#endif -#if defined(CONFIG_OMAP_ARM_30MHZ) - { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ -#endif + { 216000000, 12000000, 216000000, 0x050d, 0x2910, /* 1/1/2/2/2/8 */ + CK_1710 }, + { 195000000, 13000000, 195000000, 0x050e, 0x2790, /* 1/1/2/2/4/8 */ + CK_7XX }, + { 192000000, 19200000, 192000000, 0x050f, 0x2510, /* 1/1/2/2/8/8 */ + CK_16XX }, + { 192000000, 12000000, 192000000, 0x050f, 0x2810, /* 1/1/2/2/8/8 */ + CK_16XX }, + { 96000000, 12000000, 192000000, 0x055f, 0x2810, /* 2/2/2/2/8/8 */ + CK_16XX }, + { 48000000, 12000000, 192000000, 0x0baf, 0x2810, /* 4/4/4/8/8/8 */ + CK_16XX }, + { 24000000, 12000000, 192000000, 0x0fff, 0x2810, /* 8/8/8/8/8/8 */ + CK_16XX }, + { 182000000, 13000000, 182000000, 0x050e, 0x2710, /* 1/1/2/2/4/8 */ + CK_7XX }, + { 168000000, 12000000, 168000000, 0x010f, 0x2710, /* 1/1/1/2/8/8 */ + CK_16XX|CK_7XX }, + { 150000000, 12000000, 150000000, 0x010a, 0x2cb0, /* 1/1/1/2/4/4 */ + CK_1510 }, + { 120000000, 12000000, 120000000, 0x010a, 0x2510, /* 1/1/1/2/4/4 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, + { 96000000, 12000000, 96000000, 0x0005, 0x2410, /* 1/1/1/1/2/2 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, + { 60000000, 12000000, 60000000, 0x0005, 0x2290, /* 1/1/1/1/2/2 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, + { 30000000, 12000000, 60000000, 0x0555, 0x2290, /* 2/2/2/2/2/2 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, { 0, 0, 0, 0, 0 }, }; diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index 387a9638991b..b299b8d201c8 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -40,6 +40,7 @@ struct omap_clk { #define CK_443X (1 << 11) #define CK_TI816X (1 << 12) #define CK_446X (1 << 13) +#define CK_1710 (1 << 15) /* 1710 extra for rate selection */ #define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) -- cgit v1.2.3 From f9e5908fa04e15a681dc4695b53c2c0c1d9b9a03 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 1 Dec 2011 22:16:26 +0100 Subject: ARM: OMAP1: Update dpll1 default rate reprogramming method According to comments in omap1_select_table_rate(), reprogramming dpll1 is tricky, and should always be done from SRAM. While being at it, move OMAP730 special case handling inside omap_sram_reprogram_clock(). Created on top of version 2 of the series "ARM: OMAP1: Fix dpll1 reprogramming related issues", which it depends on. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock.c | 6 +----- arch/arm/mach-omap1/clock_data.c | 7 +++++-- arch/arm/plat-omap/sram.c | 3 +++ 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index ff27dbdba3d6..6d8f7c640237 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -218,12 +218,8 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) /* * In most cases we should not need to reprogram DPLL. * Reprogramming the DPLL is tricky, it must be done from SRAM. - * (on 730, bit 13 must always be 1) */ - if (cpu_is_omap7xx()) - omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000); - else - omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); + omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); /* XXX Do we need to recalculate the tree below DPLL1 at this point? */ ck_dpll1_p->rate = ptr->pll_rate; diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index ff2d5248df23..9d1a42a5afd8 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -25,6 +25,7 @@ #include #include #include +#include /* for omap_sram_reprogram_clock() */ #include /* for OTG_BASE */ #include "clock.h" @@ -944,8 +945,10 @@ void __init omap1_clk_late_init(void) /* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n"); - omap_writew(0x2290, DPLL_CTL); - omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL); + /* + * Reprogramming the DPLL is tricky, it must be done from SRAM. + */ + omap_sram_reprogram_clock(0x2290, 0x0005); ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; } propagate_rate(&ck_dpll1); diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 574351902c83..6b058a621e8d 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -222,6 +222,9 @@ static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) { BUG_ON(!_omap_sram_reprogram_clock); + /* On 730, bit 13 must always be 1 */ + if (cpu_is_omap7xx()) + ckctl |= 0x2000; _omap_sram_reprogram_clock(dpllctl, ckctl); } -- cgit v1.2.3 From c116abc43df9ce3ebe5fbf2fbd6ae2edd6a9bd87 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Sun, 4 Dec 2011 16:07:47 +0100 Subject: ARM: OMAP1: Always reprogram dpll1 rate at boot DPLL1 reprogramming to a different rate is actually blocked inside omap1_select_table_rate(). However, it is already forced at boot, for boards which boot at unusable clock rates, and this seems to work correctly. OTOH, we now have a fine, run time performed clock selection algorithm implemented, which prevents less powerfull SoCs from being overclocked unintentionally. Allow reprogramming of dpll1 by default, and use it for switching to the higest supported clock rate with all boards, including those already booting at a usable rate of 60 MHz or above. Created against linux-omap/master tip as of Thu Dec 1, commit f83c2a8cbb59981722d1ab610c79adfd034a2667. Requires the just submitted patch "ARM: OMAP1: Move dpll1 rates selection from config to runtime" to prevent from unintentional overclocking. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock.c | 4 ---- arch/arm/mach-omap1/clock_data.c | 6 ------ 2 files changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 6d8f7c640237..0c50df05d135 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -203,10 +203,6 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) if (ptr->xtal != ref_rate) continue; - /* DPLL1 cannot be reprogrammed without risking system crash */ - if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate) - continue; - /* Can check only after xtal frequency check */ if (ptr->rate <= rate) break; diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 9d1a42a5afd8..94699a82a734 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -936,12 +936,6 @@ void __init omap1_clk_late_init(void) { unsigned long rate = ck_dpll1.rate; - if (rate >= OMAP1_DPLL1_SANE_VALUE) - return; - - /* System booting at unusable rate, force reprogramming of DPLL1 */ - ck_dpll1_p->rate = 0; - /* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n"); -- cgit v1.2.3 From fac1d933f4691d59eb5f6ec02bb8eae8d5c68297 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 22 Nov 2011 16:02:19 +0200 Subject: ARM: OMAP: hsmmc: board-sdp4430: declare support for MMC_PM_KEEP_POWER Declare support for keeping the power of the wlan chip while suspended. this is needed for Wakeup-On-Wireless. Signed-off-by: Eliad Peller Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-4430sdp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 515646886b59..ba23224963d0 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -404,6 +404,7 @@ static struct omap2_hsmmc_info mmc[] = { { .mmc = 5, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, + .pm_caps = MMC_PM_KEEP_POWER, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, .ocr_mask = MMC_VDD_165_195, -- cgit v1.2.3 From e62245ba1caaf78d6fe2619266939c8e7caa150c Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 29 Nov 2011 11:37:48 +0200 Subject: ARM: OMAP: hsmmc: Add support for MMC 2 setup for AM35x AM35x MMC 2 controller has internal clock loopback setting which cannot be utilized without this patch and thus SDIO devices connected to this controller and depend on this setting will fail to initialize. Signed-off-by: Igor Grinberg [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 97dfedce084b..59830d0eeb55 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -171,6 +171,17 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot, } } +static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc) +{ + u32 reg; + + if (mmc->slots[0].internal_clock) { + reg = omap_ctrl_readl(control_devconf1_offset); + reg |= OMAP2_MMCSDIO2ADPCLKISEL; + omap_ctrl_writel(reg, control_devconf1_offset); + } +} + static void hsmmc23_before_set_reg(struct device *dev, int slot, int power_on, int vdd) { @@ -179,16 +190,19 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot, if (mmc->slots[0].remux) mmc->slots[0].remux(dev, slot, power_on); - if (power_on) { - /* Only MMC2 supports a CLKIN */ - if (mmc->slots[0].internal_clock) { - u32 reg; + if (power_on) + hsmmc2_select_input_clk_src(mmc); +} - reg = omap_ctrl_readl(control_devconf1_offset); - reg |= OMAP2_MMCSDIO2ADPCLKISEL; - omap_ctrl_writel(reg, control_devconf1_offset); - } - } +static int am35x_hsmmc2_set_power(struct device *dev, int slot, + int power_on, int vdd) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + if (power_on) + hsmmc2_select_input_clk_src(mmc); + + return 0; } static int nop_mmc_set_power(struct device *dev, int slot, int power_on, @@ -339,9 +353,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, */ mmc->slots[0].ocr_mask = c->ocr_mask; - if (cpu_is_omap3517() || cpu_is_omap3505()) - mmc->slots[0].set_power = nop_mmc_set_power; - else + if (!cpu_is_omap3517() && !cpu_is_omap3505()) mmc->slots[0].features |= HSMMC_HAS_PBIAS; if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) @@ -364,6 +376,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, } } + if (cpu_is_omap3517() || cpu_is_omap3505()) + mmc->slots[0].set_power = nop_mmc_set_power; + /* OMAP3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && (c->caps & MMC_CAP_8_BIT_DATA)) { @@ -373,6 +388,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, } break; case 2: + if (cpu_is_omap3517() || cpu_is_omap3505()) + mmc->slots[0].set_power = am35x_hsmmc2_set_power; + if (c->ext_clock) c->transceiver = 1; if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { -- cgit v1.2.3 From a15164f13fb3f0f70849c2a099ff0af7b2924ba1 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Thu, 17 Nov 2011 22:39:40 +0100 Subject: ARM: OMAP: hsmmc: Add support for non-OMAP pins The Devkit8000 uses a TWL4030 pin for card detection. Thats why the error: _omap_mux_init_gpio: Could not set gpio192 occurs. This patch checks that the pin is on OMAP before calling omap_mux_init_gpio. Signed-off-by: Thomas Weber [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 59830d0eeb55..997b33d76418 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -214,10 +214,12 @@ static int nop_mmc_set_power(struct device *dev, int slot, int power_on, static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, int controller_nr) { - if (gpio_is_valid(mmc_controller->slots[0].switch_pin)) + if (gpio_is_valid(mmc_controller->slots[0].switch_pin) && + (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, OMAP_PIN_INPUT_PULLUP); - if (gpio_is_valid(mmc_controller->slots[0].gpio_wp)) + if (gpio_is_valid(mmc_controller->slots[0].gpio_wp) && + (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, OMAP_PIN_INPUT_PULLUP); if (cpu_is_omap34xx()) { -- cgit v1.2.3 From e89715a7e48d505f42813a4e3ee0f0efb49832ba Mon Sep 17 00:00:00 2001 From: Abhilash K V Date: Fri, 9 Dec 2011 12:27:36 -0800 Subject: ARM: OMAP: hsmmc: Support for AM3517 MMC1 voltages This patch fixes the following error message which appears while intializing MMC1 on the AM3517 EVM base-board: mmc0: host doesn't support card's voltages mmc0: error -22 whilst initialising SD card The ocr_mask, which enumerates the volatges supported by the MMC card was not being indicated before, assuming that a separate Vcc regulator maybe another controllable regulator driver would be doing this. This patch statically specifies a subset of the voltages supported by the MMC driver, which are provided by the current fixed voltage regulator on AM3517 EVM. Signed-off-by: Vaibhav Hiremath Signed-off-by: Abhilash K V Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 997b33d76418..bd844af13af5 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -353,7 +353,15 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, * * temporary HACK: ocr_mask instead of fixed supply */ - mmc->slots[0].ocr_mask = c->ocr_mask; + if (cpu_is_omap3505() || cpu_is_omap3517()) + mmc->slots[0].ocr_mask = MMC_VDD_165_195 | + MMC_VDD_26_27 | + MMC_VDD_27_28 | + MMC_VDD_29_30 | + MMC_VDD_30_31 | + MMC_VDD_31_32; + else + mmc->slots[0].ocr_mask = c->ocr_mask; if (!cpu_is_omap3517() && !cpu_is_omap3505()) mmc->slots[0].features |= HSMMC_HAS_PBIAS; -- cgit v1.2.3 From dd6facfc0ee3e5875b39a5f368af266395171996 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Fri, 9 Dec 2011 12:27:55 -0800 Subject: ARM: OMAP: hsmmc: Add support for AM3517EVM base-board MMC slot Add support for base-board MMC slot Signed-off-by: Vaibhav Hiremath Signed-off-by: Abhilash K V [tony@atomide.com: updated subject] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-am3517evm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index d314f033c9df..f7df8d35ee90 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,7 @@ #include "mux.h" #include "control.h" +#include "hsmmc.h" #define AM35XX_EVM_MDIO_FREQUENCY (1000000) @@ -455,6 +457,23 @@ static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata) static struct omap_board_config_kernel am3517_evm_config[] __initdata = { }; +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = 127, + .gpio_wp = 126, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = 128, + .gpio_wp = 129, + }, + {} /* Terminator */ +}; + + static void __init am3517_evm_init(void) { omap_board_config = am3517_evm_config; @@ -483,6 +502,9 @@ static void __init am3517_evm_init(void) /* MUSB */ am3517_evm_musb_init(); + + /* MMC init function */ + omap2_hsmmc_init(mmc); } MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") -- cgit v1.2.3 From 7ba966804f58ccd81375827a71222efaa131aa70 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 9 Dec 2011 13:38:00 -0800 Subject: ARM: OMAP2+: DMA: Workaround for invalid source position If the DMA source position has been asked before the first actual data transfer has been done, the CSAC register does not contain valid information. We can identify this situation by checking the CDAC register: CDAC != 0 indicates that the DMA transfer on the channel has been started already. When CDAC == 0 we can not trust the CSAC value since it has not been updated, and can contain random number. Return the start address in case the DMA has not jet started. Note: The CDAC register has been initialized to 0 at dma_start time. Signed-off-by: Peter Ujfalusi Reviewed-by: Jarkko Nikula Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index c22217c2ee5f..a9983b695a18 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1034,6 +1034,18 @@ dma_addr_t omap_get_dma_src_pos(int lch) if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0) offset = p->dma_read(CSAC, lch); + if (!cpu_is_omap15xx()) { + /* + * CDAC == 0 indicates that the DMA transfer on the channel has + * not been started (no data has been transferred so far). + * Return the programmed source start address in this case. + */ + if (likely(p->dma_read(CDAC, lch))) + offset = p->dma_read(CSAC, lch); + else + offset = p->dma_read(CSSA, lch); + } + if (cpu_class_is_omap1()) offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000); -- cgit v1.2.3 From 06e8077b556a372871c04dd68f47e8c25e9ca348 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 9 Dec 2011 13:38:00 -0800 Subject: ARM: OMAP2+: DMA: Workaround for invalid destination position If the DMA destination position has been asked before the first actual data transfer has been done, the CDAC register still contains 0 (it is initialized to 0 at omsp_dma_start). If CDAC == 0, return the programmed start address. Signed-off-by: Peter Ujfalusi Reviewed-by: Jarkko Nikula Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index a9983b695a18..002fb4d96bbc 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1074,8 +1074,16 @@ dma_addr_t omap_get_dma_dst_pos(int lch) * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is * read before the DMA controller finished disabling the channel. */ - if (!cpu_is_omap15xx() && offset == 0) + if (!cpu_is_omap15xx() && offset == 0) { offset = p->dma_read(CDAC, lch); + /* + * CDAC == 0 indicates that the DMA transfer on the channel has + * not been started (no data has been transferred so far). + * Return the programmed destination start address in this case. + */ + if (unlikely(!offset)) + offset = p->dma_read(CDSA, lch); + } if (cpu_class_is_omap1()) offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000); -- cgit v1.2.3 From 9deaa53ac7fa373623123aa4f18828dd62292b1a Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 4 Dec 2011 18:42:23 -0500 Subject: serial: add irq handler for Freescale 16550 errata. Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx chips seems to cause a short lived IRQ storm (/proc/interrupts typically shows somewhere between 300 and 1500 events). Unfortunately this renders SysRQ over the serial console completely inoperable. The suggested workaround in the errata is to read the Rx register, wait one character period, and then read the Rx register again. We achieve this by tracking the old LSR value, and on the subsequent interrupt event after a break, we don't read LSR, instead we just read the RBR again and return immediately. The "fsl,ns16550" is used in the compatible field of the serial device to mark UARTs known to have this issue. Thanks to Scott Wood for providing the errata data which led to a much cleaner fix. Signed-off-by: Paul Gortmaker Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/legacy_serial.c | 3 ++ drivers/tty/serial/8250_fsl.c | 63 +++++++++++++++++++++++++++++++++++++ drivers/tty/serial/Kconfig | 5 +++ drivers/tty/serial/Makefile | 1 + include/linux/serial_8250.h | 1 + 5 files changed, 73 insertions(+) create mode 100644 drivers/tty/serial/8250_fsl.c (limited to 'arch') diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index c7b5afeecaf2..3fea3689527e 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -441,6 +441,9 @@ static void __init fixup_port_irq(int index, return; port->irq = virq; + + if (of_device_is_compatible(np, "fsl,ns16550")) + port->handle_irq = fsl8250_handle_irq; } static void __init fixup_port_pio(int index, diff --git a/drivers/tty/serial/8250_fsl.c b/drivers/tty/serial/8250_fsl.c new file mode 100644 index 000000000000..f4d3c47b88e8 --- /dev/null +++ b/drivers/tty/serial/8250_fsl.c @@ -0,0 +1,63 @@ +#include +#include + +#include "8250.h" + +/* + * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker. + * + * 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 isn't a full driver; it just provides an alternate IRQ + * handler to deal with an errata. Everything else is just + * using the bog standard 8250 support. + * + * We follow code flow of serial8250_default_handle_irq() but add + * a check for a break and insert a dummy read on the Rx for the + * immediately following IRQ event. + * + * We re-use the already existing "bug handling" lsr_saved_flags + * field to carry the "what we just did" information from the one + * IRQ event to the next one. + */ + +int fsl8250_handle_irq(struct uart_port *port) +{ + unsigned char lsr, orig_lsr; + unsigned long flags; + unsigned int iir; + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + + spin_lock_irqsave(&up->port.lock, flags); + + iir = port->serial_in(port, UART_IIR); + if (iir & UART_IIR_NO_INT) { + spin_unlock_irqrestore(&up->port.lock, flags); + return 0; + } + + /* This is the WAR; if last event was BRK, then read and return */ + if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) { + up->lsr_saved_flags &= ~UART_LSR_BI; + port->serial_in(port, UART_RX); + spin_unlock_irqrestore(&up->port.lock, flags); + return 1; + } + + lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR); + + if (lsr & (UART_LSR_DR | UART_LSR_BI)) + lsr = serial8250_rx_chars(up, lsr); + + serial8250_modem_status(up); + + if (lsr & UART_LSR_THRE) + serial8250_tx_chars(up); + + up->lsr_saved_flags = orig_lsr; + spin_unlock_irqrestore(&up->port.lock, flags); + return 1; +} diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 705d2dc39c9a..fee9e04f42e7 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -97,6 +97,11 @@ config SERIAL_8250_PNP This builds standard PNP serial support. You may be able to disable this feature if you only need legacy serial support. +config SERIAL_8250_FSL + bool + depends on SERIAL_8250 && PPC + default PPC + config SERIAL_8250_HP300 tristate depends on SERIAL_8250 && HP300 diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index af57089ddb67..75eadb8d7178 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o +obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index b44034eca123..8f012f8ac8e9 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -82,6 +82,7 @@ extern void serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old); extern void serial8250_do_pm(struct uart_port *port, unsigned int state, unsigned int oldstate); +extern int fsl8250_handle_irq(struct uart_port *port); int serial8250_handle_irq(struct uart_port *port, unsigned int iir); unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr); void serial8250_tx_chars(struct uart_8250_port *up); -- cgit v1.2.3 From 559f7a0346a48af91f6127677c843d0182ac0715 Mon Sep 17 00:00:00 2001 From: Stefan Nilsson XK Date: Wed, 26 Oct 2011 10:49:35 +0200 Subject: ARM: ux500: support SD cards on HREFv60 boards Properly support the correct SDI-init sequence on the ST-Ericsson HREFv60 and later boards in order to get support for SD cards. Signed-off-by: Stefan Nilsson XK Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500.c | 2 +- arch/arm/mach-ux500/board-mop500.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index bdd7b80dd7ad..eb85e75d86ba 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -672,7 +672,7 @@ static void __init hrefv60_init_machine(void) ARRAY_SIZE(mop500_platform_devs)); mop500_i2c_init(); - mop500_sdi_init(); + hrefv60_sdi_init(); mop500_spi_init(); mop500_uart_init(); diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index de18a2a23e6e..e82552ae97e3 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -41,6 +41,7 @@ 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); void __init mop500_u8500uib_init(void); void __init mop500_stuib_init(void); -- cgit v1.2.3 From 76d6717bce0e725b280ca18b42725421774eb554 Mon Sep 17 00:00:00 2001 From: Stefan Nilsson XK Date: Wed, 26 Oct 2011 10:50:42 +0200 Subject: ARM: ux500: add device sdi1 for SDIO Adds device sdi1 for ST-Ericsson HREFv60 and later to enable the possiblity of using the onboard CW1200 chip for WLAN. Signed-off-by: Stefan Nilsson XK Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500-sdi.c | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 6826faeecc68..cf93dca97b9a 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -131,6 +131,42 @@ void mop500_sdi_tc35892_init(void) sdi0_configure(); } +/* + * SDI1 (SDIO WLAN) + */ +#ifdef CONFIG_STE_DMA40 +static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; + +static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; +#endif + +static struct mmci_platform_data mop500_sdi1_data = { + .ocr_mask = MMC_VDD_29_30, + .f_max = 50000000, + .capabilities = MMC_CAP_4_BIT_DATA, + .gpio_cd = -1, + .gpio_wp = -1, +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &sdi1_dma_cfg_rx, + .dma_tx_param = &sdi1_dma_cfg_tx, +#endif +}; + /* * SDI 2 (POP eMMC, not on DB8500ed) */ @@ -260,4 +296,6 @@ void __init hrefv60_sdi_init(void) sdi0_en = HREFV60_SDMMC_EN_GPIO; sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; sdi0_configure(); + + db8500_add_sdi1(&mop500_sdi1_data, periphid); } -- cgit v1.2.3 From 017beaa63bd8034b6c6c0f964a57f54973f59f17 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Nov 2011 18:48:52 +0100 Subject: ARM: ux500: update the MOP500 GPIO assignments This is a more complete list of the MOP500 GPIO pins, especially for those used with the Snowball board. Sort GPIO number in falling number order so there is some structure to this file. Fix some whitespace issues in the process. Cc: Mian Yousaf Kaukab Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500.h | 62 ++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index e82552ae97e3..f926d3db6207 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -7,35 +7,71 @@ #ifndef __BOARD_MOP500_H #define __BOARD_MOP500_H -/* snowball GPIO for MMC card */ -#define SNOWBALL_SDMMC_EN_GPIO 217 -#define SNOWBALL_SDMMC_1V8_3V_GPIO 228 -#define SNOWBALL_SDMMC_CD_GPIO 218 +/* Snowball specific GPIO assignments, this board has no GPIO expander */ +#define SNOWBALL_ACCEL_INT1_GPIO 163 +#define SNOWBALL_ACCEL_INT2_GPIO 164 +#define SNOWBALL_MAGNET_DRDY_GPIO 165 +#define SNOWBALL_SDMMC_EN_GPIO 217 +#define SNOWBALL_SDMMC_1V8_3V_GPIO 228 +#define SNOWBALL_SDMMC_CD_GPIO 218 /* HREFv60-specific GPIO assignments, this board has no GPIO expander */ -#define HREFV60_TOUCH_RST_GPIO 143 -#define HREFV60_PROX_SENSE_GPIO 217 -#define HREFV60_HAL_SW_GPIO 145 -#define HREFV60_SDMMC_EN_GPIO 169 #define HREFV60_SDMMC_1V8_3V_GPIO 5 -#define HREFV60_SDMMC_CD_GPIO 95 -#define HREFV60_ACCEL_INT1_GPIO 82 -#define HREFV60_ACCEL_INT2_GPIO 83 +#define HREFV60_CAMERA_FLASH_ENABLE 21 #define HREFV60_MAGNET_DRDY_GPIO 32 #define HREFV60_DISP1_RST_GPIO 65 #define HREFV60_DISP2_RST_GPIO 66 +#define HREFV60_ACCEL_INT1_GPIO 82 +#define HREFV60_ACCEL_INT2_GPIO 83 +#define HREFV60_SDMMC_CD_GPIO 95 +#define HREFV60_XSHUTDOWN_SECONDARY_SENSOR 140 +#define HREFV60_TOUCH_RST_GPIO 143 +#define HREFV60_HAL_SW_GPIO 145 +#define HREFV60_SDMMC_EN_GPIO 169 +#define HREFV60_MMIO_XENON_CHARGE 170 +#define HREFV60_PROX_SENSE_GPIO 217 + +/* MOP500 generic GPIOs */ +#define CAMERA_FLASH_INT_PIN 7 +#define CYPRESS_TOUCH_INT_PIN 84 +#define XSHUTDOWN_PRIMARY_SENSOR 141 +#define XSHUTDOWN_SECONDARY_SENSOR 142 +#define CYPRESS_TOUCH_RST_GPIO 143 +#define MOP500_HDMI_RST_GPIO 196 +#define CYPRESS_SLAVE_SELECT_GPIO 216 /* GPIOs on the TC35892 expander */ #define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) +#define GPIO_MAGNET_DRDY MOP500_EGPIO(1) #define GPIO_SDMMC_CD MOP500_EGPIO(3) +#define GPIO_CAMERA_FLASH_ENABLE MOP500_EGPIO(4) +#define GPIO_MMIO_XENON_CHARGE MOP500_EGPIO(5) #define GPIO_PROX_SENSOR MOP500_EGPIO(7) +#define GPIO_HAL_SENSOR MOP500_EGPIO(8) +#define GPIO_ACCEL_INT1 MOP500_EGPIO(10) +#define GPIO_ACCEL_INT2 MOP500_EGPIO(11) #define GPIO_BU21013_CS MOP500_EGPIO(13) +#define MOP500_DISP2_RST_GPIO MOP500_EGPIO(14) +#define MOP500_DISP1_RST_GPIO MOP500_EGPIO(15) #define GPIO_SDMMC_EN MOP500_EGPIO(17) #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) #define MOP500_EGPIO_END MOP500_EGPIO(24) -/* GPIOs on the AB8500 mixed-signals circuit */ -#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x)) +/* + * GPIOs on the AB8500 mixed-signals circuit + * Notice that we subtract 1 from the number passed into the macro, this is + * 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) +/*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 */ +#define SNOWBALL_WLAN_CLK_REQ_GPIO MOP500_AB8500_PIN_GPIO(3) /* SYSCLKREQ4/GPIO3 */ +#define SNOWBALL_PM_GPIO4_GPIO MOP500_AB8500_PIN_GPIO(4) /* SYSCLKREQ6/GPIO4 */ +#define SNOWBALL_EN_3V6_GPIO MOP500_AB8500_PIN_GPIO(16) /* PWMOUT3/GPIO16 */ +#define SNOWBALL_PME_ETH_GPIO MOP500_AB8500_PIN_GPIO(24) /* SYSCLKREQ7/GPIO24 */ +#define SNOWBALL_EN_3V3_ETH_GPIO MOP500_AB8500_PIN_GPIO(26) /* GPIO26 */ struct i2c_board_info; -- cgit v1.2.3 From 9a35f8767a568bdbb21ba7c3276fdc5321e3960d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 2 Oct 2011 16:45:47 +0200 Subject: usb: musb: allow building USB_MUSB_TUSB6010 as a module Commit 1376d92f9 "usb: musb: allow musb and glue layers to be modules" made the USB_MUSB_TUSB6010 option modular, but actually building the driver as a module does not work, so various randconfig builds actually fail. This changes all code that depends on the option to also check for modular builds, and exports the necessary symbols. Signed-off-by: Arnd Bergmann Acked-by: Tony Lindgren Signed-off-by: Felipe Balbi --- arch/arm/mach-omap2/board-n8x0.c | 2 +- drivers/usb/musb/musb_core.c | 3 ++- drivers/usb/musb/musb_io.h | 2 +- drivers/usb/musb/tusb6010.c | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index e9d5f4a3d064..29136929ddbb 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -46,7 +46,7 @@ static struct device *mmc_device; #define TUSB6010_GPIO_ENABLE 0 #define TUSB6010_DMACHAN 0x3f -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE) /* * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and * 1.5 V voltage regulators of PM companion chip. Companion chip will then diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 2141976d423c..90b9da1428b4 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1432,7 +1432,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) struct musb_hw_ep *hw_ep = musb->endpoints + i; hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase; -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE) hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i); hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i); hw_ep->fifo_sync_va = @@ -1631,6 +1631,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) } } } +EXPORT_SYMBOL_GPL(musb_dma_completion); #else #define use_dma 0 diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 03c6ccdbb3be..e61aa95f2d2a 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h @@ -74,7 +74,7 @@ static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) { __raw_writel(data, addr + offset); } -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE) /* * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index ec1480191f78..1f405616e6cd 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -56,6 +56,7 @@ u8 tusb_get_revision(struct musb *musb) return rev; } +EXPORT_SYMBOL_GPL(tusb_get_revision); static int tusb_print_revision(struct musb *musb) { -- cgit v1.2.3 From 995411953604e3c973328dda8c7807e45aca0f2b Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 13 Dec 2011 10:46:43 -0800 Subject: ARM: OMAP: am33xx: Update common omap platform files This patch updates the common platform files with AM335X device support (AM33XX family). The approach taken in this patch is, AM33XX device will be considered as OMAP3 variant, and a separate SoC class created for AM33XX family of devices with a subclass type for AM335X device, which is newly added device in the family. This means, cpu_is_omap34xx(), cpu_is_am33xx() and cpu_is_am335x() checks will return success on AM335X device. A kernel config option CONFIG_SOC_OMAPAM33XX is added under OMAP3 to include support for AM33XX build. Also, cpu_mask and RATE_IN_XXX flags have crossed 8 bit hence struct clksel_rate.flags, struct prcm_config.flags and cpu_mask are changed to u16 from u8. Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Hiremath Cc: Hemant Pedanekar [tony@atomide.com: left out CK_AM33XX for now] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 5 +++++ arch/arm/mach-omap2/clock.c | 2 +- arch/arm/mach-omap2/clock.h | 2 +- arch/arm/mach-omap2/opp2xxx.h | 2 +- arch/arm/plat-omap/include/plat/clock.h | 3 ++- arch/arm/plat-omap/include/plat/cpu.h | 25 +++++++++++++++++++++++++ 6 files changed, 35 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index b6625130831d..ccdd442ca124 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -81,6 +81,11 @@ config SOC_OMAPTI816X depends on ARCH_OMAP3 default y +config SOC_OMAPAM33XX + bool "AM33XX support" + depends on ARCH_OMAP3 + default y + config OMAP_PACKAGE_ZAF bool diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 1f3481f8d695..f57ed5baeccf 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -35,7 +35,7 @@ #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" -u8 cpu_mask; +u16 cpu_mask; /* * clkdm_control: if true, then when a clock is enabled in the diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 2311bc217226..b8c2a686481c 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -132,7 +132,7 @@ void omap2_clk_print_new_rates(const char *hfclkin_ck_name, const char *core_ck_name, const char *mpu_ck_name); -extern u8 cpu_mask; +extern u16 cpu_mask; extern const struct clkops clkops_omap2_dflt_wait; extern const struct clkops clkops_dummy; diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h index 8affc66a92c2..8fae534eb157 100644 --- a/arch/arm/mach-omap2/opp2xxx.h +++ b/arch/arm/mach-omap2/opp2xxx.h @@ -51,7 +51,7 @@ struct prcm_config { unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ unsigned long base_sdrc_rfr; /* base refresh timing for a set */ - unsigned char flags; + unsigned short flags; }; diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index eb73ab40e955..bb3e423b731d 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -59,6 +59,7 @@ struct clkops { #define RATE_IN_4430 (1 << 5) #define RATE_IN_TI816X (1 << 6) #define RATE_IN_4460 (1 << 7) +#define RATE_IN_AM33XX (1 << 8) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) @@ -84,7 +85,7 @@ struct clkops { struct clksel_rate { u32 val; u8 div; - u8 flags; + u16 flags; }; /** diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 408a12f79205..aa52d1e61eb1 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -78,6 +78,14 @@ static inline int is_omap ##class (void) \ return (GET_OMAP_CLASS == (id)) ? 1 : 0; \ } +#define GET_AM_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_AM_CLASS(class, id) \ +static inline int is_am ##class (void) \ +{ \ + return (GET_AM_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -92,12 +100,19 @@ static inline int is_ti ##subclass (void) \ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ } +#define IS_AM_SUBCLASS(subclass, id) \ +static inline int is_am ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + IS_OMAP_CLASS(7xx, 0x07) IS_OMAP_CLASS(15xx, 0x15) IS_OMAP_CLASS(16xx, 0x16) IS_OMAP_CLASS(24xx, 0x24) IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) +IS_AM_CLASS(33xx, 0x33) IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) @@ -107,6 +122,7 @@ IS_OMAP_SUBCLASS(443x, 0x443) IS_OMAP_SUBCLASS(446x, 0x446) IS_TI_SUBCLASS(816x, 0x816) +IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap7xx() 0 #define cpu_is_omap15xx() 0 @@ -117,6 +133,8 @@ IS_TI_SUBCLASS(816x, 0x816) #define cpu_is_omap34xx() 0 #define cpu_is_omap343x() 0 #define cpu_is_ti816x() 0 +#define cpu_is_am33xx() 0 +#define cpu_is_am335x() 0 #define cpu_is_omap44xx() 0 #define cpu_is_omap443x() 0 #define cpu_is_omap446x() 0 @@ -323,6 +341,8 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3505 # undef cpu_is_omap3517 # undef cpu_is_ti816x +# undef cpu_is_am33xx +# undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() # define cpu_is_omap3503() (cpu_is_omap3430() && \ (!omap3_has_iva()) && \ @@ -340,6 +360,8 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti816x() is_ti816x() +# define cpu_is_am33xx() is_am33xx() +# define cpu_is_am335x() is_am335x() #endif # if defined(CONFIG_ARCH_OMAP4) @@ -386,6 +408,9 @@ IS_OMAP_TYPE(3517, 0x3517) #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) +#define AM335X_CLASS 0x33500034 +#define AM335X_REV_ES1_0 AM335X_CLASS + #define OMAP443X_CLASS 0x44300044 #define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) #define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) -- cgit v1.2.3 From 1e6cb146c39cdef1ffc340c13637fce2ba5575be Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 13 Dec 2011 10:46:43 -0800 Subject: ARM: OMAP: am33xx: Update common OMAP machine specific sources This patch updates the common machine specific source files for support for AM33XX/AM335x with cpu type, macros for identification of AM33XX/AM335X device. Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Hiremath Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman [tony@atomide.com: updated for map_io and common.h changes, dropped CK_AM33XX] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock3xxx_data.c | 2 ++ arch/arm/mach-omap2/common.c | 21 +++++++++++++++++++++ arch/arm/mach-omap2/common.h | 10 ++++++++++ arch/arm/mach-omap2/id.c | 6 ++++++ arch/arm/mach-omap2/io.c | 24 ++++++++++++++++++++++++ arch/arm/mach-omap2/serial.c | 4 ++-- arch/arm/plat-omap/Makefile | 1 - arch/arm/plat-omap/include/plat/am33xx.h | 25 +++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/hardware.h | 1 + arch/arm/plat-omap/include/plat/io.h | 12 ++++++++++++ arch/arm/plat-omap/include/plat/omap34xx.h | 2 ++ 11 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 arch/arm/plat-omap/include/plat/am33xx.h (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 5d0064a4fb5a..3d56d8a2b86e 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3517,6 +3517,8 @@ int __init omap3xxx_clk_init(void) } else if (cpu_is_ti816x()) { cpu_mask = RATE_IN_TI816X; cpu_clkflg = CK_TI816X; + } else if (cpu_is_am33xx()) { + cpu_mask = RATE_IN_AM33XX; } else if (cpu_is_omap34xx()) { if (omap_rev() == OMAP3430_REV_ES1_0) { cpu_mask = RATE_IN_3430ES1; diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 684b8a7cd401..c900dcb6f1fd 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -128,6 +128,27 @@ void __init omap2_set_globals_ti816x(void) { __omap2_set_globals(&ti816x_globals); } + +#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \ + TI816X_CONTROL_DEVICE_ID - 0x204) + +static struct omap_globals am33xx_globals = { + .class = AM335X_CLASS, + .tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE), + .ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE), + .prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), + .cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), +}; + +void __init omap2_set_globals_am33xx(void) +{ + __omap2_set_globals(&am33xx_globals); +} + +void __init am33xx_map_io(void) +{ + omapam33xx_map_common_io(); +} #endif #if defined(CONFIG_ARCH_OMAP4) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 012bac7d56a5..9b733e343bf5 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -60,6 +60,14 @@ static inline void omapti816x_map_common_io(void) } #endif +#ifdef CONFIG_SOC_OMAPAM33XX +extern void omapam33xx_map_common_io(void); +#else +static inline void omapam33xx_map_common_io(void) +{ +} +#endif + #ifdef CONFIG_ARCH_OMAP4 extern void omap44xx_map_common_io(void); #else @@ -107,6 +115,7 @@ void omap2_set_globals_243x(void); void omap2_set_globals_3xxx(void); void omap2_set_globals_443x(void); void omap2_set_globals_ti816x(void); +void omap2_set_globals_am33xx(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ void omap2_set_globals_tap(struct omap_globals *); @@ -117,6 +126,7 @@ void omap2_set_globals_prcm(struct omap_globals *); void omap242x_map_io(void); void omap243x_map_io(void); void omap3_map_io(void); +void am33xx_map_io(void); void omap4_map_io(void); /** diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 27ad722df637..7ab09f764600 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -340,6 +340,10 @@ static void __init omap3_check_revision(const char **cpu_rev) break; } break; + case 0xb944: + omap_revision = AM335X_REV_ES1_0; + *cpu_rev = "1.0"; + break; default: /* Unknown default to latest silicon rev as default */ omap_revision = OMAP3630_REV_ES1_2; @@ -432,6 +436,8 @@ static void __init omap3_cpuinfo(const char *cpu_rev) 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 (omap3_has_iva() && omap3_has_sgx()) { /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ cpu_name = "OMAP3430/3530"; diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3f565dd2ea8d..088d2ba60eff 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -178,12 +178,29 @@ static struct map_desc omap34xx_io_desc[] __initdata = { #ifdef CONFIG_SOC_OMAPTI816X static struct map_desc omapti816x_io_desc[] __initdata = { + { + .virtual = L4_34XX_VIRT, + .pfn = __phys_to_pfn(L4_34XX_PHYS), + .length = L4_34XX_SIZE, + .type = MT_DEVICE + } +}; +#endif + +#ifdef CONFIG_SOC_OMAPAM33XX +static struct map_desc omapam33xx_io_desc[] __initdata = { { .virtual = L4_34XX_VIRT, .pfn = __phys_to_pfn(L4_34XX_PHYS), .length = L4_34XX_SIZE, .type = MT_DEVICE }, + { + .virtual = L4_WK_AM33XX_VIRT, + .pfn = __phys_to_pfn(L4_WK_AM33XX_PHYS), + .length = L4_WK_AM33XX_SIZE, + .type = MT_DEVICE + } }; #endif @@ -270,6 +287,13 @@ void __init omapti816x_map_common_io(void) } #endif +#ifdef CONFIG_SOC_OMAPAM33XX +void __init omapam33xx_map_common_io(void) +{ + iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); +} +#endif + #ifdef CONFIG_ARCH_OMAP4 void __init omap44xx_map_common_io(void) { diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 42c326732a29..9770c7624aa0 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -464,7 +464,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); - if (cpu_is_omap34xx() && !cpu_is_ti816x()) { + if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; u32 padconf = 0; @@ -828,7 +828,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !cpu_is_ti816x()) + if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 3df04d944e4d..9a584614e7e6 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_device.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o -obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h new file mode 100644 index 000000000000..06c19bb7bca6 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/am33xx.h @@ -0,0 +1,25 @@ +/* + * This file contains the address info for various AM33XX modules. + * + * Copyright (C) 2011 Texas Instruments, Inc. - 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 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_AM33XX_H +#define __ASM_ARCH_AM33XX_H + +#define L4_SLOW_AM33XX_BASE 0x48000000 + +#define AM33XX_SCM_BASE 0x44E10000 +#define AM33XX_CTRL_BASE AM33XX_SCM_BASE +#define AM33XX_PRCM_BASE 0x44E00000 + +#endif /* __ASM_ARCH_AM33XX_H */ diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h index e87efe1499b8..e6521e120d9f 100644 --- a/arch/arm/plat-omap/include/plat/hardware.h +++ b/arch/arm/plat-omap/include/plat/hardware.h @@ -287,5 +287,6 @@ #include #include #include +#include #endif /* __ASM_ARCH_OMAP_HARDWARE_H */ diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 1234944a4da0..0696bae1818b 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -73,6 +73,9 @@ #define OMAP4_L3_IO_OFFSET 0xb4000000 #define OMAP4_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */ +#define AM33XX_L4_WK_IO_OFFSET 0xb5000000 +#define AM33XX_L4_WK_IO_ADDRESS(pa) IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET) + #define OMAP4_L3_PER_IO_OFFSET 0xb1100000 #define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET) @@ -153,6 +156,15 @@ #define L4_34XX_VIRT (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET) #define L4_34XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ +/* + * ---------------------------------------------------------------------------- + * AM33XX specific IO mapping + * ---------------------------------------------------------------------------- + */ +#define L4_WK_AM33XX_PHYS L4_WK_AM33XX_BASE +#define L4_WK_AM33XX_VIRT (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET) +#define L4_WK_AM33XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ + /* * Need to look at the Size 4M for L4. * VPOM3430 was not working for Int controller diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h index b9e85886b9d6..0d818acf3917 100644 --- a/arch/arm/plat-omap/include/plat/omap34xx.h +++ b/arch/arm/plat-omap/include/plat/omap34xx.h @@ -35,6 +35,8 @@ #define L4_EMU_34XX_BASE 0x54000000 #define L3_34XX_BASE 0x68000000 +#define L4_WK_AM33XX_BASE 0x44C00000 + #define OMAP3430_32KSYNCT_BASE 0x48320000 #define OMAP3430_CM_BASE 0x48004800 #define OMAP3430_PRM_BASE 0x48306800 -- cgit v1.2.3 From 55035c1524b5b48ac7d267167c4895f7831897ad Mon Sep 17 00:00:00 2001 From: David Anders Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: id: add chip id recognition for omap4430 es2.3 allow for the omap4430 es2.3 revision to be recognized in the omap4_check_revision() function. most aspects of all omap4430 es2.x versions are identical, however a number of small variations such as default pullup or pulldown resistor configurations vary between revisions. detailed information on silicon errata for omap4430 revisions can be found at http://focus.ti.com/pdfs/wtbu/swpz009D.pdf Signed-off-by: David Anders Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/id.c | 7 +++++-- arch/arm/plat-omap/include/plat/cpu.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 7ab09f764600..5bb4ee18564a 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -393,8 +393,11 @@ static void __init omap4_check_revision(void) omap_revision = OMAP4430_REV_ES2_1; break; case 4: - default: omap_revision = OMAP4430_REV_ES2_2; + break; + case 6: + default: + omap_revision = OMAP4430_REV_ES2_3; } break; case 0xb94e: @@ -407,7 +410,7 @@ static void __init omap4_check_revision(void) break; default: /* Unknown default to latest silicon rev as default */ - omap_revision = OMAP4430_REV_ES2_2; + omap_revision = OMAP4430_REV_ES2_3; } pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index aa52d1e61eb1..e5baa3cde900 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -416,6 +416,7 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) #define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8)) #define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8)) +#define OMAP4430_REV_ES2_3 (OMAP443X_CLASS | (0x23 << 8)) #define OMAP446X_CLASS 0x44600044 #define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) -- cgit v1.2.3 From ec023e46f7e86acb04fef5bdd1e9465f5fc39894 Mon Sep 17 00:00:00 2001 From: Leonid Iziumtsev Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: ID: Chip detection for OMAP4470 Add support for detection of the next chip in the OMAP4 family: OMAP4470 ES1.0 For more details on OMAP4470, visit: http://focus.ti.com/general/docs/wtbu/wtbuproductcontent.tsp?templateId=6123&navigationId=12869&contentId=123362 Signed-off-by: Leonid Iziumtsev Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/id.c | 10 +++++++++- arch/arm/plat-omap/include/plat/cpu.h | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 5bb4ee18564a..439afe7acdca 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -371,7 +371,7 @@ static void __init omap4_check_revision(void) * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 * Use ARM register to detect the correct ES version */ - if (!rev && (hawkeye != 0xb94e)) { + if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { idcode = read_cpuid(CPUID_ID); rev = (idcode & 0xf) - 1; } @@ -408,6 +408,14 @@ static void __init omap4_check_revision(void) break; } break; + case 0xb975: + switch (rev) { + case 0: + default: + omap_revision = OMAP4470_REV_ES1_0; + break; + } + break; default: /* Unknown default to latest silicon rev as default */ omap_revision = OMAP4430_REV_ES2_3; diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index e5baa3cde900..34fc9136b1a0 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -69,6 +69,7 @@ unsigned int omap_rev(void); * cpu_is_omap343x(): True for OMAP3430 * cpu_is_omap443x(): True for OMAP4430 * cpu_is_omap446x(): True for OMAP4460 + * cpu_is_omap447x(): True for OMAP4470 */ #define GET_OMAP_CLASS (omap_rev() & 0xff) @@ -120,6 +121,7 @@ IS_OMAP_SUBCLASS(343x, 0x343) IS_OMAP_SUBCLASS(363x, 0x363) IS_OMAP_SUBCLASS(443x, 0x443) IS_OMAP_SUBCLASS(446x, 0x446) +IS_OMAP_SUBCLASS(447x, 0x447) IS_TI_SUBCLASS(816x, 0x816) IS_AM_SUBCLASS(335x, 0x335) @@ -138,6 +140,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap44xx() 0 #define cpu_is_omap443x() 0 #define cpu_is_omap446x() 0 +#define cpu_is_omap447x() 0 #if defined(MULTI_OMAP1) # if defined(CONFIG_ARCH_OMAP730) @@ -368,9 +371,11 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap44xx # undef cpu_is_omap443x # undef cpu_is_omap446x +# undef cpu_is_omap447x # define cpu_is_omap44xx() is_omap44xx() # define cpu_is_omap443x() is_omap443x() # define cpu_is_omap446x() is_omap446x() +# define cpu_is_omap447x() is_omap447x() # endif /* Macros to detect if we have OMAP1 or OMAP2 */ @@ -421,6 +426,9 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP446X_CLASS 0x44600044 #define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) +#define OMAP447X_CLASS 0x44700044 +#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) + void omap2_check_revision(void); /* -- cgit v1.2.3 From a920360f038e976e7a86b002e209402da20e9147 Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: TI81XX: Prepare for addition of TI814X support This patch updates existing macros, functions used for TI816X, to enable addition of other SoCs belonging to TI81XX family (e.g., TI814X). The approach taken is to use TI81XX/ti81xx for code/data going to be common across all TI81XX devices. cpu_is_ti81xx() is introduced to handle code common across TI81XX devices. In addition, ti8168_evm_map_io() is now replaced with ti81xx_map_io() and moved in mach-omap2/common.c as same will be used for TI814X and is not board specific. Signed-off-by: Hemant Pedanekar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 6 +++--- arch/arm/mach-omap2/board-ti8168evm.c | 11 +++------- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/common.c | 29 +++++++++++++++----------- arch/arm/mach-omap2/common.h | 13 ++++++------ arch/arm/mach-omap2/control.h | 8 +++---- arch/arm/mach-omap2/id.c | 8 +++---- arch/arm/mach-omap2/include/mach/debug-macro.S | 12 +++++------ arch/arm/mach-omap2/io.c | 14 ++++++------- arch/arm/mach-omap2/irq.c | 2 +- arch/arm/mach-omap2/serial.c | 6 +++--- arch/arm/plat-omap/include/plat/cpu.h | 13 ++++++++++++ arch/arm/plat-omap/include/plat/hardware.h | 2 +- arch/arm/plat-omap/include/plat/serial.h | 14 ++++++------- arch/arm/plat-omap/include/plat/ti816x.h | 27 ------------------------ arch/arm/plat-omap/include/plat/ti81xx.h | 27 ++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/uncompress.h | 8 +++---- 17 files changed, 108 insertions(+), 94 deletions(-) delete mode 100644 arch/arm/plat-omap/include/plat/ti816x.h create mode 100644 arch/arm/plat-omap/include/plat/ti81xx.h (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ccdd442ca124..f475954c3b98 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -76,8 +76,8 @@ config SOC_OMAP3430 default y select ARCH_OMAP_OTG -config SOC_OMAPTI816X - bool "TI816X support" +config SOC_OMAPTI81XX + bool "TI81XX support" depends on ARCH_OMAP3 default y @@ -319,7 +319,7 @@ config MACH_OMAP_3630SDP config MACH_TI8168EVM bool "TI8168 Evaluation Module" - depends on SOC_OMAPTI816X + depends on SOC_OMAPTI81XX default y config MACH_OMAP_4430SDP diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index 8402b39b2840..b236fcc023ac 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -35,17 +35,12 @@ static void __init ti8168_evm_init(void) omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); } -static void __init ti8168_evm_map_io(void) -{ - omapti816x_map_common_io(); -} - MACHINE_START(TI8168EVM, "ti8168evm") /* Maintainer: Texas Instruments */ .atag_offset = 0x100, - .map_io = ti8168_evm_map_io, - .init_early = ti816x_init_early, - .init_irq = ti816x_init_irq, + .map_io = ti81xx_map_io, + .init_early = ti81xx_init_early, + .init_irq = ti81xx_init_irq, .timer = &omap3_timer, .init_machine = ti8168_evm_init, MACHINE_END diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 3d56d8a2b86e..be0fa34e5506 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3602,7 +3602,7 @@ int __init omap3xxx_clk_init(void) * Lock DPLL5 -- here only until other device init code can * handle this */ - if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) + if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0)) omap3_clk_lock_dpll5(); /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index c900dcb6f1fd..aaf421178c91 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -110,27 +110,32 @@ void __init omap3_map_io(void) /* * Adjust TAP register base such that omap3_check_revision accesses the correct - * TI816X register for checking device ID (it adds 0x204 to tap base while - * TI816X DEVICE ID register is at offset 0x600 from control base). + * TI81XX register for checking device ID (it adds 0x204 to tap base while + * TI81XX DEVICE ID register is at offset 0x600 from control base). */ -#define TI816X_TAP_BASE (TI816X_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) +#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \ + TI81XX_CONTROL_DEVICE_ID - 0x204) -static struct omap_globals ti816x_globals = { +static struct omap_globals ti81xx_globals = { .class = OMAP343X_CLASS, - .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), - .ctrl = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE), - .prm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), - .cm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), + .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE), + .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), }; -void __init omap2_set_globals_ti816x(void) +void __init omap2_set_globals_ti81xx(void) { - __omap2_set_globals(&ti816x_globals); + __omap2_set_globals(&ti81xx_globals); +} + +void __init ti81xx_map_io(void) +{ + omapti81xx_map_common_io(); } #define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) + TI81XX_CONTROL_DEVICE_ID - 0x204) static struct omap_globals am33xx_globals = { .class = AM335X_CLASS, diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 9b733e343bf5..4b2b416fafe1 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -52,10 +52,10 @@ static inline void omap34xx_map_common_io(void) } #endif -#ifdef CONFIG_SOC_OMAPTI816X -extern void omapti816x_map_common_io(void); +#ifdef CONFIG_SOC_OMAPTI81XX +extern void omapti81xx_map_common_io(void); #else -static inline void omapti816x_map_common_io(void) +static inline void omapti81xx_map_common_io(void) { } #endif @@ -90,7 +90,7 @@ void omap35xx_init_early(void); void omap3630_init_early(void); void omap3_init_early(void); /* Do not use this one */ void am35xx_init_early(void); -void ti816x_init_early(void); +void ti81xx_init_early(void); void omap4430_init_early(void); /* @@ -114,7 +114,7 @@ void omap2_set_globals_242x(void); void omap2_set_globals_243x(void); void omap2_set_globals_3xxx(void); void omap2_set_globals_443x(void); -void omap2_set_globals_ti816x(void); +void omap2_set_globals_ti81xx(void); void omap2_set_globals_am33xx(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ @@ -128,6 +128,7 @@ void omap243x_map_io(void); void omap3_map_io(void); void am33xx_map_io(void); void omap4_map_io(void); +void ti81xx_map_io(void); /** * omap_test_timeout - busy-loop, testing a condition @@ -156,7 +157,7 @@ extern struct device *omap4_get_dsp_device(void); void omap2_init_irq(void); void omap3_init_irq(void); -void ti816x_init_irq(void); +void ti81xx_init_irq(void); extern int omap_irq_pending(void); void omap_intc_save_context(void); void omap_intc_restore_context(void); diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index d4ef75d5a382..0ba68d3764bc 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -52,8 +52,8 @@ #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 #define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 -/* TI816X spefic control submodules */ -#define TI816X_CONTROL_DEVCONF 0x600 +/* TI81XX spefic control submodules */ +#define TI81XX_CONTROL_DEVCONF 0x600 /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ @@ -244,8 +244,8 @@ #define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 #define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 -/* TI816X CONTROL_DEVCONF register offsets */ -#define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000) +/* TI81XX CONTROL_DEVCONF register offsets */ +#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000) /* * REVISIT: This list of registers is not comprehensive - there are more diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 439afe7acdca..1dc68e64d7e2 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -226,7 +226,7 @@ static void __init omap4_check_features(void) } } -static void __init ti816x_check_features(void) +static void __init ti81xx_check_features(void) { omap_features = OMAP3_HAS_NEON; } @@ -489,11 +489,11 @@ void __init omap2_check_revision(void) } else if (cpu_is_omap34xx()) { omap3_check_revision(&cpu_rev); - /* TI816X doesn't have feature register */ - if (!cpu_is_ti816x()) + /* TI81XX doesn't have feature register */ + if (!cpu_is_ti81xx()) omap3_check_features(); else - ti816x_check_features(); + ti81xx_check_features(); omap3_cpuinfo(cpu_rev); return; diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 13f98e59cfef..cdfc2a1f0e75 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -66,11 +66,11 @@ omap_uart_lsr: .word 0 beq 34f @ configure OMAP3UART4 cmp \rp, #OMAP4UART4 @ only on 44xx beq 44f @ configure OMAP4UART4 - cmp \rp, #TI816XUART1 @ ti816x UART offsets different + cmp \rp, #TI81XXUART1 @ ti81Xx UART offsets different beq 81f @ configure UART1 - cmp \rp, #TI816XUART2 @ ti816x UART offsets different + cmp \rp, #TI81XXUART2 @ ti81Xx UART offsets different beq 82f @ configure UART2 - cmp \rp, #TI816XUART3 @ ti816x UART offsets different + cmp \rp, #TI81XXUART3 @ ti81Xx UART offsets different beq 83f @ configure UART3 cmp \rp, #ZOOM_UART @ only on zoom2/3 beq 95f @ configure ZOOM_UART @@ -94,11 +94,11 @@ omap_uart_lsr: .word 0 b 98f 44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) b 98f -81: mov \rp, #UART_OFFSET(TI816X_UART1_BASE) +81: mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) b 98f -82: mov \rp, #UART_OFFSET(TI816X_UART2_BASE) +82: mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) b 98f -83: mov \rp, #UART_OFFSET(TI816X_UART3_BASE) +83: mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) b 98f 95: ldr \rp, =ZOOM_UART_BASE diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 088d2ba60eff..73d617f0dc4a 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -176,8 +176,8 @@ static struct map_desc omap34xx_io_desc[] __initdata = { }; #endif -#ifdef CONFIG_SOC_OMAPTI816X -static struct map_desc omapti816x_io_desc[] __initdata = { +#ifdef CONFIG_SOC_OMAPTI81XX +static struct map_desc omapti81xx_io_desc[] __initdata = { { .virtual = L4_34XX_VIRT, .pfn = __phys_to_pfn(L4_34XX_PHYS), @@ -280,10 +280,10 @@ void __init omap34xx_map_common_io(void) } #endif -#ifdef CONFIG_SOC_OMAPTI816X -void __init omapti816x_map_common_io(void) +#ifdef CONFIG_SOC_OMAPTI81XX +void __init omapti81xx_map_common_io(void) { - iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); + iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); } #endif @@ -442,9 +442,9 @@ void __init am35xx_init_early(void) omap3_init_early(); } -void __init ti816x_init_early(void) +void __init ti81xx_init_early(void) { - omap2_set_globals_ti816x(); + omap2_set_globals_ti81xx(); omap_common_init_early(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 42b1d6591912..1fef061f7927 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -193,7 +193,7 @@ void __init omap3_init_irq(void) omap_init_irq(OMAP34XX_IC_BASE, 96); } -void __init ti816x_init_irq(void) +void __init ti81xx_init_irq(void) { omap_init_irq(OMAP34XX_IC_BASE, 128); } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 9770c7624aa0..d0f009cbfb50 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -464,7 +464,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); - if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) { + if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; u32 padconf = 0; @@ -746,7 +746,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) */ uart->regshift = p->regshift; uart->membase = p->membase; - if (cpu_is_omap44xx() || cpu_is_ti816x()) + if (cpu_is_omap44xx() || cpu_is_ti81xx()) uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF) >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) @@ -828,7 +828,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) + if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 34fc9136b1a0..5f7aa4981daf 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -87,6 +87,14 @@ static inline int is_am ##class (void) \ return (GET_AM_CLASS == (id)) ? 1 : 0; \ } +#define GET_TI_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_TI_CLASS(class, id) \ +static inline int is_ti ##class (void) \ +{ \ + return (GET_TI_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -115,6 +123,8 @@ IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) IS_AM_CLASS(33xx, 0x33) +IS_TI_CLASS(81xx, 0x81) + IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) IS_OMAP_SUBCLASS(343x, 0x343) @@ -134,6 +144,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap243x() 0 #define cpu_is_omap34xx() 0 #define cpu_is_omap343x() 0 +#define cpu_is_ti81xx() 0 #define cpu_is_ti816x() 0 #define cpu_is_am33xx() 0 #define cpu_is_am335x() 0 @@ -343,6 +354,7 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3530 # undef cpu_is_omap3505 # undef cpu_is_omap3517 +# undef cpu_is_ti81xx # undef cpu_is_ti816x # undef cpu_is_am33xx # undef cpu_is_am335x @@ -362,6 +374,7 @@ IS_OMAP_TYPE(3517, 0x3517) !omap3_has_sgx()) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() +# define cpu_is_ti81xx() is_ti81xx() # define cpu_is_ti816x() is_ti816x() # define cpu_is_am33xx() is_am33xx() # define cpu_is_am335x() is_am335x() diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h index e6521e120d9f..e897978371c2 100644 --- a/arch/arm/plat-omap/include/plat/hardware.h +++ b/arch/arm/plat-omap/include/plat/hardware.h @@ -286,7 +286,7 @@ #include #include #include -#include +#include #include #endif /* __ASM_ARCH_OMAP_HARDWARE_H */ diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 1ab9fd6abe6d..6975ee3f5217 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -51,10 +51,10 @@ #define OMAP4_UART3_BASE 0x48020000 #define OMAP4_UART4_BASE 0x4806e000 -/* TI816X serial ports */ -#define TI816X_UART1_BASE 0x48020000 -#define TI816X_UART2_BASE 0x48022000 -#define TI816X_UART3_BASE 0x48024000 +/* TI81XX serial ports */ +#define TI81XX_UART1_BASE 0x48020000 +#define TI81XX_UART2_BASE 0x48022000 +#define TI81XX_UART3_BASE 0x48024000 /* AM3505/3517 UART4 */ #define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ @@ -89,9 +89,9 @@ #define OMAP4UART2 OMAP2UART2 #define OMAP4UART3 43 #define OMAP4UART4 44 -#define TI816XUART1 81 -#define TI816XUART2 82 -#define TI816XUART3 83 +#define TI81XXUART1 81 +#define TI81XXUART2 82 +#define TI81XXUART3 83 #define ZOOM_UART 95 /* Only on zoom2/3 */ /* This is only used by 8250.c for omap1510 */ diff --git a/arch/arm/plat-omap/include/plat/ti816x.h b/arch/arm/plat-omap/include/plat/ti816x.h deleted file mode 100644 index 50510f5dda1e..000000000000 --- a/arch/arm/plat-omap/include/plat/ti816x.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file contains the address data for various TI816X modules. - * - * Copyright (C) 2010 Texas Instruments, Inc. - 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 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_TI816X_H -#define __ASM_ARCH_TI816X_H - -#define L4_SLOW_TI816X_BASE 0x48000000 - -#define TI816X_SCM_BASE 0x48140000 -#define TI816X_CTRL_BASE TI816X_SCM_BASE -#define TI816X_PRCM_BASE 0x48180000 - -#define TI816X_ARM_INTC_BASE 0x48200000 - -#endif /* __ASM_ARCH_TI816X_H */ diff --git a/arch/arm/plat-omap/include/plat/ti81xx.h b/arch/arm/plat-omap/include/plat/ti81xx.h new file mode 100644 index 000000000000..8f9843f78422 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/ti81xx.h @@ -0,0 +1,27 @@ +/* + * This file contains the address data for various TI81XX modules. + * + * Copyright (C) 2010 Texas Instruments, Inc. - 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 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_TI81XX_H +#define __ASM_ARCH_TI81XX_H + +#define L4_SLOW_TI81XX_BASE 0x48000000 + +#define TI81XX_SCM_BASE 0x48140000 +#define TI81XX_CTRL_BASE TI81XX_SCM_BASE +#define TI81XX_PRCM_BASE 0x48180000 + +#define TI81XX_ARM_INTC_BASE 0x48200000 + +#endif /* __ASM_ARCH_TI81XX_H */ diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 2f472e989ec6..7fbc361946b5 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -99,9 +99,9 @@ static inline void flush(void) #define DEBUG_LL_ZOOM(mach) \ _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) -#define DEBUG_LL_TI816X(p, mach) \ - _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT, \ - TI816XUART##p) +#define DEBUG_LL_TI81XX(p, mach) \ + _DEBUG_LL_ENTRY(mach, TI81XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ + TI81XXUART##p) static inline void __arch_decomp_setup(unsigned long arch_id) { @@ -177,7 +177,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_ZOOM(omap_zoom3); /* TI8168 base boards using UART3 */ - DEBUG_LL_TI816X(3, ti8168evm); + DEBUG_LL_TI81XX(3, ti8168evm); } while (0); } -- cgit v1.2.3 From 4390f5b2cb1f568c1d4b3e5bbf57158f6809627a Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Tue, 13 Dec 2011 10:46:45 -0800 Subject: ARM: OMAP: TI814X: Add cpu type macros and detection support This patch adds cpu type, macros for identification of TI814X device. Signed-off-by: Hemant Pedanekar [tony@atomide.com: left out CK_TI814X for now] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock3xxx_data.c | 2 ++ arch/arm/mach-omap2/id.c | 21 +++++++++++++++++++++ arch/arm/plat-omap/include/plat/clock.h | 1 + arch/arm/plat-omap/include/plat/cpu.h | 9 +++++++++ 4 files changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index be0fa34e5506..60424f41156b 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3519,6 +3519,8 @@ int __init omap3xxx_clk_init(void) cpu_clkflg = CK_TI816X; } else if (cpu_is_am33xx()) { cpu_mask = RATE_IN_AM33XX; + } else if (cpu_is_ti814x()) { + cpu_mask = RATE_IN_TI814X; } else if (cpu_is_omap34xx()) { if (omap_rev() == OMAP3430_REV_ES1_0) { cpu_mask = RATE_IN_3430ES1; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 1dc68e64d7e2..6c5826605eae 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -343,6 +343,25 @@ static void __init omap3_check_revision(const char **cpu_rev) case 0xb944: omap_revision = AM335X_REV_ES1_0; *cpu_rev = "1.0"; + case 0xb8f2: + switch (rev) { + case 0: + /* FALLTHROUGH */ + case 1: + omap_revision = TI8148_REV_ES1_0; + *cpu_rev = "1.0"; + break; + case 2: + omap_revision = TI8148_REV_ES2_0; + *cpu_rev = "2.0"; + break; + case 3: + /* FALLTHROUGH */ + default: + omap_revision = TI8148_REV_ES2_1; + *cpu_rev = "2.1"; + break; + } break; default: /* Unknown default to latest silicon rev as default */ @@ -449,6 +468,8 @@ static void __init omap3_cpuinfo(const char *cpu_rev) 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"; diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index bb3e423b731d..240a7b9fd946 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -60,6 +60,7 @@ struct clkops { #define RATE_IN_TI816X (1 << 6) #define RATE_IN_4460 (1 << 7) #define RATE_IN_AM33XX (1 << 8) +#define RATE_IN_TI814X (1 << 9) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 5f7aa4981daf..6b51086fce18 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -134,6 +134,7 @@ IS_OMAP_SUBCLASS(446x, 0x446) IS_OMAP_SUBCLASS(447x, 0x447) IS_TI_SUBCLASS(816x, 0x816) +IS_TI_SUBCLASS(814x, 0x814) IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap7xx() 0 @@ -146,6 +147,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap343x() 0 #define cpu_is_ti81xx() 0 #define cpu_is_ti816x() 0 +#define cpu_is_ti814x() 0 #define cpu_is_am33xx() 0 #define cpu_is_am335x() 0 #define cpu_is_omap44xx() 0 @@ -356,6 +358,7 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3517 # undef cpu_is_ti81xx # undef cpu_is_ti816x +# undef cpu_is_ti814x # undef cpu_is_am33xx # undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() @@ -376,6 +379,7 @@ IS_OMAP_TYPE(3517, 0x3517) # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti81xx() is_ti81xx() # define cpu_is_ti816x() is_ti816x() +# define cpu_is_ti814x() is_ti814x() # define cpu_is_am33xx() is_am33xx() # define cpu_is_am335x() is_am335x() #endif @@ -426,6 +430,11 @@ IS_OMAP_TYPE(3517, 0x3517) #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) +#define TI814X_CLASS 0x81400034 +#define TI8148_REV_ES1_0 TI814X_CLASS +#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8)) +#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8)) + #define AM335X_CLASS 0x33500034 #define AM335X_REV_ES1_0 AM335X_CLASS -- cgit v1.2.3 From b74f149cc9f58583ec22ba5180d2b5d00920bfbe Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 13 Dec 2011 10:48:51 -0800 Subject: ARM: OMAP3: cm-t35: Add regulator for ads7846 touchscreen ads7846 driver fails to find the regulator supply and as a result the touchscreen is not working. Fix this by adding a regulator supply for the ads7846 driver. Signed-off-by: Igor Grinberg [tony@atomide.com: updated subject] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t35.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 510b6a2ff0fa..a4dbbe7adb73 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -343,6 +343,10 @@ static struct regulator_consumer_supply cm_t35_vdvi_supply[] = { REGULATOR_SUPPLY("vdvi", "omapdss"), }; +static struct regulator_consumer_supply cm_t35_vio_supplies[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), +}; + /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ static struct regulator_init_data cm_t35_vmmc1 = { .constraints = { @@ -373,6 +377,19 @@ static struct regulator_init_data cm_t35_vsim = { .consumer_supplies = cm_t35_vsim_supply, }; +static struct regulator_init_data cm_t35_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, + .num_consumer_supplies = ARRAY_SIZE(cm_t35_vio_supplies), + .consumer_supplies = cm_t35_vio_supplies, +}; + static uint32_t cm_t35_keymap[] = { KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT), KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN), @@ -456,6 +473,7 @@ static struct twl4030_platform_data cm_t35_twldata = { .gpio = &cm_t35_gpio_data, .vmmc1 = &cm_t35_vmmc1, .vsim = &cm_t35_vsim, + .vio = &cm_t35_vio, }; static void __init cm_t35_init_i2c(void) -- cgit v1.2.3 From cd1c683c5515c35368fef7072f30aab97ef064e5 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 13 Dec 2011 10:48:52 -0800 Subject: ARM: OMAP3: cm-t35: Use correct DSS regulator supply cm-t35 DSS suplies are connected to VIO. In fact, TPS65930 does not have VPLL2. Signed-off-by: Igor Grinberg [tony@atomide.com: updated subject] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t35.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index a4dbbe7adb73..22644d2724e8 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -339,12 +339,10 @@ static struct regulator_consumer_supply cm_t35_vsim_supply[] = { REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), }; -static struct regulator_consumer_supply cm_t35_vdvi_supply[] = { - REGULATOR_SUPPLY("vdvi", "omapdss"), -}; - static struct regulator_consumer_supply cm_t35_vio_supplies[] = { REGULATOR_SUPPLY("vcc", "spi1.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), }; /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ @@ -479,12 +477,7 @@ static struct twl4030_platform_data cm_t35_twldata = { static void __init cm_t35_init_i2c(void) { omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB, - TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); - - cm_t35_twldata.vpll2->constraints.name = "VDVI"; - cm_t35_twldata.vpll2->num_consumer_supplies = - ARRAY_SIZE(cm_t35_vdvi_supply); - cm_t35_twldata.vpll2->consumer_supplies = cm_t35_vdvi_supply; + TWL_COMMON_REGULATOR_VDAC); omap3_pmic_init("tps65930", &cm_t35_twldata); } -- cgit v1.2.3 From 19ce643997c5b75df2410e9b632c2c29e6cf8ae2 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 13 Dec 2011 10:48:52 -0800 Subject: ARM: OMAP3: cm-t35: enable audio TWL4030 audio codec is not being registered if no platform data is supplied. Provide platform data for the TWL4030 audio codec. Signed-off-by: Igor Grinberg [tony@atomide.com: updated subject] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t35.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 22644d2724e8..c417b7d004d1 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -477,7 +477,8 @@ static struct twl4030_platform_data cm_t35_twldata = { static void __init cm_t35_init_i2c(void) { omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB, - TWL_COMMON_REGULATOR_VDAC); + TWL_COMMON_REGULATOR_VDAC | + TWL_COMMON_PDATA_AUDIO); omap3_pmic_init("tps65930", &cm_t35_twldata); } -- cgit v1.2.3 From 039401f3efa890cd9974d8921c19359ac2084df3 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 13 Dec 2011 10:48:53 -0800 Subject: ARM: OMAP3: cm-t35: Add reset for USB hub USB hub is not functional until is reset. Reset the USB hub on SB-T35. Signed-off-by: Igor Grinberg [tony@atomide.com: updated subject] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t35.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index c417b7d004d1..865f96da771e 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -53,7 +53,8 @@ #include "hsmmc.h" #include "common-board-devices.h" -#define CM_T35_GPIO_PENDOWN 57 +#define CM_T35_GPIO_PENDOWN 57 +#define SB_T35_USB_HUB_RESET_GPIO 167 #define CM_T35_SMSC911X_CS 5 #define CM_T35_SMSC911X_GPIO 163 @@ -436,6 +437,23 @@ static struct usbhs_omap_board_data usbhs_bdata __initdata = { .reset_gpio_port[2] = -EINVAL }; +static void cm_t35_init_usbh(void) +{ + int err; + + err = gpio_request_one(SB_T35_USB_HUB_RESET_GPIO, + GPIOF_OUT_INIT_LOW, "usb hub rst"); + if (err) { + pr_err("SB-T35: usb hub rst gpio request failed: %d\n", err); + } else { + udelay(10); + gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1); + msleep(1); + } + + usbhs_init(&usbhs_bdata); +} + static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { @@ -624,7 +642,7 @@ static void __init cm_t3x_common_init(void) cm_t35_init_display(); usb_musb_init(NULL); - usbhs_init(&usbhs_bdata); + cm_t35_init_usbh(); } static void __init cm_t35_init(void) -- cgit v1.2.3 From b2404f4275badc719b8335420c97ae9380e01227 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 13 Dec 2011 10:48:53 -0800 Subject: ARM: OMAP3: cm-t35: fix mux mode for DSS pins OMAP pin mux configuration API has been used incorrectly resulting in wrong mux mode set for several DSS pins. Signed-off-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t35.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 865f96da771e..b38cd7b240e8 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -600,24 +600,28 @@ static void __init cm_t3x_common_dss_mux_init(int mux_mode) static void __init cm_t35_init_mux(void) { - omap_mux_init_signal("gpio_70", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("gpio_71", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("gpio_72", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("gpio_73", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("gpio_74", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("gpio_75", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); - cm_t3x_common_dss_mux_init(OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT; + + omap_mux_init_signal("dss_data0.dss_data0", mux_mode); + omap_mux_init_signal("dss_data1.dss_data1", mux_mode); + omap_mux_init_signal("dss_data2.dss_data2", mux_mode); + omap_mux_init_signal("dss_data3.dss_data3", mux_mode); + omap_mux_init_signal("dss_data4.dss_data4", mux_mode); + omap_mux_init_signal("dss_data5.dss_data5", mux_mode); + cm_t3x_common_dss_mux_init(mux_mode); } static void __init cm_t3730_init_mux(void) { - omap_mux_init_signal("sys_boot0", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("sys_boot1", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("sys_boot3", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("sys_boot4", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("sys_boot5", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); - omap_mux_init_signal("sys_boot6", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); - cm_t3x_common_dss_mux_init(OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + int mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT; + + omap_mux_init_signal("sys_boot0", mux_mode); + omap_mux_init_signal("sys_boot1", mux_mode); + omap_mux_init_signal("sys_boot3", mux_mode); + omap_mux_init_signal("sys_boot4", mux_mode); + omap_mux_init_signal("sys_boot5", mux_mode); + omap_mux_init_signal("sys_boot6", mux_mode); + cm_t3x_common_dss_mux_init(mux_mode); } #else static inline void cm_t35_init_mux(void) {} -- cgit v1.2.3 From 3dad5356aa47097cf67027cf0a07298b4f5baef6 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 13 Dec 2011 10:48:53 -0800 Subject: ARM: OMAP3: rx51: enable tsc2005 touchscreen Enable TSC2005 touchscreen driver on the RX-51 board by providing the needed platform data. Signed-off-by: Aaro Koskinen Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-peripherals.c | 46 ++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index bd18d691c6ad..e9eff00cddd4 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,9 @@ #define RX51_USB_TRANSCEIVER_RST_GPIO 67 +#define RX51_TSC2005_RESET_GPIO 104 +#define RX51_TSC2005_IRQ_GPIO 100 + /* list all spi devices here */ enum { RX51_SPI_WL1251, @@ -66,6 +70,7 @@ enum { }; static struct wl12xx_platform_data wl1251_pdata; +static struct tsc2005_platform_data tsc2005_pdata; #if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE) static struct tsl2563_platform_data rx51_tsl2563_platform_data = { @@ -167,10 +172,10 @@ 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),*/ + .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO), .max_speed_hz = 6000000, .controller_data = &tsc2005_mcspi_config, - /* .platform_data = &tsc2005_config,*/ + .platform_data = &tsc2005_pdata, }, }; @@ -1086,6 +1091,42 @@ error: */ } +static struct tsc2005_platform_data tsc2005_pdata = { + .ts_pressure_max = 2048, + .ts_pressure_fudge = 2, + .ts_x_max = 4096, + .ts_x_fudge = 4, + .ts_y_max = 4096, + .ts_y_fudge = 7, + .ts_x_plate_ohm = 280, + .esd_timeout_ms = 8000, +}; + +static void rx51_tsc2005_set_reset(bool enable) +{ + gpio_set_value(RX51_TSC2005_RESET_GPIO, enable); +} + +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; + } + + 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"); + tsc2005_pdata.esd_timeout_ms = 0; + } +} + void __init rx51_peripherals_init(void) { rx51_i2c_init(); @@ -1094,6 +1135,7 @@ void __init rx51_peripherals_init(void) board_smc91x_init(); rx51_add_gpio_keys(); rx51_init_wl1251(); + rx51_init_tsc2005(); rx51_init_si4713(); spi_register_board_info(rx51_peripherals_spi_board_info, ARRAY_SIZE(rx51_peripherals_spi_board_info)); -- cgit v1.2.3 From ef211dc626beb47fc11d4aba27a8c1b20a4b3b4a Mon Sep 17 00:00:00 2001 From: Igor Dmitriev Date: Tue, 13 Dec 2011 10:48:54 -0800 Subject: ARM: OMAP3: sdram-nokia: add 200 MHz memory timings info Add memory timing info regarding the 200 MHz memory in sdram-nokia. Note that 100 MHz mode uses these same timings too. Signed-off-by: Igor Dmitriev Signed-off-by: Eduardo Valentin Signed-off-by: Aaro Koskinen [tony@atomide.com: updated comments for 100 MHz timings] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sdram-nokia.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index ee3a8ad304cb..7479d7ea1379 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -1,7 +1,7 @@ /* * SDRC register values for Nokia boards * - * Copyright (C) 2008, 2010 Nokia Corporation + * Copyright (C) 2008, 2010-2011 Nokia Corporation * * Lauri Leukkunen * @@ -107,14 +107,37 @@ static const struct sdram_timings nokia_195dot2mhz_timings[] = { }, }; +static const struct sdram_timings nokia_200mhz_timings[] = { + { + .casl = 3, + .tDAL = 30000, + .tDPL = 15000, + .tRRD = 10000, + .tRCD = 20000, + .tRP = 15000, + .tRAS = 40000, + .tRC = 55000, + .tRFC = 140000, + .tXSR = 200000, + + .tREF = 7800, + + .tXP = 2, + .tCKE = 4, + .tWTR = 2 + }, +}; + static const struct { long rate; struct sdram_timings const *data; } nokia_timings[] = { { 83000000, nokia_166mhz_timings }, { 97600000, nokia_97dot6mhz_timings }, + { 100000000, nokia_200mhz_timings }, { 166000000, nokia_166mhz_timings }, { 195200000, nokia_195dot2mhz_timings }, + { 200000000, nokia_200mhz_timings }, }; static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; -- cgit v1.2.3 From de9eb09726130dadc3e611c97fa2d753620662c1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 13 Dec 2011 10:48:54 -0800 Subject: ARM: OMAP4: devices: Register OMAP4 DMIC platform device Add platform device registration for OMAP4 DMIC. Signed-off-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index c15cfada5f13..35d5dffab7e1 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -336,6 +336,27 @@ static void omap_init_mcpdm(void) static inline void omap_init_mcpdm(void) {} #endif +#if defined(CONFIG_SND_OMAP_SOC_DMIC) || \ + defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE) + +static void omap_init_dmic(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + + oh = omap_hwmod_lookup("dmic"); + if (!oh) { + printk(KERN_ERR "Could not look up mcpdm hw_mod\n"); + return; + } + + pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n"); +} +#else +static inline void omap_init_dmic(void) {} +#endif + #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) #include @@ -681,6 +702,7 @@ static int __init omap2_init_devices(void) */ omap_init_audio(); omap_init_mcpdm(); + omap_init_dmic(); omap_init_camera(); omap_init_mbox(); omap_init_mcspi(); -- cgit v1.2.3 From 95712de0ccd42d69623462e5d17cbd444f6fcccc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 13 Dec 2011 10:48:54 -0800 Subject: ARM: OMAP4: board-4430sdp: Register platform device for digimic codec OMAP4 SDP/Blaze boards have onboard digital microphones. Register the platform device for the dmic-codec to be able to use the microphones. Signed-off-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-4430sdp.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index ef2bbc09428a..b5d9c6fe012f 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -372,11 +372,17 @@ static struct platform_device sdp4430_vbat = { }, }; +static struct platform_device sdp4430_dmic_codec = { + .name = "dmic-codec", + .id = -1, +}; + static struct platform_device *sdp4430_devices[] __initdata = { &sdp4430_gpio_keys_device, &sdp4430_leds_gpio, &sdp4430_leds_pwm, &sdp4430_vbat, + &sdp4430_dmic_codec, }; static struct omap_musb_board_data musb_board_data = { -- cgit v1.2.3 From a890b6760d975cdbdfcdf5753dab4c91059af9b1 Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Tue, 13 Dec 2011 10:48:55 -0800 Subject: ARM: OMAP: TI814X: Create board support and enable build for TI8148 EVM This patch adds minimal support and build configuration for TI8148 EVM. Also adds support for low level debugging on UART1 console on the EVM. Note that existing TI8168 EVM file (board-ti8168evm.c) is updated with machine info for TI8148 EVM. Signed-off-by: Hemant Pedanekar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 5 +++++ arch/arm/mach-omap2/Makefile | 1 + arch/arm/mach-omap2/board-ti8168evm.c | 22 ++++++++++++++++------ arch/arm/plat-omap/include/plat/uncompress.h | 3 +++ 4 files changed, 25 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index f475954c3b98..5ca19d717b3f 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -322,6 +322,11 @@ config MACH_TI8168EVM depends on SOC_OMAPTI81XX default y +config MACH_TI8148EVM + bool "TI8148 Evaluation Module" + depends on SOC_OMAPTI81XX + default y + config MACH_OMAP_4430SDP bool "OMAP 4430 SDP board" default y diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index b009f17dee56..6d226a76d057 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -232,6 +232,7 @@ obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o +obj-$(CONFIG_MACH_TI8148EVM) += board-ti8168evm.o # Platform specific device init code diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index b236fcc023ac..b3ca997a44fa 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -1,5 +1,5 @@ /* - * Code for TI8168 EVM. + * Code for TI8168/TI8148 EVM. * * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ * @@ -24,15 +24,15 @@ #include #include "common.h" -static struct omap_board_config_kernel ti8168_evm_config[] __initdata = { +static struct omap_board_config_kernel ti81xx_evm_config[] __initdata = { }; -static void __init ti8168_evm_init(void) +static void __init ti81xx_evm_init(void) { omap_serial_init(); omap_sdrc_init(NULL, NULL); - omap_board_config = ti8168_evm_config; - omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); + omap_board_config = ti81xx_evm_config; + omap_board_config_size = ARRAY_SIZE(ti81xx_evm_config); } MACHINE_START(TI8168EVM, "ti8168evm") @@ -42,5 +42,15 @@ MACHINE_START(TI8168EVM, "ti8168evm") .init_early = ti81xx_init_early, .init_irq = ti81xx_init_irq, .timer = &omap3_timer, - .init_machine = ti8168_evm_init, + .init_machine = ti81xx_evm_init, +MACHINE_END + +MACHINE_START(TI8148EVM, "ti8148evm") + /* Maintainer: Texas Instruments */ + .atag_offset = 0x100, + .map_io = ti81xx_map_io, + .init_early = ti81xx_init_early, + .init_irq = ti81xx_init_irq, + .timer = &omap3_timer, + .init_machine = ti81xx_evm_init, MACHINE_END diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 7fbc361946b5..6ee90495ca4c 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -179,6 +179,9 @@ static inline void __arch_decomp_setup(unsigned long arch_id) /* TI8168 base boards using UART3 */ DEBUG_LL_TI81XX(3, ti8168evm); + /* TI8148 base boards using UART1 */ + DEBUG_LL_TI81XX(1, ti8148evm); + } while (0); } -- cgit v1.2.3 From cada691f8675c36f738d41741a6ec5d966f39a10 Mon Sep 17 00:00:00 2001 From: Ravi Babu Date: Tue, 13 Dec 2011 10:50:58 -0800 Subject: ARM: OMAP: musb: Adding support for ti81xx Added musb support for ti81xx platform which has two instances of musb interface and uses CPPI4.1 DMA. The current patch set adds support for single instance and in PIO mode only. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Ravi Babu Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/usb-musb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 267975086a7b..8d5ed775dd56 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -93,6 +93,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) if (cpu_is_omap3517() || cpu_is_omap3505()) { oh_name = "am35x_otg_hs"; name = "musb-am35x"; + } else if (cpu_is_ti81xx()) { + oh_name = "usb_otg_hs"; + name = "musb-ti81xx"; } else { oh_name = "usb_otg_hs"; name = "musb-omap2430"; -- cgit v1.2.3 From 8f718d2414c2c13f7c886df1d1802ad0d32faaca Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Tue, 13 Dec 2011 10:50:58 -0800 Subject: ARM: OMAP: musb: Add ti81xx phy power function Adding ti81xx_musb_phy_power() which will be used by musb driver through its function pointer in board_data. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Ravi Babu Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_phy_internal.c | 35 +++++++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/usb.h | 32 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 58775e3c8476..4c90477e6f82 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -260,3 +260,38 @@ void am35x_set_mode(u8 musb_mode) omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); } + +void ti81xx_musb_phy_power(u8 on) +{ + void __iomem *scm_base = NULL; + u32 usbphycfg; + + scm_base = ioremap(TI81XX_SCM_BASE, SZ_2K); + if (!scm_base) { + pr_err("system control module ioremap failed\n"); + return; + } + + usbphycfg = __raw_readl(scm_base + USBCTRL0); + + if (on) { + if (cpu_is_ti816x()) { + usbphycfg |= TI816X_USBPHY0_NORMAL_MODE; + usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC; + } else if (cpu_is_ti814x()) { + usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN + | USBPHY_DPINPUT | USBPHY_DMINPUT); + usbphycfg |= (USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN + | USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL); + } + } else { + if (cpu_is_ti816x()) + usbphycfg &= ~TI816X_USBPHY0_NORMAL_MODE; + else if (cpu_is_ti814x()) + usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; + + } + __raw_writel(usbphycfg, scm_base + USBCTRL0); + + iounmap(scm_base); +} diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 17d3c939775c..c616385f27bd 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -114,6 +114,7 @@ extern void am35x_musb_reset(void); extern void am35x_musb_phy_power(u8 on); extern void am35x_musb_clear_irq(void); extern void am35x_set_mode(u8 musb_mode); +extern void ti81xx_musb_phy_power(u8 on); /* * FIXME correct answer depends on hmc_mode, @@ -273,6 +274,37 @@ static inline void omap2_usbfs_init(struct omap_usb_config *pdata) #define CONF2_OTGPWRDN (1 << 2) #define CONF2_DATPOL (1 << 1) +/* TI81XX specific definitions */ +#define USBCTRL0 0x620 +#define USBSTAT0 0x624 + +/* TI816X PHY controls bits */ +#define TI816X_USBPHY0_NORMAL_MODE (1 << 0) +#define TI816X_USBPHY_REFCLK_OSC (1 << 8) + +/* TI814X PHY controls bits */ +#define USBPHY_CM_PWRDN (1 << 0) +#define USBPHY_OTG_PWRDN (1 << 1) +#define USBPHY_CHGDET_DIS (1 << 2) +#define USBPHY_CHGDET_RSTRT (1 << 3) +#define USBPHY_SRCONDM (1 << 4) +#define USBPHY_SINKONDP (1 << 5) +#define USBPHY_CHGISINK_EN (1 << 6) +#define USBPHY_CHGVSRC_EN (1 << 7) +#define USBPHY_DMPULLUP (1 << 8) +#define USBPHY_DPPULLUP (1 << 9) +#define USBPHY_CDET_EXTCTL (1 << 10) +#define USBPHY_GPIO_MODE (1 << 12) +#define USBPHY_DPOPBUFCTL (1 << 13) +#define USBPHY_DMOPBUFCTL (1 << 14) +#define USBPHY_DPINPUT (1 << 15) +#define USBPHY_DMINPUT (1 << 16) +#define USBPHY_DPGPIO_PD (1 << 17) +#define USBPHY_DMGPIO_PD (1 << 18) +#define USBPHY_OTGVDET_EN (1 << 19) +#define USBPHY_OTGSESSEND_EN (1 << 20) +#define USBPHY_DATA_POLARITY (1 << 23) + #if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB) u32 omap1_usb0_init(unsigned nwires, unsigned is_device); u32 omap1_usb1_init(unsigned nwires); -- cgit v1.2.3 From f36217f3a5b5b945619192c033c2785007931e49 Mon Sep 17 00:00:00 2001 From: Ravi Babu Date: Tue, 13 Dec 2011 10:50:59 -0800 Subject: ARM: OMAP: musb: Add support for ti816evm Adding musb support in ti816 EVM board file. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Ravi Babu Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-ti8168evm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index b3ca997a44fa..5b6ad6e3ccb4 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -23,6 +23,14 @@ #include #include #include "common.h" +#include + +static struct omap_musb_board_data musb_board_data = { + .set_phy_power = ti81xx_musb_phy_power, + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 500, +}; static struct omap_board_config_kernel ti81xx_evm_config[] __initdata = { }; @@ -33,6 +41,7 @@ static void __init ti81xx_evm_init(void) omap_sdrc_init(NULL, NULL); omap_board_config = ti81xx_evm_config; omap_board_config_size = ARRAY_SIZE(ti81xx_evm_config); + usb_musb_init(&musb_board_data); } MACHINE_START(TI8168EVM, "ti8168evm") -- cgit v1.2.3 From a87d89e74f0a4b56eaee8c3ef74bce69277b780f Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Thu, 3 Nov 2011 12:57:43 +0000 Subject: ARM: Kirkwood: Recognize A1 revision of 6282 chip Recognize the Kirkwood 6282 revision A1 chip since products using this chip are shipping now, such as the QNAP TS-x19P II devices. Signed-off-by: Martin Michlmayr Acked-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/common.c | 2 ++ arch/arm/mach-kirkwood/include/mach/kirkwood.h | 1 + 2 files changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f3248cfbe51d..b9632ee57b06 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -430,6 +430,8 @@ static char * __init kirkwood_id(void) } else if (dev == MV88F6282_DEV_ID) { if (rev == MV88F6282_REV_A0) return "MV88F6282-Rev-A0"; + else if (rev == MV88F6282_REV_A1) + return "MV88F6282-Rev-A1"; else return "MV88F6282-Rev-Unsupported"; } else { diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 010bdeb4ac5f..fede3d503efa 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -135,4 +135,5 @@ #define MV88F6282_DEV_ID 0x6282 #define MV88F6282_REV_A0 0 +#define MV88F6282_REV_A1 1 #endif -- cgit v1.2.3 From 527ef0550d79e3b3a0ef8f5061072075afef6aaf Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 1 Dec 2011 11:58:25 +0100 Subject: ARM: Kirkwood: Add configuration for MPP12 as GPIO The MPP12 is listed in the 6281 HW manual as output only but the iconnect board from iomega is using it as GPIO (there's a button connected on it). So, I'm adding a definition for the MPP12 as GPIO. As I've no informations about this and which kirkwood are "affected", I'm adding a new #define instead of modifying the current one for MPP12. Signed-off-by: Arnaud Patard Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/mpp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h index ac787957e2d9..e8fda45c0736 100644 --- a/arch/arm/mach-kirkwood/mpp.h +++ b/arch/arm/mach-kirkwood/mpp.h @@ -102,6 +102,7 @@ #define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1, 1 ) #define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP12_GPIO MPP( 12, 0x0, 1, 1, 0, 0, 0, 1, 0 ) #define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1, 1 ) #define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 1, 0, 0, 0, 0, 1 ) #define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 1, 0, 0, 0, 0, 1 ) -- cgit v1.2.3 From b6d1c33a31deb1784c1d34070db6e84fd6f9d870 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 7 Dec 2011 21:48:05 +0100 Subject: ARM: Orion: Consolidate the address map setup Compile tested on Dove, orion5x, mv78xx0. Boot tested on Kirkwood. Signed-off-by: Andrew Lunn Tested-by: Michael Walle Acked-by: Nicolas Pitre Signed-off-by: Nicolas Pitre --- arch/arm/mach-dove/addr-map.c | 113 ++++++++---------- arch/arm/mach-kirkwood/addr-map.c | 138 +++++++--------------- arch/arm/mach-mv78xx0/addr-map.c | 102 ++++------------ arch/arm/mach-orion5x/addr-map.c | 146 ++++++++--------------- arch/arm/mach-orion5x/common.c | 7 +- arch/arm/mach-orion5x/common.h | 2 +- arch/arm/mach-orion5x/include/mach/orion5x.h | 2 +- arch/arm/plat-orion/Makefile | 2 +- arch/arm/plat-orion/addr-map.c | 166 +++++++++++++++++++++++++++ arch/arm/plat-orion/include/plat/addr-map.h | 52 +++++++++ 10 files changed, 375 insertions(+), 355 deletions(-) create mode 100644 arch/arm/plat-orion/addr-map.c create mode 100644 arch/arm/plat-orion/include/plat/addr-map.h (limited to 'arch') diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c index 00be4fc26dd7..1584726088e4 100644 --- a/arch/arm/mach-dove/addr-map.c +++ b/arch/arm/mach-dove/addr-map.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "common.h" /* @@ -34,14 +35,6 @@ #define ATTR_PCIE_MEM 0xe8 #define ATTR_SCRATCHPAD 0x0 -/* - * CPU Address Decode Windows registers - */ -#define WIN_CTRL(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x0) -#define WIN_BASE(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x4) -#define WIN_REMAP_LO(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x8) -#define WIN_REMAP_HI(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0xc) - struct mbus_dram_target_info dove_mbus_dram_info; static inline void __iomem *ddr_map_sc(int i) @@ -49,78 +42,62 @@ static inline void __iomem *ddr_map_sc(int i) return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); } -static int cpu_win_can_remap(int win) -{ - if (win < 4) - return 1; - - return 0; -} - -static void __init setup_cpu_win(int win, u32 base, u32 size, - u8 target, u8 attr, int remap) -{ - u32 ctrl; - - base &= 0xffff0000; - ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; - - writel(base, WIN_BASE(win)); - writel(ctrl, WIN_CTRL(win)); - if (cpu_win_can_remap(win)) { - if (remap < 0) - remap = base; - writel(remap & 0xffff0000, WIN_REMAP_LO(win)); - writel(0, WIN_REMAP_HI(win)); - } -} - -void __init dove_setup_cpu_mbus(void) -{ - int i; - int cs; +/* + * Description of the windows needed by the platform code + */ +static struct __initdata orion_addr_map_cfg addr_map_cfg = { + .num_wins = 8, + .remappable_wins = 4, + .bridge_virt_base = BRIDGE_VIRT_BASE, +}; +static const struct __initdata orion_addr_map_info addr_map_info[] = { /* - * First, disable and clear windows. + * Windows for PCIe IO+MEM space. */ - for (i = 0; i < 8; i++) { - writel(0, WIN_BASE(i)); - writel(0, WIN_CTRL(i)); - if (cpu_win_can_remap(i)) { - writel(0, WIN_REMAP_LO(i)); - writel(0, WIN_REMAP_HI(i)); - } - } - + { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, + TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE + }, + { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, + TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE + }, + { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE, + TARGET_PCIE0, ATTR_PCIE_MEM, -1 + }, + { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE, + TARGET_PCIE1, ATTR_PCIE_MEM, -1 + }, /* - * Setup windows for PCIe IO+MEM space. + * Window for CESA engine. */ - setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, - TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE); - setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, - TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE); - setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE, - TARGET_PCIE0, ATTR_PCIE_MEM, -1); - setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE, - TARGET_PCIE1, ATTR_PCIE_MEM, -1); - + { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, + TARGET_CESA, ATTR_CESA, -1 + }, /* - * Setup window for CESA engine. + * Window to the BootROM for Standby and Sleep Resume */ - setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, - TARGET_CESA, ATTR_CESA, -1); - + { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, + TARGET_BOOTROM, ATTR_BOOTROM, -1 + }, /* - * Setup the Window to the BootROM for Standby and Sleep Resume + * Window to the PMU Scratch Pad space */ - setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, - TARGET_BOOTROM, ATTR_BOOTROM, -1); + { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, + TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1 + }, + /* End marker */ + { -1, 0, 0, 0, 0, 0 } +}; + +void __init dove_setup_cpu_mbus(void) +{ + int i; + int cs; /* - * Setup the Window to the PMU Scratch Pad space + * Disable, clear and configure windows. */ - setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, - TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1); + orion_config_wins(&addr_map_cfg, addr_map_info); /* * Setup MBUS dram target info. diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c index 8d03bcef5182..935392f7e13f 100644 --- a/arch/arm/mach-kirkwood/addr-map.c +++ b/arch/arm/mach-kirkwood/addr-map.c @@ -13,12 +13,12 @@ #include #include #include +#include #include "common.h" /* * Generic Address Decode Windows bit settings */ -#define TARGET_DDR 0 #define TARGET_DEV_BUS 1 #define TARGET_SRAM 3 #define TARGET_PCIE 4 @@ -35,119 +35,59 @@ #define ATTR_PCIE1_MEM 0xd8 #define ATTR_SRAM 0x01 -/* - * Helpers to get DDR bank info - */ -#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) -#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) +struct mbus_dram_target_info kirkwood_mbus_dram_info; /* - * CPU Address Decode Windows registers + * Description of the windows needed by the platform code */ -#define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) -#define WIN_CTRL_OFF 0x0000 -#define WIN_BASE_OFF 0x0004 -#define WIN_REMAP_LO_OFF 0x0008 -#define WIN_REMAP_HI_OFF 0x000c - - -struct mbus_dram_target_info kirkwood_mbus_dram_info; - -static int __init cpu_win_can_remap(int win) -{ - if (win < 4) - return 1; - - return 0; -} - -static void __init setup_cpu_win(int win, u32 base, u32 size, - u8 target, u8 attr, int remap) -{ - void __iomem *addr = (void __iomem *)WIN_OFF(win); - u32 ctrl; - - base &= 0xffff0000; - ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; - - writel(base, addr + WIN_BASE_OFF); - writel(ctrl, addr + WIN_CTRL_OFF); - if (cpu_win_can_remap(win)) { - if (remap < 0) - remap = base; - - writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); - } -} - -void __init kirkwood_setup_cpu_mbus(void) -{ - void __iomem *addr; - int i; - int cs; +static struct __initdata orion_addr_map_cfg addr_map_cfg = { + .num_wins = 8, + .remappable_wins = 4, + .bridge_virt_base = BRIDGE_VIRT_BASE, +}; +static const struct __initdata orion_addr_map_info addr_map_info[] = { /* - * First, disable and clear windows. + * Windows for PCIe IO+MEM space. */ - for (i = 0; i < 8; i++) { - addr = (void __iomem *)WIN_OFF(i); - - writel(0, addr + WIN_BASE_OFF); - writel(0, addr + WIN_CTRL_OFF); - if (cpu_win_can_remap(i)) { - writel(0, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); - } - } - + { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, + TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE + }, + { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, + TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE + }, + { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE, + TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE + }, + { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE, + TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE + }, /* - * Setup windows for PCIe IO+MEM space. + * Window for NAND controller. */ - setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, - TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); - setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, - TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE); - setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE, - TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE); - setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE, - TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE); - + { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, + TARGET_DEV_BUS, ATTR_DEV_NAND, -1 + }, /* - * Setup window for NAND controller. + * Window for SRAM. */ - setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, - TARGET_DEV_BUS, ATTR_DEV_NAND, -1); + { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, + TARGET_SRAM, ATTR_SRAM, -1 + }, + /* End marker */ + { -1, 0, 0, 0, 0, 0 } +}; +void __init kirkwood_setup_cpu_mbus(void) +{ /* - * Setup window for SRAM. + * Disable, clear and configure windows. */ - setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, - TARGET_SRAM, ATTR_SRAM, -1); + orion_config_wins(&addr_map_cfg, addr_map_info); /* * Setup MBUS dram target info. */ - kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; - - addr = (void __iomem *)DDR_WINDOW_CPU_BASE; - - for (i = 0, cs = 0; i < 4; i++) { - u32 base = readl(addr + DDR_BASE_CS_OFF(i)); - u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); - - /* - * Chip select enabled? - */ - if (size & 1) { - struct mbus_dram_window *w; - - w = &kirkwood_mbus_dram_info.cs[cs++]; - w->cs_index = i; - w->mbus_attr = 0xf & ~(1 << i); - w->base = base & 0xffff0000; - w->size = (size | 0x0000ffff) + 1; - } - } - kirkwood_mbus_dram_info.num_cs = cs; + orion_setup_cpu_mbus_target(&addr_map_cfg, &kirkwood_mbus_dram_info, + DDR_WINDOW_CPU_BASE); } diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c index 311d5b0e9bc7..6b14555e5766 100644 --- a/arch/arm/mach-mv78xx0/addr-map.c +++ b/arch/arm/mach-mv78xx0/addr-map.c @@ -12,12 +12,12 @@ #include #include #include +#include #include "common.h" /* * Generic Address Decode Windows bit settings */ -#define TARGET_DDR 0 #define TARGET_DEV_BUS 1 #define TARGET_PCIE0 4 #define TARGET_PCIE1 8 @@ -31,22 +31,11 @@ #define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l))) #define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) -/* - * Helpers to get DDR bank info - */ -#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) -#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) - /* * CPU Address Decode Windows registers */ #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) -#define WIN_CTRL_OFF 0x0000 -#define WIN_BASE_OFF 0x0004 -#define WIN_REMAP_LO_OFF 0x0008 -#define WIN_REMAP_HI_OFF 0x000c - struct mbus_dram_target_info mv78xx0_mbus_dram_info; @@ -63,94 +52,45 @@ static void __init __iomem *win_cfg_base(int win) return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win)); } -static int __init cpu_win_can_remap(int win) -{ - if (win < 8) - return 1; - - return 0; -} - -static void __init setup_cpu_win(int win, u32 base, u32 size, - u8 target, u8 attr, int remap) -{ - void __iomem *addr = win_cfg_base(win); - u32 ctrl; - - base &= 0xffff0000; - ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; - - writel(base, addr + WIN_BASE_OFF); - writel(ctrl, addr + WIN_CTRL_OFF); - if (cpu_win_can_remap(win)) { - if (remap < 0) - remap = base; - - writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); - } -} +/* + * Description of the windows needed by the platform code + */ +static struct __initdata orion_addr_map_cfg addr_map_cfg = { + .num_wins = 14, + .remappable_wins = 8, + .win_cfg_base = win_cfg_base, +}; void __init mv78xx0_setup_cpu_mbus(void) { - void __iomem *addr; - int i; - int cs; - /* - * First, disable and clear windows. + * Disable, clear and configure windows. */ - for (i = 0; i < 14; i++) { - addr = win_cfg_base(i); - - writel(0, addr + WIN_BASE_OFF); - writel(0, addr + WIN_CTRL_OFF); - if (cpu_win_can_remap(i)) { - writel(0, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); - } - } + orion_config_wins(&addr_map_cfg, NULL); /* * Setup MBUS dram target info. */ - mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; - if (mv78xx0_core_index() == 0) - addr = (void __iomem *)DDR_WINDOW_CPU0_BASE; + orion_setup_cpu_mbus_target(&addr_map_cfg, + &mv78xx0_mbus_dram_info, + DDR_WINDOW_CPU0_BASE); else - addr = (void __iomem *)DDR_WINDOW_CPU1_BASE; - - for (i = 0, cs = 0; i < 4; i++) { - u32 base = readl(addr + DDR_BASE_CS_OFF(i)); - u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); - - /* - * Chip select enabled? - */ - if (size & 1) { - struct mbus_dram_window *w; - - w = &mv78xx0_mbus_dram_info.cs[cs++]; - w->cs_index = i; - w->mbus_attr = 0xf & ~(1 << i); - w->base = base & 0xffff0000; - w->size = (size | 0x0000ffff) + 1; - } - } - mv78xx0_mbus_dram_info.num_cs = cs; + orion_setup_cpu_mbus_target(&addr_map_cfg, + &mv78xx0_mbus_dram_info, + DDR_WINDOW_CPU1_BASE); } void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, int maj, int min) { - setup_cpu_win(window, base, size, TARGET_PCIE(maj), - ATTR_PCIE_IO(min), -1); + orion_setup_cpu_win(&addr_map_cfg, window, base, size, + TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1); } void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, int maj, int min) { - setup_cpu_win(window, base, size, TARGET_PCIE(maj), - ATTR_PCIE_MEM(min), -1); + orion_setup_cpu_win(&addr_map_cfg, window, base, size, + TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1); } diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index 5ceafdccc456..73ceb49de894 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include "common.h" /* @@ -41,7 +41,6 @@ /* * Generic Address Decode Windows bit settings */ -#define TARGET_DDR 0 #define TARGET_DEV_BUS 1 #define TARGET_PCI 3 #define TARGET_PCIE 4 @@ -57,27 +56,11 @@ #define ATTR_DEV_BOOT 0xf #define ATTR_SRAM 0x0 -/* - * Helpers to get DDR bank info - */ -#define ORION5X_DDR_REG(x) (ORION5X_DDR_VIRT_BASE | (x)) -#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3)) -#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3)) - -/* - * CPU Address Decode Windows registers - */ -#define ORION5X_BRIDGE_REG(x) (ORION5X_BRIDGE_VIRT_BASE | (x)) -#define CPU_WIN_CTRL(n) ORION5X_BRIDGE_REG(0x000 | ((n) << 4)) -#define CPU_WIN_BASE(n) ORION5X_BRIDGE_REG(0x004 | ((n) << 4)) -#define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4)) -#define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4)) - - struct mbus_dram_target_info orion5x_mbus_dram_info; static int __initdata win_alloc_count; -static int __init orion5x_cpu_win_can_remap(int win) +static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg, + const int win) { u32 dev, rev; @@ -91,116 +74,83 @@ static int __init orion5x_cpu_win_can_remap(int win) return 0; } -static int __init setup_cpu_win(int win, u32 base, u32 size, - u8 target, u8 attr, int remap) -{ - if (win >= 8) { - printk(KERN_ERR "setup_cpu_win: trying to allocate " - "window %d\n", win); - return -ENOSPC; - } - - writel(base & 0xffff0000, CPU_WIN_BASE(win)); - writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1, - CPU_WIN_CTRL(win)); - - if (orion5x_cpu_win_can_remap(win)) { - if (remap < 0) - remap = base; - - writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win)); - writel(0, CPU_WIN_REMAP_HI(win)); - } - return 0; -} - -void __init orion5x_setup_cpu_mbus_bridge(void) -{ - int i; - int cs; +/* + * Description of the windows needed by the platform code + */ +static struct __initdata orion_addr_map_cfg addr_map_cfg = { + .num_wins = 8, + .cpu_win_can_remap = cpu_win_can_remap, + .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE, +}; +static const struct __initdata orion_addr_map_info addr_map_info[] = { /* - * First, disable and clear windows. + * Setup windows for PCI+PCIe IO+MEM space. */ - for (i = 0; i < 8; i++) { - writel(0, CPU_WIN_BASE(i)); - writel(0, CPU_WIN_CTRL(i)); - if (orion5x_cpu_win_can_remap(i)) { - writel(0, CPU_WIN_REMAP_LO(i)); - writel(0, CPU_WIN_REMAP_HI(i)); - } - } + { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE, + TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE + }, + { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE, + TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE + }, + { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE, + TARGET_PCIE, ATTR_PCIE_MEM, -1 + }, + { 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, + TARGET_PCI, ATTR_PCI_MEM, -1 + }, + /* End marker */ + { -1, 0, 0, 0, 0, 0 } +}; +void __init orion5x_setup_cpu_mbus_bridge(void) +{ /* - * Setup windows for PCI+PCIe IO+MEM space. + * Disable, clear and configure windows. */ - setup_cpu_win(0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE, - TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE); - setup_cpu_win(1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE, - TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE); - setup_cpu_win(2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE, - TARGET_PCIE, ATTR_PCIE_MEM, -1); - setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, - TARGET_PCI, ATTR_PCI_MEM, -1); + orion_config_wins(&addr_map_cfg, addr_map_info); win_alloc_count = 4; /* * Setup MBUS dram target info. */ - orion5x_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; - - for (i = 0, cs = 0; i < 4; i++) { - u32 base = readl(DDR_BASE_CS(i)); - u32 size = readl(DDR_SIZE_CS(i)); - - /* - * Chip select enabled? - */ - if (size & 1) { - struct mbus_dram_window *w; - - w = &orion5x_mbus_dram_info.cs[cs++]; - w->cs_index = i; - w->mbus_attr = 0xf & ~(1 << i); - w->base = base & 0xffff0000; - w->size = (size | 0x0000ffff) + 1; - } - } - orion5x_mbus_dram_info.num_cs = cs; + orion_setup_cpu_mbus_target(&addr_map_cfg, &orion5x_mbus_dram_info, + ORION5X_DDR_WINDOW_CPU_BASE); } void __init orion5x_setup_dev_boot_win(u32 base, u32 size) { - setup_cpu_win(win_alloc_count++, base, size, - TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); + orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, + TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); } void __init orion5x_setup_dev0_win(u32 base, u32 size) { - setup_cpu_win(win_alloc_count++, base, size, - TARGET_DEV_BUS, ATTR_DEV_CS0, -1); + orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, + TARGET_DEV_BUS, ATTR_DEV_CS0, -1); } void __init orion5x_setup_dev1_win(u32 base, u32 size) { - setup_cpu_win(win_alloc_count++, base, size, - TARGET_DEV_BUS, ATTR_DEV_CS1, -1); + orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, + TARGET_DEV_BUS, ATTR_DEV_CS1, -1); } void __init orion5x_setup_dev2_win(u32 base, u32 size) { - setup_cpu_win(win_alloc_count++, base, size, - TARGET_DEV_BUS, ATTR_DEV_CS2, -1); + orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, + TARGET_DEV_BUS, ATTR_DEV_CS2, -1); } void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) { - setup_cpu_win(win_alloc_count++, base, size, - TARGET_PCIE, ATTR_PCIE_WA, -1); + orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size, + TARGET_PCIE, ATTR_PCIE_WA, -1); } -int __init orion5x_setup_sram_win(void) +void __init orion5x_setup_sram_win(void) { - return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE, - ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1); + orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, + ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE, + TARGET_SRAM, ATTR_SRAM, -1); } diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 22ace0bf2f92..47ca0ee44a6a 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -169,12 +169,7 @@ void __init orion5x_xor_init(void) ****************************************************************************/ static void __init orion5x_crypto_init(void) { - int ret; - - ret = orion5x_setup_sram_win(); - if (ret) - return; - + orion5x_setup_sram_win(); orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, SZ_8K, IRQ_ORION5X_CESA); } diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index 909489f4d23e..465e8a458bfb 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -27,7 +27,7 @@ void orion5x_setup_dev0_win(u32 base, u32 size); void orion5x_setup_dev1_win(u32 base, u32 size); void orion5x_setup_dev2_win(u32 base, u32 size); void orion5x_setup_pcie_wa_win(u32 base, u32 size); -int orion5x_setup_sram_win(void); +void orion5x_setup_sram_win(void); void orion5x_ehci0_init(void); void orion5x_ehci1_init(void); diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h index 0a28bbc76891..2745f5d95b3f 100644 --- a/arch/arm/mach-orion5x/include/mach/orion5x.h +++ b/arch/arm/mach-orion5x/include/mach/orion5x.h @@ -69,7 +69,7 @@ ******************************************************************************/ #define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000) - +#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE | 0x1500) #define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) #define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000) #define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile index 95a5fc53b6db..c20ce0f5ce33 100644 --- a/arch/arm/plat-orion/Makefile +++ b/arch/arm/plat-orion/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := irq.o pcie.o time.o common.o mpp.o +obj-y := irq.o pcie.o time.o common.o mpp.o addr-map.o obj-m := obj-n := obj- := diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c new file mode 100644 index 000000000000..d3abb34a10aa --- /dev/null +++ b/arch/arm/plat-orion/addr-map.c @@ -0,0 +1,166 @@ +/* + * arch/arm/plat-orion/addr-map.c + * + * Address map functions for Marvell Orion based SoCs + * + * 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 +#include +#include +#include +#include + +/* + * DDR target is the same on all Orion platforms. + */ +#define TARGET_DDR 0 + +/* + * Helpers to get DDR bank info + */ +#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) +#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + +/* + * CPU Address Decode Windows registers + */ +#define WIN_CTRL_OFF 0x0000 +#define WIN_BASE_OFF 0x0004 +#define WIN_REMAP_LO_OFF 0x0008 +#define WIN_REMAP_HI_OFF 0x000c + +/* + * Default implementation + */ +static void __init __iomem * +orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win) +{ + return (void __iomem *)(cfg->bridge_virt_base + (win << 4)); +} + +/* + * Default implementation + */ +static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg, + const int win) +{ + if (win < cfg->remappable_wins) + return 1; + + return 0; +} + +void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, + const int win, const u32 base, + const u32 size, const u8 target, + const u8 attr, const int remap) +{ + void __iomem *addr = cfg->win_cfg_base(cfg, win); + u32 ctrl, base_high, remap_addr; + + if (win >= cfg->num_wins) { + printk(KERN_ERR "setup_cpu_win: trying to allocate window " + "%d when only %d allowed\n", win, cfg->num_wins); + } + + base_high = base & 0xffff0000; + ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; + + writel(base_high, addr + WIN_BASE_OFF); + writel(ctrl, addr + WIN_CTRL_OFF); + if (cfg->cpu_win_can_remap(cfg, win)) { + if (remap < 0) + remap_addr = base; + else + remap_addr = remap; + writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } +} + +/* + * Configure a number of windows. + */ +static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg, + const struct orion_addr_map_info *info) +{ + while (info->win != -1) { + orion_setup_cpu_win(cfg, info->win, info->base, info->size, + info->target, info->attr, info->remap); + info++; + } +} + +static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg) +{ + void __iomem *addr; + int i; + + for (i = 0; i < cfg->num_wins; i++) { + addr = cfg->win_cfg_base(cfg, i); + + writel(0, addr + WIN_BASE_OFF); + writel(0, addr + WIN_CTRL_OFF); + if (cfg->cpu_win_can_remap(cfg, i)) { + writel(0, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } + } +} + +/* + * Disable, clear and configure windows. + */ +void __init orion_config_wins(struct orion_addr_map_cfg * cfg, + const struct orion_addr_map_info *info) +{ + if (!cfg->cpu_win_can_remap) + cfg->cpu_win_can_remap = orion_cpu_win_can_remap; + + if (!cfg->win_cfg_base) + cfg->win_cfg_base = orion_win_cfg_base; + + orion_disable_wins(cfg); + + if (info) + orion_setup_cpu_wins(cfg, info); +} + +/* + * Setup MBUS dram target info. + */ +void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, + struct mbus_dram_target_info *info, + const u32 ddr_window_cpu_base) +{ + void __iomem *addr; + int i; + int cs; + + info->mbus_dram_target_id = TARGET_DDR; + + addr = (void __iomem *)ddr_window_cpu_base; + + for (i = 0, cs = 0; i < 4; i++) { + u32 base = readl(addr + DDR_BASE_CS_OFF(i)); + u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); + + /* + * Chip select enabled? + */ + if (size & 1) { + struct mbus_dram_window *w; + + w = &info->cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); + w->base = base & 0xffff0000; + w->size = (size | 0x0000ffff) + 1; + } + } + info->num_cs = cs; +} diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h new file mode 100644 index 000000000000..55e40f43f1e6 --- /dev/null +++ b/arch/arm/plat-orion/include/plat/addr-map.h @@ -0,0 +1,52 @@ +/* + * arch/arm/plat-orion/include/plat/addr-map.h + * + * Marvell Orion SoC address map handling. + * + * 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_ADDR_MAP_H +#define __PLAT_ADDR_MAP_H + +struct orion_addr_map_cfg { + const int num_wins; /* Total number of windows */ + const int remappable_wins; + const u32 bridge_virt_base; + + /* If NULL, the default cpu_win_can_remap will be used, using + the value in remappable_wins */ + int (*cpu_win_can_remap) (const struct orion_addr_map_cfg *cfg, + const int win); + /* If NULL, the default win_cfg_base will be used, using the + value in bridge_virt_base */ + void __iomem *(*win_cfg_base) (const struct orion_addr_map_cfg *cfg, + const int win); +}; + +/* + * Information needed to setup one address mapping. + */ +struct orion_addr_map_info { + const int win; + const u32 base; + const u32 size; + const u8 target; + const u8 attr; + const int remap; +}; + +void __init orion_config_wins(struct orion_addr_map_cfg *cfg, + const struct orion_addr_map_info *info); + +void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, + const int win, const u32 base, + const u32 size, const u8 target, + const u8 attr, const int remap); + +void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, + struct mbus_dram_target_info *info, + const u32 ddr_window_cpu_base); +#endif -- cgit v1.2.3 From 45173d5ed4c9a397db31623bf6469efbd3a239cd Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 7 Dec 2011 21:48:06 +0100 Subject: ARM: Orion: mbus_dram_info consolidation Move the *_mbus_dram_info structure into the orion platform and call it orion_mbus_dram_info everywhere. Signed-off-by: Andrew Lunn Tested-by: Michael Walle Acked-by: Nicolas Pitre Signed-off-by: Nicolas Pitre --- arch/arm/mach-dove/addr-map.c | 8 +++----- arch/arm/mach-dove/common.c | 11 ++++++----- arch/arm/mach-dove/common.h | 1 - arch/arm/mach-dove/pcie.c | 3 ++- arch/arm/mach-kirkwood/addr-map.c | 5 +---- arch/arm/mach-kirkwood/common.c | 15 ++++++++------- arch/arm/mach-kirkwood/common.h | 1 - arch/arm/mach-kirkwood/pcie.c | 3 ++- arch/arm/mach-mv78xx0/addr-map.c | 4 ---- arch/arm/mach-mv78xx0/common.c | 17 +++++++++-------- arch/arm/mach-mv78xx0/common.h | 1 - arch/arm/mach-mv78xx0/pcie.c | 3 ++- arch/arm/mach-orion5x/addr-map.c | 4 +--- arch/arm/mach-orion5x/common.c | 11 ++++++----- arch/arm/mach-orion5x/common.h | 1 - arch/arm/mach-orion5x/pci.c | 5 +++-- arch/arm/plat-orion/addr-map.c | 9 +++++---- arch/arm/plat-orion/include/plat/addr-map.h | 3 ++- 18 files changed, 50 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c index 1584726088e4..98b8c83b09ab 100644 --- a/arch/arm/mach-dove/addr-map.c +++ b/arch/arm/mach-dove/addr-map.c @@ -35,8 +35,6 @@ #define ATTR_PCIE_MEM 0xe8 #define ATTR_SCRATCHPAD 0x0 -struct mbus_dram_target_info dove_mbus_dram_info; - static inline void __iomem *ddr_map_sc(int i) { return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); @@ -102,7 +100,7 @@ void __init dove_setup_cpu_mbus(void) /* * Setup MBUS dram target info. */ - dove_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; + orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; for (i = 0, cs = 0; i < 2; i++) { u32 map = readl(ddr_map_sc(i)); @@ -113,7 +111,7 @@ void __init dove_setup_cpu_mbus(void) if (map & 1) { struct mbus_dram_window *w; - w = &dove_mbus_dram_info.cs[cs++]; + w = &orion_mbus_dram_info.cs[cs++]; w->cs_index = i; w->mbus_attr = 0; /* CS address decoding done inside */ /* the DDR controller, no need to */ @@ -122,5 +120,5 @@ void __init dove_setup_cpu_mbus(void) w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); } } - dove_mbus_dram_info.num_cs = cs; + orion_mbus_dram_info.num_cs = cs; } diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index a9e0dae86a26..29c1881c8acb 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "common.h" static int get_tclk(void); @@ -71,7 +72,7 @@ void __init dove_map_io(void) ****************************************************************************/ void __init dove_ehci0_init(void) { - orion_ehci_init(&dove_mbus_dram_info, + orion_ehci_init(&orion_mbus_dram_info, DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0); } @@ -80,7 +81,7 @@ void __init dove_ehci0_init(void) ****************************************************************************/ void __init dove_ehci1_init(void) { - orion_ehci_1_init(&dove_mbus_dram_info, + orion_ehci_1_init(&orion_mbus_dram_info, DOVE_USB1_PHYS_BASE, IRQ_DOVE_USB1); } @@ -89,7 +90,7 @@ void __init dove_ehci1_init(void) ****************************************************************************/ void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) { - orion_ge00_init(eth_data, &dove_mbus_dram_info, + orion_ge00_init(eth_data, &orion_mbus_dram_info, DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0, get_tclk()); } @@ -107,7 +108,7 @@ void __init dove_rtc_init(void) ****************************************************************************/ void __init dove_sata_init(struct mv_sata_platform_data *sata_data) { - orion_sata_init(sata_data, &dove_mbus_dram_info, + orion_sata_init(sata_data, &orion_mbus_dram_info, DOVE_SATA_PHYS_BASE, IRQ_DOVE_SATA); } @@ -198,7 +199,7 @@ struct sys_timer dove_timer = { ****************************************************************************/ void __init dove_xor0_init(void) { - orion_xor0_init(&dove_mbus_dram_info, + orion_xor0_init(&orion_mbus_dram_info, DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE, IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01); } diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h index 6a2046e44706..7322371d3908 100644 --- a/arch/arm/mach-dove/common.h +++ b/arch/arm/mach-dove/common.h @@ -15,7 +15,6 @@ struct mv643xx_eth_platform_data; struct mv_sata_platform_data; extern struct sys_timer dove_timer; -extern struct mbus_dram_target_info dove_mbus_dram_info; /* * Basic Dove init functions used early by machine-setup. diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index aa2b3a09a51d..42e7d22a00f5 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "common.h" struct pcie_port { @@ -50,7 +51,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) */ orion_pcie_set_local_bus_nr(pp->base, sys->busnr); - orion_pcie_setup(pp->base, &dove_mbus_dram_info); + orion_pcie_setup(pp->base, &orion_mbus_dram_info); /* * IORESOURCE_IO diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c index 935392f7e13f..e9a7180863d9 100644 --- a/arch/arm/mach-kirkwood/addr-map.c +++ b/arch/arm/mach-kirkwood/addr-map.c @@ -35,8 +35,6 @@ #define ATTR_PCIE1_MEM 0xd8 #define ATTR_SRAM 0x01 -struct mbus_dram_target_info kirkwood_mbus_dram_info; - /* * Description of the windows needed by the platform code */ @@ -88,6 +86,5 @@ void __init kirkwood_setup_cpu_mbus(void) /* * Setup MBUS dram target info. */ - orion_setup_cpu_mbus_target(&addr_map_cfg, &kirkwood_mbus_dram_info, - DDR_WINDOW_CPU_BASE); + orion_setup_cpu_mbus_target(&addr_map_cfg, DDR_WINDOW_CPU_BASE); } diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b9632ee57b06..dd63fac9ed02 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "common.h" /***************************************************************************** @@ -73,7 +74,7 @@ unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED; void __init kirkwood_ehci_init(void) { kirkwood_clk_ctrl |= CGC_USB0; - orion_ehci_init(&kirkwood_mbus_dram_info, + orion_ehci_init(&orion_mbus_dram_info, USB_PHYS_BASE, IRQ_KIRKWOOD_USB); } @@ -85,7 +86,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) { kirkwood_clk_ctrl |= CGC_GE0; - orion_ge00_init(eth_data, &kirkwood_mbus_dram_info, + orion_ge00_init(eth_data, &orion_mbus_dram_info, GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); } @@ -99,7 +100,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) kirkwood_clk_ctrl |= CGC_GE1; - orion_ge01_init(eth_data, &kirkwood_mbus_dram_info, + orion_ge01_init(eth_data, &orion_mbus_dram_info, GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); } @@ -178,7 +179,7 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) if (sata_data->n_ports > 1) kirkwood_clk_ctrl |= CGC_SATA1; - orion_sata_init(sata_data, &kirkwood_mbus_dram_info, + orion_sata_init(sata_data, &orion_mbus_dram_info, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); } @@ -221,7 +222,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) mvsdio_data->clock = 100000000; else mvsdio_data->clock = 200000000; - mvsdio_data->dram = &kirkwood_mbus_dram_info; + mvsdio_data->dram = &orion_mbus_dram_info; kirkwood_clk_ctrl |= CGC_SDIO; kirkwood_sdio.dev.platform_data = mvsdio_data; platform_device_register(&kirkwood_sdio); @@ -285,7 +286,7 @@ static void __init kirkwood_xor0_init(void) { kirkwood_clk_ctrl |= CGC_XOR0; - orion_xor0_init(&kirkwood_mbus_dram_info, + orion_xor0_init(&orion_mbus_dram_info, XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); } @@ -364,7 +365,7 @@ static struct resource kirkwood_i2s_resources[] = { }; static struct kirkwood_asoc_platform_data kirkwood_i2s_data = { - .dram = &kirkwood_mbus_dram_info, + .dram = &orion_mbus_dram_info, .burst = 128, }; diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index b9b0f0968a36..4756b945106b 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -30,7 +30,6 @@ void kirkwood_init(void); void kirkwood_init_early(void); void kirkwood_init_irq(void); -extern struct mbus_dram_target_info kirkwood_mbus_dram_info; void kirkwood_setup_cpu_mbus(void); void kirkwood_enable_pcie(void); diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 74b992d810ea..8def894f3296 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "common.h" void kirkwood_enable_pcie(void) @@ -208,7 +209,7 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) */ orion_pcie_set_local_bus_nr(pp->base, sys->busnr); - orion_pcie_setup(pp->base, &kirkwood_mbus_dram_info); + orion_pcie_setup(pp->base, &orion_mbus_dram_info); return 1; } diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c index 6b14555e5766..62b53d710efd 100644 --- a/arch/arm/mach-mv78xx0/addr-map.c +++ b/arch/arm/mach-mv78xx0/addr-map.c @@ -37,8 +37,6 @@ #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) -struct mbus_dram_target_info mv78xx0_mbus_dram_info; - static void __init __iomem *win_cfg_base(int win) { /* @@ -73,11 +71,9 @@ void __init mv78xx0_setup_cpu_mbus(void) */ if (mv78xx0_core_index() == 0) orion_setup_cpu_mbus_target(&addr_map_cfg, - &mv78xx0_mbus_dram_info, DDR_WINDOW_CPU0_BASE); else orion_setup_cpu_mbus_target(&addr_map_cfg, - &mv78xx0_mbus_dram_info, DDR_WINDOW_CPU1_BASE); } diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index 23d3980ef59d..be0c232ea0d8 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "common.h" static int get_tclk(void); @@ -169,7 +170,7 @@ void __init mv78xx0_map_io(void) ****************************************************************************/ void __init mv78xx0_ehci0_init(void) { - orion_ehci_init(&mv78xx0_mbus_dram_info, + orion_ehci_init(&orion_mbus_dram_info, USB0_PHYS_BASE, IRQ_MV78XX0_USB_0); } @@ -179,7 +180,7 @@ void __init mv78xx0_ehci0_init(void) ****************************************************************************/ void __init mv78xx0_ehci1_init(void) { - orion_ehci_1_init(&mv78xx0_mbus_dram_info, + orion_ehci_1_init(&orion_mbus_dram_info, USB1_PHYS_BASE, IRQ_MV78XX0_USB_1); } @@ -189,7 +190,7 @@ void __init mv78xx0_ehci1_init(void) ****************************************************************************/ void __init mv78xx0_ehci2_init(void) { - orion_ehci_2_init(&mv78xx0_mbus_dram_info, + orion_ehci_2_init(&orion_mbus_dram_info, USB2_PHYS_BASE, IRQ_MV78XX0_USB_2); } @@ -199,7 +200,7 @@ void __init mv78xx0_ehci2_init(void) ****************************************************************************/ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) { - orion_ge00_init(eth_data, &mv78xx0_mbus_dram_info, + orion_ge00_init(eth_data, &orion_mbus_dram_info, GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, IRQ_MV78XX0_GE_ERR, get_tclk()); } @@ -210,7 +211,7 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) ****************************************************************************/ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data) { - orion_ge01_init(eth_data, &mv78xx0_mbus_dram_info, + orion_ge01_init(eth_data, &orion_mbus_dram_info, GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, NO_IRQ, get_tclk()); } @@ -234,7 +235,7 @@ void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data) eth_data->duplex = DUPLEX_FULL; } - orion_ge10_init(eth_data, &mv78xx0_mbus_dram_info, + orion_ge10_init(eth_data, &orion_mbus_dram_info, GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM, NO_IRQ, get_tclk()); } @@ -258,7 +259,7 @@ void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data) eth_data->duplex = DUPLEX_FULL; } - orion_ge11_init(eth_data, &mv78xx0_mbus_dram_info, + orion_ge11_init(eth_data, &orion_mbus_dram_info, GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM, NO_IRQ, get_tclk()); } @@ -277,7 +278,7 @@ void __init mv78xx0_i2c_init(void) ****************************************************************************/ void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data) { - orion_sata_init(sata_data, &mv78xx0_mbus_dram_info, + orion_sata_init(sata_data, &orion_mbus_dram_info, SATA_PHYS_BASE, IRQ_MV78XX0_SATA); } diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h index 632e63d65e7a..f2ca59c75c6f 100644 --- a/arch/arm/mach-mv78xx0/common.h +++ b/arch/arm/mach-mv78xx0/common.h @@ -23,7 +23,6 @@ void mv78xx0_init(void); void mv78xx0_init_early(void); void mv78xx0_init_irq(void); -extern struct mbus_dram_target_info mv78xx0_mbus_dram_info; void mv78xx0_setup_cpu_mbus(void); void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, int maj, int min); diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index c51af1cac300..9208667c478a 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "common.h" struct pcie_port { @@ -153,7 +154,7 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) * Generic PCIe unit setup. */ orion_pcie_set_local_bus_nr(pp->base, sys->busnr); - orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info); + orion_pcie_setup(pp->base, &orion_mbus_dram_info); sys->resource[0] = &pp->res[0]; sys->resource[1] = &pp->res[1]; diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index 73ceb49de894..3638e5c12b7e 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c @@ -56,7 +56,6 @@ #define ATTR_DEV_BOOT 0xf #define ATTR_SRAM 0x0 -struct mbus_dram_target_info orion5x_mbus_dram_info; static int __initdata win_alloc_count; static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg, @@ -114,8 +113,7 @@ void __init orion5x_setup_cpu_mbus_bridge(void) /* * Setup MBUS dram target info. */ - orion_setup_cpu_mbus_target(&addr_map_cfg, &orion5x_mbus_dram_info, - ORION5X_DDR_WINDOW_CPU_BASE); + orion_setup_cpu_mbus_target(&addr_map_cfg, ORION5X_DDR_WINDOW_CPU_BASE); } void __init orion5x_setup_dev_boot_win(u32 base, u32 size) diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 47ca0ee44a6a..acac255f9a1b 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "common.h" /***************************************************************************** @@ -71,7 +72,7 @@ void __init orion5x_map_io(void) ****************************************************************************/ void __init orion5x_ehci0_init(void) { - orion_ehci_init(&orion5x_mbus_dram_info, + orion_ehci_init(&orion_mbus_dram_info, ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL); } @@ -81,7 +82,7 @@ void __init orion5x_ehci0_init(void) ****************************************************************************/ void __init orion5x_ehci1_init(void) { - orion_ehci_1_init(&orion5x_mbus_dram_info, + orion_ehci_1_init(&orion_mbus_dram_info, ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL); } @@ -91,7 +92,7 @@ void __init orion5x_ehci1_init(void) ****************************************************************************/ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) { - orion_ge00_init(eth_data, &orion5x_mbus_dram_info, + orion_ge00_init(eth_data, &orion_mbus_dram_info, ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, IRQ_ORION5X_ETH_ERR, orion5x_tclk); } @@ -121,7 +122,7 @@ void __init orion5x_i2c_init(void) ****************************************************************************/ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) { - orion_sata_init(sata_data, &orion5x_mbus_dram_info, + orion_sata_init(sata_data, &orion_mbus_dram_info, ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA); } @@ -158,7 +159,7 @@ void __init orion5x_uart1_init(void) ****************************************************************************/ void __init orion5x_xor_init(void) { - orion_xor0_init(&orion5x_mbus_dram_info, + orion_xor0_init(&orion_mbus_dram_info, ORION5X_XOR_PHYS_BASE, ORION5X_XOR_PHYS_BASE + 0x200, IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1); diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index 465e8a458bfb..889d80c7a151 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -20,7 +20,6 @@ extern struct sys_timer orion5x_timer; * functions to map its interfaces and by the machine-setup to map its on- * board devices. Details in /mach-orion/addr-map.c */ -extern struct mbus_dram_target_info orion5x_mbus_dram_info; void orion5x_setup_cpu_mbus_bridge(void); void orion5x_setup_dev_boot_win(u32 base, u32 size); void orion5x_setup_dev0_win(u32 base, u32 size); diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index bc4a920e26ee..ddfa01acdaaa 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "common.h" /***************************************************************************** @@ -145,7 +146,7 @@ static int __init pcie_setup(struct pci_sys_data *sys) /* * Generic PCIe unit setup. */ - orion_pcie_setup(PCIE_BASE, &orion5x_mbus_dram_info); + orion_pcie_setup(PCIE_BASE, &orion_mbus_dram_info); /* * Check whether to apply Orion-1/Orion-NAS PCIe config @@ -477,7 +478,7 @@ static int __init pci_setup(struct pci_sys_data *sys) /* * Point PCI unit MBUS decode windows to DRAM space. */ - orion5x_setup_pci_wins(&orion5x_mbus_dram_info); + orion5x_setup_pci_wins(&orion_mbus_dram_info); /* * Master + Slave enable diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c index d3abb34a10aa..c27ad88bc400 100644 --- a/arch/arm/plat-orion/addr-map.c +++ b/arch/arm/plat-orion/addr-map.c @@ -14,6 +14,8 @@ #include #include +struct mbus_dram_target_info orion_mbus_dram_info; + /* * DDR target is the same on all Orion platforms. */ @@ -134,14 +136,13 @@ void __init orion_config_wins(struct orion_addr_map_cfg * cfg, * Setup MBUS dram target info. */ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, - struct mbus_dram_target_info *info, const u32 ddr_window_cpu_base) { void __iomem *addr; int i; int cs; - info->mbus_dram_target_id = TARGET_DDR; + orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; addr = (void __iomem *)ddr_window_cpu_base; @@ -155,12 +156,12 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, if (size & 1) { struct mbus_dram_window *w; - w = &info->cs[cs++]; + w = &orion_mbus_dram_info.cs[cs++]; w->cs_index = i; w->mbus_attr = 0xf & ~(1 << i); w->base = base & 0xffff0000; w->size = (size | 0x0000ffff) + 1; } } - info->num_cs = cs; + orion_mbus_dram_info.num_cs = cs; } diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h index 55e40f43f1e6..fd556f77562c 100644 --- a/arch/arm/plat-orion/include/plat/addr-map.h +++ b/arch/arm/plat-orion/include/plat/addr-map.h @@ -11,6 +11,8 @@ #ifndef __PLAT_ADDR_MAP_H #define __PLAT_ADDR_MAP_H +extern struct mbus_dram_target_info orion_mbus_dram_info; + struct orion_addr_map_cfg { const int num_wins; /* Total number of windows */ const int remappable_wins; @@ -47,6 +49,5 @@ void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, const u8 attr, const int remap); void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, - struct mbus_dram_target_info *info, const u32 ddr_window_cpu_base); #endif -- cgit v1.2.3 From 63a9332b232bdab0df6ef18a9f39e8d58a82bda4 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 7 Dec 2011 21:48:07 +0100 Subject: ARM: Orion: Get address map from plat-orion instead of via platform_data Use an getter function in plat-orion/addr-map.c to get the address map structure, rather than pass it to drivers in the platform_data structures. When the drivers are built for none orion platforms, a dummy function is provided instead which returns NULL. Signed-off-by: Andrew Lunn Tested-by: Michael Walle Acked-by: Nicolas Pitre Signed-off-by: Nicolas Pitre --- arch/arm/mach-dove/pcie.c | 3 +-- arch/arm/mach-kirkwood/mpp.c | 1 - arch/arm/mach-kirkwood/pcie.c | 3 +-- arch/arm/mach-mv78xx0/mpp.c | 1 - arch/arm/mach-mv78xx0/pcie.c | 3 +-- arch/arm/mach-orion5x/mpp.c | 1 - arch/arm/mach-orion5x/pci.c | 2 +- arch/arm/plat-orion/addr-map.c | 7 +++++++ arch/arm/plat-orion/include/plat/pcie.h | 3 +-- arch/arm/plat-orion/pcie.c | 6 +++--- drivers/ata/sata_mv.c | 19 +++++++++++-------- drivers/dma/mv_xor.c | 11 ++++++----- drivers/mmc/host/mvsdio.c | 13 ++++++++----- drivers/net/ethernet/marvell/mv643xx_eth.c | 10 ++++++---- drivers/usb/host/ehci-orion.c | 10 ++++++---- include/linux/mbus.h | 13 ++++++++++++- sound/soc/kirkwood/kirkwood-dma.c | 15 +++++++++------ 17 files changed, 73 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 42e7d22a00f5..6c11a4df7178 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -10,7 +10,6 @@ #include #include -#include #include