D: portions of the Linux Security Module (LSM) framework and security modules
N: Petr Vandrovec
-E: vandrove@vc.cvut.cz
+E: petr@vandrovec.name
D: Small contributions to ncpfs
D: Matrox framebuffer driver
-S: Chudenicka 8
-S: 10200 Prague 10, Hostivar
-S: Czech Republic
+S: 21513 Conradia Ct
+S: Cupertino, CA 95014
+S: USA
N: Thibaut Varene
E: T-Bone@parisc-linux.org
S: Maintained
F: arch/arm/mach-s3c6410/
+ARM/S5P ARM ARCHITECTURES
+M: Kukjin Kim <kgene.kim@samsung.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-s5p*/
+
ARM/SHMOBILE ARM ARCHITECTURE
M: Paul Mundt <lethal@linux-sh.org>
M: Magnus Damm <magnus.damm@gmail.com>
F: arch/arm/mach-shmobile/
F: drivers/sh/
+ARM/TELECHIPS ARM ARCHITECTURE
+M: "Hans J. Koch" <hjk@linutronix.de>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/plat-tcc/
+F: arch/arm/mach-tcc8k/
+
ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+ARM/TETON BGA MACHINE SUPPORT
+M: Mark F. Brown <mark.brown314@gmail.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+
ARM/THECUS N2100 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
F: include/linux/cfag12864b.h
AVR32 ARCHITECTURE
-M: Haavard Skinnemoen <hskinnemoen@atmel.com>
+M: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
W: http://www.atmel.com/products/AVR32/
W: http://avr32linux.org/
W: http://avrfreaks.net/
F: arch/avr32/
AVR32/AT32AP MACHINE SUPPORT
-M: Haavard Skinnemoen <hskinnemoen@atmel.com>
+M: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
S: Supported
F: arch/avr32/mach-at32ap/
S: Maintained
F: drivers/platform/x86/eeepc-laptop.c
+EFIFB FRAMEBUFFER DRIVER
+L: linux-fbdev@vger.kernel.org
+M: Peter Jones <pjones@redhat.com>
+S: Maintained
+F: drivers/video/efifb.c
+
EFS FILESYSTEM
W: http://aeschi.ch.eu.org/efs/
S: Orphan
L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/
+T: quilt kernel.org/pub/linux/kernel/people/groeck/linux-staging/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
S: Maintained
F: Documentation/hwmon/
F: drivers/hwmon/
S: Supported
MATROX FRAMEBUFFER DRIVER
-M: Petr Vandrovec <vandrove@vc.cvut.cz>
L: linux-fbdev@vger.kernel.org
-S: Maintained
+S: Orphan
F: drivers/video/matrox/matroxfb_*
F: include/linux/matroxfb.h
F: drivers/char/mxser.*
MSI LAPTOP SUPPORT
-M: Lennart Poettering <mzxreary@0pointer.de>
+M: Lee, Chun-Yi <jlee@novell.com>
L: platform-driver-x86@vger.kernel.org
-W: https://tango.0pointer.de/mailman/listinfo/s270-linux
-W: http://0pointer.de/lennart/tchibo.html
S: Maintained
F: drivers/platform/x86/msi-laptop.c
F: drivers/mfd/
MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
-S: Orphan
+M: Chris Ball <cjb@laptop.org>
L: linux-mmc@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git
+S: Maintained
F: drivers/mmc/
F: include/linux/mmc/
F: drivers/net/natsemi.c
NCP FILESYSTEM
-M: Petr Vandrovec <vandrove@vc.cvut.cz>
-S: Maintained
+M: Petr Vandrovec <petr@vandrovec.name>
+S: Odd Fixes
F: fs/ncpfs/
NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
F: drivers/mmc/host/sdricoh_cs.c
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
-S: Orphan
+M: Chris Ball <cjb@laptop.org>
L: linux-mmc@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git
+S: Maintained
F: drivers/mmc/host/sdhci.*
SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 36
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc7
NAME = Sheep on Meth
# *DOCUMENTATION*
config KPROBES
bool "Kprobes"
- depends on KALLSYMS && MODULES
+ depends on MODULES
depends on HAVE_KPROBES
+ select KALLSYMS
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
def_bool y
depends on KPROBES && HAVE_OPTPROBES
depends on !PREEMPT
- select KALLSYMS_ALL
config HAVE_EFFICIENT_UNALIGNED_ACCESS
bool
ldq $20, HAE_REG($19); \
stq $21, HAE_CACHE($19); \
stq $21, 0($20); \
- ldq $0, 0($sp); \
- ldq $1, 8($sp); \
99:; \
ldq $19, 72($sp); \
ldq $20, 80($sp); \
cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
ldq $0, SP_OFF($sp)
and $0, 8, $0
- beq $0, restore_all
+ beq $0, ret_to_kernel
ret_to_user:
/* Make sure need_resched and sigpending don't change between
sampling and the rti. */
RESTORE_ALL
call_pal PAL_rti
+ret_to_kernel:
+ lda $16, 7
+ call_pal PAL_swpipl
+ br restore_all
+
.align 3
$syscall_error:
/*
/* We don't actually care for a3 success widgetry in the kernel.
Not for positive errno values. */
stq $0, 0($sp) /* $0 */
- br restore_all
+ br ret_to_kernel
.end kernel_thread
/*
jmp $31, do_sys_execve
.end sys_execve
- .align 4
- .globl osf_sigprocmask
- .ent osf_sigprocmask
-osf_sigprocmask:
- .prologue 0
- mov $sp, $18
- jmp $31, sys_osf_sigprocmask
-.end osf_sigprocmask
-
.align 4
.globl alpha_ni_syscall
.ent alpha_ni_syscall
dest[27] = pt->r27;
dest[28] = pt->r28;
dest[29] = pt->gp;
- dest[30] = rdusp();
+ dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp;
dest[31] = pt->pc;
/* Once upon a time this was the PS value. Which is stupid
/*
* The OSF/1 sigprocmask calling sequence is different from the
* C sigprocmask() sequence..
- *
- * how:
- * 1 - SIG_BLOCK
- * 2 - SIG_UNBLOCK
- * 3 - SIG_SETMASK
- *
- * We change the range to -1 .. 1 in order to let gcc easily
- * use the conditional move instructions.
- *
- * Note that we don't need to acquire the kernel lock for SMP
- * operation, as all of this is local to this thread.
*/
-SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask,
- struct pt_regs *, regs)
+SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
{
- unsigned long oldmask = -EINVAL;
-
- if ((unsigned long)how-1 <= 2) {
- long sign = how-2; /* -1 .. 1 */
- unsigned long block, unblock;
-
- newmask &= _BLOCKABLE;
- spin_lock_irq(¤t->sighand->siglock);
- oldmask = current->blocked.sig[0];
-
- unblock = oldmask & ~newmask;
- block = oldmask | newmask;
- if (!sign)
- block = unblock;
- if (sign <= 0)
- newmask = block;
- if (_NSIG_WORDS > 1 && sign > 0)
- sigemptyset(¤t->blocked);
- current->blocked.sig[0] = newmask;
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- regs->r0 = 0; /* special no error return */
+ sigset_t oldmask;
+ sigset_t mask;
+ unsigned long res;
+
+ siginitset(&mask, newmask & _BLOCKABLE);
+ res = sigprocmask(how, &mask, &oldmask);
+ if (!res) {
+ force_successful_syscall_return();
+ res = oldmask.sig[0];
}
- return oldmask;
+ return res;
}
SYSCALL_DEFINE3(osf_sigaction, int, sig,
old_sigset_t mask;
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
return -EFAULT;
- __get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
new_ka.ka_restorer = NULL;
}
if (!ret && oact) {
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
.quad sys_open /* 45 */
.quad alpha_ni_syscall
.quad sys_getxgid
- .quad osf_sigprocmask
+ .quad sys_osf_sigprocmask
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 50 */
.quad sys_acct
bool "Atmel AT91"
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
- select ARCH_USES_GETTIMEOFFSET
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
+ select SPARSE_IRQ
help
Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
+ select SPARSE_IRQ
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>).
+config ARCH_TCC_926
+ bool "Telechips TCC ARM926-based systems"
+ select CPU_ARM926T
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for Telechips TCC ARM926-based systems.
+
config ARCH_LH7A40X
bool "Sharp LH7A40X"
select CPU_ARM922T
source "arch/arm/plat-spear/Kconfig"
+source "arch/arm/plat-tcc/Kconfig"
+
if ARCH_S3C2410
source "arch/arm/mach-s3c2400/Kconfig"
source "arch/arm/mach-s3c2410/Kconfig"
ACTLR register. Note that setting specific bits in the ACTLR register
may not be available in non-secure mode.
+config ARM_ERRATA_742230
+ bool "ARM errata: DMB operation may be faulty"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 742230 Cortex-A9
+ (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction
+ between two write operations may not ensure the correct visibility
+ ordering of the two writes. This workaround sets a specific bit in
+ the diagnostic register of the Cortex-A9 which causes the DMB
+ instruction to behave as a DSB, ensuring the correct behaviour of
+ the two writes.
+
+config ARM_ERRATA_742231
+ bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 742231 Cortex-A9
+ (r2p0..r2p2) erratum. Under certain conditions, specific to the
+ Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode,
+ accessing some data located in the same cache line, may get corrupted
+ data due to bad handling of the address hazard when the line gets
+ replaced from one of the CPUs at the same time as another CPU is
+ accessing it. This workaround sets specific bits in the diagnostic
+ register of the Cortex-A9 which reduces the linefill issuing
+ capabilities of the processor.
+
config PL310_ERRATA_588369
bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
depends on CACHE_L2X0 && ARCH_OMAP4
However, if the CPU data cache is using a write-allocate mode,
this option is unlikely to provide any performance gain.
+config SECCOMP
+ bool
+ prompt "Enable seccomp to safely compute untrusted bytecode"
+ ---help---
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
help
source "lib/Kconfig.debug"
+config STRICT_DEVMEM
+ bool "Filter access to /dev/mem"
+ depends on MMU
+ ---help---
+ If this option is disabled, you allow userspace (root) access to all
+ of memory, including kernel and userspace memory. Accidental
+ access to this is obviously disastrous, but specific access can
+ be used by people debugging the kernel.
+
+ If this option is switched on, the /dev/mem file only allows
+ userspace access to memory mapped peripherals.
+
+ If in doubt, say Y.
+
# RMK wants arm kernels compiled with frame pointers or stack unwinding.
# If you know what you are doing and are willing to live without stack
# traces, you can get a slightly smaller kernel by setting this option to
machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
+machine-$(CONFIG_ARCH_TCC8K) := tcc8k
machine-$(CONFIG_ARCH_TEGRA) := tegra
machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_U8500) := ux500
plat-$(CONFIG_ARCH_OMAP) := omap
plat-$(CONFIG_ARCH_S3C64XX) := samsung
plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
+plat-$(CONFIG_ARCH_TCC_926) := tcc
plat-$(CONFIG_PLAT_IOP) := iop
plat-$(CONFIG_PLAT_NOMADIK) := nomadik
plat-$(CONFIG_PLAT_ORION) := orion
FASTFPE_OBJ :=$(FASTFPE)/
endif
-# If we have a machine-specific directory, then include it in the build.
-core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
-core-y += $(machdirs) $(platdirs)
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
+# If we have a machine-specific directory, then include it in the build.
+core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += $(machdirs) $(platdirs)
+
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
libs-y := arch/arm/lib/ $(libs-y)
$(obj)/font.c: $(FONTC)
$(call cmd,shipped)
-$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
+$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
@sed "$(SEDFLAGS)" < $< > $@
((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
}
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (mask >= PHYS_OFFSET + SZ_64M - 1)
+ return 0;
+
+ return -EIO;
+}
+
int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
{
it8152_io.start = IT8152_IO_BASE + 0x12000;
CONFIG_ARCH_AT91=y
CONFIG_ARCH_AT91SAM9G20=y
CONFIG_MACH_AT91SAM9G20EK=y
+CONFIG_MACH_AT91SAM9G20EK_2MMC=y
CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
# CONFIG_ARM_THUMB is not set
CONFIG_AEABI=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_ESATA_SHEEVAPLUG=y
CONFIG_MACH_GURUPLUG=y
+CONFIG_MACH_DOCKSTAR=y
CONFIG_MACH_TS219=y
CONFIG_MACH_TS41X=y
CONFIG_MACH_OPENRD_BASE=y
CONFIG_MACH_MX27=y
CONFIG_MACH_MX27ADS=y
CONFIG_MACH_PCM038=y
+CONFIG_MACH_CPUIMX27=y
+CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2=y
+CONFIG_MACH_EUKREA_CPUIMX27_USEUART4=y
CONFIG_MACH_MX27_3DS=y
+CONFIG_MACH_IMX27_VISSTRIM_M10=y
CONFIG_MACH_IMX27LITE=y
+CONFIG_MACH_PCA100=y
+CONFIG_MACH_MXT_TD60=y
CONFIG_MXC_IRQ_PRIOR=y
CONFIG_MXC_PWM=y
CONFIG_NO_HZ=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=m
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IMX=y
CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
+CONFIG_SPI_IMX=y
CONFIG_W1=y
CONFIG_W1_MASTER_MXC=y
CONFIG_W1_SLAVE_THERM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FB_IMX=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=m
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_ULPI=y
CONFIG_MMC=y
CONFIG_MMC_MXC=y
CONFIG_RTC_CLASS=y
+++ /dev/null
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_MACH_MX31ADS is not set
-CONFIG_MACH_MX31_3DS=y
-CONFIG_AEABI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_LRO is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-# CONFIG_BLK_DEV is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRC32 is not set
CONFIG_MACH_ARMADILLO5X0=y
CONFIG_MACH_MX35_3DS=y
CONFIG_MACH_KZM_ARM11_01=y
+CONFIG_MACH_EUKREA_CPUIMX35=y
CONFIG_MXC_IRQ_PRIOR=y
CONFIG_MXC_PWM=y
CONFIG_NO_HZ=y
CONFIG_MMC_MXC=y
CONFIG_DMADEVICES=y
# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_UBIFS_FS=y
CONFIG_ARCH_MXC=y
CONFIG_ARCH_MX5=y
CONFIG_MACH_MX51_BABBAGE=y
+CONFIG_MACH_MX51_3DS=y
+CONFIG_MACH_EUKREA_CPUIMX51=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_NATIONAL_PHY=y
CONFIG_STE10XP=y
CONFIG_LSI_ET1011C_PHY=y
-CONFIG_FIXED_PHY=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_GPIO=y
CONFIG_NET_ETHERNET=y
CONFIG_I2C_ALGOPCA=m
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
-CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_INOTIFY=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_PRINT_QUOTA_WARNING is not set
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
CONFIG_CONFIGFS_FS=m
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
-# CONFIG_DETECT_SOFTLOCKUP is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_ARM_UNWIND is not set
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
-CONFIG_KEYS=y
CONFIG_SECURITYFS=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_LZO=y
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
+extern int vectors_user_mapping(void);
+#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+
#endif
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern int valid_phys_addr_range(unsigned long addr, size_t size);
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
+extern int devmem_is_allowed(unsigned long pfn);
#endif
/*
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
#include <asm/proc-fns.h>
-#include <asm-generic/mm_hooks.h>
void __check_kvm_seq(struct mm_struct *mm);
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) switch_mm(prev, next, NULL)
+/*
+ * We are inserting a "fake" vma for the user-accessible vector page so
+ * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
+ * But we also want to remove it before the generic code gets to see it
+ * during process exit or the unmapping of it would cause total havoc.
+ * (the macro is used as remove_vma() is static to mm/mmap.c)
+ */
+#define arch_exit_mmap(mm) \
+do { \
+ struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
+ if (high_vma) { \
+ BUG_ON(high_vma->vm_next); /* it should be last */ \
+ if (high_vma->vm_prev) \
+ high_vma->vm_prev->vm_next = NULL; \
+ else \
+ mm->mmap = NULL; \
+ rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
+ mm->mmap_cache = NULL; \
+ mm->map_count--; \
+ remove_vma(high_vma); \
+ } \
+} while (0)
+
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+ struct mm_struct *mm)
+{
+}
+
#endif
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
#else
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
--- /dev/null
+#ifndef _ASM_ARM_SECCOMP_H
+#define _ASM_ARM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_ARM_SECCOMP_H */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19
#define TIF_RESTORE_SIGMASK 20
+#define TIF_SECCOMP 21
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
/*
* Change these and you break ASM code in entry-common.S
beq no_work_pending
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
+ tst r1, #_TIF_SIGPENDING @ delivering a signal?
+ movne why, #0 @ prevent further restarts
bl do_notify_resume
b ret_slow_syscall @ Check work again
get_thread_info tsk
adr tbl, sys_call_table @ load syscall table pointer
- ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
#if defined(CONFIG_OABI_COMPAT)
/*
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif
+ ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args
- tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+
+#ifdef CONFIG_SECCOMP
+ tst r10, #_TIF_SECCOMP
+ beq 1f
+ mov r0, scno
+ bl __secure_computing
+ add r0, sp, #S_R0 + S_OFF @ pointer to regs
+ ldmia r0, {r0 - r3} @ have to reload r0 - r3
+1:
+#endif
+
+ tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace
cmp scno, #NR_syscalls @ check upper syscall limit
unsigned long range_end = mm->brk + 0x02000000;
return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}
+
+/*
+ * The vectors page is always readable from user space for the
+ * atomic helpers and the signal restart code. Let's declare a mapping
+ * for it so it is visible through ptrace and /proc/<pid>/mem.
+ */
+
+int vectors_user_mapping(void)
+{
+ struct mm_struct *mm = current->mm;
+ return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
+ VM_READ | VM_EXEC |
+ VM_MAYREAD | VM_MAYEXEC |
+ VM_ALWAYSDUMP | VM_RESERVED,
+ NULL);
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
+}
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
#endif /* __ASM_ARCH_VMALLOC_H */
select HAVE_AT91_USART3
select HAVE_AT91_USART4
select HAVE_AT91_USART5
+ select HAVE_NET_MACB
config ARCH_AT91SAM9261
bool "AT91SAM9261"
select CPU_ARM926T
select GENERIC_CLOCKEVENTS
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
select HAVE_AT91_USART3
select HAVE_AT91_USART4
select HAVE_AT91_USART5
+ select HAVE_NET_MACB
config ARCH_AT91SAM9G45
bool "AT91SAM9G45"
select GENERIC_CLOCKEVENTS
select HAVE_AT91_USART3
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
config ARCH_AT91CAP9
bool "AT91CAP9"
that embeds only one SD/MMC slot.
config MACH_AT91SAM9G20EK_2MMC
+ depends on MACH_AT91SAM9G20EK
bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
select HAVE_NAND_ATMEL_BUSWIDTH_16
help
comment "AT91SAM9G45 Board Type"
-config MACH_AT91SAM9G45EKES
- bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
+config MACH_AT91SAM9M10G45EK
+ bool "Atmel AT91SAM9M10G45-EK Evaluation Kits"
select HAVE_NAND_ATMEL_BUSWIDTH_16
help
Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
# AT91SAM9G20 board-specific support
obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
-obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
# AT91SAM9G45 board-specific support
-obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
+obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
# AT91CAP9 board-specific support
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
.sda_is_open_drain = 1,
.scl_pin = AT91_PIN_PA21,
.scl_is_open_drain = 1,
- .udelay = 2, /* ~100 kHz */
+ .udelay = 5, /* ~100 kHz */
};
static struct platform_device at91sam9g45_twi0_device = {
.sda_is_open_drain = 1,
.scl_pin = AT91_PIN_PB11,
.scl_is_open_drain = 1,
- .udelay = 2, /* ~100 kHz */
+ .udelay = 5, /* ~100 kHz */
};
static struct platform_device at91sam9g45_twi1_device = {
/* .rdy_pin = AT91_PIN_PC16, */
.enable_pin = AT91_PIN_PA15,
.partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,
+++ /dev/null
-/*
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- * Copyright (C) 2009 Rob Emanuele
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/at73c213.h>
-#include <linux/clk.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/consumer.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91sam9_smc.h>
-
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init ek_map_io(void)
-{
- /* Initialize processor: 18.432 MHz crystal */
- at91sam9260_initialize(18432000);
-
- /* DGBU on ttyS0. (Rx & Tx only) */
- at91_register_uart(0, 0, 0);
-
- /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
- at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
- | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
- | ATMEL_UART_RI);
-
- /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
- at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
-
- /* set serial console to ttyS0 (ie, DBGU) */
- at91_set_serial_console(0);
-}
-
-static void __init ek_init_irq(void)
-{
- at91sam9260_init_interrupts(NULL);
-}
-
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata ek_usbh_data = {
- .ports = 2,
-};
-
-/*
- * USB Device port
- */
-static struct at91_udc_data __initdata ek_udc_data = {
- .vbus_pin = AT91_PIN_PC5,
- .pullup_pin = 0, /* pull-up driven by UDC */
-};
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info ek_spi_devices[] = {
-#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
- { /* DataFlash chip */
- .modalias = "mtd_dataflash",
- .chip_select = 1,
- .max_speed_hz = 15 * 1000 * 1000,
- .bus_num = 0,
- },
-#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
- { /* DataFlash card */
- .modalias = "mtd_dataflash",
- .chip_select = 0,
- .max_speed_hz = 15 * 1000 * 1000,
- .bus_num = 0,
- },
-#endif
-#endif
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct at91_eth_data __initdata ek_macb_data = {
- .phy_irq_pin = AT91_PIN_PB0,
- .is_rmii = 1,
-};
-
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata ek_nand_partition[] = {
- {
- .name = "Bootstrap",
- .offset = 0,
- .size = 4 * SZ_1M,
- },
- {
- .name = "Partition 1",
- .offset = MTDPART_OFS_NXTBLK,
- .size = 60 * SZ_1M,
- },
- {
- .name = "Partition 2",
- .offset = MTDPART_OFS_NXTBLK,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
- *num_partitions = ARRAY_SIZE(ek_nand_partition);
- return ek_nand_partition;
-}
-
-/* det_pin is not connected */
-static struct atmel_nand_data __initdata ek_nand_data = {
- .ale = 21,
- .cle = 22,
- .rdy_pin = AT91_PIN_PC13,
- .enable_pin = AT91_PIN_PC14,
- .partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
- .bus_width_16 = 1,
-#else
- .bus_width_16 = 0,
-#endif
-};
-
-static struct sam9_smc_config __initdata ek_nand_smc_config = {
- .ncs_read_setup = 0,
- .nrd_setup = 2,
- .ncs_write_setup = 0,
- .nwe_setup = 2,
-
- .ncs_read_pulse = 4,
- .nrd_pulse = 4,
- .ncs_write_pulse = 4,
- .nwe_pulse = 4,
-
- .read_cycle = 7,
- .write_cycle = 7,
-
- .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
- .tdf_cycles = 3,
-};
-
-static void __init ek_add_device_nand(void)
-{
- /* setup bus-width (8 or 16) */
- if (ek_nand_data.bus_width_16)
- ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
- else
- ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
- /* configure chip-select 3 (NAND) */
- sam9_smc_configure(3, &ek_nand_smc_config);
-
- at91_add_device_nand(&ek_nand_data);
-}
-
-
-/*
- * MCI (SD/MMC)
- * wp_pin is not connected
- */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-static struct mci_platform_data __initdata ek_mmc_data = {
- .slot[0] = {
- .bus_width = 4,
- .detect_pin = AT91_PIN_PC2,
- .wp_pin = -ENODEV,
- },
- .slot[1] = {
- .bus_width = 4,
- .detect_pin = AT91_PIN_PC9,
- .wp_pin = -ENODEV,
- },
-
-};
-#else
-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,
-};
-#endif
-
-/*
- * LEDs
- */
-static struct gpio_led ek_leds[] = {
- { /* "bottom" led, green, userled1 to be defined */
- .name = "ds5",
- .gpio = AT91_PIN_PB8,
- .active_low = 1,
- .default_trigger = "none",
- },
- { /* "power" led, yellow */
- .name = "ds1",
- .gpio = AT91_PIN_PB9,
- .default_trigger = "heartbeat",
- }
-};
-
-#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
-static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
- REGULATOR_SUPPLY("AVDD", "0-001b"),
- REGULATOR_SUPPLY("HPVDD", "0-001b"),
- REGULATOR_SUPPLY("DBVDD", "0-001b"),
- REGULATOR_SUPPLY("DCVDD", "0-001b"),
-};
-
-static struct regulator_init_data ek_avdd_reg_init_data = {
- .constraints = {
- .name = "3V3",
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- },
- .consumer_supplies = ek_audio_consumer_supplies,
- .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
-};
-
-static struct fixed_voltage_config ek_vdd_pdata = {
- .supply_name = "board-3V3",
- .microvolts = 3300000,
- .gpio = -EINVAL,
- .enabled_at_boot = 0,
- .init_data = &ek_avdd_reg_init_data,
-};
-static struct platform_device ek_voltage_regulator = {
- .name = "reg-fixed-voltage",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &ek_vdd_pdata,
- },
-};
-static void __init ek_add_regulators(void)
-{
- platform_device_register(&ek_voltage_regulator);
-}
-#else
-static void __init ek_add_regulators(void) {}
-#endif
-
-static struct i2c_board_info __initdata ek_i2c_devices[] = {
- {
- I2C_BOARD_INFO("24c512", 0x50),
- },
-};
-
-
-static void __init ek_board_init(void)
-{
- /* Serial */
- at91_add_device_serial();
- /* USB Host */
- at91_add_device_usbh(&ek_usbh_data);
- /* USB Device */
- at91_add_device_udc(&ek_udc_data);
- /* SPI */
- at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
- /* NAND */
- ek_add_device_nand();
- /* Ethernet */
- at91_add_device_eth(&ek_macb_data);
- /* Regulators */
- ek_add_regulators();
- /* MMC */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
- at91_add_device_mci(0, &ek_mmc_data);
-#else
- at91_add_device_mmc(0, &ek_mmc_data);
-#endif
- /* I2C */
- at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
- /* LEDs */
- at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
- /* PCK0 provides MCLK to the WM8731 */
- at91_set_B_periph(AT91_PIN_PC1, 0);
- /* SSC (for WM8731) */
- at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
-}
-
-MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
- /* Maintainer: Rob Emanuele */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
- .boot_params = AT91_SDRAM_BASE + 0x100,
- .timer = &at91sam926x_timer,
- .map_io = ek_map_io,
- .init_irq = ek_init_irq,
- .init_machine = ek_board_init,
-MACHINE_END
#include "sam9_smc.h"
#include "generic.h"
+/*
+ * board revision encoding
+ * bit 0:
+ * 0 => 1 sd/mmc slot
+ * 1 => 2 sd/mmc slots connectors (board from revision C)
+ */
+#define HAVE_2MMC (1 << 0)
+static int inline ek_have_2mmc(void)
+{
+ return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC);
+}
+
static void __init ek_map_io(void)
{
* SPI devices.
*/
static struct spi_board_info ek_spi_devices[] = {
-#if !defined(CONFIG_MMC_AT91)
+#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
{ /* DataFlash chip */
.modalias = "mtd_dataflash",
.chip_select = 1,
.is_rmii = 1,
};
+static void __init ek_add_device_macb(void)
+{
+ if (ek_have_2mmc())
+ ek_macb_data.phy_irq_pin = AT91_PIN_PB0;
+
+ at91_add_device_eth(&ek_macb_data);
+}
/*
* NAND flash
/*
* MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
+ * wp_pin and vcc_pin are not connected
*/
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata ek_mmc_data = {
+ .slot[1] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PC9,
+ },
+
+};
+#else
static struct at91_mmc_data __initdata ek_mmc_data = {
- .slot_b = 1,
+ .slot_b = 1, /* Only one slot so use slot B */
.wire4 = 1,
+ .det_pin = AT91_PIN_PC9,
};
+#endif
+static void __init ek_add_device_mmc(void)
+{
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ if (ek_have_2mmc()) {
+ ek_mmc_data.slot[0].bus_width = 4;
+ ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2;
+ }
+ at91_add_device_mci(0, &ek_mmc_data);
+#else
+ at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+}
/*
* LEDs
}
};
+static void __init ek_add_device_gpio_leds(void)
+{
+ if (ek_have_2mmc()) {
+ ek_leds[0].gpio = AT91_PIN_PB8;
+ ek_leds[1].gpio = AT91_PIN_PB9;
+ }
+
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+}
/*
* GPIO Buttons
/* NAND */
ek_add_device_nand();
/* Ethernet */
- at91_add_device_eth(&ek_macb_data);
+ ek_add_device_macb();
/* Regulators */
ek_add_regulators();
/* MMC */
- at91_add_device_mmc(0, &ek_mmc_data);
+ ek_add_device_mmc();
/* I2C */
at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
/* LEDs */
- at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ ek_add_device_gpio_leds();
/* Push Buttons */
ek_add_device_buttons();
/* PCK0 provides MCLK to the WM8731 */
.init_irq = ek_init_irq,
.init_machine = ek_board_init,
MACHINE_END
+
+MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
+ /* Maintainer: Atmel */
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = ek_map_io,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
.rdy_pin = AT91_PIN_PC8,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,
at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
}
-MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
+MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
/* Maintainer: Atmel */
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
#define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */
#define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */
+/*
+ * Support defines for the simple Power Controller module.
+ */
+#define AT91_PS_CR (AT91_PS + 0) /* PS Control register */
+#define AT91_PS_CR_CPU (1 << 0) /* CPU clock disable bit */
+
#endif /* AT91X40_H */
* Disable the processor clock. The processor will be automatically
* re-enabled by an interrupt or by a reset.
*/
+#ifdef AT91_PS
+ at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
+#else
at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#endif
#else
/*
* Set the processor (CP15) into 'Wait for Interrupt' mode.
* 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
* larger physical memory designs better.
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
+#define VMALLOC_END 0xf0000000
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
.virtual = SRAM_VIRT,
.pfn = __phys_to_pfn(0x00010000),
.length = SZ_32K,
- /* MT_MEMORY_NONCACHED requires supersection alignment */
- .type = MT_DEVICE,
+ .type = MT_MEMORY_NONCACHED,
},
};
.virtual = SRAM_VIRT,
.pfn = __phys_to_pfn(0x00010000),
.length = SZ_32K,
- /* MT_MEMORY_NONCACHED requires supersection alignment */
- .type = MT_DEVICE,
+ .type = MT_MEMORY_NONCACHED,
},
};
.virtual = SRAM_VIRT,
.pfn = __phys_to_pfn(0x00008000),
.length = SZ_16K,
- /* MT_MEMORY_NONCACHED requires supersection alignment */
- .type = MT_DEVICE,
+ .type = MT_MEMORY_NONCACHED,
},
};
.virtual = SRAM_VIRT,
.pfn = __phys_to_pfn(0x00010000),
.length = SZ_32K,
- /* MT_MEMORY_NONCACHED requires supersection alignment */
- .type = MT_DEVICE,
+ .type = MT_MEMORY_NONCACHED,
},
};
#define IO_SPACE_LIMIT 0xffffffff
-#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\
- DOVE_PCIE0_IO_VIRT_BASE))
-#define __mem_pci(a) (a)
+#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \
+ DOVE_PCIE0_IO_VIRT_BASE))
+#define __mem_pci(a) (a)
#endif
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x1f000000)
+#define VMALLOC_END 0xdf000000
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
+#define VMALLOC_END 0xf0000000
#ifndef __ARCH_ARM_VMALLOC_H
#define __ARCH_ARM_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
#endif
default MACH_EUKREA_MBIMX27_BASEBOARD
config MACH_EUKREA_MBIMX27_BASEBOARD
- prompt "Eukrea MBIMX27 development board"
- bool
+ bool "Eukrea MBIMX27 development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_SPI_IMX
help
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
+config MACH_IMX27_VISSTRIM_M10
+ bool "Vista Silicon i.MX27 Visstrim_m10"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for Visstrim_m10 platform and its different variants.
+ This includes specific configurations for the board and its
+ peripherals.
+
config MACH_IMX27LITE
bool "LogicPD MX27 LITEKIT platform"
select IMX_HAVE_PLATFORM_IMX_UART
config MACH_PCA100
bool "Phytec phyCARD-s (pca100)"
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SPI_IMX
obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
+obj-$(CONFIG_MACH_IMX27_VISSTRIM_M10) += mach-imx27_visstrim_m10.o
obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, spi_clk)
+ _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
_REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
_REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
_REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
_REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
- _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
- _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
- _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
+ _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
+ _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
+ _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
_REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
/* Clocks we cannot directly gate, but drivers need their rates */
-DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk);
-DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk);
-DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk);
-DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk);
-DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk);
-DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk);
-DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk);
-DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk);
-DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk);
-DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk);
-DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk);
-DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk);
-DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk);
-DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk);
-DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk);
-DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk);
-DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk);
-DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk);
+DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk);
+DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk);
+DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk);
+DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk);
+DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk);
+DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk);
+DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk);
+DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk);
+DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk);
+DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk);
+DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk);
+DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk);
+DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk);
+DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk);
+DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk);
+DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk);
+DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk);
+DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
#define _REGISTER_CLOCK(d, n, c) \
{ \
_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
_REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
_REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
#include <mach/mx1.h>
#include <mach/devices-common.h>
-#define imx1_add_i2c_imx(pdata) \
- imx_add_imx_i2c(0, MX1_I2C_BASE_ADDR, SZ_4K, MX1_INT_I2C, pdata)
+extern const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst;
+#define imx1_add_imx_i2c(pdata) \
+ imx_add_imx_i2c(&imx1_imx_i2c_data, pdata)
-#define imx1_add_imx_uart0(pdata) \
- imx_add_imx_uart_3irq(0, MX1_UART1_BASE_ADDR, 0xd0, MX1_INT_UART1RX, MX1_INT_UART1TX, MX1_INT_UART1RTS, pdata)
-#define imx1_add_imx_uart1(pdata) \
- imx_add_imx_uart_3irq(0, MX1_UART2_BASE_ADDR, 0xd0, MX1_INT_UART2RX, MX1_INT_UART2TX, MX1_INT_UART2RTS, pdata)
+extern const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst;
+#define imx1_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_3irq(&imx1_imx_uart_data[id], pdata)
+#define imx1_add_imx_uart0(pdata) imx1_add_imx_uart(0, pdata)
+#define imx1_add_imx_uart1(pdata) imx1_add_imx_uart(1, pdata)
#include <mach/mx21.h>
#include <mach/devices-common.h>
-#define imx21_add_i2c_imx(pdata) \
- imx_add_imx_i2c(0, MX2x_I2C_BASE_ADDR, SZ_4K, MX2x_INT_I2C, pdata)
+extern const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst;
+#define imx21_add_imx_i2c(pdata) \
+ imx_add_imx_i2c(&imx21_imx_i2c_data, pdata)
-#define imx21_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX21_UART1_BASE_ADDR, SZ_4K, MX21_INT_UART1, pdata)
-#define imx21_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX21_UART2_BASE_ADDR, SZ_4K, MX21_INT_UART2, pdata)
-#define imx21_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX21_UART3_BASE_ADDR, SZ_4K, MX21_INT_UART3, pdata)
-#define imx21_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX21_UART4_BASE_ADDR, SZ_4K, MX21_INT_UART4, pdata)
+extern const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst;
+#define imx21_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata)
+extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst;
+#define imx21_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx21_imx_uart_data[id], pdata)
+#define imx21_add_imx_uart0(pdata) imx21_add_imx_uart(0, pdata)
+#define imx21_add_imx_uart1(pdata) imx21_add_imx_uart(1, pdata)
+#define imx21_add_imx_uart2(pdata) imx21_add_imx_uart(2, pdata)
+#define imx21_add_imx_uart3(pdata) imx21_add_imx_uart(3, pdata)
+
+extern const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst;
#define imx21_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v1(MX21_NFC_BASE_ADDR, MX21_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx21_mxc_nand_data, pdata)
-#define imx21_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX21_CSPI1_BASE_ADDR, SZ_4K, MX21_INT_CSPI1, pdata)
-#define imx21_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX21_CSPI2_BASE_ADDR, SZ_4K, MX21_INT_CSPI2, pdata)
+extern const struct imx_spi_imx_data imx21_cspi_data[] __initconst;
+#define imx21_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx21_cspi_data[id], pdata)
+#define imx21_add_spi_imx0(pdata) imx21_add_cspi(0, pdata)
+#define imx21_add_spi_imx1(pdata) imx21_add_cspi(1, pdata)
#include <mach/mx27.h>
#include <mach/devices-common.h>
-#define imx27_add_i2c_imx0(pdata) \
- imx_add_imx_i2c(0, MX27_I2C1_BASE_ADDR, SZ_4K, MX27_INT_I2C1, pdata)
-#define imx27_add_i2c_imx1(pdata) \
- imx_add_imx_i2c(1, MX27_I2C2_BASE_ADDR, SZ_4K, MX27_INT_I2C2, pdata)
+extern const struct imx_fec_data imx27_fec_data __initconst;
+#define imx27_add_fec(pdata) \
+ imx_add_fec(&imx27_fec_data, pdata)
-#define imx27_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX27_UART1_BASE_ADDR, SZ_4K, MX27_INT_UART1, pdata)
-#define imx27_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX27_UART2_BASE_ADDR, SZ_4K, MX27_INT_UART2, pdata)
-#define imx27_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX27_UART3_BASE_ADDR, SZ_4K, MX27_INT_UART3, pdata)
-#define imx27_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX27_UART4_BASE_ADDR, SZ_4K, MX27_INT_UART4, pdata)
-#define imx27_add_imx_uart4(pdata) \
- imx_add_imx_uart_1irq(4, MX27_UART5_BASE_ADDR, SZ_4K, MX27_INT_UART5, pdata)
-#define imx27_add_imx_uart5(pdata) \
- imx_add_imx_uart_1irq(5, MX27_UART6_BASE_ADDR, SZ_4K, MX27_INT_UART6, pdata)
+extern const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst;
+#define imx27_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata)
+extern const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst;
+#define imx27_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst;
+#define imx27_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx27_imx_uart_data[id], pdata)
+#define imx27_add_imx_uart0(pdata) imx27_add_imx_uart(0, pdata)
+#define imx27_add_imx_uart1(pdata) imx27_add_imx_uart(1, pdata)
+#define imx27_add_imx_uart2(pdata) imx27_add_imx_uart(2, pdata)
+#define imx27_add_imx_uart3(pdata) imx27_add_imx_uart(3, pdata)
+#define imx27_add_imx_uart4(pdata) imx27_add_imx_uart(4, pdata)
+#define imx27_add_imx_uart5(pdata) imx27_add_imx_uart(5, pdata)
+
+extern const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst;
#define imx27_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v1(MX27_NFC_BASE_ADDR, MX27_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx27_mxc_nand_data, pdata)
-#define imx27_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX27_CSPI1_BASE_ADDR, SZ_4K, MX27_INT_CSPI1, pdata)
-#define imx27_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX27_CSPI2_BASE_ADDR, SZ_4K, MX27_INT_CSPI2, pdata)
-#define imx27_add_spi_imx2(pdata) \
- imx_add_spi_imx(2, MX27_CSPI3_BASE_ADDR, SZ_4K, MX27_INT_CSPI3, pdata)
+extern const struct imx_spi_imx_data imx27_cspi_data[] __initconst;
+#define imx27_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx27_cspi_data[id], pdata)
+#define imx27_add_spi_imx0(pdata) imx27_add_cspi(0, pdata)
+#define imx27_add_spi_imx1(pdata) imx27_add_cspi(1, pdata)
+#define imx27_add_spi_imx2(pdata) imx27_add_cspi(2, pdata)
},
};
-#ifdef CONFIG_MACH_MX27
-static struct resource mxc_fec_resources[] = {
- {
- .start = MX27_FEC_BASE_ADDR,
- .end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_FEC,
- .end = MX27_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fec_resources),
- .resource = mxc_fec_resources,
-};
-#endif
-
static struct resource mxc_pwm_resources[] = {
{
.start = MX2x_PWM_BASE_ADDR,
};
#endif
-#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \
- { \
- .name = _name, \
- .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
- .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
- .flags = IORESOURCE_DMA, \
- }
-
-#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \
- static struct resource imx_ssi_resources ## n[] = { \
- { \
- .start = MX2x_SSI ## ssin ## _BASE_ADDR, \
- .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \
- .flags = IORESOURCE_MEM, \
- }, { \
- .start = MX2x_INT_SSI1, \
- .end = MX2x_INT_SSI1, \
- .flags = IORESOURCE_IRQ, \
- }, \
- DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \
- DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \
- DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \
- DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \
- }; \
- \
- struct platform_device imx_ssi_device ## n = { \
- .name = "imx-ssi", \
- .id = n, \
- .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
- .resource = imx_ssi_resources ## n, \
- }
-
-DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
-DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
-
/* GPIO port description */
#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \
{ \
extern struct platform_device mxc_wdt;
extern struct platform_device mxc_w1_master_device;
extern struct platform_device mxc_fb_device;
-extern struct platform_device mxc_fec_device;
extern struct platform_device mxc_pwm_device;
extern struct platform_device mxc_sdhc_device0;
extern struct platform_device mxc_sdhc_device1;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
extern struct platform_device mx21_usbhc_device;
-extern struct platform_device imx_ssi_device0;
-extern struct platform_device imx_ssi_device1;
extern struct platform_device imx_kpp_device;
#endif
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/spi.h>
-#include <mach/ssi.h>
#include <mach/audmux.h>
#include "devices-imx27.h"
#include "devices.h"
-static int eukrea_mbimx27_pins[] = {
+static const int eukrea_mbimx27_pins[] __initconst = {
/* UART2 */
PE3_PF_UART2_CTS,
PE4_PF_UART2_RTS,
.dat3_card_detect = 1,
};
-struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata = {
+static const
+struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata __initconst = {
.flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE,
};
i2c_register_board_info(0, eukrea_mbimx27_i2c_devices,
ARRAY_SIZE(eukrea_mbimx27_i2c_devices));
- mxc_register_device(&imx_ssi_device0, &eukrea_mbimx27_ssi_pdata);
+ imx27_add_imx_ssi(0, &eukrea_mbimx27_ssi_pdata);
#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
|| defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
#include "devices-imx27.h"
#include "devices.h"
-static int eukrea_cpuimx27_pins[] = {
+static const int eukrea_cpuimx27_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
static struct platform_device *platform_devices[] __initdata = {
&eukrea_cpuimx27_nor_mtd_device,
- &mxc_fec_device,
&mxc_wdt,
&mxc_w1_master_device,
};
i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
- imx27_add_i2c_imx1(&cpuimx27_i2c1_data);
+ imx27_add_imx_i2c(1, &cpuimx27_i2c1_data);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
--- /dev/null
+/*
+ * mach-imx27_visstrim_m10.c
+ *
+ * Copyright 2010 Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/iomux.h>
+#include <mach/mxc_ehci.h>
+
+#include "devices-imx27.h"
+#include "devices.h"
+
+#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
+#define SDHC1_IRQ IRQ_GPIOB(25)
+
+static const int visstrim_m10_pins[] __initconst = {
+ /* UART1 (console) */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* SDHC1 */
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ /* Both I2Cs */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* USB OTG */
+ OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ PC9_PF_USBOTG_DATA0,
+ PC11_PF_USBOTG_DATA1,
+ PC10_PF_USBOTG_DATA2,
+ PC13_PF_USBOTG_DATA3,
+ PC12_PF_USBOTG_DATA4,
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PE25_PF_USBOTG_DATA7,
+ PE24_PF_USBOTG_CLK,
+ PE2_PF_USBOTG_DIR,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PB23_PF_USB_PWR,
+ PB24_PF_USB_OC,
+};
+
+/* GPIOs used as events for applications */
+static struct gpio_keys_button visstrim_gpio_keys[] = {
+ {
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .gpio = (GPIO_PORTC + 15),
+ .desc = "Default config",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_RECORD,
+ .gpio = (GPIO_PORTF + 14),
+ .desc = "Record",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_STOP,
+ .gpio = (GPIO_PORTF + 13),
+ .desc = "Stop",
+ .active_low = 0,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data visstrim_gpio_keys_platform_data = {
+ .buttons = visstrim_gpio_keys,
+ .nbuttons = ARRAY_SIZE(visstrim_gpio_keys),
+};
+
+static struct platform_device visstrim_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &visstrim_gpio_keys_platform_data,
+ },
+};
+
+/* Visstrim_SM10 has a microSD slot connected to sdhc1 */
+static int visstrim_m10_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ ret = request_irq(SDHC1_IRQ, detect_irq, IRQF_TRIGGER_FALLING,
+ "mmc-detect", data);
+ return ret;
+}
+
+static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(SDHC1_IRQ, data);
+}
+
+static struct imxmmc_platform_data visstrim_m10_sdhc_pdata = {
+ .init = visstrim_m10_sdhc1_init,
+ .exit = visstrim_m10_sdhc1_exit,
+};
+
+/* Visstrim_SM10 NOR flash */
+static struct physmap_flash_data visstrim_m10_flash_data = {
+ .width = 2,
+};
+
+static struct resource visstrim_m10_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc0000000 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device visstrim_m10_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &visstrim_m10_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &visstrim_m10_flash_resource,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &visstrim_gpio_keys_device,
+ &visstrim_m10_nor_mtd_device,
+};
+
+/* Visstrim_M10 uses UART0 as console */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* I2C */
+static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct pca953x_platform_data visstrim_m10_pca9555_pdata = {
+ .gpio_base = 240, /* After MX27 internal GPIOs */
+ .invert = 0,
+};
+
+static struct i2c_board_info visstrim_m10_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pca9555", 0x20),
+ .platform_data = &visstrim_m10_pca9555_pdata,
+ },
+};
+
+/* USB OTG */
+static int otg_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data visstrim_m10_usbotg_pdata = {
+ .init = otg_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static void __init visstrim_m10_board_init(void)
+{
+ int ret;
+
+ ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
+ ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
+ if (ret)
+ pr_err("Failed to setup pins (%d)\n", ret);
+
+ imx27_add_imx_uart0(&uart_pdata);
+
+ i2c_register_board_info(0, visstrim_m10_i2c_devices,
+ ARRAY_SIZE(visstrim_m10_i2c_devices));
+ imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
+ imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
+ mxc_register_device(&mxc_sdhc_device0, &visstrim_m10_sdhc_pdata);
+ mxc_register_device(&mxc_otg_host, &visstrim_m10_usbotg_pdata);
+ imx27_add_fec(NULL);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init visstrim_m10_timer_init(void)
+{
+ mx27_clocks_init((unsigned long)25000000);
+}
+
+static struct sys_timer visstrim_m10_timer = {
+ .init = visstrim_m10_timer_init,
+};
+
+MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = visstrim_m10_board_init,
+ .timer = &visstrim_m10_timer,
+MACHINE_END
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mx27lite_pins[] = {
+static const int mx27lite_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
static void __init mx27lite_init(void)
{
mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
"imx27lite");
imx27_add_imx_uart0(&uart_pdata);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_fec(NULL);
}
static void __init mx27lite_timer_init(void)
#include "devices-imx1.h"
#include "devices.h"
-static int mx1ads_pins[] = {
+static const int mx1ads_pins[] __initconst = {
/* UART1 */
PC9_PF_UART1_CTS,
PC10_PF_UART1_RTS,
i2c_register_board_info(0, mx1ads_i2c_devices,
ARRAY_SIZE(mx1ads_i2c_devices));
- imx1_add_i2c_imx(&mx1ads_i2c_data);
+ imx1_add_imx_i2c(&mx1ads_i2c_data);
}
static void __init mx1ads_timer_init(void)
#define MX21ADS_IO_LED4_ON 0x4000
#define MX21ADS_IO_LED3_ON 0x8000
-static unsigned int mx21ads_pins[] = {
+static const int mx21ads_pins[] __initconst = {
/* CS8900A */
(GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mx27pdk_pins[] = {
+static const int mx27pdk_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
/*
* Matrix keyboard
*/
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
"mx27pdk");
imx27_add_imx_uart0(&uart_pdata);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_fec(NULL);
mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
}
/* to determine the correct external crystal reference */
#define CKIH_27MHZ_BIT_SET (1 << 3)
-static unsigned int mx27ads_pins[] = {
+static const int mx27ads_pins[] __initconst = {
/* UART0 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
static struct platform_device *platform_devices[] __initdata = {
&mx27ads_nor_mtd_device,
- &mxc_fec_device,
&mxc_w1_master_device,
};
/* only the i2c master 1 is used on this CPU card */
i2c_register_board_info(1, mx27ads_i2c_devices,
ARRAY_SIZE(mx27ads_i2c_devices));
- imx27_add_i2c_imx1(&mx27ads_i2c1_data);
+ imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mxt_td60_pins[] __initdata = {
+static const int mxt_td60_pins[] __initconst = {
/* UART0 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
.exit = mxt_td60_sdhc1_exit,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
i2c_register_board_info(1, mxt_td60_i2c2_devices,
ARRAY_SIZE(mxt_td60_i2c2_devices));
- imx27_add_i2c_imx0(&mxt_td60_i2c0_data);
- imx27_add_i2c_imx1(&mxt_td60_i2c1_data);
+ imx27_add_imx_i2c(0, &mxt_td60_i2c0_data);
+ imx27_add_imx_i2c(1, &mxt_td60_i2c1_data);
mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_fec(NULL);
}
static void __init mxt_td60_timer_init(void)
#include <mach/iomux-mx27.h>
#include <asm/mach/time.h>
#include <mach/audmux.h>
-#include <mach/ssi.h>
#include <mach/mxc_nand.h>
#include <mach/irqs.h>
#include <mach/mmc.h>
#define SPI1_SS1 (GPIO_PORTD + 27)
#define SD2_CD (GPIO_PORTC + 29)
-static int pca100_pins[] = {
+static const int pca100_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
static struct platform_device *platform_devices[] __initdata = {
&mxc_w1_master_device,
- &mxc_fec_device,
&mxc_wdt,
};
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
.platform_data = &board_eeprom,
}, {
- I2C_BOARD_INFO("rtc-pcf8563", 0x51),
- .type = "pcf8563"
+ I2C_BOARD_INFO("pcf8563", 0x51),
}, {
I2C_BOARD_INFO("lm75", 0x4a),
- .type = "lm75"
}
};
msleep(2);
}
-static struct imx_ssi_platform_data pca100_ssi_pdata = {
+static const struct imx_ssi_platform_data pca100_ssi_pdata __initconst = {
.ac97_reset = pca100_ac97_cold_reset,
.ac97_warm_reset = pca100_ac97_warm_reset,
.flags = IMX_SSI_USE_AC97,
if (ret)
printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
- mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
+ imx27_add_imx_ssi(0, &pca100_ssi_pdata);
imx27_add_imx_uart0(&uart_pdata);
i2c_register_board_info(1, pca100_i2c_devices,
ARRAY_SIZE(pca100_i2c_devices));
- imx27_add_i2c_imx1(&pca100_i2c1_data);
+ imx27_add_imx_i2c(1, &pca100_i2c1_data);
#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN);
mxc_register_device(&mxc_fb_device, &pca100_fb_data);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
#include "devices-imx27.h"
#include "devices.h"
-static int pcm038_pins[] = {
+static const int pcm038_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
static struct platform_device *platform_devices[] __initdata = {
&pcm038_nor_mtd_device,
&mxc_w1_master_device,
- &mxc_fec_device,
&pcm038_sram_mtd_device,
&mxc_wdt,
};
.consumer_supplies = cam_consumers,
};
-struct mc13783_regulator_init_data pcm038_regulators[] = {
+static struct mc13783_regulator_init_data pcm038_regulators[] = {
{
.id = MC13783_REGU_VCAM,
.init_data = &cam_data,
i2c_register_board_info(1, pcm038_i2c_devices,
ARRAY_SIZE(pcm038_i2c_devices));
- imx27_add_i2c_imx1(&pcm038_i2c1_data);
+ imx27_add_imx_i2c(1, &pcm038_i2c1_data);
/* PE18 for user-LED D40 */
mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#ifdef CONFIG_MACH_PCM970_BASEBOARD
}
};
-static int mxc_uart1_pins[] = {
+static const int mxc_uart1_pins[] = {
PC9_PF_UART1_CTS,
PC10_PF_UART1_RTS,
PC11_PF_UART1_TXD,
#include "devices.h"
-static int pcm970_pins[] = {
+static const int pcm970_pins[] __initconst = {
/* SDHC */
PB4_PF_SD2_D0,
PB5_PF_SD2_D1,
},
};
-struct sja1000_platform_data pcm970_sja1000_platform_data = {
+static struct sja1000_platform_data pcm970_sja1000_platform_data = {
.osc_freq = 16000000,
.ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
.cdr = CDR_CBP,
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
}
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (mask >= SZ_64M - 1)
+ return 0;
+
+ return -EIO;
+}
+
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);
#define PCIBIOS_MAX_MEM 0x4BFFFFFF
#endif
+#define ARCH_HAS_DMA_SET_COHERENT_MASK
+
#define pcibios_assign_all_busses() 1
/* Register locations and bits */
QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
devices.
+config MACH_DOCKSTAR
+ bool "Seagate FreeAgent DockStar"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Seagate FreeAgent DockStar.
+
config MACH_OPENRD
bool
Say 'Y' here if you want your kernel to support the
LaCie Network Space Max v2 NAS.
+config MACH_D2NET_V2
+ bool "LaCie d2 Network v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie d2 Network v2 NAS.
+
config MACH_NET2BIG_V2
bool "LaCie 2Big Network v2 NAS Board"
help
obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o
+obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o
obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o
-obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o
-obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o
-obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o
-obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o
-obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o
+obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
--- /dev/null
+/*
+ * arch/arm/mach-kirkwood/d2net_v2-setup.c
+ *
+ * LaCie d2 Network Space v2 Board Setup
+ *
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <mach/leds-ns2.h>
+#include "common.h"
+#include "mpp.h"
+#include "lacie_v2-common.h"
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data d2net_v2_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data d2net_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_PUSH_BUTTON 34
+#define D2NET_V2_GPIO_POWER_SWITCH_ON 13
+#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15
+
+#define D2NET_V2_SWITCH_POWER_ON 0x1
+#define D2NET_V2_SWITCH_POWER_OFF 0x2
+
+static struct gpio_keys_button d2net_v2_buttons[] = {
+ [0] = {
+ .type = EV_SW,
+ .code = D2NET_V2_SWITCH_POWER_ON,
+ .gpio = D2NET_V2_GPIO_POWER_SWITCH_ON,
+ .desc = "Back power switch (on|auto)",
+ .active_low = 0,
+ },
+ [1] = {
+ .type = EV_SW,
+ .code = D2NET_V2_SWITCH_POWER_OFF,
+ .gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF,
+ .desc = "Back power switch (auto|off)",
+ .active_low = 0,
+ },
+ [2] = {
+ .code = KEY_POWER,
+ .gpio = D2NET_V2_GPIO_PUSH_BUTTON,
+ .desc = "Front Push Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data d2net_v2_button_data = {
+ .buttons = d2net_v2_buttons,
+ .nbuttons = ARRAY_SIZE(d2net_v2_buttons),
+};
+
+static struct platform_device d2net_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_RED_LED 12
+
+static struct gpio_led d2net_v2_gpio_led_pins[] = {
+ {
+ .name = "d2net_v2:red:fail",
+ .gpio = D2NET_V2_GPIO_RED_LED,
+ },
+};
+
+static struct gpio_led_platform_data d2net_v2_gpio_leds_data = {
+ .num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins),
+ .leds = d2net_v2_gpio_led_pins,
+};
+
+static struct platform_device d2net_v2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_gpio_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * Dual-GPIO CPLD LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_BLUE_LED_SLOW 29
+#define D2NET_V2_GPIO_BLUE_LED_CMD 30
+
+static struct ns2_led d2net_v2_led_pins[] = {
+ {
+ .name = "d2net_v2:blue:sata",
+ .cmd = D2NET_V2_GPIO_BLUE_LED_CMD,
+ .slow = D2NET_V2_GPIO_BLUE_LED_SLOW,
+ },
+};
+
+static struct ns2_led_platform_data d2net_v2_leds_data = {
+ .num_leds = ARRAY_SIZE(d2net_v2_led_pins),
+ .leds = d2net_v2_led_pins,
+};
+
+static struct platform_device d2net_v2_leds = {
+ .name = "leds-ns2",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int d2net_v2_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Request power-off */
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO, /* Red led */
+ MPP13_GPIO, /* Rear power switch (on|auto) */
+ MPP14_GPIO, /* USB fuse */
+ MPP15_GPIO, /* Rear power switch (auto|off) */
+ MPP16_GPIO, /* SATA 0 power */
+ MPP21_SATA0_ACTn,
+ MPP24_GPIO, /* USB mode select */
+ MPP26_GPIO, /* USB device vbus */
+ MPP28_GPIO, /* USB enable host vbus */
+ MPP29_GPIO, /* Blue led (slow register) */
+ MPP30_GPIO, /* Blue led (command register) */
+ MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */
+ MPP35_GPIO, /* Inhibit power-off */
+ 0
+};
+
+#define D2NET_V2_GPIO_POWER_OFF 7
+
+static void d2net_v2_power_off(void)
+{
+ gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init d2net_v2_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(d2net_v2_mpp_config);
+
+ lacie_v2_hdd_power_init(1);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&d2net_v2_ge00_data);
+ kirkwood_sata_init(&d2net_v2_sata_data);
+ kirkwood_uart0_init();
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+
+ platform_device_register(&d2net_v2_leds);
+ platform_device_register(&d2net_v2_gpio_leds);
+ platform_device_register(&d2net_v2_gpio_buttons);
+
+ if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = d2net_v2_power_off;
+ else
+ pr_err("d2net_v2: failed to configure power-off GPIO\n");
+}
+
+MACHINE_START(D2NET_V2, "LaCie d2 Network v2")
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = d2net_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &lacie_v2_timer,
+MACHINE_END
--- /dev/null
+/*
+ * arch/arm/mach-kirkwood/dockstar-setup.c
+ *
+ * Seagate FreeAgent DockStar Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition dockstar_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data dockstar_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct gpio_led dockstar_led_pins[] = {
+ {
+ .name = "dockstar:green:health",
+ .default_trigger = "default-on",
+ .gpio = 46,
+ .active_low = 1,
+ },
+ {
+ .name = "dockstar:orange:misc",
+ .default_trigger = "none",
+ .gpio = 47,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data dockstar_led_data = {
+ .leds = dockstar_led_pins,
+ .num_leds = ARRAY_SIZE(dockstar_led_pins),
+};
+
+static struct platform_device dockstar_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &dockstar_led_data,
+ }
+};
+
+static unsigned int dockstar_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP46_GPIO, /* LED green */
+ MPP47_GPIO, /* LED orange */
+ 0
+};
+
+static void __init dockstar_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+
+ /* setup gpio pin select */
+ kirkwood_mpp_conf(dockstar_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25);
+
+ if (gpio_request(29, "USB Power Enable") != 0 ||
+ gpio_direction_output(29, 1) != 0)
+ printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&dockstar_ge00_data);
+
+ platform_device_register(&dockstar_leds);
+}
+
+MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar")
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = dockstar_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000
#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000
-#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000
+#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000
#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
--- /dev/null
+/*
+ * arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
+ *
+ * Platform data structure for netxbig LED driver
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_LEDS_NETXBIG_H
+#define __MACH_LEDS_NETXBIG_H
+
+struct netxbig_gpio_ext {
+ unsigned *addr;
+ int num_addr;
+ unsigned *data;
+ int num_data;
+ unsigned enable;
+};
+
+enum netxbig_led_mode {
+ NETXBIG_LED_OFF,
+ NETXBIG_LED_ON,
+ NETXBIG_LED_SATA,
+ NETXBIG_LED_TIMER1,
+ NETXBIG_LED_TIMER2,
+ NETXBIG_LED_MODE_NUM,
+};
+
+#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM
+
+struct netxbig_led_timer {
+ unsigned long delay_on;
+ unsigned long delay_off;
+ enum netxbig_led_mode mode;
+};
+
+struct netxbig_led {
+ const char *name;
+ const char *default_trigger;
+ int mode_addr;
+ int *mode_val;
+ int bright_addr;
+};
+
+struct netxbig_led_platform_data {
+ struct netxbig_gpio_ext *gpio_ext;
+ struct netxbig_led_timer *timer;
+ int num_timer;
+ struct netxbig_led *leds;
+ int num_leds;
+};
+
+#endif /* __MACH_LEDS_NETXBIG_H */
--- /dev/null
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <mach/irqs.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
+ ****************************************************************************/
+
+static struct mtd_partition lacie_v2_flash_parts[] = {
+ {
+ .name = "u-boot",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+};
+
+static const struct flash_platform_data lacie_v2_flash = {
+ .type = "mx25l4005a",
+ .name = "spi_flash",
+ .parts = lacie_v2_flash_parts,
+ .nr_parts = ARRAY_SIZE(lacie_v2_flash_parts),
+};
+
+static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &lacie_v2_flash,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+void __init lacie_v2_register_flash(void)
+{
+ spi_register_board_info(lacie_v2_spi_slave_info,
+ ARRAY_SIZE(lacie_v2_spi_slave_info));
+ kirkwood_spi_init();
+}
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+static struct at24_platform_data at24c04 = {
+ .byte_len = SZ_4K / 8,
+ .page_size = 16,
+};
+
+/*
+ * i2c addr | chip | description
+ * 0x50 | HT24LC04 | eeprom (512B)
+ */
+
+static struct i2c_board_info __initdata lacie_v2_i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c04", 0x50),
+ .platform_data = &at24c04,
+ }
+};
+
+void __init lacie_v2_register_i2c_devices(void)
+{
+ kirkwood_i2c_init();
+ i2c_register_board_info(0, lacie_v2_i2c_info,
+ ARRAY_SIZE(lacie_v2_i2c_info));
+}
+
+/*****************************************************************************
+ * Hard Disk power
+ ****************************************************************************/
+
+static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
+
+void __init lacie_v2_hdd_power_init(int hdd_num)
+{
+ int i;
+ int err;
+
+ /* Power up all hard disks. */
+ for (i = 0; i < hdd_num; i++) {
+ err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL);
+ if (err == 0) {
+ err = gpio_direction_output(
+ lacie_v2_gpio_hdd_power[i], 1);
+ /* Free the HDD power GPIOs. This allow user-space to
+ * configure them via the gpiolib sysfs interface. */
+ gpio_free(lacie_v2_gpio_hdd_power[i]);
+ }
+ if (err)
+ pr_err("Failed to power up HDD%d\n", i + 1);
+ }
+}
+
+/*****************************************************************************
+ * Timer
+ ****************************************************************************/
+
+static void lacie_v2_timer_init(void)
+{
+ kirkwood_tclk = 166666667;
+ orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer lacie_v2_timer = {
+ .init = lacie_v2_timer_init,
+};
--- /dev/null
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+
+void lacie_v2_register_flash(void);
+void lacie_v2_register_i2c_devices(void);
+void lacie_v2_hdd_power_init(int hdd_num);
+
+extern struct sys_timer lacie_v2_timer;
+
+#endif
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
#include <mach/kirkwood.h>
#include <mach/leds-ns2.h>
-#include <plat/time.h>
#include "common.h"
#include "mpp.h"
-
-/*****************************************************************************
- * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
- ****************************************************************************/
-
-static struct mtd_partition netspace_v2_flash_parts[] = {
- {
- .name = "u-boot",
- .size = MTDPART_SIZ_FULL,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
-};
-
-static const struct flash_platform_data netspace_v2_flash = {
- .type = "mx25l4005a",
- .name = "spi_flash",
- .parts = netspace_v2_flash_parts,
- .nr_parts = ARRAY_SIZE(netspace_v2_flash_parts),
-};
-
-static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = {
- {
- .modalias = "m25p80",
- .platform_data = &netspace_v2_flash,
- .irq = -1,
- .max_speed_hz = 20000000,
- .bus_num = 0,
- .chip_select = 0,
- },
-};
+#include "lacie_v2-common.h"
/*****************************************************************************
* Ethernet
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
-/*****************************************************************************
- * I2C devices
- ****************************************************************************/
-
-static struct at24_platform_data at24c04 = {
- .byte_len = SZ_4K / 8,
- .page_size = 16,
-};
-
-/*
- * i2c addr | chip | description
- * 0x50 | HT24LC04 | eeprom (512B)
- */
-
-static struct i2c_board_info __initdata netspace_v2_i2c_info[] = {
- {
- I2C_BOARD_INFO("24c04", 0x50),
- .platform_data = &at24c04,
- }
-};
-
/*****************************************************************************
* SATA
****************************************************************************/
.n_ports = 2,
};
-#define NETSPACE_V2_GPIO_SATA0_POWER 16
-#define NETSPACE_V2_GPIO_SATA1_POWER 17
-
-static void __init netspace_v2_sata_power_init(void)
-{
- int err;
-
- err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power");
- if (err == 0) {
- err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1);
- if (err)
- gpio_free(NETSPACE_V2_GPIO_SATA0_POWER);
- }
- if (err)
- pr_err("netspace_v2: failed to setup SATA0 power\n");
-
- if (machine_is_netspace_max_v2()) {
- err = gpio_request(NETSPACE_V2_GPIO_SATA1_POWER, "SATA1 power");
- if (err == 0) {
- err = gpio_direction_output(
- NETSPACE_V2_GPIO_SATA1_POWER, 1);
- if (err)
- gpio_free(NETSPACE_V2_GPIO_SATA1_POWER);
- }
- if (err)
- pr_err("netspace_v2: failed to setup SATA1 power\n");
- }
-}
-
/*****************************************************************************
* GPIO keys
****************************************************************************/
},
};
-/*****************************************************************************
- * Timer
- ****************************************************************************/
-
-static void netspace_v2_timer_init(void)
-{
- kirkwood_tclk = 166666667;
- orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
-
-struct sys_timer netspace_v2_timer = {
- .init = netspace_v2_timer_init,
-};
-
/*****************************************************************************
* General Setup
****************************************************************************/
kirkwood_init();
kirkwood_mpp_conf(netspace_v2_mpp_config);
- netspace_v2_sata_power_init();
+ if (machine_is_netspace_max_v2())
+ lacie_v2_hdd_power_init(2);
+ else
+ lacie_v2_hdd_power_init(1);
kirkwood_ehci_init();
kirkwood_ge00_init(&netspace_v2_ge00_data);
kirkwood_sata_init(&netspace_v2_sata_data);
kirkwood_uart0_init();
- spi_register_board_info(netspace_v2_spi_slave_info,
- ARRAY_SIZE(netspace_v2_spi_slave_info));
- kirkwood_spi_init();
- kirkwood_i2c_init();
- i2c_register_board_info(0, netspace_v2_i2c_info,
- ARRAY_SIZE(netspace_v2_i2c_info));
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
platform_device_register(&netspace_v2_leds);
platform_device_register(&netspace_v2_gpio_leds);
.init_machine = netspace_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netspace_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
.init_machine = netspace_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netspace_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
.init_machine = netspace_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netspace_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
#include <mach/kirkwood.h>
-#include <plat/time.h>
+#include <mach/leds-netxbig.h>
#include "common.h"
#include "mpp.h"
-
-/*****************************************************************************
- * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
- ****************************************************************************/
-
-static struct mtd_partition netxbig_v2_flash_parts[] = {
- {
- .name = "u-boot",
- .size = MTDPART_SIZ_FULL,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
-};
-
-static const struct flash_platform_data netxbig_v2_flash = {
- .type = "mx25l4005a",
- .name = "spi_flash",
- .parts = netxbig_v2_flash_parts,
- .nr_parts = ARRAY_SIZE(netxbig_v2_flash_parts),
-};
-
-static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = {
- {
- .modalias = "m25p80",
- .platform_data = &netxbig_v2_flash,
- .irq = -1,
- .max_speed_hz = 20000000,
- .bus_num = 0,
- .chip_select = 0,
- },
-};
+#include "lacie_v2-common.h"
/*****************************************************************************
* Ethernet
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
-/*****************************************************************************
- * I2C devices
- ****************************************************************************/
-
-static struct at24_platform_data at24c04 = {
- .byte_len = SZ_4K / 8,
- .page_size = 16,
-};
-
-/*
- * i2c addr | chip | description
- * 0x50 | HT24LC04 | eeprom (512B)
- */
-
-static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = {
- {
- I2C_BOARD_INFO("24c04", 0x50),
- .platform_data = &at24c04,
- }
-};
-
/*****************************************************************************
* SATA
****************************************************************************/
.n_ports = 2,
};
-static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
-
-static void __init netxbig_v2_sata_power_init(void)
-{
- int i;
- int err;
- int hdd_nb;
-
- if (machine_is_net2big_v2())
- hdd_nb = 2;
- else
- hdd_nb = 5;
-
- /* Power up all hard disks. */
- for (i = 0; i < hdd_nb; i++) {
- err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL);
- if (err == 0) {
- err = gpio_direction_output(
- netxbig_v2_gpio_hdd_power[i], 1);
- /* Free the HDD power GPIOs. This allow user-space to
- * configure them via the gpiolib sysfs interface. */
- gpio_free(netxbig_v2_gpio_hdd_power[i]);
- }
- if (err)
- pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1);
- }
-}
-
/*****************************************************************************
* GPIO keys
****************************************************************************/
};
/*****************************************************************************
- * GPIO LEDs
+ * GPIO extension LEDs
****************************************************************************/
/*
* - address register : bit [0-2] -> GPIO [47-49]
* - data register : bit [0-2] -> GPIO [44-46]
* - enable register : GPIO 29
- *
+ */
+
+static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
+static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
+
+static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
+ .addr = netxbig_v2_gpio_ext_addr,
+ .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
+ .data = netxbig_v2_gpio_ext_data,
+ .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
+ .enable = 29,
+};
+
+/*
* Address register selection:
*
* addr | register
* ----------------------------
* 0 | front LED
* 1 | front LED brightness
- * 2 | HDD LED brightness
- * 3 | HDD1 LED
- * 4 | HDD2 LED
- * 5 | HDD3 LED
- * 6 | HDD4 LED
- * 7 | HDD5 LED
+ * 2 | SATA LED brightness
+ * 3 | SATA0 LED
+ * 4 | SATA1 LED
+ * 5 | SATA2 LED
+ * 6 | SATA3 LED
+ * 7 | SATA4 LED
*
* Data register configuration:
*
* 6 | blink blue on=1 sec and red on=1 sec
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
*
- * data | HDD LED mode
+ * data | SATA LED mode
* -------------------------------------------------
- * 0 | fix blue on
+ * 0 | fix off
* 1 | SATA activity blink
* 2 | fix red on
* 3 | blink blue on=1 sec and blue off=1 sec
* 4 | blink red on=1 sec and red off=1 sec
* 5 | blink blue on=2.5 sec and red on=0.5 sec
* 6 | blink blue on=1 sec and red on=1 sec
- * 7 | blink blue on=0.5 sec and blue off=2.5 sec
+ * 7 | fix blue on
*/
-/*****************************************************************************
- * Timer
- ****************************************************************************/
+static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 2,
+ [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
+ [NETXBIG_LED_TIMER1] = 4,
+ [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
+};
-static void netxbig_v2_timer_init(void)
-{
- kirkwood_tclk = 166666667;
- orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
+static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 1,
+ [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
+ [NETXBIG_LED_TIMER1] = 3,
+ [NETXBIG_LED_TIMER2] = 7,
+};
+
+static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 7,
+ [NETXBIG_LED_SATA] = 1,
+ [NETXBIG_LED_TIMER1] = 3,
+ [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
+};
+
+static struct netxbig_led_timer netxbig_v2_led_timer[] = {
+ [0] = {
+ .delay_on = 500,
+ .delay_off = 500,
+ .mode = NETXBIG_LED_TIMER1,
+ },
+ [1] = {
+ .delay_on = 500,
+ .delay_off = 1000,
+ .mode = NETXBIG_LED_TIMER2,
+ },
+};
+
+#define NETXBIG_LED(_name, maddr, mval, baddr) \
+ { .name = _name, \
+ .mode_addr = maddr, \
+ .mode_val = mval, \
+ .bright_addr = baddr }
+
+static struct netxbig_led net2big_v2_leds_ctrl[] = {
+ NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
+ NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1),
+ NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
+};
+
+static struct netxbig_led_platform_data net2big_v2_leds_data = {
+ .gpio_ext = &netxbig_v2_gpio_ext,
+ .timer = netxbig_v2_led_timer,
+ .num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
+ .leds = net2big_v2_leds_ctrl,
+ .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl),
+};
+
+static struct netxbig_led net5big_v2_leds_ctrl[] = {
+ NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
+ NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1),
+ NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2),
+};
-struct sys_timer netxbig_v2_timer = {
- .init = netxbig_v2_timer_init,
+static struct netxbig_led_platform_data net5big_v2_leds_data = {
+ .gpio_ext = &netxbig_v2_gpio_ext,
+ .timer = netxbig_v2_led_timer,
+ .num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
+ .leds = net5big_v2_leds_ctrl,
+ .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl),
+};
+
+static struct platform_device netxbig_v2_leds = {
+ .name = "leds-netxbig",
+ .id = -1,
+ .dev = {
+ .platform_data = &net2big_v2_leds_data,
+ },
};
/*****************************************************************************
MPP24_GPIO, /* USB mode select */
MPP26_GPIO, /* USB device vbus */
MPP28_GPIO, /* USB enable host vbus */
- MPP29_GPIO, /* CPLD extension ALE */
+ MPP29_GPIO, /* GPIO extension ALE */
MPP34_GPIO, /* Rear Push button */
MPP35_GPIO, /* Inhibit switch power-off */
MPP36_GPIO, /* SATA HDD1 presence */
MPP37_GPIO, /* SATA HDD2 presence */
MPP40_GPIO, /* eSATA presence */
- MPP44_GPIO, /* CPLD extension (data 0) */
- MPP45_GPIO, /* CPLD extension (data 1) */
- MPP46_GPIO, /* CPLD extension (data 2) */
- MPP47_GPIO, /* CPLD extension (addr 0) */
- MPP48_GPIO, /* CPLD extension (addr 1) */
- MPP49_GPIO, /* CPLD extension (addr 2) */
+ MPP44_GPIO, /* GPIO extension (data 0) */
+ MPP45_GPIO, /* GPIO extension (data 1) */
+ MPP46_GPIO, /* GPIO extension (data 2) */
+ MPP47_GPIO, /* GPIO extension (addr 0) */
+ MPP48_GPIO, /* GPIO extension (addr 1) */
+ MPP49_GPIO, /* GPIO extension (addr 2) */
0
};
MPP26_GE1_RXD2,
MPP27_GE1_RXD3,
MPP28_GPIO, /* USB enable host vbus */
- MPP29_GPIO, /* CPLD extension ALE */
+ MPP29_GPIO, /* GPIO extension ALE */
MPP30_GE1_RXCTL,
MPP31_GE1_RXCLK,
MPP32_GE1_TCLKOUT,
MPP41_GPIO, /* SATA HDD3 power */
MPP42_GPIO, /* SATA HDD4 power */
MPP43_GPIO, /* SATA HDD5 power */
- MPP44_GPIO, /* CPLD extension (data 0) */
- MPP45_GPIO, /* CPLD extension (data 1) */
- MPP46_GPIO, /* CPLD extension (data 2) */
- MPP47_GPIO, /* CPLD extension (addr 0) */
- MPP48_GPIO, /* CPLD extension (addr 1) */
- MPP49_GPIO, /* CPLD extension (addr 2) */
+ MPP44_GPIO, /* GPIO extension (data 0) */
+ MPP45_GPIO, /* GPIO extension (data 1) */
+ MPP46_GPIO, /* GPIO extension (data 2) */
+ MPP47_GPIO, /* GPIO extension (addr 0) */
+ MPP48_GPIO, /* GPIO extension (addr 1) */
+ MPP49_GPIO, /* GPIO extension (addr 2) */
0
};
else
kirkwood_mpp_conf(net5big_v2_mpp_config);
- netxbig_v2_sata_power_init();
+ if (machine_is_net2big_v2())
+ lacie_v2_hdd_power_init(2);
+ else
+ lacie_v2_hdd_power_init(5);
kirkwood_ehci_init();
kirkwood_ge00_init(&netxbig_v2_ge00_data);
kirkwood_ge01_init(&netxbig_v2_ge01_data);
kirkwood_sata_init(&netxbig_v2_sata_data);
kirkwood_uart0_init();
- spi_register_board_info(netxbig_v2_spi_slave_info,
- ARRAY_SIZE(netxbig_v2_spi_slave_info));
- kirkwood_spi_init();
- kirkwood_i2c_init();
- i2c_register_board_info(0, netxbig_v2_i2c_info,
- ARRAY_SIZE(netxbig_v2_i2c_info));
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+ if (machine_is_net5big_v2())
+ netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
+ platform_device_register(&netxbig_v2_leds);
platform_device_register(&netxbig_v2_gpio_buttons);
if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
.init_machine = netxbig_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netxbig_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
.init_machine = netxbig_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netxbig_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
+#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
};
static unsigned int openrd_mpp_config[] __initdata = {
+ MPP12_SD_CLK,
+ MPP13_SD_CMD,
+ MPP14_SD_D0,
+ MPP15_SD_D1,
+ MPP16_SD_D2,
+ MPP17_SD_D3,
+ MPP28_GPIO,
MPP29_GPIO,
+ MPP34_GPIO,
+ 0
+};
+
+/* Configure MPP for UART1 */
+static unsigned int openrd_uart1_mpp_config[] __initdata = {
+ MPP13_UART1_TXD,
+ MPP14_UART1_RXD,
0
};
},
};
+static int __initdata uart1;
+
+static int __init sd_uart_selection(char *str)
+{
+ uart1 = -EINVAL;
+
+ /* Default is SD. Change if required, for UART */
+ if (!str)
+ return 0;
+
+ if (!strncmp(str, "232", 3)) {
+ uart1 = 232;
+ } else if (!strncmp(str, "485", 3)) {
+ /* OpenRD-Base doesn't have RS485. Treat is as an
+ * unknown argument & just have default setting -
+ * which is SD */
+ if (machine_is_openrd_base()) {
+ uart1 = -ENODEV;
+ return 1;
+ }
+
+ uart1 = 485;
+ }
+ return 1;
+}
+/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */
+__setup("kw_openrd_init_uart1=", sd_uart_selection);
+
+static int __init uart1_mpp_config(void)
+{
+ kirkwood_mpp_conf(openrd_uart1_mpp_config);
+
+ if (gpio_request(34, "SD_UART1_SEL")) {
+ printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
+ ", gpio: 34\n");
+ return -EIO;
+ }
+
+ if (gpio_request(28, "RS232_RS485_SEL")) {
+ printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
+ ", gpio# 28\n");
+ gpio_free(34);
+ return -EIO;
+ }
+
+ /* Select UART1
+ * Pin # 34: 0 => UART1, 1 => SD */
+ gpio_direction_output(34, 0);
+
+ /* Select RS232 OR RS485
+ * Pin # 28: 0 => RS232, 1 => RS485 */
+ if (uart1 == 232)
+ gpio_direction_output(28, 0);
+ else
+ gpio_direction_output(28, 1);
+
+ gpio_free(34);
+ gpio_free(28);
+
+ return 0;
+}
+
static void __init openrd_init(void)
{
/*
kirkwood_ge01_init(&openrd_ge01_data);
kirkwood_sata_init(&openrd_sata_data);
- kirkwood_sdio_init(&openrd_mvsdio_data);
kirkwood_i2c_init();
ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init();
}
+
+ if (uart1 <= 0) {
+ if (uart1 < 0)
+ printk(KERN_ERR "Invalid kernel parameter to select "
+ "UART1. Defaulting to SD. ERROR CODE: %d\n",
+ uart1);
+
+ /* Select SD
+ * Pin # 34: 0 => UART1, 1 => SD */
+ if (gpio_request(34, "SD_UART1_SEL")) {
+ printk(KERN_ERR "GPIO request failed for SD/UART1 "
+ "selection, gpio: 34\n");
+ } else {
+
+ gpio_direction_output(34, 1);
+ gpio_free(34);
+ kirkwood_sdio_init(&openrd_mvsdio_data);
+ }
+ } else {
+ if (!uart1_mpp_config())
+ kirkwood_uart1_init();
+ }
}
static int __init openrd_pci_init(void)
* IORESOURCE_IO
*/
pp->res[0].name = "PCIe 0 I/O Space";
- pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+ pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
* IORESOURCE_IO
*/
pp->res[0].name = "PCIe 1 I/O Space";
- pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE;
+ pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE;
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
pp->res[0].flags = IORESOURCE_IO;
PXA910-based development board. Since MMP2 is compatible to
ARMv6 architecture.
+config MACH_TETON_BGA
+ bool "Marvell's PXA168 Teton BGA Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Teton BGA Development Board.
+
endmenu
config CPU_PXA168
obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o
obj-$(CONFIG_MACH_FLINT) += flint.o
obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
+obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/mfp-pxa168.h>
#include <mach/pxa168.h>
#include <mach/gpio.h>
+#include <video/pxa168fb.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
#include "common.h"
GPIO115_I2S_BCLK,
GPIO116_I2S_RXD,
GPIO117_I2S_TXD,
+
+ /* LCD */
+ GPIO56_LCD_FCLK_RD,
+ GPIO57_LCD_LCLK_A0,
+ GPIO58_LCD_PCLK_WR,
+ GPIO59_LCD_DENA_BIAS,
+ GPIO60_LCD_DD0,
+ GPIO61_LCD_DD1,
+ GPIO62_LCD_DD2,
+ GPIO63_LCD_DD3,
+ GPIO64_LCD_DD4,
+ GPIO65_LCD_DD5,
+ GPIO66_LCD_DD6,
+ GPIO67_LCD_DD7,
+ GPIO68_LCD_DD8,
+ GPIO69_LCD_DD9,
+ GPIO70_LCD_DD10,
+ GPIO71_LCD_DD11,
+ GPIO72_LCD_DD12,
+ GPIO73_LCD_DD13,
+ GPIO74_LCD_DD14,
+ GPIO75_LCD_DD15,
+ GPIO76_LCD_DD16,
+ GPIO77_LCD_DD17,
+ GPIO78_LCD_DD18,
+ GPIO79_LCD_DD19,
+ GPIO80_LCD_DD20,
+ GPIO81_LCD_DD21,
+ GPIO82_LCD_DD22,
+ GPIO83_LCD_DD23,
+
+ /* Keypad */
+ GPIO109_KP_MKIN1,
+ GPIO110_KP_MKIN0,
+ GPIO111_KP_MKOUT7,
+ GPIO112_KP_MKOUT6,
+ GPIO121_KP_MKIN4,
};
static struct smc91x_platdata smc91x_info = {
{ I2C_BOARD_INFO("wm8753", 0x1b), },
};
+static struct fb_videomode video_modes[] = {
+ [0] = {
+ .pixclock = 30120,
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .hsync_len = 1,
+ .left_margin = 215,
+ .right_margin = 40,
+ .vsync_len = 1,
+ .upper_margin = 34,
+ .lower_margin = 10,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ },
+};
+
+struct pxa168fb_mach_info aspenite_lcd_info = {
+ .id = "Graphic Frame",
+ .modes = video_modes,
+ .num_modes = ARRAY_SIZE(video_modes),
+ .pix_fmt = PIX_FMT_RGB565,
+ .io_pin_allocation_mode = PIN_MODE_DUMB_24,
+ .dumb_mode = DUMB_MODE_RGB888,
+ .active = 1,
+ .panel_rbswap = 0,
+ .invert_pixclock = 0,
+};
+
+static unsigned int aspenite_matrix_key_map[] = {
+ KEY(0, 6, KEY_UP), /* SW 4 */
+ KEY(0, 7, KEY_DOWN), /* SW 5 */
+ KEY(1, 6, KEY_LEFT), /* SW 6 */
+ KEY(1, 7, KEY_RIGHT), /* SW 7 */
+ KEY(4, 6, KEY_ENTER), /* SW 8 */
+ KEY(4, 7, KEY_ESC), /* SW 9 */
+};
+
+static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 8,
+ .matrix_key_map = aspenite_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(aspenite_matrix_key_map),
+ .debounce_interval = 30,
+};
+
static void __init common_init(void)
{
mfp_config(ARRAY_AND_SIZE(common_pin_config));
pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
pxa168_add_ssp(1);
pxa168_add_nand(&aspenite_nand_info);
+ pxa168_add_fb(&aspenite_lcd_info);
+ pxa168_add_keypad(&aspenite_keypad_info);
/* off-chip devices */
platform_device_register(&smc91x_device);
.phys_io = APB_PHYS_BASE,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
.init_machine = common_init,
.phys_io = APB_PHYS_BASE,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
.init_machine = common_init,
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <asm/page.h>
#include <asm/mach/map.h>
#include <mach/addr-map.h>
+#include <mach/cputype.h>
#include "common.h"
+#define MMP_CHIPID (AXI_VIRT_BASE + 0x82c00)
+
+unsigned int mmp_chip_id;
+EXPORT_SYMBOL(mmp_chip_id);
+
static struct map_desc standard_io_desc[] __initdata = {
{
.pfn = __phys_to_pfn(APB_PHYS_BASE),
void __init mmp_map_io(void)
{
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+
+ /* this is early, initialize mmp_chip_id here */
+ mmp_chip_id = __raw_readl(MMP_CHIPID);
}
#include <linux/smc91x.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "common.h"
+#define FLINT_NR_IRQS (IRQ_BOARD_START + 48)
+
static unsigned long flint_pin_config[] __initdata = {
/* UART1 */
GPIO45_UART1_RXD,
.phys_io = APB_PHYS_BASE,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = FLINT_NR_IRQS,
.init_irq = mmp2_init_irq,
.timer = &mmp2_timer,
.init_machine = flint_init,
#include <asm/cputype.h>
/*
- * CPU Stepping OLD_ID CPU_ID CHIP_ID
+ * CPU Stepping CPU_ID CHIP_ID
*
- * PXA168 A0 0x41159263 0x56158400 0x00A0A333
- * PXA910 Y0 0x41159262 0x56158000 0x00F0C910
- * MMP2 Z0 0x560f5811
+ * PXA168 S0 0x56158400 0x0000C910
+ * PXA168 A0 0x56158400 0x00A0A168
+ * PXA910 Y1 0x56158400 0x00F2C920
+ * PXA910 A0 0x56158400 0x00F2C910
+ * PXA910 A1 0x56158400 0x00A0C910
+ * PXA920 Y0 0x56158400 0x00F2C920
+ * PXA920 A0 0x56158400 0x00A0C920
+ * PXA920 A1 0x56158400 0x00A1C920
+ * MMP2 Z0 0x560f5811 0x00F00410
+ * MMP2 Z1 0x560f5811 0x00E00410
+ * MMP2 A0 0x560f5811 0x00A0A610
*/
+extern unsigned int mmp_chip_id;
+
#ifdef CONFIG_CPU_PXA168
-# define __cpu_is_pxa168(id) \
- ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; })
+static inline int cpu_is_pxa168(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+ ((mmp_chip_id & 0xfff) == 0x168);
+}
#else
-# define __cpu_is_pxa168(id) (0)
+#define cpu_is_pxa168() (0)
#endif
+/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */
#ifdef CONFIG_CPU_PXA910
-# define __cpu_is_pxa910(id) \
- ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x80; })
+static inline int cpu_is_pxa910(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+ (((mmp_chip_id & 0xfff) == 0x910) ||
+ ((mmp_chip_id & 0xfff) == 0x920));
+}
#else
-# define __cpu_is_pxa910(id) (0)
+#define cpu_is_pxa910() (0)
#endif
#ifdef CONFIG_CPU_MMP2
-# define __cpu_is_mmp2(id) \
- ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x58; })
+static inline int cpu_is_mmp2(void)
+{
+ return (((cpu_readid_id() >> 8) & 0xff) == 0x58);
#else
-# define __cpu_is_mmp2(id) (0)
+#define cpu_is_mmp2() (0)
#endif
-#define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); })
-#define cpu_is_pxa910() ({ __cpu_is_pxa910(read_cpuid_id()); })
-#define cpu_is_mmp2() ({ __cpu_is_mmp2(read_cpuid_id()); })
-
#endif /* __ASM_MACH_CPUTYPE_H */
#define IRQ_GPIO_NUM 192
#define IRQ_GPIO(x) (IRQ_GPIO_START + (x))
-/* Board IRQ - 64 by default, increase if not enough */
#define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 64)
-#define NR_IRQS (IRQ_BOARD_END)
+#define NR_IRQS (IRQ_BOARD_START)
#endif /* __ASM_MACH_IRQS_H */
#define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2)
#define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3)
+/* Keypad */
+#define GPIO109_KP_MKIN1 MFP_CFG(GPIO109, AF7)
+#define GPIO110_KP_MKIN0 MFP_CFG(GPIO110, AF7)
+#define GPIO111_KP_MKOUT7 MFP_CFG(GPIO111, AF7)
+#define GPIO112_KP_MKOUT6 MFP_CFG(GPIO112, AF7)
+#define GPIO121_KP_MKIN4 MFP_CFG(GPIO121, AF7)
+
#endif /* __ASM_MACH_MFP_PXA168_H */
extern struct sys_timer pxa168_timer;
extern void __init pxa168_init_irq(void);
+extern void pxa168_clear_keypad_wakeup(void);
#include <linux/i2c.h>
#include <mach/devices.h>
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
+#include <video/pxa168fb.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/cputype.h>
extern struct pxa_device_desc pxa168_device_uart1;
extern struct pxa_device_desc pxa168_device_uart2;
extern struct pxa_device_desc pxa168_device_ssp4;
extern struct pxa_device_desc pxa168_device_ssp5;
extern struct pxa_device_desc pxa168_device_nand;
+extern struct pxa_device_desc pxa168_device_fb;
+extern struct pxa_device_desc pxa168_device_keypad;
static inline int pxa168_add_uart(int id)
{
{
return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
}
+
+static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi)
+{
+ return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi));
+}
+
+static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
+{
+ if (cpu_is_pxa168())
+ data->clear_wakeup_event = pxa168_clear_keypad_wakeup;
+
+ return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
+}
+
#endif /* __ASM_MACH_PXA168_H */
#define APMU_FNRST_DIS (1 << 1)
#define APMU_AXIRST_DIS (1 << 0)
+/* Wake Clear Register */
+#define APMU_WAKE_CLR APMU_REG(0x07c)
+
+#define APMU_PXA168_KP_WAKE_CLR (1 << 7)
+#define APMU_PXA168_CFI_WAKE_CLR (1 << 6)
+#define APMU_PXA168_XD_WAKE_CLR (1 << 5)
+#define APMU_PXA168_MSP_WAKE_CLR (1 << 4)
+#define APMU_PXA168_SD4_WAKE_CLR (1 << 3)
+#define APMU_PXA168_SD3_WAKE_CLR (1 << 2)
+#define APMU_PXA168_SD2_WAKE_CLR (1 << 1)
+#define APMU_PXA168_SD1_WAKE_CLR (1 << 0)
+
#endif /* __ASM_MACH_REGS_APMU_H */
#ifndef __ASM_MACH_SYSTEM_H
#define __ASM_MACH_SYSTEM_H
+#include <mach/cputype.h>
+
static inline void arch_idle(void)
{
cpu_do_idle();
static inline void arch_reset(char mode, const char *cmd)
{
- cpu_reset(0);
+ if (cpu_is_pxa168())
+ cpu_reset(0xffff0000);
+ else
+ cpu_reset(0);
}
#endif /* __ASM_MACH_SYSTEM_H */
--- /dev/null
+/*
+ * linux/arch/arm/mach-mmp/include/mach/teton_bga.h
+ *
+ * Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_TETON_BGA_H
+#define __ASM_MACH_TETON_BGA_H
+
+/* GPIOs */
+#define MMC_PWENA_GPIO 27
+#define USBHPENB_GPIO 55
+#define RTC_INT_GPIO 78
+#define LCD_VBLK_EN_GPIO 79
+#define LCD_DVDD_EN_GPIO 80
+#define RST_WIFI_GPIO 81
+#define CF_PWEN_GPIO 82
+#define USB_OC_GPIO 83
+#define PWM_GPIO 84
+#define USBHPENA_GPIO 85
+#define TS_INT_GPIO 86
+#define CIR_GPIO 108
+
+#endif /* __ASM_MACH_TETON_BGA_H */
#include <linux/regulator/machine.h>
#include <linux/regulator/max8649.h>
#include <linux/mfd/max8925.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/addr-map.h>
#include <mach/mfp-mmp2.h>
#include <mach/mmp2.h>
-#include <mach/irqs.h>
#include "common.h"
+#define JASPER_NR_IRQS (IRQ_BOARD_START + 48)
+
static unsigned long jasper_pin_config[] __initdata = {
/* UART1 */
GPIO29_UART1_RXD,
.phys_io = APB_PHYS_BASE,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = JASPER_NR_IRQS,
.init_irq = mmp2_init_irq,
.timer = &mmp2_timer,
.init_machine = jasper_init,
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(keypad, PXA168_KPC, 0, 32000);
static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(lcd, LCD, 0x7f, 312000000);
/* device and clock bindings */
static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
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_keypad, "pxa27x-keypad", NULL),
};
static int __init pxa168_init(void)
.init = pxa168_timer_init,
};
+void pxa168_clear_keypad_wakeup(void)
+{
+ uint32_t val;
+ uint32_t mask = APMU_PXA168_KP_WAKE_CLR;
+
+ /* wake event clear is needed in order to clear keypad interrupt */
+ val = __raw_readl(APMU_WAKE_CLR);
+ __raw_writel(val | mask, APMU_WAKE_CLR);
+}
+
/* on-chip devices */
PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57);
PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
+PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
+PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
--- /dev/null
+/*
+ * linux/arch/arm/mach-mmp/teton_bga.c
+ *
+ * Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ * Author: Mark F. Brown <mark.brown314@gmail.com>
+ *
+ * This code is based on aspenite.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/teton_bga.h>
+
+#include "common.h"
+
+static unsigned long teton_bga_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO107_UART1_TXD,
+ GPIO108_UART1_RXD,
+
+ /* Keypad */
+ GPIO109_KP_MKIN1,
+ GPIO110_KP_MKIN0,
+ GPIO111_KP_MKOUT7,
+ GPIO112_KP_MKOUT6,
+
+ /* I2C Bus */
+ GPIO105_CI2C_SDA,
+ GPIO106_CI2C_SCL,
+
+ /* RTC */
+ GPIO78_GPIO,
+};
+
+static unsigned int teton_bga_matrix_key_map[] = {
+ KEY(0, 6, KEY_ESC),
+ KEY(0, 7, KEY_ENTER),
+ KEY(1, 6, KEY_LEFT),
+ KEY(1, 7, KEY_RIGHT),
+};
+
+static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
+ .matrix_key_rows = 2,
+ .matrix_key_cols = 8,
+ .matrix_key_map = teton_bga_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(teton_bga_matrix_key_map),
+ .debounce_interval = 30,
+};
+
+static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ .irq = gpio_to_irq(RTC_INT_GPIO)
+ },
+};
+
+static void __init teton_bga_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(teton_bga_pin_config));
+
+ /* on-chip devices */
+ pxa168_add_uart(1);
+ pxa168_add_keypad(&teton_bga_keypad_info);
+ pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+}
+
+MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = teton_bga_init,
+MACHINE_END
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/onenand.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "common.h"
+#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 24)
+
static unsigned long ttc_dkb_pin_config[] __initdata = {
/* UART2 */
GPIO47_UART2_RXD,
.phys_io = APB_PHYS_BASE,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = TTCDKB_NR_IRQS,
.init_irq = pxa910_init_irq,
.timer = &pxa910_timer,
.init_machine = ttc_dkb_init,
#ifndef __ASM_ARCH_MSM_VMALLOC_H
#define __ASM_ARCH_MSM_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
#endif
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_ESDHC
select MXC_ULPI if USB_ULPI
choice
default MACH_EUKREA_MBIMXSD25_BASEBOARD
config MACH_EUKREA_MBIMXSD25_BASEBOARD
- prompt "Eukrea MBIMXSD development board"
- bool
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
help
This adds board specific devices that can be found on Eukrea's
MBIMXSD evaluation board.
return get_rate_per(7);
}
+static unsigned long get_rate_esdhc1(struct clk *clk)
+{
+ return get_rate_per(3);
+}
+
+static unsigned long get_rate_esdhc2(struct clk *clk)
+{
+ return get_rate_per(4);
+}
+
static unsigned long get_rate_csi(struct clk *clk)
{
return get_rate_per(0);
DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
+DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
+ &esdhc1_ahb_clk);
+DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
+DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
+ &esdhc2_ahb_clk);
DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
+ &esdhc1_per_clk);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
+ &esdhc2_per_clk);
DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx25-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx25-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx25-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
_REGISTER_CLOCK("imx-wdt.0", NULL, wdt_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
_REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
#include <mach/mx25.h>
#include <mach/devices-common.h>
+extern const struct imx_fec_data imx25_fec_data __initconst;
+#define imx25_add_fec(pdata) \
+ imx_add_fec(&imx25_fec_data, pdata)
+
#define imx25_add_flexcan0(pdata) \
imx_add_flexcan(0, MX25_CAN1_BASE_ADDR, SZ_16K, MX25_INT_CAN1, pdata)
#define imx25_add_flexcan1(pdata) \
imx_add_flexcan(1, MX25_CAN2_BASE_ADDR, SZ_16K, MX25_INT_CAN2, pdata)
-#define imx25_add_imx_i2c0(pdata) \
- imx_add_imx_i2c(0, MX25_I2C1_BASE_ADDR, SZ_16K, MX25_INT_I2C1, pdata)
-#define imx25_add_imx_i2c1(pdata) \
- imx_add_imx_i2c(1, MX25_I2C2_BASE_ADDR, SZ_16K, MX25_INT_I2C2, pdata)
-#define imx25_add_imx_i2c2(pdata) \
- imx_add_imx_i2c(2, MX25_I2C3_BASE_ADDR, SZ_16K, MX25_INT_I2C3, pdata)
-
-#define imx25_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX25_UART1_BASE_ADDR, SZ_16K, MX25_INT_UART1, pdata)
-#define imx25_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX25_UART2_BASE_ADDR, SZ_16K, MX25_INT_UART2, pdata)
-#define imx25_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX25_UART3_BASE_ADDR, SZ_16K, MX25_INT_UART3, pdata)
-#define imx25_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX25_UART4_BASE_ADDR, SZ_16K, MX25_INT_UART4, pdata)
-#define imx25_add_imx_uart4(pdata) \
- imx_add_imx_uart_1irq(4, MX25_UART5_BASE_ADDR, SZ_16K, MX25_INT_UART5, pdata)
+extern const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst;
+#define imx25_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata)
+#define imx25_add_imx_i2c0(pdata) imx25_add_imx_i2c(0, pdata)
+#define imx25_add_imx_i2c1(pdata) imx25_add_imx_i2c(1, pdata)
+#define imx25_add_imx_i2c2(pdata) imx25_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst;
+#define imx25_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst;
+#define imx25_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx25_imx_uart_data[id], pdata)
+#define imx25_add_imx_uart0(pdata) imx25_add_imx_uart(0, pdata)
+#define imx25_add_imx_uart1(pdata) imx25_add_imx_uart(1, pdata)
+#define imx25_add_imx_uart2(pdata) imx25_add_imx_uart(2, pdata)
+#define imx25_add_imx_uart3(pdata) imx25_add_imx_uart(3, pdata)
+#define imx25_add_imx_uart4(pdata) imx25_add_imx_uart(4, pdata)
+extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst;
#define imx25_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v21(MX25_NFC_BASE_ADDR, MX25_INT_NANDFC, pdata)
-
-#define imx25_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX25_CSPI1_BASE_ADDR, SZ_16K, MX25_INT_CSPI1, pdata)
-#define imx25_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX25_CSPI2_BASE_ADDR, SZ_16K, MX25_INT_CSPI2, pdata)
-#define imx25_add_spi_imx2(pdata) \
- imx_add_spi_imx(2, MX25_CSPI3_BASE_ADDR, SZ_16K, MX25_INT_CSPI3, pdata)
+ imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
+
+extern const struct imx_spi_imx_data imx25_spi_imx_data[] __initconst;
+#define imx25_add_spi_imx(id, pdata) \
+ imx_add_spi_imx(&imx25_spi_imx_data[id], pdata)
+#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata)
+#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata)
+#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata)
+
+#define imx25_add_esdhc0(pdata) \
+ imx_add_esdhc(0, MX25_ESDHC1_BASE_ADDR, SZ_16K, MX25_INT_MMC_SDHC1, pdata)
+#define imx25_add_esdhc1(pdata) \
+ imx_add_esdhc(1, MX25_ESDHC2_BASE_ADDR, SZ_16K, MX25_INT_MMC_SDHC2, pdata)
return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
}
-static struct resource mx25_fec_resources[] = {
- {
- .start = MX25_FEC_BASE_ADDR,
- .end = MX25_FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MX25_INT_FEC,
- .end = MX25_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mx25_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mx25_fec_resources),
- .resource = mx25_fec_resources,
-};
-
static struct resource mx25_rtc_resources[] = {
{
.start = MX25_DRYICE_BASE_ADDR,
.resource = mx25_kpp_resources,
};
-static struct resource imx_ssi_resources0[] = {
- {
- .start = MX25_SSI1_BASE_ADDR,
- .end = MX25_SSI1_BASE_ADDR + 0x3fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX25_INT_SSI1,
- .end = MX25_INT_SSI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource imx_ssi_resources1[] = {
- {
- .start = MX25_SSI2_BASE_ADDR,
- .end = MX25_SSI2_BASE_ADDR + 0x3fff,
- .flags = IORESOURCE_MEM
- }, {
- .start = MX25_INT_SSI2,
- .end = MX25_INT_SSI2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_ssi_device0 = {
- .name = "imx-ssi",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_ssi_resources0),
- .resource = imx_ssi_resources0,
-};
-
-struct platform_device imx_ssi_device1 = {
- .name = "imx-ssi",
- .id = 1,
- .num_resources = ARRAY_SIZE(imx_ssi_resources1),
- .resource = imx_ssi_resources1,
-};
-
static struct resource mx25_csi_resources[] = {
{
.start = MX25_CSI_BASE_ADDR,
extern struct platform_device mxc_pwm_device2;
extern struct platform_device mxc_pwm_device3;
extern struct platform_device mxc_keypad_device;
-extern struct platform_device mx25_fec_device;
extern struct platform_device mx25_rtc_device;
extern struct platform_device mx25_fb_device;
extern struct platform_device mxc_wdt;
extern struct platform_device mx25_kpp_device;
-extern struct platform_device imx_ssi_device0;
-extern struct platform_device imx_ssi_device1;
extern struct platform_device mx25_csi_device;
#include <mach/mx25.h>
#include <mach/imx-uart.h>
#include <mach/imxfb.h>
-#include <mach/ssi.h>
#include <mach/audmux.h>
#include "devices-imx25.h"
MX25_PAD_KPP_COL2__AUD5_TXC,
MX25_PAD_KPP_COL1__AUD5_RXD,
MX25_PAD_KPP_COL0__AUD5_TXD,
+ /* CAN */
+ MX25_PAD_GPIO_D__CAN2_RX,
+ MX25_PAD_GPIO_C__CAN2_TX,
};
#define GPIO_LED1 83
},
};
-struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = {
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
imx25_add_imx_uart1(&uart_pdata);
mxc_register_device(&mx25_fb_device, &eukrea_mximxsd_fb_pdata);
- mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata);
+ imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx25_add_flexcan1(NULL);
+ imx25_add_esdhc0(NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/fec.h>
#include <linux/platform_device.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
MX25_PAD_I2C1_DAT__I2C1_DAT,
};
-static struct fec_platform_data mx25_fec_pdata = {
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
imx25_add_imx_uart0(&uart_pdata);
imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info);
mxc_register_device(&mx25_rtc_device, NULL);
- mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+ imx25_add_fec(&mx25_fec_pdata);
i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx25_i2c_devices));
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/fec.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
MX25_PAD_KPP_COL3__KPP_COL3,
};
-static struct fec_platform_data mx25_fec_pdata = {
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
mxc_register_device(&mxc_wdt, NULL);
mx25pdk_fec_reset();
- mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+ imx25_add_fec(&mx25_fec_pdata);
mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data);
}
bool
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
+ select HAVE_EPIT
comment "MX3 platforms:"
bool "Support MX31ADS platforms"
select ARCH_MX31
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
default y
help
bool "Support Phytec pcm043 (i.MX35) platforms"
select ARCH_MX35
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_ESDHC
select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm043 platform. This includes
bool "Support MX35PDK platform"
select ARCH_MX35
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
default n
help
Include support for MX35PDK platform. This includes specific
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_ESDHC
select MXC_ULPI if USB_ULPI
help
Include support for Eukrea CPUIMX35 platform. This includes
default MACH_EUKREA_MBIMXSD35_BASEBOARD
config MACH_EUKREA_MBIMXSD35_BASEBOARD
- prompt "Eukrea MBIMXSD development board"
- bool
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
help
This adds board specific devices that can be found on Eukrea's
MBIMXSD evaluation board.
obj-y := mm.o devices.o cpu.o
CFLAGS_mm.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
CFLAGS_devices.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
-CFLAGS_cpu.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
obj-$(CONFIG_ARCH_MX31) += clock-imx31.o iomux-imx31.o
obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk);
+DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk);
DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
_REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "ata", ata_clk)
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
_REGISTER_CLOCK(NULL, "rng", rng_clk)
- _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1)
_REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
_REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
_REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL);
DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL);
DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL);
DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL);
DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
_REGISTER_CLOCK(NULL, "ata", ata_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
_REGISTER_CLOCK(NULL, "ect", ect_clk)
_REGISTER_CLOCK(NULL, "edio", edio_clk)
_REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK(NULL, "epit", epit1_clk)
- _REGISTER_CLOCK(NULL, "epit", epit2_clk)
+ _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
+ _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
_REGISTER_CLOCK(NULL, "esai", esai_clk)
- _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk)
- _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk)
- _REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
_REGISTER_CLOCK(NULL, "scc", scc_clk)
- _REGISTER_CLOCK(NULL, "sdma", sdma_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
_REGISTER_CLOCK(NULL, "spba", spba_clk)
_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
__raw_writel(cgr2, CCM_BASE + CCM_CGR2);
__raw_writel(cgr3, CCM_BASE + CCM_CGR3);
+ clk_enable(&iim_clk);
+ mx35_read_cpu_rev();
+
+#ifdef CONFIG_MXC_USE_EPIT
+ epit_timer_init(&epit1_clk,
+ MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
mxc_timer_init(&gpt_clk,
MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
+#endif
return 0;
}
};
static struct mx3_cpu_type mx31_cpu_type[] __initdata = {
- { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = CHIP_REV_1_0 },
- { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = CHIP_REV_1_1 },
- { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = CHIP_REV_1_1 },
- { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = CHIP_REV_1_1 },
- { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = CHIP_REV_1_1 },
- { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = CHIP_REV_1_2 },
- { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = CHIP_REV_1_2 },
- { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = CHIP_REV_2_0 },
- { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = CHIP_REV_2_0 },
+ { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = MX3x_CHIP_REV_1_0 },
+ { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 },
+ { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 },
+ { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 },
+ { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 },
};
void __init mx31_read_cpu_rev(void)
u32 i, srev;
/* read SREV register from IIM module */
- srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR + MXC_IIMSREV));
+ srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV));
for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
if (srev == mx31_cpu_type[i].srev) {
printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
}
+
+unsigned int mx35_cpu_rev;
+EXPORT_SYMBOL(mx35_cpu_rev);
+
+void __init mx35_read_cpu_rev(void)
+{
+ u32 rev;
+ char *srev = "unknown";
+
+ rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
+ switch (rev) {
+ case 0x00:
+ mx35_cpu_rev = MX3x_CHIP_REV_1_0;
+ srev = "1.0";
+ break;
+ case 0x10:
+ mx35_cpu_rev = MX3x_CHIP_REV_2_0;
+ srev = "2.0";
+ break;
+ case 0x11:
+ mx35_cpu_rev = MX3x_CHIP_REV_2_1;
+ srev = "2.1";
+ break;
+ }
+
+ printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev);
+}
#include <mach/mx31.h>
#include <mach/devices-common.h>
-#define imx31_add_imx_i2c0(pdata) \
- imx_add_imx_i2c(0, MX31_I2C1_BASE_ADDR, SZ_4K, MX31_INT_I2C1, pdata)
-#define imx31_add_imx_i2c1(pdata) \
- imx_add_imx_i2c(1, MX31_I2C2_BASE_ADDR, SZ_4K, MX31_INT_I2C2, pdata)
-#define imx31_add_imx_i2c2(pdata) \
- imx_add_imx_i2c(2, MX31_I2C3_BASE_ADDR, SZ_4K, MX31_INT_I2C3, pdata)
+extern const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst;
+#define imx31_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata)
+#define imx31_add_imx_i2c0(pdata) imx31_add_imx_i2c(0, pdata)
+#define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata)
+#define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata)
-#define imx31_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX31_UART1_BASE_ADDR, SZ_16K, MX31_INT_UART1, pdata)
-#define imx31_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX31_UART2_BASE_ADDR, SZ_16K, MX31_INT_UART2, pdata)
-#define imx31_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX31_UART3_BASE_ADDR, SZ_16K, MX31_INT_UART3, pdata)
-#define imx31_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX31_UART4_BASE_ADDR, SZ_16K, MX31_INT_UART4, pdata)
-#define imx31_add_imx_uart4(pdata) \
- imx_add_imx_uart_1irq(4, MX31_UART5_BASE_ADDR, SZ_16K, MX31_INT_UART5, pdata)
+extern const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst;
+#define imx31_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata)
+extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst;
+#define imx31_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata)
+#define imx31_add_imx_uart0(pdata) imx31_add_imx_uart(0, pdata)
+#define imx31_add_imx_uart1(pdata) imx31_add_imx_uart(1, pdata)
+#define imx31_add_imx_uart2(pdata) imx31_add_imx_uart(2, pdata)
+#define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata)
+#define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata)
+
+extern const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst;
#define imx31_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v1(MX31_NFC_BASE_ADDR, MX31_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx31_mxc_nand_data, pdata)
-#define imx31_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX31_CSPI1_BASE_ADDR, SZ_4K, MX31_INT_CSPI1, pdata)
-#define imx31_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX31_CSPI2_BASE_ADDR, SZ_4K, MX31_INT_CSPI2, pdata)
-#define imx31_add_spi_imx2(pdata) \
- imx_add_spi_imx(2, MX31_CSPI3_BASE_ADDR, SZ_4K, MX31_INT_CSPI3, pdata)
+extern const struct imx_spi_imx_data imx31_cspi_data[] __initconst;
+#define imx31_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx31_cspi_data[id], pdata)
+#define imx31_add_spi_imx0(pdata) imx31_add_cspi(0, pdata)
+#define imx31_add_spi_imx1(pdata) imx31_add_cspi(1, pdata)
+#define imx31_add_spi_imx2(pdata) imx31_add_cspi(2, pdata)
#include <mach/mx35.h>
#include <mach/devices-common.h>
+extern const struct imx_fec_data imx35_fec_data __initconst;
+#define imx35_add_fec(pdata) \
+ imx_add_fec(&imx35_fec_data, pdata)
+
#define imx35_add_flexcan0(pdata) \
imx_add_flexcan(0, MX35_CAN1_BASE_ADDR, SZ_16K, MX35_INT_CAN1, pdata)
#define imx35_add_flexcan1(pdata) \
imx_add_flexcan(1, MX35_CAN2_BASE_ADDR, SZ_16K, MX35_INT_CAN2, pdata)
-#define imx35_add_imx_i2c0(pdata) \
- imx_add_imx_i2c(0, MX35_I2C1_BASE_ADDR, SZ_4K, MX35_INT_I2C1, pdata)
-#define imx35_add_imx_i2c1(pdata) \
- imx_add_imx_i2c(1, MX35_I2C2_BASE_ADDR, SZ_4K, MX35_INT_I2C2, pdata)
-#define imx35_add_imx_i2c2(pdata) \
- imx_add_imx_i2c(2, MX35_I2C3_BASE_ADDR, SZ_4K, MX35_INT_I2C3, pdata)
+extern const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst;
+#define imx35_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata)
+#define imx35_add_imx_i2c0(pdata) imx35_add_imx_i2c(0, pdata)
+#define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata)
+#define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst;
+#define imx35_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata)
-#define imx35_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX35_UART1_BASE_ADDR, SZ_16K, MX35_INT_UART1, pdata)
-#define imx35_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX35_UART2_BASE_ADDR, SZ_16K, MX35_INT_UART2, pdata)
-#define imx35_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX35_UART3_BASE_ADDR, SZ_16K, MX35_INT_UART3, pdata)
+extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst;
+#define imx35_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata)
+#define imx35_add_imx_uart0(pdata) imx35_add_imx_uart(0, pdata)
+#define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata)
+#define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata)
+extern const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst;
#define imx35_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v21(MX35_NFC_BASE_ADDR, MX35_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx35_mxc_nand_data, pdata)
+
+extern const struct imx_spi_imx_data imx35_cspi_data[] __initconst;
+#define imx35_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx35_cspi_data[id], pdata)
+#define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata)
+#define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata)
-#define imx35_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX35_CSPI1_BASE_ADDR, SZ_4K, MX35_INT_CSPI1, pdata)
-#define imx35_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX35_CSPI2_BASE_ADDR, SZ_4K, MX35_INT_CSPI2, pdata)
+#define imx35_add_esdhc0(pdata) \
+ imx_add_esdhc(0, MX35_ESDHC1_BASE_ADDR, SZ_16K, MX35_INT_MMC_SDHC1, pdata)
+#define imx35_add_esdhc1(pdata) \
+ imx_add_esdhc(1, MX35_ESDHC2_BASE_ADDR, SZ_16K, MX35_INT_MMC_SDHC2, pdata)
+#define imx35_add_esdhc2(pdata) \
+ imx_add_esdhc(2, MX35_ESDHC3_BASE_ADDR, SZ_16K, MX35_INT_MMC_SDHC3, pdata)
.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
};
-#if defined(CONFIG_ARCH_MX35)
-static struct resource mxc_fec_resources[] = {
- {
- .start = MXC_FEC_BASE_ADDR,
- .end = MXC_FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_FEC,
- .end = MXC_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fec_resources),
- .resource = mxc_fec_resources,
-};
-#endif
-
-static struct resource imx_ssi_resources0[] = {
- {
- .start = SSI1_BASE_ADDR,
- .end = SSI1_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX31_INT_SSI1,
- .end = MX31_INT_SSI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource imx_ssi_resources1[] = {
- {
- .start = SSI2_BASE_ADDR,
- .end = SSI2_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM
- }, {
- .start = MX31_INT_SSI2,
- .end = MX31_INT_SSI2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_ssi_device0 = {
- .name = "imx-ssi",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_ssi_resources0),
- .resource = imx_ssi_resources0,
-};
-
-struct platform_device imx_ssi_device1 = {
- .name = "imx-ssi",
- .id = 1,
- .num_resources = ARRAY_SIZE(imx_ssi_resources1),
- .resource = imx_ssi_resources1,
-};
-
static struct resource imx_wdt_resources[] = {
{
.flags = IORESOURCE_MEM,
mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff;
mxc_usbh1_resources[1].start = MXC_INT_USBHS;
mxc_usbh1_resources[1].end = MXC_INT_USBHS;
- imx_ssi_resources0[1].start = MX35_INT_SSI1;
- imx_ssi_resources0[1].end = MX35_INT_SSI1;
- imx_ssi_resources1[1].start = MX35_INT_SSI2;
- imx_ssi_resources1[1].end = MX35_INT_SSI2;
imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
}
extern struct platform_device mx3_ipu;
extern struct platform_device mx3_fb;
extern struct platform_device mx3_camera;
-extern struct platform_device mxc_fec_device;
extern struct platform_device mxcsdhc_device0;
extern struct platform_device mxcsdhc_device1;
extern struct platform_device mxc_otg_udc_device;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
extern struct platform_device mxc_rnga_device;
-extern struct platform_device imx_ssi_device0;
-extern struct platform_device imx_ssi_device1;
-extern struct platform_device imx_ssi_device1;
extern struct platform_device imx_wdt_device0;
extern struct platform_device imx_rtc_device0;
extern struct platform_device imx_kpp_device;
#include <mach/ipu.h>
#include <mach/mx3fb.h>
#include <mach/audmux.h>
-#include <mach/ssi.h>
#include "devices-imx35.h"
#include "devices.h"
MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+ /* CAN2 */
+ MX35_PAD_TX5_RX0__CAN2_TXCAN,
+ MX35_PAD_TX4_RX1__CAN2_RXCAN,
+ /* SDCARD */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
};
#define GPIO_LED1 (2 * 32 + 29)
},
};
-struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = {
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
mxc_register_device(&mx3_fb, &mx3fb_pdata);
- mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata);
+ imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx35_add_flexcan1(NULL);
+ imx35_add_esdhc0(NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <linux/fsl_devices.h>
+#include <linux/i2c-gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
};
static const struct imxi2c_platform_data
-eukrea_cpuimx35_i2c0_data __initconst = {
- .bitrate = 50000,
+ eukrea_cpuimx35_i2c0_data __initconst = {
+ .bitrate = 100000,
};
-#define TSC2007_IRQGPIO (2 * 32 + 2)
-static int ts_get_pendown_state(void)
-{
- int val = 0;
- gpio_free(TSC2007_IRQGPIO);
- gpio_request(TSC2007_IRQGPIO, NULL);
- gpio_direction_input(TSC2007_IRQGPIO);
-
- val = gpio_get_value(TSC2007_IRQGPIO);
-
- gpio_free(TSC2007_IRQGPIO);
- gpio_request(TSC2007_IRQGPIO, NULL);
-
- return val ? 0 : 1;
-}
-
-static int ts_init(void)
-{
- gpio_request(TSC2007_IRQGPIO, NULL);
- return 0;
-}
-
static struct tsc2007_platform_data tsc2007_info = {
.model = 2007,
.x_plate_ohms = 180,
- .get_pendown_state = ts_get_pendown_state,
- .init_platform_hw = ts_init,
};
+#define TSC2007_IRQGPIO (2 * 32 + 2)
static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
};
static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
&imx_wdt_device0,
};
};
static const struct mxc_nand_platform_data
-eukrea_cpuimx35_nand_board_info __initconst = {
+ eukrea_cpuimx35_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
.flash_bbt = 1,
};
-static struct mxc_usbh_platform_data otg_pdata = {
+static struct mxc_usbh_platform_data __maybe_unused otg_pdata = {
.portsc = MXC_EHCI_MODE_UTMI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data usbh1_pdata = {
+static struct mxc_usbh_platform_data __maybe_unused usbh1_pdata = {
.portsc = MXC_EHCI_MODE_SERIAL,
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
MXC_EHCI_IPPUE_DOWN,
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
ARRAY_SIZE(eukrea_cpuimx35_pads));
+ imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
static void mxc_init_audio(void)
{
- mxc_register_device(&imx_ssi_device0, NULL);
+ imx31_add_imx_ssi(0, NULL);
mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
}
/*
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
*
* Author: Fabio Estevam <fabio.estevam@freescale.com>
*
#include <linux/gpio.h>
#include <linux/fsl_devices.h>
+#include <linux/mtd/physmap.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx35.h>
+#include <mach/mxc_ehci.h>
#include "devices-imx35.h"
#include "devices.h"
.flags = IMXUART_HAVE_RTSCTS,
};
+static struct physmap_flash_data mx35pdk_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx35pdk_flash_resource = {
+ .start = MX35_CS0_BASE_ADDR,
+ .end = MX35_CS0_BASE_ADDR + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx35pdk_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx35pdk_flash_data,
+ },
+ .resource = &mx35pdk_flash_resource,
+ .num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
+ &mx35pdk_flash,
};
static struct pad_desc mx35pdk_pads[] = {
/* USBOTG */
MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+ /* USBH1 */
+ MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+ MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
};
/* OTG config */
-static struct fsl_usb2_platform_data usb_pdata = {
+static struct fsl_usb2_platform_data usb_otg_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI_WIDE,
};
+/* USB HOST config */
+static struct mxc_usbh_platform_data usb_host_pdata = {
+ .portsc = MXC_EHCI_MODE_SERIAL,
+ .flags = MXC_EHCI_INTERFACE_SINGLE_UNI |
+ MXC_EHCI_INTERNAL_PHY,
+};
+
/*
* Board specific initialization.
*/
{
mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+ imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+ mxc_register_device(&mxc_otg_udc_device, &usb_otg_pdata);
+
+ mxc_register_device(&mxc_usbh1, &usb_host_pdata);
+
+ imx35_add_mxc_nand(&mx35pdk_nand_board_info);
}
static void __init mx35pdk_timer_init(void)
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
-#include <mach/ssi.h>
#include "devices-imx35.h"
#include "devices.h"
static struct platform_device *devices[] __initdata = {
&pcm043_flash,
- &mxc_fec_device,
&imx_wdt_device0,
};
/* CAN2 */
MX35_PAD_TX5_RX0__CAN2_TXCAN,
MX35_PAD_TX4_RX1__CAN2_RXCAN,
+ /* esdhc */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
};
#define AC97_GPIO_TXFS (1 * 32 + 31)
mdelay(1);
}
-static struct imx_ssi_platform_data pcm043_ssi_pdata = {
+static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
.ac97_reset = pcm043_ac97_cold_reset,
.ac97_warm_reset = pcm043_ac97_warm_reset,
.flags = IMX_SSI_USE_AC97,
MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
MXC_AUDMUX_V2_PDCR_RXDSEL(3));
+ imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
imx35_add_mxc_nand(&pcm037_nand_board_info);
- mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata);
+ imx35_add_imx_ssi(0, &pcm043_ssi_pdata);
imx35_add_imx_uart1(&uart_pdata);
mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
imx35_add_flexcan1(NULL);
+ imx35_add_esdhc0(NULL);
}
static void __init pcm043_timer_init(void)
static int mxc_init_l2x0(void)
{
void __iomem *l2x0_base;
+ void __iomem *clkctl_base;
+/*
+ * First of all, we must repair broken chip settings. There are some
+ * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
+ * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
+ * Workaraound is to setup the correct register setting prior enabling the
+ * L2 cache. This should not hurt already working CPUs, as they are using the
+ * same value
+ */
+#define L2_MEM_VAL 0x10
+
+ clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
+ if (clkctl_base != NULL) {
+ writel(0x00000515, clkctl_base + L2_MEM_VAL);
+ iounmap(clkctl_base);
+ } else {
+ pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
+ }
l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
if (IS_ERR(l2x0_base)) {
default y
select MXC_TZIC
select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
comment "MX5 platforms:"
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for MX51 Babbage platform, also known as MX51EVK in
u-boot. This includes specific configurations for the board and its
config MACH_MX51_3DS
bool "Support MX51PDK (3DS)"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_DEBUG_BOARD
help
Include support for MX51PDK (3DS) platform. This includes specific
config MACH_EUKREA_CPUIMX51
bool "Support Eukrea CPUIMX51 module"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for Eukrea CPUIMX51 platform. This includes
specific configurations for the module and its peripherals.
endchoice
+config MACH_MX51_EFIKAMX
+ bool "Support MX51 Genesi Efika MX nettop"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for Genesi Efika MX nettop. This includes specific
+ configurations for the board and its peripherals.
+
endif
obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o
+obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o
#include <mach/eukrea-baseboards.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
#include <mach/mxc_ehci.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
+#include "devices-imx51.h"
#include "devices.h"
#define CPUIMX51_USBH1_STP (0*32 + 27)
#endif
static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
&serial_device,
#endif
MX51_PAD_USBH1_STP__USBH1_STP,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct imxi2c_platform_data eukrea_cpuimx51_i2c_data = {
+static const
+struct imxi2c_platform_data eukrea_cpuimx51_i2c_data __initconst = {
.bitrate = 100000,
};
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,
ARRAY_SIZE(eukrea_cpuimx51_pads));
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx51_add_imx_uart(0, &uart_pdata);
gpio_request(CPUIMX51_QUARTA_GPIO, "quarta_irq");
gpio_direction_input(CPUIMX51_QUARTA_GPIO);
gpio_free(CPUIMX51_QUARTA_GPIO);
gpio_direction_input(CPUIMX51_QUARTD_GPIO);
gpio_free(CPUIMX51_QUARTD_GPIO);
+ imx51_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_register_device(&mxc_i2c_device1, &eukrea_cpuimx51_i2c_data);
+ imx51_add_imx_i2c(1, &eukrea_cpuimx51_i2c_data);
i2c_register_board_info(1, eukrea_cpuimx51_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx51_i2c_devices));
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx51.h>
-#include <mach/imx-uart.h>
#include <mach/3ds_debugboard.h>
+#include "devices-imx51.h"
#include "devices.h"
#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6)
+#define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28)
static struct pad_desc mx51_3ds_pads[] = {
/* UART1 */
MX51_PAD_KEY_COL3__KEY_COL3,
MX51_PAD_KEY_COL4__KEY_COL4,
MX51_PAD_KEY_COL5__KEY_COL5,
+
+ /* eCSPI2 */
+ MX51_PAD_NANDF_RB2__ECSPI2_SCLK,
+ MX51_PAD_NANDF_RB3__ECSPI2_MISO,
+ MX51_PAD_NANDF_D15__ECSPI2_MOSI,
+ MX51_PAD_NANDF_D12__GPIO_3_28,
};
/* Serial ports */
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static inline void mxc_init_imx_uart(void)
{
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
}
#else /* !SERIAL_IMX */
static inline void mxc_init_imx_uart(void)
}
#endif
+static int mx51_3ds_spi2_cs[] = {
+ MXC_SPI_CS(0),
+ MX51_3DS_ECSPI2_CS,
+};
+
+static const struct spi_imx_master mx51_3ds_ecspi2_pdata __initconst = {
+ .chipselect = mx51_3ds_spi2_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_3ds_spi2_cs),
+};
+
+static struct spi_board_info mx51_3ds_spi_nor_device[] = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = NULL,},
+};
+
/*
* Board specific initialization.
*/
ARRAY_SIZE(mx51_3ds_pads));
mxc_init_imx_uart();
+ imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata);
+ spi_register_board_info(mx51_3ds_spi_nor_device,
+ ARRAY_SIZE(mx51_3ds_spi_nor_device));
+
if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT))
printk(KERN_WARNING "Init of the debugboard failed, all "
"devices on the board are unusable.\n");
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/fsl_devices.h>
+#include <linux/fec.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
#include <mach/mxc_ehci.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
+#include "devices-imx51.h"
#include "devices.h"
#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */
#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */
-#define BABBAGE_PHY_RESET (1*32 +5) /* GPIO_2_5 */
+#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */
+#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */
/* USB_CTRL_1 */
#define MX51_USB_CTRL_1_OFFSET 0x10
#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
#define MX51_USB_PLL_DIV_24_MHZ 0x02
-static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
-};
-
static struct pad_desc mx51babbage_pads[] = {
/* UART1 */
MX51_PAD_UART1_RXD__UART1_RXD,
/* USB HUB reset line*/
MX51_PAD_GPIO_1_7__GPIO_1_7,
+
+ /* FEC */
+ MX51_PAD_EIM_EB2__FEC_MDIO,
+ MX51_PAD_EIM_EB3__FEC_RDAT1,
+ MX51_PAD_EIM_CS2__FEC_RDAT2,
+ MX51_PAD_EIM_CS3__FEC_RDAT3,
+ MX51_PAD_EIM_CS4__FEC_RX_ER,
+ MX51_PAD_EIM_CS5__FEC_CRS,
+ MX51_PAD_NANDF_RB2__FEC_COL,
+ MX51_PAD_NANDF_RB3__FEC_RXCLK,
+ MX51_PAD_NANDF_RB6__FEC_RDAT0,
+ MX51_PAD_NANDF_RB7__FEC_TDAT0,
+ MX51_PAD_NANDF_CS2__FEC_TX_ER,
+ MX51_PAD_NANDF_CS3__FEC_MDC,
+ MX51_PAD_NANDF_CS4__FEC_TDAT1,
+ MX51_PAD_NANDF_CS5__FEC_TDAT2,
+ MX51_PAD_NANDF_CS6__FEC_TDAT3,
+ MX51_PAD_NANDF_CS7__FEC_TX_EN,
+ MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK,
+
+ /* FEC PHY reset line */
+ MX51_PAD_EIM_A20__GPIO_2_14,
};
/* Serial ports */
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static inline void mxc_init_imx_uart(void)
{
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
}
#else /* !SERIAL_IMX */
static inline void mxc_init_imx_uart(void)
}
#endif /* SERIAL_IMX */
-static struct imxi2c_platform_data babbage_i2c_data = {
+static const struct imxi2c_platform_data babbage_i2c_data __initconst = {
.bitrate = 100000,
};
gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
}
+static inline void babbage_fec_reset(void)
+{
+ int ret;
+
+ /* reset FEC PHY */
+ ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0);
+ gpio_set_value(BABBAGE_FEC_PHY_RESET, 0);
+ msleep(1);
+ gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
+}
+
/* This function is board specific as the bit mask for the plldiv will also
be different for other Freescale SoCs, thus a common bitmask is not
possible and cannot get place in /plat-mxc/ehci.c.*/
{
u32 v;
void __iomem *usb_base;
- u32 usbother_base;
+ void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
{
u32 v;
void __iomem *usb_base;
- u32 usbother_base;
+ void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
ARRAY_SIZE(mx51babbage_pads));
mxc_init_imx_uart();
- platform_add_devices(devices, ARRAY_SIZE(devices));
+ babbage_fec_reset();
+ imx51_add_fec(NULL);
- mxc_register_device(&mxc_i2c_device0, &babbage_i2c_data);
- mxc_register_device(&mxc_i2c_device1, &babbage_i2c_data);
+ imx51_add_imx_i2c(0, &babbage_i2c_data);
+ imx51_add_imx_i2c(1, &babbage_i2c_data);
mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data);
if (otg_mode_host)
/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
.phys_io = MX51_AIPS1_BASE_ADDR,
.io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
.init_machine = mxc_board_init,
--- /dev/null
+/*
+ * Copyright (C) 2010 Linaro Limited
+ *
+ * based on code from the following
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved.
+ * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/fsl_devices.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+#include <mach/i2c.h>
+#include <mach/mxc_ehci.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define MX51_USB_PLL_DIV_24_MHZ 0x01
+
+static struct pad_desc mx51efikamx_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+};
+
+/* Serial ports */
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static const struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* SERIAL_IMX */
+
+/* This function is board specific as the bit mask for the plldiv will also
+ * be different for other Freescale SoCs, thus a common bitmask is not
+ * possible and cannot get place in /plat-mxc/ehci.c.
+ */
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ usbother_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET);
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_24_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+ .flags = MXC_EHCI_INTERNAL_PHY,
+};
+
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
+ ARRAY_SIZE(mx51efikamx_pads));
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ mxc_init_imx_uart();
+}
+
+static void __init mx51_efikamx_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 24576000);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx51_efikamx_timer_init,
+};
+
+MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop")
+ /* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */
+ .phys_io = MX51_AIPS1_BASE_ADDR,
+ .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_irq = mx51_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
-static int _clk_ccgr_enable(struct clk *clk)
+static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
{
- u32 reg;
+ u32 reg = __raw_readl(clk->enable_reg);
+
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= mode << clk->enable_shift;
- reg = __raw_readl(clk->enable_reg);
- reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
__raw_writel(reg, clk->enable_reg);
+}
+static int _clk_ccgr_enable(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
return 0;
}
static void _clk_ccgr_disable(struct clk *clk)
{
- u32 reg;
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
+}
+static int _clk_ccgr_enable_inrun(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+ return 0;
}
static void _clk_ccgr_disable_inwait(struct clk *clk)
{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
- reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
}
/*
return 0;
}
+#define clk_nfc_set_parent NULL
+
+static unsigned long clk_nfc_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
+ MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
+ rate = clk_get_rate(clk->parent) / div;
+ WARN_ON(rate == 0);
+ return rate;
+}
+
+static unsigned long clk_nfc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+
+ if (!rate)
+ return -EINVAL;
+
+ div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 8)
+ return -EINVAL;
+
+ return parent_rate / div;
+
+}
+
+static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ div = clk_get_rate(clk->parent) / rate;
+ if (div == 0)
+ div++;
+ if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
+ }
+
+ return 0;
+}
+
static unsigned long clk_usboh3_get_rate(struct clk *clk)
{
u32 reg, prediv, podf;
return ckih2_reference;
}
+static unsigned long clk_emi_slow_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
+ MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
/* External high frequency clock */
static struct clk ckih_clk = {
.get_rate = get_high_reference_clock_rate,
.id = 0,
};
-#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
+static struct clk emi_slow_clk = {
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+ .get_rate = clk_emi_slow_get_rate,
+};
+
+#define DEFINE_CLOCK1(name, i, er, es, pfx, p, s) \
static struct clk name = { \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
- .get_rate = gr, \
- .set_rate = sr, \
+ .get_rate = pfx##_get_rate, \
+ .set_rate = pfx##_set_rate, \
+ .round_rate = pfx##_round_rate, \
+ .set_parent = pfx##_set_parent, \
.enable = _clk_ccgr_enable, \
.disable = _clk_ccgr_disable, \
.parent = p, \
.secondary = s, \
}
-/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
- get_rate, set_rate, parent, secondary); */
+/* eCSPI */
+static unsigned long clk_ecspi_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+
+ pred = (reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET;
+ podf = (reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET;
+
+ return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent),
+ (pred + 1) * (podf + 1));
+}
+
+static int clk_ecspi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ecspi_main_clk = {
+ .parent = &pll3_sw_clk,
+ .get_rate = clk_ecspi_get_rate,
+ .set_parent = clk_ecspi_set_parent,
+};
+
+#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = e, \
+ .disable = d, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
+ DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
/* Shared peripheral bus arbiter */
DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
NULL, NULL, &ipg_clk, NULL);
/* UART */
-DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
- NULL, NULL, &uart_root_clk, NULL);
-DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &uart_root_clk, NULL);
-DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
- NULL, NULL, &uart_root_clk, NULL);
DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
NULL, NULL, &ipg_clk, &aips_tz1_clk);
DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
NULL, NULL, &ipg_clk, &aips_tz1_clk);
DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
NULL, NULL, &ipg_clk, &spba_clk);
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart1_ipg_clk);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart2_ipg_clk);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart3_ipg_clk);
/* GPT */
-DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, &gpt_ipg_clk);
/* I2C */
DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
NULL, NULL, &ipg_clk, NULL);
+/* NFC */
+DEFINE_CLOCK1(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
+ clk_nfc, &emi_slow_clk, NULL);
+
+/* SSI */
+DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
+DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
+
+/* eCSPI */
+DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ &ipg_clk, &spba_clk);
+DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
+DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ &ipg_clk, &aips_tz2_clk);
+DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
+ NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
+
+/* CSPI */
+DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz2_clk);
+DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
+ NULL, NULL, &ipg_clk, &cspi_ipg_clk);
+
+/* SDMA */
+DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
+ NULL, NULL, &ahb_clk, NULL);
+
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
_REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk)
+ _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
+ _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
+ _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
+ _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
+ _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
};
static void clk_tree_init(void)
}
EXPORT_SYMBOL(mx51_revision);
+#ifdef CONFIG_NEON
+
+/*
+ * All versions of the silicon before Rev. 3 have broken NEON implementations.
+ * Dependent on link order - so the assumption is that vfp_init is called
+ * before us.
+ */
+static int __init mx51_neon_fixup(void)
+{
+ if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) {
+ elf_hwcap &= ~HWCAP_NEON;
+ pr_info("Turning off NEON support, detected broken NEON implementation\n");
+ }
+ return 0;
+}
+
+late_initcall(mx51_neon_fixup);
+#endif
+
static int __init post_cpu_init(void)
{
unsigned int reg;
--- /dev/null
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx51.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx51_fec_data __initconst;
+#define imx51_add_fec(pdata) \
+ imx_add_fec(&imx51_fec_data, pdata)
+
+extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst;
+#define imx51_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
+
+extern const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst;
+#define imx51_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx51_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst;
+#define imx51_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx51_imx_uart_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst;
+#define imx51_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx51_mxc_nand_data, pdata)
+
+extern const struct imx_spi_imx_data imx51_cspi_data __initconst;
+#define imx51_add_cspi(pdata) \
+ imx_add_spi_imx(&imx51_cspi_data, pdata)
+
+extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst;
+#define imx51_add_ecspi(id, pdata) \
+ imx_add_spi_imx(&imx51_ecspi_data[id], pdata)
#include <mach/imx-uart.h>
#include <mach/irqs.h>
-static struct resource uart0[] = {
- {
- .start = MX51_UART1_BASE_ADDR,
- .end = MX51_UART1_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_UART1,
- .end = MX51_MXC_INT_UART1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device0 = {
- .name = "imx-uart",
- .id = 0,
- .resource = uart0,
- .num_resources = ARRAY_SIZE(uart0),
-};
-
-static struct resource uart1[] = {
- {
- .start = MX51_UART2_BASE_ADDR,
- .end = MX51_UART2_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_UART2,
- .end = MX51_MXC_INT_UART2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device1 = {
- .name = "imx-uart",
- .id = 1,
- .resource = uart1,
- .num_resources = ARRAY_SIZE(uart1),
-};
-
-static struct resource uart2[] = {
- {
- .start = MX51_UART3_BASE_ADDR,
- .end = MX51_UART3_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_UART3,
- .end = MX51_MXC_INT_UART3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device2 = {
- .name = "imx-uart",
- .id = 2,
- .resource = uart2,
- .num_resources = ARRAY_SIZE(uart2),
-};
-
-static struct resource mxc_fec_resources[] = {
- {
- .start = MX51_MXC_FEC_BASE_ADDR,
- .end = MX51_MXC_FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_FEC,
- .end = MX51_MXC_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fec_resources),
- .resource = mxc_fec_resources,
-};
-
-static struct resource mxc_i2c0_resources[] = {
- {
- .start = MX51_I2C1_BASE_ADDR,
- .end = MX51_I2C1_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_I2C1,
- .end = MX51_MXC_INT_I2C1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device0 = {
- .name = "imx-i2c",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_i2c0_resources),
- .resource = mxc_i2c0_resources,
-};
-
-static struct resource mxc_i2c1_resources[] = {
- {
- .start = MX51_I2C2_BASE_ADDR,
- .end = MX51_I2C2_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_I2C2,
- .end = MX51_MXC_INT_I2C2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device1 = {
- .name = "imx-i2c",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_i2c1_resources),
- .resource = mxc_i2c1_resources,
-};
-
static struct resource mxc_hsi2c_resources[] = {
{
.start = MX51_HSI2C_DMA_BASE_ADDR,
-extern struct platform_device mxc_uart_device0;
-extern struct platform_device mxc_uart_device1;
-extern struct platform_device mxc_uart_device2;
-extern struct platform_device mxc_fec_device;
extern struct platform_device mxc_usbdr_host_device;
extern struct platform_device mxc_usbh1_device;
extern struct platform_device mxc_usbdr_udc_device;
extern struct platform_device mxc_wdt;
-extern struct platform_device mxc_i2c_device0;
-extern struct platform_device mxc_i2c_device1;
extern struct platform_device mxc_hsi2c_device;
extern struct platform_device mxc_keypad_device;
#include <asm/mach/arch.h>
+#include "devices-imx51.h"
#include "devices.h"
#define MBIMX51_TSC2007_GPIO (2*32 + 30)
MX51_PAD_KEY_COL3__KEY_COL3,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
mxc_iomux_v3_setup_multiple_pads(mbimx51_pads,
ARRAY_SIZE(mbimx51_pads));
- mxc_register_device(&mxc_uart_device1, NULL);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx51_add_imx_uart(1, NULL);
+ imx51_add_imx_uart(2, &uart_pdata);
gpio_request(MBIMX51_LED0, "LED0");
gpio_direction_output(MBIMX51_LED0, 1);
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
+#define VMALLOC_END 0xd8000000
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x38000000)
+#define VMALLOC_END 0xf8000000
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
bool "Intel DBPXA250 Development Platform (aka Lubbock)"
select PXA25x
select SA1111
- select PXA_HAVE_BOARD_IRQS
config MACH_MAINSTONE
bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_ZYLONITE
bool
select PXA3xx
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_ZYLONITE300
bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
select PXA3xx
select CPU_PXA930
+config MACH_TAVOREVB3
+ bool "PXA95x Development Platform (aka TavorEVB III)"
+ select CPU_PXA950
+
config MACH_SAAR
bool "PXA930 Handheld Platform (aka SAAR)"
select PXA3xx
select ISA
select I2C_GPIO
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
select PXA_HAVE_ISA_IRQS
select ARCOM_PCMCIA
bool "Arcom/Eurotech ZEUS SBC"
select PXA27x
select ISA
- select PXA_HAVE_BOARD_IRQS
select PXA_HAVE_ISA_IRQS
select ARCOM_PCMCIA
bool "Balloon 3 board"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_CSB726
bool "Enable Cogent CSB726 System On a Module"
bool "Intel Mote 2 Platform"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_STARGATE2
bool "Intel Stargate 2 Platform"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_XCEP
bool "Iskratel Electronics XCEP"
bool "LogicPD PXA270 Card Engine Development Platform"
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_PCM027
bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_PCM990_BASEBOARD
bool "PHYTEC PCM-990 development board"
depends on MACH_COLIBRI
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_COLIBRI300
bool "Toradex Colibri PXA300/310"
select PXA27x
select IWMMXT
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_H5000
bool "HP iPAQ h5000"
select PXA27x
select IWMMXT
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_MIOA701
bool "Mitac Mio A701 Support"
select PXA27x
select IWMMXT
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_EZX_A780
bool "Motorola EZX A780"
depends on PXA_SHARPSL
select PXA25x
select SHARP_LOCOMO
- select PXA_HAVE_BOARD_IRQS
config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
bool "Enable Sharp SL-6000x (Tosa) Support"
depends on PXA_SHARPSL
select PXA25x
- select PXA_HAVE_BOARD_IRQS
config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select PXA25x
- select PXA_HAVE_BOARD_IRQS
config MACH_E330
bool "Toshiba e330"
bool "Zipit Z2 Handheld"
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
endmenu
config CPU_PXA310
bool
select CPU_PXA300
+ select PXA310_ULPI if USB_ULPI
help
PXA310 (codename Monahans-LV)
select HWMON
select SENSORS_MAX1111
-config PXA_HAVE_BOARD_IRQS
+config PXA_HAVE_ISA_IRQS
bool
-config PXA_HAVE_ISA_IRQS
+config PXA310_ULPI
bool
endif
# SoC-specific code
obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o
obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o
-obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o
+obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
obj-$(CONFIG_CPU_PXA300) += pxa300.o
obj-$(CONFIG_CPU_PXA320) += pxa320.o
obj-$(CONFIG_CPU_PXA930) += pxa930.o
obj-$(CONFIG_MACH_ZYLONITE320) += zylonite.o zylonite_pxa320.o
obj-$(CONFIG_MACH_LITTLETON) += littleton.o
obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
+obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o
obj-$(CONFIG_MACH_SAAR) += saar.o
# 3rd Party Dev Platforms
/* Reset, configured as GPIO wakeup source */
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
-
- /* LEDs */
- GPIO9_GPIO, /* NAND activity LED */
- GPIO10_GPIO, /* Heartbeat LED */
-
- /* AC97 */
- GPIO28_AC97_BITCLK,
- GPIO29_AC97_SDATA_IN_0,
- GPIO30_AC97_SDATA_OUT,
- GPIO31_AC97_SYNC,
- GPIO113_AC97_nRESET,
- GPIO95_GPIO,
-
- /* MMC */
- GPIO32_MMC_CLK,
- GPIO92_MMC_DAT_0,
- GPIO109_MMC_DAT_1,
- GPIO110_MMC_DAT_2,
- GPIO111_MMC_DAT_3,
- GPIO112_MMC_CMD,
-
- /* USB Host */
- GPIO88_USBH1_PWR,
- GPIO89_USBH1_PEN,
-
- /* PC Card */
- GPIO48_nPOE,
- GPIO49_nPWE,
- GPIO50_nPIOR,
- GPIO51_nPIOW,
- GPIO85_nPCE_1,
- GPIO54_nPCE_2,
- GPIO79_PSKTSEL,
- GPIO55_nPREG,
- GPIO56_nPWAIT,
- GPIO57_nIOIS16,
};
/******************************************************************************
}
early_param("balloon3_features", parse_balloon3_features);
+/******************************************************************************
+ * Compact Flash slot
+ ******************************************************************************/
+#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
+static unsigned long balloon3_cf_pin_config[] __initdata = {
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+};
+
+static void __init balloon3_cf_init(void)
+{
+ if (!balloon3_has(BALLOON3_FEATURE_CF))
+ return;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config));
+}
+#else
+static inline void balloon3_cf_init(void) {}
+#endif
+
/******************************************************************************
* NOR Flash
******************************************************************************/
******************************************************************************/
#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static unsigned long balloon3_ac97_pin_config[] __initdata = {
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO113_AC97_nRESET,
+ GPIO95_GPIO,
+};
+
static struct ucb1400_pdata vpac270_ucb1400_pdata = {
.irq = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ),
};
if (!balloon3_has(BALLOON3_FEATURE_AUDIO))
return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
pxa_set_ac97_info(NULL);
platform_device_register(&balloon3_ucb1400_device);
}
* Framebuffer
******************************************************************************/
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static unsigned long balloon3_lcd_pin_config[] __initdata = {
+ GPIOxx_LCD_TFT_16BPP,
+ GPIO99_GPIO,
+};
+
static struct pxafb_mode_info balloon3_lcd_modes[] = {
{
.pixclock = 38000,
if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY))
return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
+
ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON");
if (ret) {
pr_err("Requesting BKL-ON GPIO failed!\n");
* SD/MMC card controller
******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static unsigned long balloon3_mmc_pin_config[] __initdata = {
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+};
+
static struct pxamci_platform_data balloon3_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.gpio_card_detect = -1,
static void __init balloon3_mmc_init(void)
{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config));
pxa_set_mci_info(&balloon3_mci_platform_data);
}
#else
* USB Host
******************************************************************************/
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static unsigned long balloon3_uhc_pin_config[] __initdata = {
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+};
+
static struct pxaohci_platform_data balloon3_ohci_info = {
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
{
if (!balloon3_has(BALLOON3_FEATURE_OHCI))
return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config));
pxa_set_ohci_info(&balloon3_ohci_info);
}
#else
* LEDs
******************************************************************************/
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static unsigned long balloon3_led_pin_config[] __initdata = {
+ GPIO9_GPIO, /* NAND activity LED */
+ GPIO10_GPIO, /* Heartbeat LED */
+};
+
struct gpio_led balloon3_gpio_leds[] = {
{
.name = "balloon3:green:idle",
static void __init balloon3_leds_init(void)
{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config));
platform_device_register(&balloon3_leds);
platform_device_register(&balloon3_pcf_leds);
}
balloon3_ts_init();
balloon3_udc_init();
balloon3_uhc_init();
+ balloon3_cf_init();
}
static struct map_desc balloon3_io_desc[] __initdata = {
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = balloon3_map_io,
+ .nr_irqs = BALLOON3_NR_IRQS,
.init_irq = balloon3_init_irq,
.timer = &pxa_timer,
.init_machine = balloon3_init,
extern void cmx255_init(void);
extern void cmx270_init(void);
+/* reserve IRQs for IT8152 */
+#define CMX2XX_NR_IRQS (IRQ_BOARD_START + 40)
+
/* virtual addresses for statically mapped regions */
#define CMX2XX_VIRT_BASE (0xe8000000)
#define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE)
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = cmx2xx_map_io,
+ .nr_irqs = CMX2XX_NR_IRQS,
.init_irq = cmx2xx_init_irq,
.timer = &pxa_timer,
.init_machine = cmx2xx_init,
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/dm9000.h>
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
#include <mach/audio.h>
+#include <mach/pxa3xx-u2d.h>
#include <asm/mach/map.h>
#define GPIO97_RTC_RD (97)
#define GPIO98_RTC_IO (98)
+#define GPIO_ULPI_PHY_RST (127)
+
static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
/* LCD */
GPIO54_LCD_LDD_0,
static inline void cm_x300_init_mmc(void) {}
#endif
+#if defined(CONFIG_PXA310_ULPI)
+static struct clk *pout_clk;
+
+static int cm_x300_ulpi_phy_reset(void)
+{
+ int err;
+
+ /* reset the PHY */
+ err = gpio_request(GPIO_ULPI_PHY_RST, "ulpi reset");
+ if (err) {
+ pr_err("%s: failed to request ULPI reset GPIO: %d\n",
+ __func__, err);
+ return err;
+ }
+
+ gpio_direction_output(GPIO_ULPI_PHY_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO_ULPI_PHY_RST, 1);
+ msleep(10);
+
+ gpio_free(GPIO_ULPI_PHY_RST);
+
+ return 0;
+}
+
+static inline int cm_x300_u2d_init(struct device *dev)
+{
+ int err = 0;
+
+ if (cpu_is_pxa310()) {
+ /* CLK_POUT is connected to the ULPI PHY */
+ pout_clk = clk_get(NULL, "CLK_POUT");
+ if (IS_ERR(pout_clk)) {
+ err = PTR_ERR(pout_clk);
+ pr_err("%s: failed to get CLK_POUT: %d\n",
+ __func__, err);
+ return err;
+ }
+ clk_enable(pout_clk);
+
+ err = cm_x300_ulpi_phy_reset();
+ if (err) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+ }
+
+ return err;
+}
+
+static void cm_x300_u2d_exit(struct device *dev)
+{
+ if (cpu_is_pxa310()) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+}
+
+static struct pxa3xx_u2d_platform_data cm_x300_u2d_platform_data = {
+ .ulpi_mode = ULPI_SER_6PIN,
+ .init = cm_x300_u2d_init,
+ .exit = cm_x300_u2d_exit,
+};
+
+static void cm_x300_init_u2d(void)
+{
+ pxa3xx_set_u2d_info(&cm_x300_u2d_platform_data);
+}
+#else
+static inline void cm_x300_init_u2d(void) {}
+#endif
+
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int cm_x300_ohci_init(struct device *dev)
{
cm_x300_init_da9030();
cm_x300_init_dm9000();
cm_x300_init_lcd();
+ cm_x300_init_u2d();
cm_x300_init_ohci();
cm_x300_init_mmc();
cm_x300_init_nand();
freqs.cpu = policy->cpu;
if (freq_debug)
- pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
- "(SDRAM %d Mhz)\n",
+ pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
(new_freq_mem / 2000) : (new_freq_mem / 1000));
static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
{
- return get_clk_frequency_khz(0);
+ return pxa3xx_get_clk_frequency_khz(0);
}
static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
policy->cpuinfo.min_freq = 104000;
policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
- policy->cur = policy->min = policy->max = get_clk_frequency_khz(0);
+ policy->max = pxa3xx_get_clk_frequency_khz(0);
+ policy->cur = policy->min = policy->max;
if (cpu_is_pxa300() || cpu_is_pxa310())
ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs));
#include <asm/pmu.h>
#include <mach/udc.h>
+#include <mach/pxa3xx-u2d.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/pxa2xx_spi.h>
#include <mach/camera.h>
#include <mach/audio.h>
}
};
+#ifdef CONFIG_PXA3xx
+static struct resource pxa3xx_u2d_resources[] = {
+ [0] = {
+ .start = 0x54100000,
+ .end = 0x54100fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB2,
+ .end = IRQ_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa3xx_device_u2d = {
+ .name = "pxa3xx-u2d",
+ .id = -1,
+ .resource = pxa3xx_u2d_resources,
+ .num_resources = ARRAY_SIZE(pxa3xx_u2d_resources),
+};
+
+void __init pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_u2d, info);
+}
+#endif /* CONFIG_PXA3xx */
+
static struct resource pxafb_resources[] = {
[0] = {
.start = 0x44000000,
extern struct platform_device pxa3xx_device_mci3;
extern struct platform_device pxa25x_device_udc;
extern struct platform_device pxa27x_device_udc;
+extern struct platform_device pxa3xx_device_u2d;
extern struct platform_device pxa_device_fb;
extern struct platform_device pxa_device_ffuart;
extern struct platform_device pxa_device_btuart;
#include <mach/pxafb.h>
#include <mach/ohci.h>
#include <mach/mmc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <plat/i2c.h>
#include <mach/camera.h>
#include <mach/pxa2xx_spi.h>
#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
+#include <mach/eseries-irq.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/udc.h>
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e330_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e350_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e400_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e740_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e750_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e800_init,
#include <mach/ohci.h>
#include <plat/i2c.h>
#include <mach/hardware.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/camera.h>
#include "devices.h"
#include "generic.h"
+#define EZX_NR_IRQS (IRQ_BOARD_START + 24)
+
#define GPIO12_A780_FLIP_LID 12
#define GPIO15_A1200_FLIP_LID 15
#define GPIO15_A910_FLIP_LID 15
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = a780_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = e680_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = a1200_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = a910_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = e6_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = e2_init,
return pxa25x_get_clk_frequency_khz(info);
else if (cpu_is_pxa27x())
return pxa27x_get_clk_frequency_khz(info);
- else
- return pxa3xx_get_clk_frequency_khz(info);
+ return 0;
}
EXPORT_SYMBOL(get_clk_frequency_khz);
return pxa25x_get_memclk_frequency_10khz();
else if (cpu_is_pxa27x())
return pxa27x_get_memclk_frequency_10khz();
- else
- return pxa3xx_get_memclk_frequency_10khz();
+ return 0;
}
EXPORT_SYMBOL(get_memclk_frequency_10khz);
#ifdef CONFIG_PXA3xx
extern unsigned pxa3xx_get_clk_frequency_khz(int);
-extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
extern void pxa3xx_clear_reset_status(unsigned int);
#else
#define pxa3xx_get_clk_frequency_khz(x) (0)
-#define pxa3xx_get_memclk_frequency_10khz() (0)
static inline void pxa3xx_clear_reset_status(unsigned int mask) {}
#endif
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = HX4700_NR_IRQS,
.init_irq = pxa27x_init_irq,
.init_machine = hx4700_init,
.timer = &pxa_timer,
#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD)
+#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 4)
+
extern int balloon3_has(enum balloon3_features feature);
#endif
#define TMIO_SD_IRQ IRQ_TMIO(1)
#define TMIO_USB_IRQ IRQ_TMIO(2)
+#define ESERIES_NR_IRQS (IRQ_BOARD_START + 16)
* <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
* == 0x3 for pxa300/pxa310/pxa320
*/
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
#define __cpu_is_pxa2xx(id) \
({ \
unsigned int _id = (id) >> 13 & 0x7; \
_id <= 0x2; \
})
+#else
+#define __cpu_is_pxa2xx(id) (0)
+#endif
+#ifdef CONFIG_PXA3xx
#define __cpu_is_pxa3xx(id) \
({ \
unsigned int _id = (id) >> 13 & 0x7; \
_id == 0x3; \
})
+#else
+#define __cpu_is_pxa3xx(id) (0)
+#endif
+#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
#define __cpu_is_pxa93x(id) \
({ \
unsigned int _id = (id) >> 4 & 0xfff; \
_id == 0x683 || _id == 0x693; \
})
+#else
+#define __cpu_is_pxa93x(id) (0)
+#endif
#define cpu_is_pxa2xx() \
({ \
#define PCIBIOS_MIN_IO 0
#define PCIBIOS_MIN_MEM 0
#define pcibios_assign_all_busses() 1
+#define ARCH_HAS_DMA_SET_COHERENT_MASK
#endif
-
#endif /* _ASM_ARCH_HARDWARE_H */
#define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO
#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
+#define HX4700_NR_IRQS (IRQ_BOARD_START + 70)
/*
* PXA GPIOs
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <mach/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
/*
* The following interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
- * these. There will be 16 IRQs by default. If it is not enough,
- * IRQ_BOARD_END is allowed be customized for each board, but keep
- * the numbers within sensible limits and in descending order, so
- * when multiple config options are selected, the maximum will be
- * used.
+ * these.
+ * 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)
-#if defined(CONFIG_MACH_H4700)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 70)
-#elif defined(CONFIG_MACH_ZYLONITE)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 32)
-#elif defined(CONFIG_PXA_EZX)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 23)
-#else
-#define IRQ_BOARD_END (IRQ_BOARD_START + 16)
-#endif
-
-/*
- * Figure out the MAX IRQ number.
- *
- * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
- * Otherwise, we have the standard IRQs only.
- */
-#ifdef CONFIG_SA1111
-#define NR_IRQS (IRQ_BOARD_END + 55)
-#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
-#define NR_IRQS (IRQ_BOARD_END)
-#else
#define NR_IRQS (IRQ_BOARD_START)
-#endif
-
-/* add IT8152 IRQs beyond BOARD_END */
-#ifdef CONFIG_PCI_HOST_ITE8152
-#define IT8152_LAST_IRQ (IRQ_BOARD_END + 40)
-
-#if NR_IRQS < (IT8152_LAST_IRQ+1)
-#undef NR_IRQS
-#define NR_IRQS (IT8152_LAST_IRQ+1)
-#endif
-
-#endif /* CONFIG_PCI_HOST_ITE8152 */
#endif /* __ASM_MACH_IRQS_H */
#define EXT0_GPIO_BASE (NR_BUILTIN_GPIO)
#define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x))
+#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8)
+
#endif /* __ASM_ARCH_LITTLETON_H */
#define LPD270_USBC_IRQ LPD270_IRQ(2)
#define LPD270_ETHERNET_IRQ LPD270_IRQ(3)
#define LPD270_AC97_IRQ LPD270_IRQ(4)
+#define LPD270_NR_IRQS (IRQ_BOARD_START + 5)
#endif
#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
+#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16)
+#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55)
+
#ifndef __ASSEMBLY__
extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
#endif
#define IRQ_MAGICIAN_BT (IRQ_BOARD_START + 2)
#define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3)
+#define MAGICIAN_NR_IRQS (IRQ_BOARD_START + 8)
+
/*
* CPLD EGPIOs
*/
#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15)
+#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16)
+
#endif
#define nBE0_GPIO_60 MFP_CFG(nBE0, AF0)
#define nBE1_GPIO_61 MFP_CFG(nBE1, AF0)
#define RDY_GPIO_62 MFP_CFG(RDY, AF0)
+#define PMIC_INT_GPIO83 MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH)
/* Chip Select */
#define DF_nCS0_nCS2 MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
#define GPIO63_CI2C_SCL MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
#define GPIO64_CI2C_SDA MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
+#define GPIO73_CI2C_SCL MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH)
+#define GPIO74_CI2C_SDA MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH)
+
#define GPIO77_CI2C_SCL MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
#define GPIO78_CI2C_SDA MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
#define GPIO69_UART1_CTS MFP_CFG(GPIO69, AF2)
#define GPIO70_UART1_RTS MFP_CFG(GPIO70, AF2)
+#define GPIO53_UART1_TXD MFP_CFG(GPIO53, AF2)
+#define GPIO54_UART1_RXD MFP_CFG(GPIO54, AF2)
+
/* UART2 - BTUART */
#define GPIO91_UART2_RXD MFP_CFG(GPIO91, AF1)
#define GPIO92_UART2_TXD MFP_CFG(GPIO92, AF1)
#define PCM027_MMCDET_IRQ PCM027_IRQ(2)
#define PCM027_PM_5V_IRQ PCM027_IRQ(3)
+#define PCM027_NR_IRQS (IRQ_BOARD_START + 32)
+
/* I2C RTC */
#define PCM027_RTC_IRQ_GPIO 0
#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
#define POODLE_LOCOMO_GPIO_232VCC_ON LOCOMO_GPIO(12)
#define POODLE_LOCOMO_GPIO_JK_B LOCOMO_GPIO(13)
+#define POODLE_NR_IRQS (IRQ_BOARD_START + 4) /* 4 for LoCoMo */
+
extern struct platform_device poodle_locomo_device;
#endif /* __ASM_ARCH_POODLE_H */
--- /dev/null
+/*
+ * PXA3xx U2D header
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * 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 __PXA310_U2D__
+#define __PXA310_U2D__
+
+#include <linux/usb/ulpi.h>
+
+struct pxa3xx_u2d_platform_data {
+
+#define ULPI_SER_6PIN (1 << 0)
+#define ULPI_SER_3PIN (1 << 1)
+ unsigned int ulpi_mode;
+
+ int (*init)(struct device *);
+ void (*exit)(struct device *);
+};
+
+
+/* Start PXA3xx U2D host */
+int pxa3xx_u2d_start_hc(struct usb_bus *host);
+/* Stop PXA3xx U2D host */
+void pxa3xx_u2d_stop_hc(struct usb_bus *host);
+
+extern void pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info);
+
+#endif /* __PXA310_U2D__ */
/* Jacket Scoop */
#define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
+#define TOSA_NR_IRQS (IRQ_BOARD_START + TC6393XB_NR_IRQS)
/*
* SCOOP2 internal GPIOs
*/
#ifndef _MACH_ZEUS_H
#define _MACH_ZEUS_H
+#define ZEUS_NR_IRQS (IRQ_BOARD_START + 48)
+
/* Physical addresses */
#define ZEUS_FLASH_PHYS PXA_CS0_PHYS
#define ZEUS_ETH0_PHYS PXA_CS1_PHYS
#define EXT_GPIO(x) (128 + (x))
+#define ZYLONITE_NR_IRQS (IRQ_BOARD_START + 32)
+
/* the following variables are processor specific and initialized
* by the corresponding zylonite_pxa3xx_init()
*/
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/pxa2xx_spi.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/littleton.h>
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
.boot_params = 0xa0000100,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
+ .nr_irqs = LITTLETON_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = littleton_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = lpd270_map_io,
+ .nr_irqs = LPD270_NR_IRQS,
.init_irq = lpd270_init_irq,
.timer = &pxa_timer,
.init_machine = lpd270_init,
};
static struct sa1111_platform_data sa1111_info = {
- .irq_base = IRQ_BOARD_END,
+ .irq_base = LUBBOCK_SA1111_IRQ_BASE,
};
static struct platform_device sa1111_device = {
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = lubbock_map_io,
+ .nr_irqs = LUBBOCK_NR_IRQS,
.init_irq = lubbock_init_irq,
.timer = &pxa_timer,
.init_machine = lubbock_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = MAGICIAN_NR_IRQS,
.init_irq = pxa27x_init_irq,
.init_machine = magician_init,
.timer = &pxa_timer,
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include "generic.h"
#include "devices.h"
.boot_params = 0xa0000100, /* BLOB boot parameter setting */
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = mainstone_map_io,
+ .nr_irqs = MAINSTONE_NR_IRQS,
.init_irq = mainstone_init_irq,
.timer = &pxa_timer,
.init_machine = mainstone_init,
#include <mach/pxa27x.h>
#include <mach/regs-rtc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/udc.h>
},
};
+static struct i2c_pxa_platform_data palm27x_i2c_power_info = {
+ .use_pio = 1,
+};
+
void __init palm27x_pmic_init(void)
{
i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info));
- pxa27x_set_i2c_power_info(NULL);
+ pxa27x_set_i2c_power_info(&palm27x_i2c_power_info);
}
#endif
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pcm027_map_io,
+ .nr_irqs = PCM027_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = pcm027_init,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_poodle,
.map_io = pxa_map_io,
+ .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
.init_machine = poodle_init,
--- /dev/null
+/*
+ * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c
+ *
+ * code specific to pxa3xx aka Monahans
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il>
+ * initial version: pxa310 USB Host mode support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-u2d.h>
+#include <mach/pxa3xx-u2d.h>
+
+struct pxa3xx_u2d_ulpi {
+ struct clk *clk;
+ void __iomem *mmio_base;
+
+ struct otg_transceiver *otg;
+ unsigned int ulpi_mode;
+};
+
+static struct pxa3xx_u2d_ulpi *u2d;
+
+static inline u32 u2d_readl(u32 reg)
+{
+ return __raw_readl(u2d->mmio_base + reg);
+}
+
+static inline void u2d_writel(u32 reg, u32 val)
+{
+ __raw_writel(val, u2d->mmio_base + reg);
+}
+
+#if defined(CONFIG_PXA310_ULPI)
+enum u2d_ulpi_phy_mode {
+ SYNCH = 0,
+ CARKIT = (1 << 0),
+ SER_3PIN = (1 << 1),
+ SER_6PIN = (1 << 2),
+ LOWPOWER = (1 << 3),
+};
+
+static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void)
+{
+ return (u2d_readl(U2DOTGUSR) >> 28) & 0xF;
+}
+
+static int pxa310_ulpi_poll(void)
+{
+ int timeout = 50000;
+
+ while (timeout--) {
+ if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN))
+ return 0;
+
+ cpu_relax();
+ }
+
+ pr_warning("%s: ULPI access timed out!\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+static int pxa310_ulpi_read(struct otg_transceiver *otg, u32 reg)
+{
+ int err;
+
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+ return -EBUSY;
+ }
+
+ u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16));
+ msleep(5);
+
+ err = pxa310_ulpi_poll();
+ if (err)
+ return err;
+
+ return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA;
+}
+
+static int pxa310_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
+{
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+ return -EBUSY;
+ }
+
+ u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8));
+ msleep(5);
+
+ return pxa310_ulpi_poll();
+}
+
+struct otg_io_access_ops pxa310_ulpi_access_ops = {
+ .read = pxa310_ulpi_read,
+ .write = pxa310_ulpi_write,
+};
+
+static void pxa310_otg_transceiver_rtsm(void)
+{
+ u32 u2dotgcr;
+
+ /* put PHY to sync mode */
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_RTSM | U2DOTGCR_UTMID;
+ u2d_writel(U2DOTGCR, u2dotgcr);
+ msleep(10);
+
+ /* setup OTG sync mode */
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_ULAF;
+ u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+ u2d_writel(U2DOTGCR, u2dotgcr);
+}
+
+static int pxa310_start_otg_host_transcvr(struct usb_bus *host)
+{
+ int err;
+
+ pxa310_otg_transceiver_rtsm();
+
+ err = otg_init(u2d->otg);
+ if (err) {
+ pr_err("OTG transceiver init failed");
+ return err;
+ }
+
+ err = otg_set_vbus(u2d->otg, 1);
+ if (err) {
+ pr_err("OTG transceiver VBUS set failed");
+ return err;
+ }
+
+ err = otg_set_host(u2d->otg, host);
+ if (err)
+ pr_err("OTG transceiver Host mode set failed");
+
+ return err;
+}
+
+static int pxa310_start_otg_hc(struct usb_bus *host)
+{
+ u32 u2dotgcr;
+ int err;
+
+ /* disable USB device controller */
+ u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE);
+ u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID);
+ u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+
+ err = pxa310_start_otg_host_transcvr(host);
+ if (err)
+ return err;
+
+ /* set xceiver mode */
+ if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL)
+ u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS);
+ else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL)
+ u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS);
+
+ /* start OTG host controller */
+ u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF;
+ u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF));
+
+ return 0;
+}
+
+static void pxa310_stop_otg_hc(void)
+{
+ pxa310_otg_transceiver_rtsm();
+
+ otg_set_host(u2d->otg, NULL);
+ otg_set_vbus(u2d->otg, 0);
+ otg_shutdown(u2d->otg);
+}
+
+static void pxa310_u2d_setup_otg_hc(void)
+{
+ u32 u2dotgcr;
+
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID;
+ u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+ u2d_writel(U2DOTGCR, u2dotgcr);
+ msleep(5);
+ u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE);
+ msleep(5);
+ u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+}
+
+static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+ unsigned int ulpi_mode = ULPI_OTG_DRVVBUS;
+
+ if (pdata) {
+ if (pdata->ulpi_mode & ULPI_SER_6PIN)
+ ulpi_mode |= ULPI_IC_6PIN_SERIAL;
+ else if (pdata->ulpi_mode & ULPI_SER_3PIN)
+ ulpi_mode |= ULPI_IC_3PIN_SERIAL;
+ }
+
+ u2d->ulpi_mode = ulpi_mode;
+
+ u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode);
+ if (!u2d->otg)
+ return -ENOMEM;
+
+ u2d->otg->io_priv = u2d->mmio_base;
+
+ return 0;
+}
+
+static void pxa310_otg_exit(void)
+{
+ kfree(u2d->otg);
+}
+#else
+static inline void pxa310_u2d_setup_otg_hc(void) {}
+static inline int pxa310_start_otg_hc(struct usb_bus *host)
+{
+ return 0;
+}
+static inline void pxa310_stop_otg_hc(void) {}
+static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+ return 0;
+}
+static inline void pxa310_otg_exit(void) {}
+#endif /* CONFIG_PXA310_ULPI */
+
+int pxa3xx_u2d_start_hc(struct usb_bus *host)
+{
+ int err = 0;
+
+ /* In case the PXA3xx ULPI isn't used, do nothing. */
+ if (!u2d)
+ return 0;
+
+ clk_enable(u2d->clk);
+
+ if (cpu_is_pxa310()) {
+ pxa310_u2d_setup_otg_hc();
+ err = pxa310_start_otg_hc(host);
+ }
+
+ return err;
+}
+
+void pxa3xx_u2d_stop_hc(struct usb_bus *host)
+{
+ /* In case the PXA3xx ULPI isn't used, do nothing. */
+ if (!u2d)
+ return;
+
+ if (cpu_is_pxa310())
+ pxa310_stop_otg_hc();
+
+ clk_disable(u2d->clk);
+}
+
+static int pxa3xx_u2d_probe(struct platform_device *pdev)
+{
+ struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *r;
+ int err;
+
+ u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
+ if (!u2d) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ u2d->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(u2d->clk)) {
+ dev_err(&pdev->dev, "failed to get u2d clock\n");
+ err = PTR_ERR(u2d->clk);
+ goto err_free_mem;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no IO memory resource defined\n");
+ err = -ENODEV;
+ goto err_put_clk;
+ }
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ err = -EBUSY;
+ goto err_put_clk;
+ }
+
+ u2d->mmio_base = ioremap(r->start, resource_size(r));
+ if (!u2d->mmio_base) {
+ dev_err(&pdev->dev, "ioremap() failed\n");
+ err = -ENODEV;
+ goto err_free_res;
+ }
+
+ if (pdata->init) {
+ err = pdata->init(&pdev->dev);
+ if (err)
+ goto err_free_io;
+ }
+
+ /* Only PXA310 U2D has OTG functionality */
+ if (cpu_is_pxa310()) {
+ err = pxa310_otg_init(pdata);
+ if (err)
+ goto err_free_plat;
+ }
+
+ platform_set_drvdata(pdev, &u2d);
+
+ return 0;
+
+err_free_plat:
+ if (pdata->exit)
+ pdata->exit(&pdev->dev);
+err_free_io:
+ iounmap(u2d->mmio_base);
+err_free_res:
+ release_mem_region(r->start, resource_size(r));
+err_put_clk:
+ clk_put(u2d->clk);
+err_free_mem:
+ kfree(u2d);
+ return err;
+}
+
+static int pxa3xx_u2d_remove(struct platform_device *pdev)
+{
+ struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *r;
+
+ if (cpu_is_pxa310()) {
+ pxa310_stop_otg_hc();
+ pxa310_otg_exit();
+ }
+
+ if (pdata->exit)
+ pdata->exit(&pdev->dev);
+
+ platform_set_drvdata(pdev, NULL);
+ iounmap(u2d->mmio_base);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_put(u2d->clk);
+
+ kfree(u2d);
+
+ return 0;
+}
+
+static struct platform_driver pxa3xx_u2d_ulpi_driver = {
+ .driver = {
+ .name = "pxa3xx-u2d",
+ .owner = THIS_MODULE,
+ },
+ .probe = pxa3xx_u2d_probe,
+ .remove = pxa3xx_u2d_remove,
+};
+
+static int pxa3xx_u2d_ulpi_init(void)
+{
+ return platform_driver_register(&pxa3xx_u2d_ulpi_driver);
+}
+module_init(pxa3xx_u2d_ulpi_init);
+
+static void __exit pxa3xx_u2d_ulpi_exit(void)
+{
+ platform_driver_unregister(&pxa3xx_u2d_ulpi_driver);
+}
+module_exit(pxa3xx_u2d_ulpi_exit);
+
+MODULE_DESCRIPTION("PXA3xx U2D ULPI driver");
+MODULE_AUTHOR("Igor Grinberg");
+MODULE_LICENSE("GPL v2");
return CLK / 1000;
}
-/*
- * Return the current static memory controller clock frequency
- * in units of 10kHz
- */
-unsigned int pxa3xx_get_memclk_frequency_10khz(void)
-{
- unsigned long acsr;
- unsigned int smcfs, clk = 0;
-
- acsr = ACSR;
-
- smcfs = (acsr >> 23) & 0x7;
- clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK;
-
- return (clk / 10000);
-}
-
void pxa3xx_clear_reset_status(unsigned int mask)
{
/* RESET_STATUS_* has a 1:1 mapping with ARSR */
INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
- INIT_CLKREG(&clk_pxa3xx_u2d, NULL, "U2DCLK"),
+ INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL),
INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL),
INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL),
static int __init pxa930_init(void)
{
- if (cpu_is_pxa930() || cpu_is_pxa935()) {
+ if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
mfp_init_base(io_p2v(MFPR_BASE));
mfp_init_addr(pxa930_mfp_addr_map);
}
#include "devices.h"
#include "generic.h"
+#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8)
+
/* Bluetooth */
#define SG2_BT_RESET 81
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
+ .nr_irqs = STARGATE_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = stargate2_init,
#include <mach/pxa930.h>
#include <mach/pxafb.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include "devices.h"
#include "generic.h"
--- /dev/null
+/*
+ * linux/arch/arm/mach-pxa/tavorevb3.c
+ *
+ * Support for the Marvell EVB3 Development Platform.
+ *
+ * Copyright: (C) Copyright 2008-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa930.h>
+
+#include <plat/i2c.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define TAVOREVB3_NR_IRQS (IRQ_BOARD_START + 24)
+
+static mfp_cfg_t evb3_mfp_cfg[] __initdata = {
+ /* UART */
+ GPIO53_UART1_TXD,
+ GPIO54_UART1_RXD,
+
+ /* PMIC */
+ PMIC_INT_GPIO83,
+};
+
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct pm860x_touch_pdata evb3_touch = {
+ .gpadc_prebias = 1,
+ .slot_cycle = 1,
+ .tsi_prebias = 6,
+ .pen_prebias = 16,
+ .pen_prechg = 2,
+ .res_x = 300,
+};
+
+static struct pm860x_backlight_pdata evb3_backlight[] = {
+ {
+ .id = PM8606_ID_BACKLIGHT,
+ .iset = PM8606_WLED_CURRENT(24),
+ .flags = PM8606_BACKLIGHT1,
+ },
+ {},
+};
+
+static struct pm860x_led_pdata evb3_led[] = {
+ {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_BLUE,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_BLUE,
+ },
+};
+
+static struct pm860x_platform_data evb3_pm8607_info = {
+ .touch = &evb3_touch,
+ .backlight = &evb3_backlight[0],
+ .led = &evb3_led[0],
+ .companion_addr = 0x10,
+ .irq_mode = 0,
+ .irq_base = IRQ_BOARD_START,
+
+ .i2c_port = GI2C_PORT,
+};
+
+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)),
+ },
+};
+
+static void __init evb3_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(evb3_i2c_info));
+}
+#else
+static inline void evb3_init_i2c(void) {}
+#endif
+
+static void __init evb3_init(void)
+{
+ /* initialize MFP configurations */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(evb3_mfp_cfg));
+
+ pxa_set_ffuart_info(NULL);
+
+ evb3_init_i2c();
+}
+
+MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)")
+ .phys_io = 0x40000000,
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .nr_irqs = TAVOREVB3_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = evb3_init,
+MACHINE_END
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_tosa,
.map_io = pxa_map_io,
+ .nr_irqs = TOSA_NR_IRQS,
.init_irq = pxa25x_init_irq,
.init_machine = tosa_init,
.timer = &pxa_timer,
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
static struct pxamci_platform_data vpac270_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_power = -1,
.gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N,
.gpio_card_ro = GPIO52_VPAC270_SD_READONLY,
.detect_delay_ms = 200,
#include <mach/z2.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/pxa2xx_spi.h>
#include <plat/i2c.h>
.io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc),
.boot_params = 0xa0000100,
.map_io = zeus_map_io,
+ .nr_irqs = ZEUS_NR_IRQS,
.init_irq = zeus_init_irq,
.timer = &pxa_timer,
.init_machine = zeus_init,
#include <mach/zylonite.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <plat/pxa3xx_nand.h>
#include "devices.h"
.boot_params = 0xa0000100,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
+ .nr_irqs = ZYLONITE_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = zylonite_init,
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x1c000000)
+#define VMALLOC_END 0xdc000000
/*
* arch/arm/mach-shark/include/mach/vmalloc.h
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
--- /dev/null
+if ARCH_TCC8K
+
+comment "TCC8000 systems:"
+
+config MACH_TCC8000_SDK
+ bool "Telechips TCC8000-SDK development kit"
+ default y
+ help
+ Support for the Telechips TCC8000-SDK board.
+
+endif
--- /dev/null
+#
+# Makefile for TCC8K boards and common files.
+#
+
+# Common support
+obj-y += clock.o irq.o time.o io.o devices.o
+
+# Board specific support
+obj-$(CONFIG_MACH_TCC8000_SDK) += board-tcc8000-sdk.o
--- /dev/null
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
+initrd_phys-y := 0x20800000
--- /dev/null
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/clock.h>
+
+#include "common.h"
+
+#define XI_FREQUENCY 12000000
+#define XTI_FREQUENCY 32768
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND */
+static struct tcc_nand_platform_data tcc8k_sdk_nand_data = {
+ .width = 1,
+ .hw_ecc = 0,
+};
+#endif
+
+static void __init tcc8k_init(void)
+{
+#ifdef CONFIG_MTD_NAND_TCC
+ tcc_nand_device.dev.platform_data = &tcc8k_sdk_nand_data;
+ platform_device_register(&tcc_nand_device);
+#endif
+}
+
+static void __init tcc8k_init_timer(void)
+{
+ tcc_clocks_init(XI_FREQUENCY, XTI_FREQUENCY);
+}
+
+static struct sys_timer tcc8k_timer = {
+ .init = tcc8k_init_timer,
+};
+
+static void __init tcc8k_map_io(void)
+{
+ tcc8k_map_common_io();
+}
+
+MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board")
+ .phys_io = 0x90000000,
+ .io_pg_offst = ((0xf1000000) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x00000100,
+ .map_io = tcc8k_map_io,
+ .init_irq = tcc8k_init_irq,
+ .init_machine = tcc8k_init,
+ .timer = &tcc8k_timer,
+MACHINE_END
--- /dev/null
+/*
+ * Lowlevel clock handling for Telechips TCC8xxx SoCs
+ *
+ * Copyright (C) 2010 by Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/irqs.h>
+#include <mach/tcc8k-regs.h>
+
+#include "common.h"
+
+#define BCLKCTR0 (CKC_BASE + BCLKCTR0_OFFS)
+#define BCLKCTR1 (CKC_BASE + BCLKCTR1_OFFS)
+
+#define ACLKREF (CKC_BASE + ACLKREF_OFFS)
+#define ACLKUART0 (CKC_BASE + ACLKUART0_OFFS)
+#define ACLKUART1 (CKC_BASE + ACLKUART1_OFFS)
+#define ACLKUART2 (CKC_BASE + ACLKUART2_OFFS)
+#define ACLKUART3 (CKC_BASE + ACLKUART3_OFFS)
+#define ACLKUART4 (CKC_BASE + ACLKUART4_OFFS)
+#define ACLKI2C (CKC_BASE + ACLKI2C_OFFS)
+#define ACLKADC (CKC_BASE + ACLKADC_OFFS)
+#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKLCD (CKC_BASE + ACLKLCD_OFFS)
+#define ACLKSDH0 (CKC_BASE + ACLKSDH0_OFFS)
+#define ACLKSDH1 (CKC_BASE + ACLKSDH1_OFFS)
+#define ACLKSPI0 (CKC_BASE + ACLKSPI0_OFFS)
+#define ACLKSPI1 (CKC_BASE + ACLKSPI1_OFFS)
+#define ACLKSPDIF (CKC_BASE + ACLKSPDIF_OFFS)
+#define ACLKC3DEC (CKC_BASE + ACLKC3DEC_OFFS)
+#define ACLKCAN0 (CKC_BASE + ACLKCAN0_OFFS)
+#define ACLKCAN1 (CKC_BASE + ACLKCAN1_OFFS)
+#define ACLKGSB0 (CKC_BASE + ACLKGSB0_OFFS)
+#define ACLKGSB1 (CKC_BASE + ACLKGSB1_OFFS)
+#define ACLKGSB2 (CKC_BASE + ACLKGSB2_OFFS)
+#define ACLKGSB3 (CKC_BASE + ACLKGSB3_OFFS)
+#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKTCT (CKC_BASE + ACLKTCT_OFFS)
+#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS)
+#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS)
+
+/* Crystal frequencies */
+static unsigned long xi_rate, xti_rate;
+
+static void __iomem *pll_cfg_addr(int pll)
+{
+ switch (pll) {
+ case 0: return (CKC_BASE + PLL0CFG_OFFS);
+ case 1: return (CKC_BASE + PLL1CFG_OFFS);
+ case 2: return (CKC_BASE + PLL2CFG_OFFS);
+ default:
+ BUG();
+ }
+}
+
+static int pll_enable(int pll, int enable)
+{
+ u32 reg;
+ void __iomem *addr = pll_cfg_addr(pll);
+
+ reg = __raw_readl(addr);
+ if (enable)
+ reg &= ~PLLxCFG_PD;
+ else
+ reg |= PLLxCFG_PD;
+
+ __raw_writel(reg, addr);
+ return 0;
+}
+
+static int xi_enable(int enable)
+{
+ u32 reg;
+
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ if (enable)
+ reg |= CLKCTRL_XE;
+ else
+ reg &= ~CLKCTRL_XE;
+
+ __raw_writel(reg, CKC_BASE + CLKCTRL_OFFS);
+ return 0;
+}
+
+static int root_clk_enable(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return pll_enable(0, 1);
+ case CLK_SRC_PLL1: return pll_enable(1, 1);
+ case CLK_SRC_PLL2: return pll_enable(2, 1);
+ case CLK_SRC_XI: return xi_enable(1);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static int root_clk_disable(enum root_clks root_src)
+{
+ switch (root_src) {
+ case CLK_SRC_PLL0: return pll_enable(0, 0);
+ case CLK_SRC_PLL1: return pll_enable(1, 0);
+ case CLK_SRC_PLL2: return pll_enable(2, 0);
+ case CLK_SRC_XI: return xi_enable(0);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static int enable_clk(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->root_id != CLK_SRC_NOROOT)
+ return root_clk_enable(clk->root_id);
+
+ if (clk->aclkreg) {
+ reg = __raw_readl(clk->aclkreg);
+ reg |= ACLK_EN;
+ __raw_writel(reg, clk->aclkreg);
+ }
+ if (clk->bclkctr) {
+ reg = __raw_readl(clk->bclkctr);
+ reg |= 1 << clk->bclk_shift;
+ __raw_writel(reg, clk->bclkctr);
+ }
+ return 0;
+}
+
+static void disable_clk(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->root_id != CLK_SRC_NOROOT) {
+ root_clk_disable(clk->root_id);
+ return;
+ }
+
+ if (clk->bclkctr) {
+ reg = __raw_readl(clk->bclkctr);
+ reg &= ~(1 << clk->bclk_shift);
+ __raw_writel(reg, clk->bclkctr);
+ }
+ if (clk->aclkreg) {
+ reg = __raw_readl(clk->aclkreg);
+ reg &= ~ACLK_EN;
+ __raw_writel(reg, clk->aclkreg);
+ }
+}
+
+static unsigned long get_rate_pll(int pll)
+{
+ u32 reg;
+ unsigned long s, m, p;
+ void __iomem *addr = pll_cfg_addr(pll);
+
+ reg = __raw_readl(addr);
+ s = (reg >> 16) & 0x07;
+ m = (reg >> 8) & 0xff;
+ p = reg & 0x3f;
+
+ return (m * xi_rate) / (p * (1 << s));
+}
+
+static unsigned long get_rate_pll_div(int pll)
+{
+ u32 reg;
+ unsigned long div = 0;
+ void __iomem *addr;
+
+ switch (pll) {
+ case 0:
+ addr = CKC_BASE + CLKDIVC0_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC0_P0E)
+ div = (reg >> 24) & 0x3f;
+ break;
+ case 1:
+ addr = CKC_BASE + CLKDIVC0_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC0_P1E)
+ div = (reg >> 16) & 0x3f;
+ break;
+ case 2:
+ addr = CKC_BASE + CLKDIVC1_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC1_P2E)
+ div = __raw_readl(addr) & 0x3f;
+ break;
+ }
+ return get_rate_pll(pll) / (div + 1);
+}
+
+static unsigned long get_rate_xi_div(void)
+{
+ unsigned long div = 0;
+ u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+ if (reg & CLKDIVC0_XE)
+ div = (reg >> 8) & 0x3f;
+
+ return xi_rate / (div + 1);
+}
+
+static unsigned long get_rate_xti_div(void)
+{
+ unsigned long div = 0;
+ u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+ if (reg & CLKDIVC0_XTE)
+ div = reg & 0x3f;
+
+ return xti_rate / (div + 1);
+}
+
+static unsigned long root_clk_get_rate(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return get_rate_pll(0);
+ case CLK_SRC_PLL1: return get_rate_pll(1);
+ case CLK_SRC_PLL2: return get_rate_pll(2);
+ case CLK_SRC_PLL0DIV: return get_rate_pll_div(0);
+ case CLK_SRC_PLL1DIV: return get_rate_pll_div(1);
+ case CLK_SRC_PLL2DIV: return get_rate_pll_div(2);
+ case CLK_SRC_XI: return xi_rate;
+ case CLK_SRC_XTI: return xti_rate;
+ case CLK_SRC_XIDIV: return get_rate_xi_div();
+ case CLK_SRC_XTIDIV: return get_rate_xti_div();
+ default: return 0;
+ }
+}
+
+static unsigned long aclk_get_rate(struct clk *clk)
+{
+ u32 reg;
+ unsigned long div;
+ unsigned int src;
+
+ reg = __raw_readl(clk->aclkreg);
+ div = reg & 0x0fff;
+ src = (reg >> ACLK_SEL_SHIFT) & CLK_SRC_MASK;
+ return root_clk_get_rate(src) / (div + 1);
+}
+
+static unsigned long aclk_best_div(struct clk *clk, unsigned long rate)
+{
+ unsigned long div, src, freq, r1, r2;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+ freq = root_clk_get_rate(src);
+ div = freq / rate + 1;
+ r1 = freq / div;
+ r2 = freq / (div + 1);
+ if (r2 >= rate)
+ return div + 1;
+ if ((rate - r2) < (r1 - rate))
+ return div + 1;
+
+ return div;
+}
+
+static unsigned long aclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int src;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+
+ return root_clk_get_rate(src) / aclk_best_div(clk, rate);
+}
+
+static int aclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK;
+ reg |= aclk_best_div(clk, rate);
+ return 0;
+}
+
+static unsigned long get_rate_sys(struct clk *clk)
+{
+ unsigned int src;
+
+ src = __raw_readl(CKC_BASE + CLKCTRL_OFFS) & CLK_SRC_MASK;
+ return root_clk_get_rate(src);
+}
+
+static unsigned long get_rate_bus(struct clk *clk)
+{
+ unsigned int div;
+
+ div = (__raw_readl(CKC_BASE + CLKCTRL_OFFS) >> 4) & 0xff;
+ return get_rate_sys(clk) / (div + 1);
+}
+
+static unsigned long get_rate_cpu(struct clk *clk)
+{
+ unsigned int reg, div, fsys, fbus;
+
+ fbus = get_rate_bus(clk);
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ if (reg & (1 << 29))
+ return fbus;
+ fsys = get_rate_sys(clk);
+ div = (reg >> 16) & 0x0f;
+ return fbus + ((fsys - fbus) * (div + 1)) / 16;
+}
+
+static unsigned long get_rate_root(struct clk *clk)
+{
+ return root_clk_get_rate(clk->root_id);
+}
+
+static int aclk_set_parent(struct clk *clock, struct clk *parent)
+{
+ u32 reg;
+
+ if (clock->parent == parent)
+ return 0;
+
+ clock->parent = parent;
+
+ if (!parent)
+ return 0;
+
+ if (parent->root_id == CLK_SRC_NOROOT)
+ return 0;
+ reg = __raw_readl(clock->aclkreg);
+ reg &= ~ACLK_SEL_MASK;
+ reg |= (parent->root_id << ACLK_SEL_SHIFT) & ACLK_SEL_MASK;
+ __raw_writel(reg, clock->aclkreg);
+
+ return 0;
+}
+
+#define DEFINE_ROOT_CLOCK(name, ri, p) \
+ static struct clk name = { \
+ .root_id = ri, \
+ .get_rate = get_rate_root, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .parent = p, \
+ };
+
+#define DEFINE_SPECIAL_CLOCK(name, gr, p) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .get_rate = gr, \
+ .parent = p, \
+ };
+
+#define DEFINE_ACLOCK(name, bc, bs, ar) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .bclkctr = bc, \
+ .bclk_shift = bs, \
+ .aclkreg = ar, \
+ .get_rate = aclk_get_rate, \
+ .set_rate = aclk_set_rate, \
+ .round_rate = aclk_round_rate, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .set_parent = aclk_set_parent, \
+ };
+
+#define DEFINE_BCLOCK(name, bc, bs, gr, p) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .bclkctr = bc, \
+ .bclk_shift = bs, \
+ .get_rate = gr, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .parent = p, \
+ };
+
+DEFINE_ROOT_CLOCK(xi, CLK_SRC_XI, NULL)
+DEFINE_ROOT_CLOCK(xti, CLK_SRC_XTI, NULL)
+DEFINE_ROOT_CLOCK(xidiv, CLK_SRC_XIDIV, &xi)
+DEFINE_ROOT_CLOCK(xtidiv, CLK_SRC_XTIDIV, &xti)
+DEFINE_ROOT_CLOCK(pll0, CLK_SRC_PLL0, &xi)
+DEFINE_ROOT_CLOCK(pll1, CLK_SRC_PLL1, &xi)
+DEFINE_ROOT_CLOCK(pll2, CLK_SRC_PLL2, &xi)
+DEFINE_ROOT_CLOCK(pll0div, CLK_SRC_PLL0DIV, &pll0)
+DEFINE_ROOT_CLOCK(pll1div, CLK_SRC_PLL1DIV, &pll1)
+DEFINE_ROOT_CLOCK(pll2div, CLK_SRC_PLL2DIV, &pll2)
+
+/* The following 3 clocks are special and are initialized explicitly later */
+DEFINE_SPECIAL_CLOCK(sys, get_rate_sys, NULL)
+DEFINE_SPECIAL_CLOCK(bus, get_rate_bus, &sys)
+DEFINE_SPECIAL_CLOCK(cpu, get_rate_cpu, &sys)
+
+DEFINE_ACLOCK(tct, NULL, 0, ACLKTCT)
+DEFINE_ACLOCK(tcx, NULL, 0, ACLKTCX)
+DEFINE_ACLOCK(tcz, NULL, 0, ACLKTCZ)
+DEFINE_ACLOCK(ref, NULL, 0, ACLKREF)
+DEFINE_ACLOCK(uart0, BCLKCTR0, 5, ACLKUART0)
+DEFINE_ACLOCK(uart1, BCLKCTR0, 23, ACLKUART1)
+DEFINE_ACLOCK(uart2, BCLKCTR0, 6, ACLKUART2)
+DEFINE_ACLOCK(uart3, BCLKCTR0, 8, ACLKUART3)
+DEFINE_ACLOCK(uart4, BCLKCTR1, 6, ACLKUART4)
+DEFINE_ACLOCK(i2c, BCLKCTR0, 7, ACLKI2C)
+DEFINE_ACLOCK(adc, BCLKCTR0, 10, ACLKADC)
+DEFINE_ACLOCK(usbh0, BCLKCTR0, 11, ACLKUSBH)
+DEFINE_ACLOCK(lcd, BCLKCTR0, 13, ACLKLCD)
+DEFINE_ACLOCK(sd0, BCLKCTR0, 17, ACLKSDH0)
+DEFINE_ACLOCK(sd1, BCLKCTR1, 5, ACLKSDH1)
+DEFINE_ACLOCK(spi0, BCLKCTR0, 24, ACLKSPI0)
+DEFINE_ACLOCK(spi1, BCLKCTR0, 30, ACLKSPI1)
+DEFINE_ACLOCK(spdif, BCLKCTR1, 2, ACLKSPDIF)
+DEFINE_ACLOCK(c3dec, BCLKCTR1, 9, ACLKC3DEC)
+DEFINE_ACLOCK(can0, BCLKCTR1, 10, ACLKCAN0)
+DEFINE_ACLOCK(can1, BCLKCTR1, 11, ACLKCAN1)
+DEFINE_ACLOCK(gsb0, BCLKCTR1, 13, ACLKGSB0)
+DEFINE_ACLOCK(gsb1, BCLKCTR1, 14, ACLKGSB1)
+DEFINE_ACLOCK(gsb2, BCLKCTR1, 15, ACLKGSB2)
+DEFINE_ACLOCK(gsb3, BCLKCTR1, 16, ACLKGSB3)
+DEFINE_ACLOCK(usbh1, BCLKCTR1, 20, ACLKUSBH)
+
+DEFINE_BCLOCK(dai0, BCLKCTR0, 0, NULL, NULL)
+DEFINE_BCLOCK(pic, BCLKCTR0, 1, NULL, NULL)
+DEFINE_BCLOCK(tc, BCLKCTR0, 2, NULL, NULL)
+DEFINE_BCLOCK(gpio, BCLKCTR0, 3, NULL, NULL)
+DEFINE_BCLOCK(usbd, BCLKCTR0, 4, NULL, NULL)
+DEFINE_BCLOCK(ecc, BCLKCTR0, 9, NULL, NULL)
+DEFINE_BCLOCK(gdma0, BCLKCTR0, 12, NULL, NULL)
+DEFINE_BCLOCK(rtc, BCLKCTR0, 15, NULL, NULL)
+DEFINE_BCLOCK(nfc, BCLKCTR0, 16, NULL, NULL)
+DEFINE_BCLOCK(g2d, BCLKCTR0, 18, NULL, NULL)
+DEFINE_BCLOCK(gdma1, BCLKCTR0, 22, NULL, NULL)
+DEFINE_BCLOCK(mscl, BCLKCTR0, 25, NULL, NULL)
+DEFINE_BCLOCK(bdma, BCLKCTR1, 0, NULL, NULL)
+DEFINE_BCLOCK(adma0, BCLKCTR1, 1, NULL, NULL)
+DEFINE_BCLOCK(scfg, BCLKCTR1, 3, NULL, NULL)
+DEFINE_BCLOCK(cid, BCLKCTR1, 4, NULL, NULL)
+DEFINE_BCLOCK(dai1, BCLKCTR1, 7, NULL, NULL)
+DEFINE_BCLOCK(adma1, BCLKCTR1, 8, NULL, NULL)
+DEFINE_BCLOCK(gps, BCLKCTR1, 12, NULL, NULL)
+DEFINE_BCLOCK(gdma2, BCLKCTR1, 17, NULL, NULL)
+DEFINE_BCLOCK(gdma3, BCLKCTR1, 18, NULL, NULL)
+DEFINE_BCLOCK(ddrc, BCLKCTR1, 19, NULL, NULL)
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "bus", bus)
+ _REGISTER_CLOCK(NULL, "cpu", cpu)
+ _REGISTER_CLOCK(NULL, "tct", tct)
+ _REGISTER_CLOCK(NULL, "tcx", tcx)
+ _REGISTER_CLOCK(NULL, "tcz", tcz)
+ _REGISTER_CLOCK(NULL, "ref", ref)
+ _REGISTER_CLOCK(NULL, "dai0", dai0)
+ _REGISTER_CLOCK(NULL, "pic", pic)
+ _REGISTER_CLOCK(NULL, "tc", tc)
+ _REGISTER_CLOCK(NULL, "gpio", gpio)
+ _REGISTER_CLOCK(NULL, "usbd", usbd)
+ _REGISTER_CLOCK("tcc-uart.0", NULL, uart0)
+ _REGISTER_CLOCK("tcc-uart.2", NULL, uart2)
+ _REGISTER_CLOCK("tcc-i2c", NULL, i2c)
+ _REGISTER_CLOCK("tcc-uart.3", NULL, uart3)
+ _REGISTER_CLOCK(NULL, "ecc", ecc)
+ _REGISTER_CLOCK(NULL, "adc", adc)
+ _REGISTER_CLOCK("tcc-usbh.0", "usb", usbh0)
+ _REGISTER_CLOCK(NULL, "gdma0", gdma0)
+ _REGISTER_CLOCK(NULL, "lcd", lcd)
+ _REGISTER_CLOCK(NULL, "rtc", rtc)
+ _REGISTER_CLOCK(NULL, "nfc", nfc)
+ _REGISTER_CLOCK("tcc-mmc.0", NULL, sd0)
+ _REGISTER_CLOCK(NULL, "g2d", g2d)
+ _REGISTER_CLOCK(NULL, "gdma1", gdma1)
+ _REGISTER_CLOCK("tcc-uart.1", NULL, uart1)
+ _REGISTER_CLOCK("tcc-spi.0", NULL, spi0)
+ _REGISTER_CLOCK(NULL, "mscl", mscl)
+ _REGISTER_CLOCK("tcc-spi.1", NULL, spi1)
+ _REGISTER_CLOCK(NULL, "bdma", bdma)
+ _REGISTER_CLOCK(NULL, "adma0", adma0)
+ _REGISTER_CLOCK(NULL, "spdif", spdif)
+ _REGISTER_CLOCK(NULL, "scfg", scfg)
+ _REGISTER_CLOCK(NULL, "cid", cid)
+ _REGISTER_CLOCK("tcc-mmc.1", NULL, sd1)
+ _REGISTER_CLOCK("tcc-uart.4", NULL, uart4)
+ _REGISTER_CLOCK(NULL, "dai1", dai1)
+ _REGISTER_CLOCK(NULL, "adma1", adma1)
+ _REGISTER_CLOCK(NULL, "c3dec", c3dec)
+ _REGISTER_CLOCK("tcc-can.0", NULL, can0)
+ _REGISTER_CLOCK("tcc-can.1", NULL, can1)
+ _REGISTER_CLOCK(NULL, "gps", gps)
+ _REGISTER_CLOCK("tcc-gsb.0", NULL, gsb0)
+ _REGISTER_CLOCK("tcc-gsb.1", NULL, gsb1)
+ _REGISTER_CLOCK("tcc-gsb.2", NULL, gsb2)
+ _REGISTER_CLOCK("tcc-gsb.3", NULL, gsb3)
+ _REGISTER_CLOCK(NULL, "gdma2", gdma2)
+ _REGISTER_CLOCK(NULL, "gdma3", gdma3)
+ _REGISTER_CLOCK(NULL, "ddrc", ddrc)
+ _REGISTER_CLOCK("tcc-usbh.1", "usb", usbh1)
+};
+
+static struct clk *root_clk_by_index(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return &pll0;
+ case CLK_SRC_PLL1: return &pll1;
+ case CLK_SRC_PLL2: return &pll2;
+ case CLK_SRC_PLL0DIV: return &pll0div;
+ case CLK_SRC_PLL1DIV: return &pll1div;
+ case CLK_SRC_PLL2DIV: return &pll2div;
+ case CLK_SRC_XI: return ξ
+ case CLK_SRC_XTI: return &xti;
+ case CLK_SRC_XIDIV: return &xidiv;
+ case CLK_SRC_XTIDIV: return &xtidiv;
+ default: return NULL;
+ }
+}
+
+static void find_aclk_parent(struct clk *clk)
+{
+ unsigned int src;
+ struct clk *clock;
+
+ if (!clk->aclkreg)
+ return;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+
+ clock = root_clk_by_index(src);
+ if (!clock)
+ return;
+
+ clk->parent = clock;
+ clk->set_parent = aclk_set_parent;
+}
+
+void __init tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq)
+{
+ int i;
+
+ xi_rate = xi_freq;
+ xti_rate = xti_freq;
+
+ /* fixup parents and add the clock */
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ find_aclk_parent(lookups[i].clk);
+ clkdev_add(&lookups[i]);
+ }
+ tcc8k_timer_init(&tcz, (void __iomem *)TIMER_BASE, INT_TC32);
+}
--- /dev/null
+#ifndef MACH_TCC8K_COMMON_H
+#define MACH_TCC8K_COMMON_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device tcc_nand_device;
+
+struct clk;
+
+extern void tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq);
+extern void tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq);
+extern void tcc8k_init_irq(void);
+extern void tcc8k_map_common_io(void);
+
+#endif
--- /dev/null
+/*
+ * linux/arch/arm/mach-tcc8k/devices.c
+ *
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of GPL v2.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static u64 tcc8k_dmamask = DMA_BIT_MASK(32);
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND controller */
+static struct resource tcc_nand_resources[] = {
+ {
+ .start = (resource_size_t)NFC_BASE,
+ .end = (resource_size_t)NFC_BASE + 0x7f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_NFC,
+ .end = INT_NFC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tcc_nand_device = {
+ .name = "tcc_nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tcc_nand_resources),
+ .resource = tcc_nand_resources,
+};
+#endif
+
+#ifdef CONFIG_MMC_TCC8K
+/* MMC controller */
+static struct resource tcc8k_mmc0_resource[] = {
+ {
+ .start = INT_SD0,
+ .end = INT_SD0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tcc8k_mmc1_resource[] = {
+ {
+ .start = INT_SD1,
+ .end = INT_SD1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tcc8k_mmc0_device = {
+ .name = "tcc-mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tcc8k_mmc0_resource),
+ .resource = tcc8k_mmc0_resource,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+struct platform_device tcc8k_mmc1_device = {
+ .name = "tcc-mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(tcc8k_mmc1_resource),
+ .resource = tcc8k_mmc1_resource,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+static inline void tcc8k_init_mmc(void)
+{
+ u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+ reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS;
+ __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+ platform_device_register(&tcc8k_mmc0_device);
+ platform_device_register(&tcc8k_mmc1_device);
+}
+#else
+static inline void tcc8k_init_mmc(void) { }
+#endif
+
+#ifdef CONFIG_USB_OHCI_HCD
+static int tcc8k_ohci_init(struct device *dev)
+{
+ u32 reg;
+
+ /* Use GPIO PK19 as VBUS control output */
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS);
+ reg &= ~(1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS);
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS);
+ reg &= ~(1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS);
+
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS);
+ reg |= (1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS);
+ /* Turn on VBUS */
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS);
+ reg |= (1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS);
+
+ return 0;
+}
+
+static struct resource tcc8k_ohci0_resources[] = {
+ [0] = {
+ .start = (resource_size_t)USBH0_BASE,
+ .end = (resource_size_t)USBH0_BASE + 0x5c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USBH0,
+ .end = INT_USBH0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource tcc8k_ohci1_resources[] = {
+ [0] = {
+ .start = (resource_size_t)USBH1_BASE,
+ .end = (resource_size_t)USBH1_BASE + 0x5c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USBH1,
+ .end = INT_USBH1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct tccohci_platform_data tcc8k_ohci0_platform_data = {
+ .controller = 0,
+ .port_mode = PMM_PERPORT_MODE,
+ .init = tcc8k_ohci_init,
+};
+
+static struct tccohci_platform_data tcc8k_ohci1_platform_data = {
+ .controller = 1,
+ .port_mode = PMM_PERPORT_MODE,
+ .init = tcc8k_ohci_init,
+};
+
+static struct platform_device ohci0_device = {
+ .name = "tcc-ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tcc8k_ohci0_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(tcc8k_ohci0_resources),
+ .resource = tcc8k_ohci0_resources,
+};
+
+static struct platform_device ohci1_device = {
+ .name = "tcc-ohci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tcc8k_ohci1_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(tcc8k_ohci1_resources),
+ .resource = tcc8k_ohci1_resources,
+};
+
+static void __init tcc8k_init_usbhost(void)
+{
+ platform_device_register(&ohci0_device);
+ platform_device_register(&ohci1_device);
+}
+#else
+static void __init tcc8k_init_usbhost(void) { }
+#endif
+
+/* USB device controller*/
+#ifdef CONFIG_USB_GADGET_TCC8K
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = INT_USBD,
+ .end = INT_USBD,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = INT_UDMA,
+ .end = INT_UDMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tcc8k_udc_device = {
+ .name = "tcc-udc",
+ .id = 0,
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static void __init tcc8k_init_usb_gadget(void)
+{
+ platform_device_register(&tcc8k_udc_device);
+}
+#else
+static void __init tcc8k_init_usb_gadget(void) { }
+#endif /* CONFIG_USB_GADGET_TCC83X */
+
+static int __init tcc8k_init_devices(void)
+{
+ tcc8k_init_mmc();
+ tcc8k_init_usbhost();
+ tcc8k_init_usb_gadget();
+ return 0;
+}
+
+arch_initcall(tcc8k_init_devices);
--- /dev/null
+/*
+ * linux/arch/arm/mach-tcc8k/io.c
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * derived from TCC83xx io.c
+ * Copyright (C) Telechips, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc tcc8k_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)CS1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CS1_BASE),
+ .length = CS1_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)AHB_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(AHB_PERI_BASE),
+ .length = AHB_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)APB0_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(APB0_PERI_BASE),
+ .length = APB0_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)APB1_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(APB1_PERI_BASE),
+ .length = APB1_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)EXT_MEM_CTRL_BASE_VIRT,
+ .pfn = __phys_to_pfn(EXT_MEM_CTRL_BASE),
+ .length = EXT_MEM_CTRL_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/*
+ * Maps common IO regions for tcc8k.
+ *
+ */
+void __init tcc8k_map_common_io(void)
+{
+ iotable_init(tcc8k_io_desc, ARRAY_SIZE(tcc8k_io_desc));
+}
--- /dev/null
+/*
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU GPL version 2.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+/* Disable IRQ */
+static void tcc8000_mask_ack_irq0(unsigned int irq)
+{
+ PIC0_IEN &= ~(1 << irq);
+ PIC0_CREQ |= (1 << irq);
+}
+
+static void tcc8000_mask_ack_irq1(unsigned int irq)
+{
+ PIC1_IEN &= ~(1 << (irq - 32));
+ PIC1_CREQ |= (1 << (irq - 32));
+}
+
+static void tcc8000_mask_irq0(unsigned int irq)
+{
+ PIC0_IEN &= ~(1 << irq);
+}
+
+static void tcc8000_mask_irq1(unsigned int irq)
+{
+ PIC1_IEN &= ~(1 << (irq - 32));
+}
+
+static void tcc8000_ack_irq0(unsigned int irq)
+{
+ PIC0_CREQ |= (1 << irq);
+}
+
+static void tcc8000_ack_irq1(unsigned int irq)
+{
+ PIC1_CREQ |= (1 << (irq - 32));
+}
+
+/* Enable IRQ */
+static void tcc8000_unmask_irq0(unsigned int irq)
+{
+ PIC0_IEN |= (1 << irq);
+ PIC0_INTOEN |= (1 << irq);
+}
+
+static void tcc8000_unmask_irq1(unsigned int irq)
+{
+ PIC1_IEN |= (1 << (irq - 32));
+ PIC1_INTOEN |= (1 << (irq - 32));
+}
+
+static struct irq_chip tcc8000_irq_chip0 = {
+ .name = "tcc_irq0",
+ .mask = tcc8000_mask_irq0,
+ .ack = tcc8000_ack_irq0,
+ .mask_ack = tcc8000_mask_ack_irq0,
+ .unmask = tcc8000_unmask_irq0,
+};
+
+static struct irq_chip tcc8000_irq_chip1 = {
+ .name = "tcc_irq1",
+ .mask = tcc8000_mask_irq1,
+ .ack = tcc8000_ack_irq1,
+ .mask_ack = tcc8000_mask_ack_irq1,
+ .unmask = tcc8000_unmask_irq1,
+};
+
+void __init tcc8k_init_irq(void)
+{
+ int irqno;
+
+ /* Mask and clear all interrupts */
+ PIC0_IEN = 0x00000000;
+ PIC0_CREQ = 0xffffffff;
+ PIC1_IEN = 0x00000000;
+ PIC1_CREQ = 0xffffffff;
+
+ PIC0_MEN0 = 0x00000003;
+ PIC1_MEN1 = 0x00000003;
+ PIC1_MEN = 0x00000003;
+
+ /* let all IRQs be level triggered */
+ PIC0_TMODE = 0xffffffff;
+ PIC1_TMODE = 0xffffffff;
+ /* all IRQs are IRQs (not FIQs) */
+ PIC0_IRQSEL = 0xffffffff;
+ PIC1_IRQSEL = 0xffffffff;
+
+ for (irqno = 0; irqno < NR_IRQS; irqno++) {
+ if (irqno < 32)
+ set_irq_chip(irqno, &tcc8000_irq_chip0);
+ else
+ set_irq_chip(irqno, &tcc8000_irq_chip1);
+ set_irq_handler(irqno, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+}
--- /dev/null
+/*
+ * TCC8000 system timer setup
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL version 2.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static void __iomem *timer_base;
+
+static cycle_t tcc_get_cycles(struct clocksource *cs)
+{
+ return __raw_readl(timer_base + TC32MCNT_OFFS);
+}
+
+static struct clocksource clocksource_tcc = {
+ .name = "tcc_tc32",
+ .rating = 200,
+ .read = tcc_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 28,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int tcc_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long reg = __raw_readl(timer_base + TC32MCNT_OFFS);
+
+ __raw_writel(reg + evt, timer_base + TC32CMP0_OFFS);
+ return 0;
+}
+
+static void tcc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long tc32irq;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+ tc32irq |= TC32IRQ_IRQEN0;
+ __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+ tc32irq &= ~TC32IRQ_IRQEN0;
+ __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+ break;
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static irqreturn_t tcc8k_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ /* Acknowledge TC32 interrupt by reading TC32IRQ */
+ __raw_readl(timer_base + TC32IRQ_OFFS);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_tcc = {
+ .name = "tcc_timer1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = tcc_set_mode,
+ .set_next_event = tcc_set_next_event,
+ .rating = 200,
+};
+
+static struct irqaction tcc8k_timer_irq = {
+ .name = "TC32_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = tcc8k_timer_interrupt,
+ .dev_id = &clockevent_tcc,
+};
+
+static int __init tcc_clockevent_init(struct clk *clock)
+{
+ unsigned int c = clk_get_rate(clock);
+
+ clocksource_tcc.mult = clocksource_hz2mult(c,
+ clocksource_tcc.shift);
+ clocksource_register(&clocksource_tcc);
+
+ clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_tcc.shift);
+ clockevent_tcc.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_tcc);
+ clockevent_tcc.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_tcc);
+
+ clockevent_tcc.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_tcc);
+
+ return 0;
+}
+
+void __init tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq)
+{
+ u32 reg;
+
+ timer_base = base;
+ tcc8k_timer_irq.irq = irq;
+
+ /* Enable clocks */
+ clk_enable(clock);
+
+ /* Initialize 32-bit timer */
+ reg = __raw_readl(timer_base + TC32EN_OFFS);
+ reg &= ~TC32EN_ENABLE; /* Disable timer */
+ __raw_writel(reg, timer_base + TC32EN_OFFS);
+ /* Free running timer, counting from 0 to 0xffffffff */
+ __raw_writel(0, timer_base + TC32EN_OFFS);
+ __raw_writel(0, timer_base + TC32LDV_OFFS);
+ reg = __raw_readl(timer_base + TC32IRQ_OFFS);
+ reg |= TC32IRQ_IRQEN0; /* irq at match with CMP0 */
+ __raw_writel(reg, timer_base + TC32IRQ_OFFS);
+
+ __raw_writel(TC32EN_ENABLE, timer_base + TC32EN_OFFS);
+
+ tcc_clockevent_init(clock);
+ setup_irq(irq, &tcc8k_timer_irq);
+}
extern int gpio_get_value(unsigned gpio);
extern void gpio_set_value(unsigned gpio, int value);
+#define gpio_get_value_cansleep gpio_get_value
+#define gpio_set_value_cansleep gpio_set_value
+
/* wrappers to sleep-enable the previous two functions */
static inline unsigned gpio_to_irq(unsigned gpio)
{
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
+#define VMALLOC_END 0xd8000000
int i;
#ifdef CONFIG_CACHE_L2X0
- l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff);
+ void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC);
+
+ /* set RAM latencies to 1 cycle for this core tile. */
+ writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
+ writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+ l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
#endif
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (ai_usermode & UM_SIGNAL)
force_sig(SIGBUS, current);
- else
- set_cr(cr_no_alignment);
+ else {
+ /*
+ * We're about to disable the alignment trap and return to
+ * user space. But if an interrupt occurs before actually
+ * reaching user space, then the IRQ vector entry code will
+ * notice that we were still in kernel space and therefore
+ * the alignment trap won't be re-enabled in that case as it
+ * is presumed to be always on from kernel space.
+ * Let's prevent that race by disabling interrupts here (they
+ * are disabled on the way back to user space anyway in
+ * entry-common.S) and disable the alignment trap only if
+ * there is no work pending for this thread.
+ */
+ raw_local_irq_disable();
+ if (!(current_thread_info()->flags & _TIF_WORK_MASK))
+ set_cr(cr_no_alignment);
+ }
return 0;
}
{
return !(pfn + (size >> PAGE_SHIFT) > 0x00100000);
}
+
+#ifdef CONFIG_STRICT_DEVMEM
+
+#include <linux/ioport.h>
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain
+ * address is valid. The argument is a physical page number.
+ * We mimic x86 here by disallowing access to system RAM as well as
+ * device-exclusive MMIO regions. This effectively disable read()/write()
+ * on /dev/mem.
+ */
+int devmem_is_allowed(unsigned long pfn)
+{
+ if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+ return 0;
+ if (!page_is_ram(pfn))
+ return 1;
+ return 0;
+}
+
+#endif
#include <linux/nodemask.h>
#include <linux/memblock.h>
#include <linux/sort.h>
+#include <linux/fs.h>
#include <asm/cputype.h>
#include <asm/sections.h>
.domain = DOMAIN_USER,
},
[MT_MEMORY] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_USER | L_PTE_EXEC,
+ .prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_NONCACHED] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
+ .prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
* Enable CPU-specific coherency if supported.
* (Only available on XSC3 at the moment.)
*/
- if (arch_is_coherent() && cpu_is_xsc3())
+ if (arch_is_coherent() && cpu_is_xsc3()) {
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
-
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+ }
/*
* ARMv6 and above have extended page tables.
*/
mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
#endif
}
mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
+ mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
mem_types[MT_ROM].prot_sect |= cp->pmd;
switch (cp->pmd) {
}
}
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot)
+{
+ if (!pfn_valid(pfn))
+ return pgprot_noncached(vma_prot);
+ else if (file->f_flags & O_SYNC)
+ return pgprot_writecombine(vma_prot);
+ return vma_prot;
+}
+EXPORT_SYMBOL(phys_mem_access_prot);
+#endif
+
#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
static void __init *early_alloc(unsigned long sz)
* It is assumed that:
* - cache type register is implemented
*/
-__v7_setup:
+__v7_ca9mp_setup:
#ifdef CONFIG_SMP
mrc p15, 0, r0, c1, c0, 1
tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
#endif
+__v7_setup:
adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr}
bl v7_flush_dcache_all
mrc p15, 0, r0, c0, c0, 0 @ read main ID register
and r10, r0, #0xff000000 @ ARM?
teq r10, #0x41000000
- bne 2f
+ bne 3f
and r5, r0, #0x00f00000 @ variant
and r6, r0, #0x0000000f @ revision
- orr r0, r6, r5, lsr #20-4 @ combine variant and revision
+ orr r6, r6, r5, lsr #20-4 @ combine variant and revision
+ ubfx r0, r0, #4, #12 @ primary part number
+ /* Cortex-A8 Errata */
+ ldr r10, =0x00000c08 @ Cortex-A8 primary part number
+ teq r0, r10
+ bne 2f
#ifdef CONFIG_ARM_ERRATA_430973
teq r5, #0x00100000 @ only present in r1p*
mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
#endif
#ifdef CONFIG_ARM_ERRATA_458693
- teq r0, #0x20 @ only present in r2p0
+ teq r6, #0x20 @ only present in r2p0
mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
orreq r10, r10, #(1 << 5) @ set L1NEON to 1
orreq r10, r10, #(1 << 9) @ set PLDNOP to 1
mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
#endif
#ifdef CONFIG_ARM_ERRATA_460075
- teq r0, #0x20 @ only present in r2p0
+ teq r6, #0x20 @ only present in r2p0
mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register
tsteq r10, #1 << 22
orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit
mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register
#endif
+ b 3f
+
+ /* Cortex-A9 Errata */
+2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number
+ teq r0, r10
+ bne 3f
+#ifdef CONFIG_ARM_ERRATA_742230
+ cmp r6, #0x22 @ only present up to r2p2
+ mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orrle r10, r10, #1 << 4 @ set bit #4
+ mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
+#ifdef CONFIG_ARM_ERRATA_742231
+ teq r6, #0x20 @ present in r2p0
+ teqne r6, #0x21 @ present in r2p1
+ teqne r6, #0x22 @ present in r2p2
+ mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orreq r10, r10, #1 << 12 @ set bit #12
+ orreq r10, r10, #1 << 22 @ set bit #22
+ mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
-2: mov r10, #0
+3: mov r10, #0
#ifdef HARVARD_CACHE
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
#endif
.section ".proc.info.init", #alloc, #execinstr
+ .type __v7_ca9mp_proc_info, #object
+__v7_ca9mp_proc_info:
+ .long 0x410fc090 @ Required ID value
+ .long 0xff0ffff0 @ Mask for ID
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_XN | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ b __v7_ca9mp_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long cpu_v7_name
+ .long v7_processor_functions
+ .long v7wbi_tlb_fns
+ .long v6_user_fns
+ .long v7_cache_fns
+ .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
+
/*
* Match any ARMv7 processor core.
*/
if (IS_ERR(pevent)) {
ret = PTR_ERR(pevent);
} else if (pevent->state != PERF_EVENT_STATE_ACTIVE) {
+ perf_event_release_kernel(pevent);
pr_warning("oprofile: failed to enable event %d "
"on CPU %d\n", event, cpu);
ret = -EBUSY;
ret = init_driverfs();
if (ret) {
kfree(counter_config);
+ counter_config = NULL;
return ret;
}
struct perf_event *event;
if (*perf_events) {
- exit_driverfs();
for_each_possible_cpu(cpu) {
for (id = 0; id < perf_num_counters; ++id) {
event = perf_events[cpu][id];
}
}
- if (counter_config)
+ if (counter_config) {
kfree(counter_config);
+ exit_driverfs();
+ }
}
#else
int __init oprofile_arch_init(struct oprofile_operations *ops)
data/address de-multiplexing and decode, signal level shift,
interrupt control and various board functions.
+config HAVE_EPIT
+ bool
+
+config MXC_USE_EPIT
+ bool "Use EPIT instead of GPT"
+ depends on HAVE_EPIT
+ help
+ Use EPIT as the system timer on systems that have it. Normally you
+ don't have a reason to do so as the EPIT has the same features and
+ uses the same clocks as the GPT. Anyway, on some systems the GPT
+ may be in use for other purposes.
+
config MXC_ULPI
bool
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
+obj-$(CONFIG_MXC_USE_EPIT) += epit.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
static int mxc_audmux_v2_init(void)
{
int ret;
-
+#if defined(CONFIG_ARCH_MX5)
+ if (cpu_is_mx51()) {
+ audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR);
+ ret = 0;
+ return ret;
+ }
+#endif
#if defined(CONFIG_ARCH_MX3)
if (cpu_is_mx31())
audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
+config IMX_HAVE_PLATFORM_ESDHC
+ bool
+
+config IMX_HAVE_PLATFORM_FEC
+ bool
+ default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51
+
config IMX_HAVE_PLATFORM_FLEXCAN
select HAVE_CAN_FLEXCAN
bool
config IMX_HAVE_PLATFORM_IMX_I2C
bool
+config IMX_HAVE_PLATFORM_IMX_SSI
+ bool
+
config IMX_HAVE_PLATFORM_IMX_UART
bool
-ifdef CONFIG_CAN_FLEXCAN
-# the ifdef can be removed once the flexcan driver has been merged
-obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
-endif
+obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-y += platform-imx-dma.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
--- /dev/null
+/*
+ * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <mach/devices-common.h>
+#include <mach/esdhc.h>
+
+struct platform_device *__init imx_add_esdhc(int id,
+ resource_size_t iobase, resource_size_t iosize,
+ resource_size_t irq,
+ const struct esdhc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("sdhci-esdhc-imx", id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
--- /dev/null
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * 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 <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fec_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _FEC_BASE_ADDR, \
+ .irq = soc ## _INT_FEC, \
+ }
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_fec_data imx25_fec_data __initconst =
+ imx_fec_data_entry_single(MX25);
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_fec_data imx27_fec_data __initconst =
+ imx_fec_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_fec_data imx35_fec_data __initconst =
+ imx_fec_data_entry_single(MX35);
+#endif
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_fec_data imx51_fec_data __initconst =
+ imx_fec_data_entry_single(MX51);
+#endif
+
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("fec", 0 /* -1? */,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
--- /dev/null
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#ifdef SDMA_IS_MERGED
+#include <mach/sdma.h>
+#else
+struct sdma_platform_data {
+ int sdma_version;
+ char *cpu_name;
+ int to_version;
+};
+#endif
+
+struct imx_imx_sdma_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+ struct sdma_platform_data pdata;
+};
+
+#define imx_imx_sdma_data_entry_single(soc, _sdma_version, _cpu_name, _to_version)\
+ { \
+ .iobase = soc ## _SDMA ## _BASE_ADDR, \
+ .irq = soc ## _INT_SDMA, \
+ .pdata = { \
+ .sdma_version = _sdma_version, \
+ .cpu_name = _cpu_name, \
+ .to_version = _to_version, \
+ }, \
+ }
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_sdma_data imx25_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX25, 1, "imx25", 0);
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_ARCH_MX31
+struct imx_imx_sdma_data imx31_imx_sdma_data __initdata =
+ imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 0);
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+struct imx_imx_sdma_data imx35_imx_sdma_data __initdata =
+ imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 0);
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_sdma_data imx51_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 0);
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+static struct platform_device __init __maybe_unused *imx_add_imx_sdma(
+ const struct imx_imx_sdma_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-sdma", -1,
+ res, ARRAY_SIZE(res),
+ &data->pdata, sizeof(data->pdata));
+}
+
+static struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
+{
+ return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0);
+}
+
+static int __init imxXX_add_imx_dma(void)
+{
+ struct platform_device *ret;
+
+#if defined(CONFIG_SOC_IMX21) || defined(CONFIG_SOC_IMX27)
+ if (cpu_is_mx21() || cpu_is_mx27())
+ ret = imx_add_imx_dma();
+ else
+#endif
+
+#if defined(CONFIG_ARCH_MX25)
+ if (cpu_is_mx25())
+ ret = imx_add_imx_sdma(&imx25_imx_sdma_data);
+ else
+#endif
+
+#if defined(CONFIG_ARCH_MX31)
+ if (cpu_is_mx31()) {
+ imx31_imx_sdma_data.pdata.to_version = mx31_revision() >> 4;
+ ret = imx_add_imx_sdma(&imx31_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_ARCH_MX35)
+ if (cpu_is_mx35()) {
+ imx35_imx_sdma_data.pdata.to_version = mx35_revision() >> 4;
+ ret = imx_add_imx_sdma(&imx35_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_ARCH_MX51)
+ if (cpu_is_mx51())
+ ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
+ else
+#endif
+ ret = ERR_PTR(-ENODEV);
+
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+
+ return 0;
+}
+arch_initcall(imxXX_add_imx_dma);
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_imx_i2c(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+#define imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _I2C ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_I2C ## _hwid, \
+ }
+
+#define imx_imx_i2c_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst =
+ imx_imx_i2c_data_entry_single(MX1, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst =
+ imx_imx_i2c_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
+#define imx25_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_imx_i2c_data_entry(0, 1),
+ imx25_imx_i2c_data_entry(1, 2),
+ imx25_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
+#define imx27_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_i2c_data_entry(0, 1),
+ imx27_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = {
+#define imx31_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_i2c_data_entry(0, 1),
+ imx31_imx_i2c_data_entry(1, 2),
+ imx31_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = {
+#define imx35_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX35, _id, _hwid, SZ_4K)
+ imx35_imx_i2c_data_entry(0, 1),
+ imx35_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = {
+#define imx51_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_i2c_data_entry(0, 1),
+ imx51_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_imx_i2c(
+ const struct imx_imx_i2c_data *data,
const struct imxi2c_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("imx-i2c", id, res, ARRAY_SIZE(res),
+ return imx_add_platform_device("imx-i2c", data->id,
+ res, ARRAY_SIZE(res),
pdata, sizeof(*pdata));
}
--- /dev/null
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_ssi_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _SSI ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_SSI ## _hwid, \
+ .dmatx0 = soc ## _DMA_REQ_SSI ## _hwid ## _TX0, \
+ .dmarx0 = soc ## _DMA_REQ_SSI ## _hwid ## _RX0, \
+ .dmatx1 = soc ## _DMA_REQ_SSI ## _hwid ## _TX1, \
+ .dmarx1 = soc ## _DMA_REQ_SSI ## _hwid ## _RX1, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = {
+#define imx21_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_imx_ssi_data_entry(0, 1),
+ imx21_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst = {
+#define imx25_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX25, _id, _hwid, SZ_4K)
+ imx25_imx_ssi_data_entry(0, 1),
+ imx25_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = {
+#define imx27_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_ssi_data_entry(0, 1),
+ imx27_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst = {
+#define imx31_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_ssi_data_entry(0, 1),
+ imx31_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst = {
+#define imx35_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX35, _id, _hwid, SZ_4K)
+ imx35_imx_ssi_data_entry(0, 1),
+ imx35_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst = {
+#define imx51_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_ssi_data_entry(0, 1),
+ imx51_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_imx_ssi(
+ const struct imx_imx_ssi_data *data,
+ const struct imx_ssi_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+#define DMARES(_name) { \
+ .name = #_name, \
+ .start = data->dma ## _name, \
+ .end = data->dma ## _name, \
+ .flags = IORESOURCE_DMA, \
+}
+ DMARES(tx0),
+ DMARES(rx0),
+ DMARES(tx1),
+ DMARES(rx1),
+ };
+
+ return imx_add_platform_device("imx-ssi", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_imx_uart_3irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irqrx, resource_size_t irqtx,
- resource_size_t irqrts,
+#define imx_imx_uart_3irq_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irqrx = soc ## _INT_UART ## _hwid ## RX, \
+ .irqtx = soc ## _INT_UART ## _hwid ## TX, \
+ .irqrts = soc ## _INT_UART ## _hwid ## RTS, \
+ }
+
+#define imx_imx_uart_1irq_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_UART ## _hwid, \
+ }
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst = {
+#define imx1_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_3irq_data_entry(MX1, _id, _hwid, 0xd0)
+ imx1_imx_uart_data_entry(0, 1),
+ imx1_imx_uart_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = {
+#define imx21_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_imx_uart_data_entry(0, 1),
+ imx21_imx_uart_data_entry(1, 2),
+ imx21_imx_uart_data_entry(2, 3),
+ imx21_imx_uart_data_entry(3, 4),
+};
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = {
+#define imx25_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_imx_uart_data_entry(0, 1),
+ imx25_imx_uart_data_entry(1, 2),
+ imx25_imx_uart_data_entry(2, 3),
+ imx25_imx_uart_data_entry(3, 4),
+ imx25_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = {
+#define imx27_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_uart_data_entry(0, 1),
+ imx27_imx_uart_data_entry(1, 2),
+ imx27_imx_uart_data_entry(2, 3),
+ imx27_imx_uart_data_entry(3, 4),
+ imx27_imx_uart_data_entry(4, 5),
+ imx27_imx_uart_data_entry(5, 6),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = {
+#define imx31_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_uart_data_entry(0, 1),
+ imx31_imx_uart_data_entry(1, 2),
+ imx31_imx_uart_data_entry(2, 3),
+ imx31_imx_uart_data_entry(3, 4),
+ imx31_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = {
+#define imx35_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_16K)
+ imx35_imx_uart_data_entry(0, 1),
+ imx35_imx_uart_data_entry(1, 2),
+ imx35_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = {
+#define imx51_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_uart_data_entry(0, 1),
+ imx51_imx_uart_data_entry(1, 2),
+ imx51_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_imx_uart_3irq(
+ const struct imx_imx_uart_3irq_data *data,
const struct imxuart_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irqrx,
- .end = irqrx,
+ .start = data->irqrx,
+ .end = data->irqrx,
.flags = IORESOURCE_IRQ,
}, {
- .start = irqtx,
- .end = irqtx,
+ .start = data->irqtx,
+ .end = data->irqtx,
.flags = IORESOURCE_IRQ,
}, {
- .start = irqrts,
- .end = irqrx,
+ .start = data->irqrts,
+ .end = data->irqrx,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
- pdata, sizeof(*pdata));
+ return imx_add_platform_device("imx-uart", data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
-struct platform_device *__init imx_add_imx_uart_1irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
+struct platform_device *__init imx_add_imx_uart_1irq(
+ const struct imx_imx_uart_1irq_data *data,
const struct imxuart_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
+ return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res),
pdata, sizeof(*pdata));
}
* Free Software Foundation.
*/
#include <asm/sizes.h>
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-static struct platform_device *__init imx_add_mxc_nand(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata,
- resource_size_t iosize)
+#define imx_mxc_nand_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#define imx_mxc_nandv3_data_entry_single(soc, _size) \
+ { \
+ .id = -1, \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .axibase = soc ## _NFC_AXI_BASE_ADDR, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX21, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX25, SZ_8K);
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX27, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX31, SZ_4K);
+#endif
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX35, SZ_8K);
+#endif
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst =
+ imx_mxc_nandv3_data_entry_single(MX51, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_mxc_nand(
+ const struct imx_mxc_nand_data *data,
+ const struct mxc_nand_platform_data *pdata)
{
- static int id = 0;
-
+ /* AXI has to come first, that's how the mxc_nand driver expect it */
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->axibase,
+ .end = data->axibase + SZ_16K - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
-
- return imx_add_platform_device("mxc_nand", id++, res, ARRAY_SIZE(res),
+ return imx_add_platform_device("mxc_nand", data->id,
+ res + !data->axibase,
+ ARRAY_SIZE(res) - !data->axibase,
pdata, sizeof(*pdata));
}
-
-struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata)
-{
- return imx_add_mxc_nand(iobase, irq, pdata, SZ_4K);
-}
-
-struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata)
-{
- return imx_add_mxc_nand(iobase, irq, pdata, SZ_8K);
-}
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
-#include <asm/sizes.h>
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_spi_imx(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+#define imx_spi_imx_data_entry_single(soc, type, _devid, _id, hwid, _size) \
+ { \
+ .devid = _devid, \
+ .id = _id, \
+ .iobase = soc ## _ ## type ## hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ ## type ## hwid, \
+ }
+
+#define imx_spi_imx_data_entry(soc, type, devid, id, hwid, size) \
+ [id] = imx_spi_imx_data_entry_single(soc, type, devid, id, hwid, size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {
+#define imx21_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K)
+ imx21_cspi_data_entry(0, 1),
+ imx21_cspi_data_entry(1, 2),
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_spi_imx_data imx25_cspi_data[] __initconst = {
+#define imx25_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX25, CSPI, "imx25-cspi", _id, _hwid, SZ_16K)
+ imx25_cspi_data_entry(0, 1),
+ imx25_cspi_data_entry(1, 2),
+ imx25_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_spi_imx_data imx27_cspi_data[] __initconst = {
+#define imx27_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX27, CSPI, "imx27-cspi", _id, _hwid, SZ_4K)
+ imx27_cspi_data_entry(0, 1),
+ imx27_cspi_data_entry(1, 2),
+ imx27_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_spi_imx_data imx31_cspi_data[] __initconst = {
+#define imx31_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX31, CSPI, "imx31-cspi", _id, _hwid, SZ_4K)
+ imx31_cspi_data_entry(0, 1),
+ imx31_cspi_data_entry(1, 2),
+ imx31_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_spi_imx_data imx35_cspi_data[] __initconst = {
+#define imx35_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX35, CSPI, "imx35-cspi", _id, _hwid, SZ_4K)
+ imx35_cspi_data_entry(0, 1),
+ imx35_cspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_spi_imx_data imx51_cspi_data __initconst =
+ imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 0, , SZ_4K);
+
+const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = {
+#define imx51_ecspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX51, ECSPI, "imx51-ecspi", _id, _hwid, SZ_4K)
+ imx51_ecspi_data_entry(0, 1),
+ imx51_ecspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
const struct spi_imx_master *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("spi_imx", id, res, ARRAY_SIZE(res),
- pdata, sizeof(*pdata));
+ return imx_add_platform_device(data->devid, data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
#ifdef CONFIG_ARCH_MX51
if (cpu_is_mx51()) {
void __iomem *usb_base;
- u32 usbotg_base;
- u32 usbother_base;
+ void __iomem *usbotg_base;
+ void __iomem *usbother_base;
int ret = 0;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
--- /dev/null
+/*
+ * linux/arch/arm/plat-mxc/epit.c
+ *
+ * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#define EPITCR 0x00
+#define EPITSR 0x04
+#define EPITLR 0x08
+#define EPITCMPR 0x0c
+#define EPITCNR 0x10
+
+#define EPITCR_EN (1 << 0)
+#define EPITCR_ENMOD (1 << 1)
+#define EPITCR_OCIEN (1 << 2)
+#define EPITCR_RLD (1 << 3)
+#define EPITCR_PRESC(x) (((x) & 0xfff) << 4)
+#define EPITCR_SWR (1 << 16)
+#define EPITCR_IOVW (1 << 17)
+#define EPITCR_DBGEN (1 << 18)
+#define EPITCR_WAITEN (1 << 19)
+#define EPITCR_RES (1 << 20)
+#define EPITCR_STOPEN (1 << 21)
+#define EPITCR_OM_DISCON (0 << 22)
+#define EPITCR_OM_TOGGLE (1 << 22)
+#define EPITCR_OM_CLEAR (2 << 22)
+#define EPITCR_OM_SET (3 << 22)
+#define EPITCR_CLKSRC_OFF (0 << 24)
+#define EPITCR_CLKSRC_PERIPHERAL (1 << 24)
+#define EPITCR_CLKSRC_REF_HIGH (1 << 24)
+#define EPITCR_CLKSRC_REF_LOW (3 << 24)
+
+#define EPITSR_OCIF (1 << 0)
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+static struct clock_event_device clockevent_epit;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void epit_irq_disable(void)
+{
+ u32 val;
+
+ val = __raw_readl(timer_base + EPITCR);
+ val &= ~EPITCR_OCIEN;
+ __raw_writel(val, timer_base + EPITCR);
+}
+
+static inline void epit_irq_enable(void)
+{
+ u32 val;
+
+ val = __raw_readl(timer_base + EPITCR);
+ val |= EPITCR_OCIEN;
+ __raw_writel(val, timer_base + EPITCR);
+}
+
+static void epit_irq_acknowledge(void)
+{
+ __raw_writel(EPITSR_OCIF, timer_base + EPITSR);
+}
+
+static cycle_t epit_read(struct clocksource *cs)
+{
+ return 0 - __raw_readl(timer_base + EPITCNR);
+}
+
+static struct clocksource clocksource_epit = {
+ .name = "epit",
+ .rating = 200,
+ .read = epit_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init epit_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clocksource_epit.mult = clocksource_hz2mult(c,
+ clocksource_epit.shift);
+ clocksource_register(&clocksource_epit);
+
+ return 0;
+}
+
+/* clock event */
+
+static int epit_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long tcmp;
+
+ tcmp = __raw_readl(timer_base + EPITCNR);
+
+ __raw_writel(tcmp - evt, timer_base + EPITCMPR);
+
+ return 0;
+}
+
+static void epit_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ /*
+ * The timer interrupt generation is disabled at least
+ * for enough time to call epit_set_next_event()
+ */
+ local_irq_save(flags);
+
+ /* Disable interrupt in GPT module */
+ epit_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+
+ /* Clear pending interrupt */
+ epit_irq_acknowledge();
+ }
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+ local_irq_restore(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR "epit_set_mode: Periodic mode is not "
+ "supported for i.MX EPIT\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /*
+ * Do not put overhead of interrupt enable/disable into
+ * epit_set_next_event(), the core has about 4 minutes
+ * to call epit_set_next_event() or shutdown clock after
+ * mode switching
+ */
+ local_irq_save(flags);
+ epit_irq_enable();
+ local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_epit;
+
+ epit_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction epit_timer_irq = {
+ .name = "i.MX EPIT Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = epit_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_epit = {
+ .name = "epit",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = epit_set_mode,
+ .set_next_event = epit_set_next_event,
+ .rating = 200,
+};
+
+static int __init epit_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_epit.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_epit.shift);
+ clockevent_epit.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_epit);
+ clockevent_epit.min_delta_ns =
+ clockevent_delta2ns(0x800, &clockevent_epit);
+
+ clockevent_epit.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_epit);
+
+ return 0;
+}
+
+void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
+{
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialise to a known state (all timers off, and timing reset)
+ */
+ __raw_writel(0x0, timer_base + EPITCR);
+
+ __raw_writel(0xffffffff, timer_base + EPITLR);
+ __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
+ timer_base + EPITCR);
+
+ /* init and register the timer to the framework */
+ epit_clocksource_init(timer_clk);
+ epit_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &epit_timer_irq);
+}
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset);
+ l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
__raw_writel(l, reg);
spin_unlock_irqrestore(&port->lock, flags);
}
extern void mx35_init_irq(void);
extern void mx51_init_irq(void);
extern void mxc91231_init_irq(void);
+extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
extern int mx1_clocks_init(unsigned long fref);
extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data);
-#if defined (CONFIG_CAN_FLEXCAN) || defined (CONFIG_CAN_FLEXCAN_MODULE)
+#include <linux/fec.h>
+struct imx_fec_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata);
+
#include <linux/can/platform/flexcan.h>
struct platform_device *__init imx_add_flexcan(int id,
resource_size_t iobase, resource_size_t iosize,
resource_size_t irq,
const struct flexcan_platform_data *pdata);
-#else
-/* the ifdef can be removed once the flexcan driver has been merged */
-struct flexcan_platform_data;
-static inline struct platform_device *__init imx_add_flexcan(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
- const struct flexcan_platform_data *pdata)
-{
- return NULL;
-}
-#endif
#include <mach/i2c.h>
-struct platform_device *__init imx_add_imx_i2c(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+struct imx_imx_i2c_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_i2c(
+ const struct imx_imx_i2c_data *data,
const struct imxi2c_platform_data *pdata);
+#include <mach/ssi.h>
+struct imx_imx_ssi_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmatx0;
+ resource_size_t dmarx0;
+ resource_size_t dmatx1;
+ resource_size_t dmarx1;
+};
+struct platform_device *__init imx_add_imx_ssi(
+ const struct imx_imx_ssi_data *data,
+ const struct imx_ssi_platform_data *pdata);
+
#include <mach/imx-uart.h>
-struct platform_device *__init imx_add_imx_uart_3irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irqrx, resource_size_t irqtx,
- resource_size_t irqrts,
+struct imx_imx_uart_3irq_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irqrx;
+ resource_size_t irqtx;
+ resource_size_t irqrts;
+};
+struct platform_device *__init imx_add_imx_uart_3irq(
+ const struct imx_imx_uart_3irq_data *data,
const struct imxuart_platform_data *pdata);
-struct platform_device *__init imx_add_imx_uart_1irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
+
+struct imx_imx_uart_1irq_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_uart_1irq(
+ const struct imx_imx_uart_1irq_data *data,
const struct imxuart_platform_data *pdata);
#include <mach/mxc_nand.h>
-struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata);
-struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata);
+struct imx_mxc_nand_data {
+ /*
+ * id is traditionally 0, but -1 is more appropriate. We use -1 for new
+ * machines but don't change existing devices as the nand device usually
+ * appears in the kernel command line to pass its partitioning.
+ */
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t axibase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_nand(
+ const struct imx_mxc_nand_data *data,
+ const struct mxc_nand_platform_data *pdata);
#include <mach/spi.h>
-struct platform_device *__init imx_add_spi_imx(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+struct imx_spi_imx_data {
+ const char *devid;
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ int irq;
+};
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
const struct spi_imx_master *pdata);
+
+#include <mach/esdhc.h>
+struct platform_device *__init imx_add_esdhc(int id,
+ resource_size_t iobase, resource_size_t iosize,
+ resource_size_t irq,
+ const struct esdhc_platform_data *pdata);
--- /dev/null
+/*
+ * Copyright 2010 Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef __ASM_ARCH_IMX_ESDHC_H
+#define __ASM_ARCH_IMX_ESDHC_H
+
+struct esdhc_platform_data {
+ unsigned int wp_gpio; /* write protect pin */
+};
+#endif /* __ASM_ARCH_IMX_ESDHC_H */
PAD_CTL_PKE | PAD_CTL_HYS)
#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
PAD_CTL_SRE_FAST)
+#define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_SRE_FAST)
+
+#define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_2 (PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX51_PAD_CTRL_3 (PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_CTRL_4 (PAD_CTL_DVS | PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX51_PAD_CTRL_5 (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
/*
* The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
#define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_EB2__GPIO_2_22 IOMUX_PAD(0x468, 0x0d4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0x0d4, 3, 0x0, 0, MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
#define MX51_PAD_EIM_EB3__GPIO_2_23 IOMUX_PAD(0x46c, 0x0d8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB3__FEC_RDAT1 IOMUX_PAD(0x46c, 0x0d8, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_OE__GPIO_2_24 IOMUX_PAD(0x470, 0x0dc, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CS0__GPIO_2_25 IOMUX_PAD(0x474, 0x0e0, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CS1__GPIO_2_26 IOMUX_PAD(0x478, 0x0e4, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CS2__GPIO_2_27 IOMUX_PAD(0x47c, 0x0e8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS2__FEC_RDAT2 IOMUX_PAD(0x47c, 0x0e8, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_CS3__GPIO_2_28 IOMUX_PAD(0x480, 0x0ec, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS3__FEC_RDAT3 IOMUX_PAD(0x480, 0x0ec, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_CS4__GPIO_2_29 IOMUX_PAD(0x484, 0x0f0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0x0f0, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_CS5__GPIO_2_30 IOMUX_PAD(0x488, 0x0f4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x488, 0x0f4, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_DTACK__GPIO_2_31 IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_LBA__GPIO_3_1 IOMUX_PAD(0x494, 0x0FC, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CRE__GPIO_3_2 IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_RB0__GPIO_3_8 IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_RB1__GPIO_3_9 IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_RB2__GPIO_3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
+#define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_NANDF_RB3__GPIO_3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
+#define MX51_PAD_NANDF_RB3__FEC_RXCLK IOMUX_PAD(0x504, 0x128, 1, 0x0, 0, MX51_PAD_CTRL_2)
+#define MX51_PAD_NANDF_RB6__FEC_RDAT0 IOMUX_PAD(0x5DC, 0x134, 1, 0x0, 0, MX51_PAD_CTRL_4)
+#define MX51_PAD_NANDF_RB7__FEC_TDAT0 IOMUX_PAD(0x5E0, 0x138, 1, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_GPIO_NAND__GPIO_3_12 IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_CS0__GPIO_3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_CS1__GPIO_3_17 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_CS2__GPIO_3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS2__FEC_TX_ER IOMUX_PAD(0x520, 0x138, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS3__GPIO_3_19 IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13C, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS4__GPIO_3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS4__FEC_TDAT1 IOMUX_PAD(0x528, 0x140, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS5__GPIO_3_21 IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS5__FEC_TDAT2 IOMUX_PAD(0x52C, 0x144, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS6__GPIO_3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS6__FEC_TDAT3 IOMUX_PAD(0x530, 0x148, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS7__GPIO_3_23 IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14C, 1, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_RDY_INT__GPIO_3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x0, 0, MX51_PAD_CTRL_4)
#define MX51_PAD_NANDF_D15__GPIO_3_25 IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53C, 0x154, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_NANDF_D14__GPIO_3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_D13__GPIO_3_27 IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_D12__GPIO_3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_I2C1_CLK__HSI2C_CLK IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_I2C1_DAT__GPIO_4_17 IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_I2C1_DAT__HSI2C_DAT IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_TXD__GPIO_4_18 IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_RXD__GPIO_4_19 IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_CK__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_CK__GPIO_4_20 IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_FS__AUD3_BB_FS IOMUX_PAD(0x5FC, 0x20C, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_FS__GPIO_4_21 IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_MOSI__GPIO_4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_MISO__GPIO_4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_SS0__GPIO_4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 IOMUX_PAD(0x60C, 0x21C, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_SS1__GPIO_4_25 IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_RDY__GPIO_4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_SCLK__GPIO_4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
#define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
#define MX51_PAD_DI1_PIN11__GPIO_3_0 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x978, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x97c, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x980, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x984, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x988, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x98c, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x990, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x994, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79C, 0x394, 1, 0x8e0, 1, NO_PAD_CTRL)
#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__AUD5_RXC IOMUX_PAD(0x7A0, 0x398, 1, 0x8dc, 1, NO_PAD_CTRL)
#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7A4, 0x39C, 1, 0x8d8, 2, NO_PAD_CTRL)
#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__AUD5_RXD IOMUX_PAD(0x7A8, 0x3A0, 1, 0x8d4, 2, NO_PAD_CTRL)
#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__AUD5_TXC IOMUX_PAD(0x7AC, 0x3A4, 1, 0x8e4, 2, NO_PAD_CTRL)
#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7B0, 0x3A8, 1, 0x8e8, 2, NO_PAD_CTRL)
#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
#define MX21_INT_GPT1 26
#define MX21_INT_WDOG 27
#define MX21_INT_PCMCIA 28
-#define MX21_INT_NANDFC 29
+#define MX21_INT_NFC 29
#define MX21_INT_BMI 30
#define MX21_INT_CSI 31
#define MX21_INT_DMACH0 32
#define MX25_SSI1_BASE_ADDR 0x50034000
#define MX25_NFC_BASE_ADDR 0xbb000000
#define MX25_DRYICE_BASE_ADDR 0x53ffc000
+#define MX25_ESDHC1_BASE_ADDR 0x53fb4000
+#define MX25_ESDHC2_BASE_ADDR 0x53fb8000
#define MX25_LCDC_BASE_ADDR 0x53fbc000
#define MX25_KPP_BASE_ADDR 0x43fa8000
#define MX25_OTG_BASE_ADDR 0x53ff4000
#define MX25_INT_I2C1 3
#define MX25_INT_I2C2 4
#define MX25_INT_UART4 5
+#define MX25_INT_MMC_SDHC2 8
+#define MX25_INT_MMC_SDHC1 9
#define MX25_INT_I2C3 10
#define MX25_INT_SSI2 11
#define MX25_INT_SSI1 12
#define MX25_INT_KPP 24
#define MX25_INT_DRYICE 25
#define MX25_INT_UART2 32
-#define MX25_INT_NANDFC 33
+#define MX25_INT_NFC 33
#define MX25_INT_LCDC 39
#define MX25_INT_UART5 40
#define MX25_INT_CAN1 43
#define MX25_INT_UART1 45
#define MX25_INT_FEC 57
+#define MX25_DMA_REQ_SSI2_RX1 22
+#define MX25_DMA_REQ_SSI2_TX1 23
+#define MX25_DMA_REQ_SSI2_RX0 24
+#define MX25_DMA_REQ_SSI2_TX0 25
+#define MX25_DMA_REQ_SSI1_RX1 26
+#define MX25_DMA_REQ_SSI1_TX1 27
+#define MX25_DMA_REQ_SSI1_RX0 28
+#define MX25_DMA_REQ_SSI1_TX0 29
+
#endif /* ifndef __MACH_MX25_H__ */
#define MX27_INT_GPT1 26
#define MX27_INT_WDOG 27
#define MX27_INT_PCMCIA 28
-#define MX27_INT_NANDFC 29
+#define MX27_INT_NFC 29
#define MX27_INT_ATA 30
#define MX27_INT_CSI 31
#define MX27_INT_DMACH0 32
#define MX31_INT_POWER_FAIL 30
#define MX31_INT_CCM_DVFS 31
#define MX31_INT_UART2 32
-#define MX31_INT_NANDFC 33
+#define MX31_INT_NFC 33
#define MX31_INT_SDMA 34
#define MX31_INT_USB1 35
#define MX31_INT_USB2 36
#define MX31_INT_EXT_WDOG 62
#define MX31_INT_EXT_TV 63
+#define MX31_DMA_REQ_SSI2_RX1 22
+#define MX31_DMA_REQ_SSI2_TX1 23
+#define MX31_DMA_REQ_SSI2_RX0 24
+#define MX31_DMA_REQ_SSI2_TX0 25
+#define MX31_DMA_REQ_SSI1_RX1 26
+#define MX31_DMA_REQ_SSI1_TX1 27
+#define MX31_DMA_REQ_SSI1_RX0 28
+#define MX31_DMA_REQ_SSI1_TX0 29
+
#define MX31_PROD_SIGNATURE 0x1 /* For MX31 */
/* silicon revisions specific to i.MX31 */
#ifndef __MACH_MX35_H__
#define __MACH_MX35_H__
+
/*
* IRAM
*/
#define MX35_GPIO3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xa4000)
#define MX35_SCC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xac000)
#define MX35_RNGA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb0000)
+#define MX35_ESDHC1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb4000)
+#define MX35_ESDHC2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb8000)
+#define MX35_ESDHC3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xbc000)
#define MX35_IPU_CTRL_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc0000)
#define MX35_AUDMUX_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc4000)
#define MX35_GPIO1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xcc000)
#define MX35_CAN1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe4000)
#define MX35_CAN2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe8000)
#define MX35_RTIC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xec000)
+#define MX35_IIM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf0000)
+
#define MX35_OTG_BASE_ADDR 0x53ff4000
#define MX35_ROMP_BASE_ADDR 0x60000000
#define MX35_INT_GPT 29
#define MX35_INT_POWER_FAIL 30
#define MX35_INT_UART2 32
-#define MX35_INT_NANDFC 33
+#define MX35_INT_NFC 33
#define MX35_INT_SDMA 34
#define MX35_INT_USBHS 35
#define MX35_INT_USBOTG 37
#define MX35_INT_EXT_WDOG 62
#define MX35_INT_EXT_TV 63
+#define MX35_DMA_REQ_SSI2_RX1 22
+#define MX35_DMA_REQ_SSI2_TX1 23
+#define MX35_DMA_REQ_SSI2_RX0 24
+#define MX35_DMA_REQ_SSI2_TX0 25
+#define MX35_DMA_REQ_SSI1_RX1 26
+#define MX35_DMA_REQ_SSI1_TX1 27
+#define MX35_DMA_REQ_SSI1_RX0 28
+#define MX35_DMA_REQ_SSI1_TX0 29
+
#define MX35_PROD_SIGNATURE 0x1 /* For MX31 */
-/* silicon revisions specific to i.MX31 */
-#define MX35_CHIP_REV_1_0 0x10
-#define MX35_CHIP_REV_1_1 0x11
-#define MX35_CHIP_REV_1_2 0x12
-#define MX35_CHIP_REV_1_3 0x13
-#define MX35_CHIP_REV_2_0 0x20
-#define MX35_CHIP_REV_2_1 0x21
-#define MX35_CHIP_REV_2_2 0x22
-#define MX35_CHIP_REV_2_3 0x23
-#define MX35_CHIP_REV_3_0 0x30
-#define MX35_CHIP_REV_3_1 0x31
-#define MX35_CHIP_REV_3_2 0x32
-
-#define MX35_SYSTEM_REV_MIN MX35_CHIP_REV_1_0
+#define MX35_SYSTEM_REV_MIN MX3x_CHIP_REV_1_0
#define MX35_SYSTEM_REV_NUM 3
#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
#define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */
-/* silicon revisions specific to i.MX31 */
+/* silicon revisions specific to i.MX31 and i.MX35 */
#define MX3x_CHIP_REV_1_0 0x10
#define MX3x_CHIP_REV_1_1 0x11
#define MX3x_CHIP_REV_1_2 0x12
{
return mx31_cpu_rev;
}
+
+extern unsigned int mx35_cpu_rev;
+extern void mx35_read_cpu_rev(void);
+
+static inline int mx35_revision(void)
+{
+ return mx35_cpu_rev;
+}
#endif
#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
#define MXC_INT_EXT_WDOG MX3x_INT_EXT_WDOG
#define MXC_INT_EXT_TV MX3x_INT_EXT_TV
#define PROD_SIGNATURE MX3x_PROD_SIGNATURE
-#define CHIP_REV_1_0 MX3x_CHIP_REV_1_0
-#define CHIP_REV_1_1 MX3x_CHIP_REV_1_1
-#define CHIP_REV_1_2 MX3x_CHIP_REV_1_2
-#define CHIP_REV_1_3 MX3x_CHIP_REV_1_3
-#define CHIP_REV_2_0 MX3x_CHIP_REV_2_0
-#define CHIP_REV_2_1 MX3x_CHIP_REV_2_1
-#define CHIP_REV_2_2 MX3x_CHIP_REV_2_2
-#define CHIP_REV_2_3 MX3x_CHIP_REV_2_3
-#define CHIP_REV_3_0 MX3x_CHIP_REV_3_0
-#define CHIP_REV_3_1 MX3x_CHIP_REV_3_1
-#define CHIP_REV_3_2 MX3x_CHIP_REV_3_2
-#define SYSTEM_REV_MIN MX3x_SYSTEM_REV_MIN
-#define SYSTEM_REV_NUM MX3x_SYSTEM_REV_NUM
#endif
#endif /* ifndef __MACH_MX3x_H__ */
-#ifndef __ASM_ARCH_MXC_MX51_H__
-#define __ASM_ARCH_MXC_MX51_H__
+#ifndef __MACH_MX51_H__
+#define __MACH_MX51_H__
/*
* MX51 memory map:
*
* Virt Phys Size What
* ---------------------------------------------------------------------------
- * FA3E0000 1FFE0000 128K IRAM (SCCv2 RAM)
+ * fa3e0000 1ffe0000 128K IRAM (SCCv2 RAM)
* 30000000 256M GPU
* 40000000 512M IPU
- * FA200000 60000000 1M DEBUG
- * FB100000 70000000 1M SPBA 0
- * FB000000 73F00000 1M AIPS 1
- * FB200000 83F00000 1M AIPS 2
- * 8FFFC000 16K TZIC (interrupt controller)
+ * fa200000 60000000 1M DEBUG
+ * fb100000 70000000 1M SPBA 0
+ * fb000000 73f00000 1M AIPS 1
+ * fb200000 83f00000 1M AIPS 2
+ * 8fffc000 16K TZIC (interrupt controller)
* 90000000 256M CSD0 SDRAM/DDR
- * A0000000 256M CSD1 SDRAM/DDR
- * B0000000 128M CS0 Flash
- * B8000000 128M CS1 Flash
- * C0000000 128M CS2 Flash
- * C8000000 64M CS3 Flash
- * CC000000 32M CS4 SRAM
- * CE000000 32M CS5 SRAM
- * CFFF0000 64K NFC (NAND Flash AXI)
- *
+ * a0000000 256M CSD1 SDRAM/DDR
+ * b0000000 128M CS0 Flash
+ * b8000000 128M CS1 Flash
+ * c0000000 128M CS2 Flash
+ * c8000000 64M CS3 Flash
+ * cc000000 32M CS4 SRAM
+ * ce000000 32M CS5 SRAM
+ * cfff0000 64K NFC (NAND Flash AXI)
*/
/*
/*
* IRAM
*/
-#define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */
-#define MX51_IRAM_BASE_ADDR_VIRT 0xFA3E0000
+#define MX51_IRAM_BASE_ADDR 0x1ffe0000 /* internal ram */
+#define MX51_IRAM_BASE_ADDR_VIRT 0xfa3e0000
#define MX51_IRAM_PARTITIONS 16
-#define MX51_IRAM_PARTITIONS_TO1 12
#define MX51_IRAM_SIZE (MX51_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+#define MX51_GPU_BASE_ADDR 0x20000000
+#define MX51_GPU_CTRL_BASE_ADDR 0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
+
+#define MX51_DEBUG_BASE_ADDR 0x60000000
+#define MX51_DEBUG_BASE_ADDR_VIRT 0xfa200000
+#define MX51_DEBUG_SIZE SZ_1M
+
+#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x01000)
+#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x02000)
+#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x03000)
+#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x04000)
+#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x05000)
+#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x06000)
+#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x07000)
+#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x08000)
+
/*
- * NFC
+ * SPBA global module enabled #0
*/
-#define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */
-#define MX51_NFC_AXI_SIZE SZ_64K
+#define MX51_SPBA0_BASE_ADDR 0x70000000
+#define MX51_SPBA0_BASE_ADDR_VIRT 0xfb100000
+#define MX51_SPBA0_SIZE SZ_1M
+
+#define MX51_MMC_SDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x04000)
+#define MX51_MMC_SDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x08000)
+#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0c000)
+#define MX51_ECSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x10000)
+#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x14000)
+#define MX51_MMC_SDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x20000)
+#define MX51_MMC_SDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x24000)
+#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x28000)
+#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x30000)
+#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x34000)
+#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x38000)
+#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x3c000)
/*
- * Graphics Memory of GPU
+ * AIPS 1
*/
-#define MX51_GPU_BASE_ADDR 0x20000000
-#define MX51_GPU2D_BASE_ADDR 0xD0000000
+#define MX51_AIPS1_BASE_ADDR 0x73f00000
+#define MX51_AIPS1_BASE_ADDR_VIRT 0xfb000000
+#define MX51_AIPS1_SIZE SZ_1M
+
+#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x80000)
+#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x84000)
+#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x88000)
+#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x8c000)
+#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x90000)
+#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x94000)
+#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x98000)
+#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x9c000)
+#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa0000)
+#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa4000)
+#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa8000)
+#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xac000)
+#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb0000)
+#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb4000)
+#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb8000)
+#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xbc000)
+#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xc0000)
+#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd0000)
+#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd4000)
+#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd8000)
-#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000
-#define MX51_TZIC_BASE_ADDR 0xE0000000
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR 0x83f00000
+#define MX51_AIPS2_BASE_ADDR_VIRT 0xfb200000
+#define MX51_AIPS2_SIZE SZ_1M
-#define MX51_DEBUG_BASE_ADDR 0x60000000
-#define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000
-#define MX51_DEBUG_SIZE SZ_1M
-#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00001000)
-#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00002000)
-#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00003000)
-#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00004000)
-#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00005000)
-#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00006000)
-#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00007000)
-#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00008000)
+#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x80000)
+#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x84000)
+#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x88000)
+#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x94000)
+#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x98000)
+#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x9c000)
+#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa0000)
+#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa4000)
+#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa8000)
+#define MX51_ECSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xac000)
+#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb0000)
+#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb4000)
+#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb8000)
+#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xbc000)
+#define MX51_CSPI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc0000)
+#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc4000)
+#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc8000)
+#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xcc000)
+#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd0000)
+#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd8000)
+#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd9000)
+#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xda000)
+#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdb000)
+#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdbf00)
+#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdc000)
+#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe0000)
+#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe4000)
+#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe8000)
+#define MX51_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xec000)
+#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf0000)
+#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf4000)
+#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf8000)
+
+#define MX51_CSD0_BASE_ADDR 0x90000000
+#define MX51_CSD1_BASE_ADDR 0xa0000000
+#define MX51_CS0_BASE_ADDR 0xb0000000
+#define MX51_CS1_BASE_ADDR 0xb8000000
+#define MX51_CS2_BASE_ADDR 0xc0000000
+#define MX51_CS3_BASE_ADDR 0xc8000000
+#define MX51_CS4_BASE_ADDR 0xcc000000
+#define MX51_CS5_BASE_ADDR 0xce000000
/*
- * SPBA global module enabled #0
+ * NFC
*/
-#define MX51_SPBA0_BASE_ADDR 0x70000000
-#define MX51_SPBA0_BASE_ADDR_VIRT 0xFB100000
-#define MX51_SPBA0_SIZE SZ_1M
+#define MX51_NFC_AXI_BASE_ADDR 0xcfff0000 /* NAND flash AXI */
+#define MX51_NFC_AXI_SIZE SZ_64K
+
+#define MX51_GPU2D_BASE_ADDR 0xd0000000
+#define MX51_TZIC_BASE_ADDR 0xe0000000
-#define MX51_MMC_SDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00004000)
-#define MX51_MMC_SDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00008000)
-#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0000C000)
-#define MX51_CSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00010000)
-#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00014000)
-#define MX51_MMC_SDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00020000)
-#define MX51_MMC_SDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00024000)
-#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00028000)
-#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00030000)
-#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00034000)
-#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00038000)
-#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0003C000)
+#define MX51_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX51_IRAM) ?: \
+ IMX_IO_ADDRESS(x, MX51_DEBUG) ?: \
+ IMX_IO_ADDRESS(x, MX51_SPBA0) ?: \
+ IMX_IO_ADDRESS(x, MX51_AIPS1) ?: \
+ IMX_IO_ADDRESS(x, MX51_AIPS2))
+
+/* This is currently used in <mach/debug-macro.S>, but should go away */
+#define MX51_AIPS1_IO_ADDRESS(x) \
+ (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
/*
* defines for SPBA modules
*/
#define MX51_SPBA_SDHC1 0x04
#define MX51_SPBA_SDHC2 0x08
-#define MX51_SPBA_UART3 0x0C
+#define MX51_SPBA_UART3 0x0c
#define MX51_SPBA_CSPI1 0x10
#define MX51_SPBA_SSI2 0x14
#define MX51_SPBA_SDHC3 0x20
#define MX51_SPBA_ATA 0x30
#define MX51_SPBA_SLIM 0x34
#define MX51_SPBA_HSI2C 0x38
-#define MX51_SPBA_CTRL 0x3C
-
-/*
- * AIPS 1
- */
-#define MX51_AIPS1_BASE_ADDR 0x73F00000
-#define MX51_AIPS1_BASE_ADDR_VIRT 0xFB000000
-#define MX51_AIPS1_SIZE SZ_1M
-
-#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00080000)
-#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00084000)
-#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00088000)
-#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0008C000)
-#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00090000)
-#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00094000)
-#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00098000)
-#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0009C000)
-#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A0000)
-#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A4000)
-#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A8000)
-#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000AC000)
-#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B0000)
-#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B4000)
-#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B8000)
-#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000BC000)
-#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000C0000)
-#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D0000)
-#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D4000)
-#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D8000)
+#define MX51_SPBA_CTRL 0x3c
/*
* Defines for modules using static and dynamic DMA channels
#define MX51_MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
#define MX51_MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
-/*
- * AIPS 2
- */
-#define MX51_AIPS2_BASE_ADDR 0x83F00000
-#define MX51_AIPS2_BASE_ADDR_VIRT 0xFB200000
-#define MX51_AIPS2_SIZE SZ_1M
-
-#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00080000)
-#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00084000)
-#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00088000)
-#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00094000)
-#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00098000)
-#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x0009C000)
-#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A0000)
-#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A4000)
-#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A8000)
-#define MX51_CSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000AC000)
-#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B0000)
-#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B4000)
-#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B8000)
-#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000BC000)
-#define MX51_CSPI3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C0000)
-#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C4000)
-#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C8000)
-#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000CC000)
-#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D0000)
-#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D8000)
-#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D9000)
-#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DA000)
-#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DB000)
-#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DBF00)
-#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DC000)
-#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E0000)
-#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E4000)
-#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E8000)
-#define MX51_MXC_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000EC000)
-#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F0000)
-#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F4000)
-#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F8000)
-
-/*
- * Memory regions and CS
- */
-#define MX51_GPU_CTRL_BASE_ADDR 0x30000000
-#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
-#define MX51_CSD0_BASE_ADDR 0x90000000
-#define MX51_CSD1_BASE_ADDR 0xA0000000
-#define MX51_CS0_BASE_ADDR 0xB0000000
-#define MX51_CS1_BASE_ADDR 0xB8000000
-#define MX51_CS2_BASE_ADDR 0xC0000000
-#define MX51_CS3_BASE_ADDR 0xC8000000
-#define MX51_CS4_BASE_ADDR 0xCC000000
-#define MX51_CS5_BASE_ADDR 0xCE000000
-
-/* Does given address belongs to the specified memory region? */
-#define ADDRESS_IN_REGION(addr, start, size) \
- (((addr) >= (start)) && ((addr) < (start)+(size)))
-
-/* Does given address belongs to the specified named `module'? */
-#define MX51_IS_MODULE(addr, module) \
- ADDRESS_IN_REGION(addr, MX51_ ## module ## _BASE_ADDR, \
- MX51_ ## module ## _SIZE)
-/*
- * This macro defines the physical to virtual address mapping for all the
- * peripheral modules. It is used by passing in the physical address as x
- * and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-
-#define MX51_IO_ADDRESS(x) \
- (void __iomem *) \
- (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
- 0xDEADBEEF)
-
-/*
- * define the address mapping macros: in physical address order
- */
-#define MX51_IRAM_IO_ADDRESS(x) \
- (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
-
-#define MX51_DEBUG_IO_ADDRESS(x) \
- (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
-
-#define MX51_SPBA0_IO_ADDRESS(x) \
- (((x) - MX51_SPBA0_BASE_ADDR) + MX51_SPBA0_BASE_ADDR_VIRT)
-
-#define MX51_AIPS1_IO_ADDRESS(x) \
- (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
-
-#define MX51_AIPS2_IO_ADDRESS(x) \
- (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
-
#define MX51_IS_MEM_DEVICE_NONSHARED(x) 0
/*
* DMA request assignments
*/
-#define MX51_DMA_REQ_SSI3_TX1 47
-#define MX51_DMA_REQ_SSI3_RX1 46
-#define MX51_DMA_REQ_SPDIF 45
-#define MX51_DMA_REQ_UART3_TX 44
-#define MX51_DMA_REQ_UART3_RX 43
-#define MX51_DMA_REQ_SLIM_B_TX 42
-#define MX51_DMA_REQ_SDHC4 41
-#define MX51_DMA_REQ_SDHC3 40
-#define MX51_DMA_REQ_CSPI_TX 39
-#define MX51_DMA_REQ_CSPI_RX 38
-#define MX51_DMA_REQ_SSI3_TX2 37
-#define MX51_DMA_REQ_IPU 36
-#define MX51_DMA_REQ_SSI3_RX2 35
-#define MX51_DMA_REQ_EPIT2 34
-#define MX51_DMA_REQ_CTI2_1 33
-#define MX51_DMA_REQ_EMI_WR 32
-#define MX51_DMA_REQ_CTI2_0 31
-#define MX51_DMA_REQ_EMI_RD 30
-#define MX51_DMA_REQ_SSI1_TX1 29
-#define MX51_DMA_REQ_SSI1_RX1 28
-#define MX51_DMA_REQ_SSI1_TX2 27
-#define MX51_DMA_REQ_SSI1_RX2 26
-#define MX51_DMA_REQ_SSI2_TX1 25
-#define MX51_DMA_REQ_SSI2_RX1 24
-#define MX51_DMA_REQ_SSI2_TX2 23
-#define MX51_DMA_REQ_SSI2_RX2 22
-#define MX51_DMA_REQ_SDHC2 21
-#define MX51_DMA_REQ_SDHC1 20
-#define MX51_DMA_REQ_UART1_TX 19
-#define MX51_DMA_REQ_UART1_RX 18
-#define MX51_DMA_REQ_UART2_TX 17
-#define MX51_DMA_REQ_UART2_RX 16
-#define MX51_DMA_REQ_GPU 15
-#define MX51_DMA_REQ_EXTREQ1 14
-#define MX51_DMA_REQ_FIRI_TX 13
-#define MX51_DMA_REQ_FIRI_RX 12
-#define MX51_DMA_REQ_HS_I2C_RX 11
-#define MX51_DMA_REQ_HS_I2C_TX 10
-#define MX51_DMA_REQ_CSPI2_TX 9
-#define MX51_DMA_REQ_CSPI2_RX 8
-#define MX51_DMA_REQ_CSPI1_TX 7
-#define MX51_DMA_REQ_CSPI1_RX 6
-#define MX51_DMA_REQ_SLIM_B 5
-#define MX51_DMA_REQ_ATA_TX_END 4
-#define MX51_DMA_REQ_ATA_TX 3
-#define MX51_DMA_REQ_ATA_RX 2
-#define MX51_DMA_REQ_GPC 1
-#define MX51_DMA_REQ_VPU 0
+#define MX51_DMA_REQ_VPU 0
+#define MX51_DMA_REQ_GPC 1
+#define MX51_DMA_REQ_ATA_RX 2
+#define MX51_DMA_REQ_ATA_TX 3
+#define MX51_DMA_REQ_ATA_TX_END 4
+#define MX51_DMA_REQ_SLIM_B 5
+#define MX51_DMA_REQ_CSPI1_RX 6
+#define MX51_DMA_REQ_CSPI1_TX 7
+#define MX51_DMA_REQ_CSPI2_RX 8
+#define MX51_DMA_REQ_CSPI2_TX 9
+#define MX51_DMA_REQ_HS_I2C_TX 10
+#define MX51_DMA_REQ_HS_I2C_RX 11
+#define MX51_DMA_REQ_FIRI_RX 12
+#define MX51_DMA_REQ_FIRI_TX 13
+#define MX51_DMA_REQ_EXTREQ1 14
+#define MX51_DMA_REQ_GPU 15
+#define MX51_DMA_REQ_UART2_RX 16
+#define MX51_DMA_REQ_UART2_TX 17
+#define MX51_DMA_REQ_UART1_RX 18
+#define MX51_DMA_REQ_UART1_TX 19
+#define MX51_DMA_REQ_SDHC1 20
+#define MX51_DMA_REQ_SDHC2 21
+#define MX51_DMA_REQ_SSI2_RX1 22
+#define MX51_DMA_REQ_SSI2_TX1 23
+#define MX51_DMA_REQ_SSI2_RX0 24
+#define MX51_DMA_REQ_SSI2_TX0 25
+#define MX51_DMA_REQ_SSI1_RX1 26
+#define MX51_DMA_REQ_SSI1_TX1 27
+#define MX51_DMA_REQ_SSI1_RX0 28
+#define MX51_DMA_REQ_SSI1_TX0 29
+#define MX51_DMA_REQ_EMI_RD 30
+#define MX51_DMA_REQ_CTI2_0 31
+#define MX51_DMA_REQ_EMI_WR 32
+#define MX51_DMA_REQ_CTI2_1 33
+#define MX51_DMA_REQ_EPIT2 34
+#define MX51_DMA_REQ_SSI3_RX2 35
+#define MX51_DMA_REQ_IPU 36
+#define MX51_DMA_REQ_SSI3_TX2 37
+#define MX51_DMA_REQ_CSPI_RX 38
+#define MX51_DMA_REQ_CSPI_TX 39
+#define MX51_DMA_REQ_SDHC3 40
+#define MX51_DMA_REQ_SDHC4 41
+#define MX51_DMA_REQ_SLIM_B_TX 42
+#define MX51_DMA_REQ_UART3_RX 43
+#define MX51_DMA_REQ_UART3_TX 44
+#define MX51_DMA_REQ_SPDIF 45
+#define MX51_DMA_REQ_SSI3_RX1 46
+#define MX51_DMA_REQ_SSI3_TX1 47
/*
* Interrupt numbers
*/
-#define MX51_MXC_INT_BASE 0
-#define MX51_MXC_INT_RESV0 0
-#define MX51_MXC_INT_MMC_SDHC1 1
-#define MX51_MXC_INT_MMC_SDHC2 2
-#define MX51_MXC_INT_MMC_SDHC3 3
-#define MX51_MXC_INT_MMC_SDHC4 4
-#define MX51_MXC_INT_RESV5 5
-#define MX51_MXC_INT_SDMA 6
-#define MX51_MXC_INT_IOMUX 7
-#define MX51_MXC_INT_NFC 8
-#define MX51_MXC_INT_VPU 9
-#define MX51_MXC_INT_IPU_ERR 10
-#define MX51_MXC_INT_IPU_SYN 11
-#define MX51_MXC_INT_GPU 12
-#define MX51_MXC_INT_RESV13 13
-#define MX51_MXC_INT_USB_H1 14
-#define MX51_MXC_INT_EMI 15
-#define MX51_MXC_INT_USB_H2 16
-#define MX51_MXC_INT_USB_H3 17
-#define MX51_MXC_INT_USB_OTG 18
-#define MX51_MXC_INT_SAHARA_H0 19
-#define MX51_MXC_INT_SAHARA_H1 20
-#define MX51_MXC_INT_SCC_SMN 21
-#define MX51_MXC_INT_SCC_STZ 22
-#define MX51_MXC_INT_SCC_SCM 23
-#define MX51_MXC_INT_SRTC_NTZ 24
-#define MX51_MXC_INT_SRTC_TZ 25
-#define MX51_MXC_INT_RTIC 26
-#define MX51_MXC_INT_CSU 27
-#define MX51_MXC_INT_SLIM_B 28
-#define MX51_MXC_INT_SSI1 29
-#define MX51_MXC_INT_SSI2 30
-#define MX51_MXC_INT_UART1 31
-#define MX51_MXC_INT_UART2 32
-#define MX51_MXC_INT_UART3 33
-#define MX51_MXC_INT_RESV34 34
-#define MX51_MXC_INT_RESV35 35
-#define MX51_MXC_INT_CSPI1 36
-#define MX51_MXC_INT_CSPI2 37
-#define MX51_MXC_INT_CSPI 38
-#define MX51_MXC_INT_GPT 39
-#define MX51_MXC_INT_EPIT1 40
-#define MX51_MXC_INT_EPIT2 41
-#define MX51_MXC_INT_GPIO1_INT7 42
-#define MX51_MXC_INT_GPIO1_INT6 43
-#define MX51_MXC_INT_GPIO1_INT5 44
-#define MX51_MXC_INT_GPIO1_INT4 45
-#define MX51_MXC_INT_GPIO1_INT3 46
-#define MX51_MXC_INT_GPIO1_INT2 47
-#define MX51_MXC_INT_GPIO1_INT1 48
-#define MX51_MXC_INT_GPIO1_INT0 49
-#define MX51_MXC_INT_GPIO1_LOW 50
-#define MX51_MXC_INT_GPIO1_HIGH 51
-#define MX51_MXC_INT_GPIO2_LOW 52
-#define MX51_MXC_INT_GPIO2_HIGH 53
-#define MX51_MXC_INT_GPIO3_LOW 54
-#define MX51_MXC_INT_GPIO3_HIGH 55
-#define MX51_MXC_INT_GPIO4_LOW 56
-#define MX51_MXC_INT_GPIO4_HIGH 57
-#define MX51_MXC_INT_WDOG1 58
-#define MX51_MXC_INT_WDOG2 59
-#define MX51_MXC_INT_KPP 60
-#define MX51_MXC_INT_PWM1 61
-#define MX51_MXC_INT_I2C1 62
-#define MX51_MXC_INT_I2C2 63
-#define MX51_MXC_INT_HS_I2C 64
-#define MX51_MXC_INT_RESV65 65
-#define MX51_MXC_INT_RESV66 66
-#define MX51_MXC_INT_SIM_IPB 67
-#define MX51_MXC_INT_SIM_DAT 68
-#define MX51_MXC_INT_IIM 69
-#define MX51_MXC_INT_ATA 70
-#define MX51_MXC_INT_CCM1 71
-#define MX51_MXC_INT_CCM2 72
-#define MX51_MXC_INT_GPC1 73
-#define MX51_MXC_INT_GPC2 74
-#define MX51_MXC_INT_SRC 75
-#define MX51_MXC_INT_NM 76
-#define MX51_MXC_INT_PMU 77
-#define MX51_MXC_INT_CTI_IRQ 78
-#define MX51_MXC_INT_CTI1_TG0 79
-#define MX51_MXC_INT_CTI1_TG1 80
-#define MX51_MXC_INT_MCG_ERR 81
-#define MX51_MXC_INT_MCG_TMR 82
-#define MX51_MXC_INT_MCG_FUNC 83
-#define MX51_MXC_INT_GPU2_IRQ 84
-#define MX51_MXC_INT_GPU2_BUSY 85
-#define MX51_MXC_INT_RESV86 86
-#define MX51_MXC_INT_FEC 87
-#define MX51_MXC_INT_OWIRE 88
-#define MX51_MXC_INT_CTI1_TG2 89
-#define MX51_MXC_INT_SJC 90
-#define MX51_MXC_INT_SPDIF 91
-#define MX51_MXC_INT_TVE 92
-#define MX51_MXC_INT_FIRI 93
-#define MX51_MXC_INT_PWM2 94
-#define MX51_MXC_INT_SLIM_EXP 95
-#define MX51_MXC_INT_SSI3 96
-#define MX51_MXC_INT_EMI_BOOT 97
-#define MX51_MXC_INT_CTI1_TG3 98
-#define MX51_MXC_INT_SMC_RX 99
-#define MX51_MXC_INT_VPU_IDLE 100
-#define MX51_MXC_INT_EMI_NFC 101
-#define MX51_MXC_INT_GPU_IDLE 102
+#define MX51_MXC_INT_BASE 0
+#define MX51_MXC_INT_RESV0 0
+#define MX51_MXC_INT_MMC_SDHC1 1
+#define MX51_MXC_INT_MMC_SDHC2 2
+#define MX51_MXC_INT_MMC_SDHC3 3
+#define MX51_MXC_INT_MMC_SDHC4 4
+#define MX51_MXC_INT_RESV5 5
+#define MX51_INT_SDMA 6
+#define MX51_MXC_INT_IOMUX 7
+#define MX51_INT_NFC 8
+#define MX51_MXC_INT_VPU 9
+#define MX51_MXC_INT_IPU_ERR 10
+#define MX51_MXC_INT_IPU_SYN 11
+#define MX51_MXC_INT_GPU 12
+#define MX51_MXC_INT_RESV13 13
+#define MX51_MXC_INT_USB_H1 14
+#define MX51_MXC_INT_EMI 15
+#define MX51_MXC_INT_USB_H2 16
+#define MX51_MXC_INT_USB_H3 17
+#define MX51_MXC_INT_USB_OTG 18
+#define MX51_MXC_INT_SAHARA_H0 19
+#define MX51_MXC_INT_SAHARA_H1 20
+#define MX51_MXC_INT_SCC_SMN 21
+#define MX51_MXC_INT_SCC_STZ 22
+#define MX51_MXC_INT_SCC_SCM 23
+#define MX51_MXC_INT_SRTC_NTZ 24
+#define MX51_MXC_INT_SRTC_TZ 25
+#define MX51_MXC_INT_RTIC 26
+#define MX51_MXC_INT_CSU 27
+#define MX51_MXC_INT_SLIM_B 28
+#define MX51_INT_SSI1 29
+#define MX51_INT_SSI2 30
+#define MX51_INT_UART1 31
+#define MX51_INT_UART2 32
+#define MX51_INT_UART3 33
+#define MX51_MXC_INT_RESV34 34
+#define MX51_MXC_INT_RESV35 35
+#define MX51_INT_ECSPI1 36
+#define MX51_INT_ECSPI2 37
+#define MX51_INT_CSPI 38
+#define MX51_MXC_INT_GPT 39
+#define MX51_MXC_INT_EPIT1 40
+#define MX51_MXC_INT_EPIT2 41
+#define MX51_MXC_INT_GPIO1_INT7 42
+#define MX51_MXC_INT_GPIO1_INT6 43
+#define MX51_MXC_INT_GPIO1_INT5 44
+#define MX51_MXC_INT_GPIO1_INT4 45
+#define MX51_MXC_INT_GPIO1_INT3 46
+#define MX51_MXC_INT_GPIO1_INT2 47
+#define MX51_MXC_INT_GPIO1_INT1 48
+#define MX51_MXC_INT_GPIO1_INT0 49
+#define MX51_MXC_INT_GPIO1_LOW 50
+#define MX51_MXC_INT_GPIO1_HIGH 51
+#define MX51_MXC_INT_GPIO2_LOW 52
+#define MX51_MXC_INT_GPIO2_HIGH 53
+#define MX51_MXC_INT_GPIO3_LOW 54
+#define MX51_MXC_INT_GPIO3_HIGH 55
+#define MX51_MXC_INT_GPIO4_LOW 56
+#define MX51_MXC_INT_GPIO4_HIGH 57
+#define MX51_MXC_INT_WDOG1 58
+#define MX51_MXC_INT_WDOG2 59
+#define MX51_MXC_INT_KPP 60
+#define MX51_MXC_INT_PWM1 61
+#define MX51_INT_I2C1 62
+#define MX51_INT_I2C2 63
+#define MX51_MXC_INT_HS_I2C 64
+#define MX51_MXC_INT_RESV65 65
+#define MX51_MXC_INT_RESV66 66
+#define MX51_MXC_INT_SIM_IPB 67
+#define MX51_MXC_INT_SIM_DAT 68
+#define MX51_MXC_INT_IIM 69
+#define MX51_MXC_INT_ATA 70
+#define MX51_MXC_INT_CCM1 71
+#define MX51_MXC_INT_CCM2 72
+#define MX51_MXC_INT_GPC1 73
+#define MX51_MXC_INT_GPC2 74
+#define MX51_MXC_INT_SRC 75
+#define MX51_MXC_INT_NM 76
+#define MX51_MXC_INT_PMU 77
+#define MX51_MXC_INT_CTI_IRQ 78
+#define MX51_MXC_INT_CTI1_TG0 79
+#define MX51_MXC_INT_CTI1_TG1 80
+#define MX51_MXC_INT_MCG_ERR 81
+#define MX51_MXC_INT_MCG_TMR 82
+#define MX51_MXC_INT_MCG_FUNC 83
+#define MX51_MXC_INT_GPU2_IRQ 84
+#define MX51_MXC_INT_GPU2_BUSY 85
+#define MX51_MXC_INT_RESV86 86
+#define MX51_INT_FEC 87
+#define MX51_MXC_INT_OWIRE 88
+#define MX51_MXC_INT_CTI1_TG2 89
+#define MX51_MXC_INT_SJC 90
+#define MX51_MXC_INT_SPDIF 91
+#define MX51_MXC_INT_TVE 92
+#define MX51_MXC_INT_FIRI 93
+#define MX51_MXC_INT_PWM2 94
+#define MX51_MXC_INT_SLIM_EXP 95
+#define MX51_MXC_INT_SSI3 96
+#define MX51_MXC_INT_EMI_BOOT 97
+#define MX51_MXC_INT_CTI1_TG3 98
+#define MX51_MXC_INT_SMC_RX 99
+#define MX51_MXC_INT_VPU_IDLE 100
+#define MX51_MXC_INT_EMI_NFC 101
+#define MX51_MXC_INT_GPU_IDLE 102
/* silicon revisions specific to i.MX51 */
-#define MX51_CHIP_REV_1_0 0x10
-#define MX51_CHIP_REV_1_1 0x11
-#define MX51_CHIP_REV_1_2 0x12
-#define MX51_CHIP_REV_1_3 0x13
-#define MX51_CHIP_REV_2_0 0x20
-#define MX51_CHIP_REV_2_1 0x21
-#define MX51_CHIP_REV_2_2 0x22
-#define MX51_CHIP_REV_2_3 0x23
-#define MX51_CHIP_REV_3_0 0x30
-#define MX51_CHIP_REV_3_1 0x31
-#define MX51_CHIP_REV_3_2 0x32
-
-/* Mandatory defines used globally */
+#define MX51_CHIP_REV_1_0 0x10
+#define MX51_CHIP_REV_1_1 0x11
+#define MX51_CHIP_REV_1_2 0x12
+#define MX51_CHIP_REV_1_3 0x13
+#define MX51_CHIP_REV_2_0 0x20
+#define MX51_CHIP_REV_2_1 0x21
+#define MX51_CHIP_REV_2_2 0x22
+#define MX51_CHIP_REV_2_3 0x23
+#define MX51_CHIP_REV_3_0 0x30
+#define MX51_CHIP_REV_3_1 0x31
+#define MX51_CHIP_REV_3_2 0x32
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
-
extern int mx51_revision(void);
#endif
-#endif /* __ASM_ARCH_MXC_MX51_H__ */
+/* tape-out 1 defines */
+#define MX51_TZIC_BASE_ADDR_TO1 0x8fffc000
+
+#endif /* ifndef __MACH_MX51_H__ */
/*
- * linux/arch/arm/mach-nomadik/timer.c
+ * linux/arch/arm/plat-nomadik/timer.c
*
* Copyright (C) 2008 STMicroelectronics
* Copyright (C) 2010 Alessandro Rubini
cr = readl(mtu_base + MTU_CR(1));
writel(0, mtu_base + MTU_LR(1));
writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1));
- writel(0x2, mtu_base + MTU_IMSC);
+ writel(1 << 1, mtu_base + MTU_IMSC);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
{
unsigned long rate;
struct clk *clk0;
- struct clk *clk1;
- u32 cr;
+ u32 cr = MTU_CRn_32BITS;
clk0 = clk_get_sys("mtu0", NULL);
BUG_ON(IS_ERR(clk0));
- clk1 = clk_get_sys("mtu1", NULL);
- BUG_ON(IS_ERR(clk1));
-
clk_enable(clk0);
- clk_enable(clk1);
/*
- * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500:
- * use a divide-by-16 counter if it's more than 16MHz
+ * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
+ * for ux500.
+ * Use a divide-by-16 counter if the tick rate is more than 32MHz.
+ * At 32 MHz, the timer (with 32 bit counter) can be programmed
+ * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer
+ * with 16 gives too low timer resolution.
*/
- cr = MTU_CRn_32BITS;;
rate = clk_get_rate(clk0);
- if (rate > 16 << 20) {
+ if (rate > 32000000) {
rate /= 16;
cr |= MTU_CRn_PRESCALE_16;
} else {
pr_err("timer: failed to initialize clock source %s\n",
nmdk_clksrc.name);
- /* Timer 1 is used for events, fix according to rate */
- cr = MTU_CRn_32BITS;
- rate = clk_get_rate(clk1);
- if (rate > 16 << 20) {
- rate /= 16;
- cr |= MTU_CRn_PRESCALE_16;
- } else {
- cr |= MTU_CRn_PRESCALE_1;
- }
+ /* Timer 1 is used for events */
+
clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
config OMAP_DEBUG_LEDS
bool
depends on OMAP_DEBUG_DEVICES
- default y if LEDS
+ default y if LEDS_CLASS
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
/* Writing zero to RSYNC_ERR clears the IRQ */
MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
} else {
- complete(&mcbsp_rx->tx_irq_completion);
+ complete(&mcbsp_rx->rx_irq_completion);
}
return IRQ_HANDLED;
if (omap_sram_size == 0)
return;
- if (cpu_is_omap24xx()) {
- omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
-
- base = OMAP2_SRAM_PA;
- base = ROUND_DOWN(base, PAGE_SIZE);
- omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
- }
-
if (cpu_is_omap34xx()) {
- omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA;
- base = OMAP3_SRAM_PA;
- base = ROUND_DOWN(base, PAGE_SIZE);
- omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
-
/*
* SRAM must be marked as non-cached on OMAP3 since the
* CORE DPLL M2 divider change code (in SRAM) runs with the
omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED;
}
- if (cpu_is_omap44xx()) {
- omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA;
- base = OMAP4_SRAM_PA;
- base = ROUND_DOWN(base, PAGE_SIZE);
- omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
- }
- omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */
+ omap_sram_io_desc[0].virtual = omap_sram_base;
+ base = omap_sram_start;
+ base = ROUND_DOWN(base, PAGE_SIZE);
+ omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
+ omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE);
iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
*
* 4. matrix key and direct key will use the same debounce_interval by
* default, which should be sufficient in most cases
+ *
+ * pxa168 keypad platform specific parameter
+ *
+ * NOTE:
+ * clear_wakeup_event callback is a workaround required to clear the
+ * keypad interrupt. The keypad wake must be cleared in addition to
+ * reading the MI/DI bits in the KPC register.
*/
struct pxa27x_keypad_platform_data {
/* key debounce interval */
unsigned int debounce_interval;
+
+ /* clear wakeup event requirement for pxa168 */
+ void (*clear_wakeup_event)(void);
};
extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
--- /dev/null
+if ARCH_TCC_926
+
+menu "Telechips ARM926-based CPUs"
+
+choice
+ prompt "Telechips CPU type:"
+ default ARCH_TCC8K
+
+config ARCH_TCC8K
+ bool TCC8000
+ select USB_ARCH_HAS_OHCI
+ help
+ Support for Telechips TCC8000 systems
+
+endchoice
+
+source "arch/arm/mach-tcc8k/Kconfig"
+
+endmenu
+endif
--- /dev/null
+# "Telechips Platform Common Modules"
+
+obj-y := clock.o system.o
--- /dev/null
+/*
+ * Clock framework for Telechips SoCs
+ * Based on arch/arm/plat-mxc/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2010 Hans J. Koch, hjk@linutronix.de
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ BUG_ON(clk->refcount == 0);
+
+ if (!(--clk->refcount) && clk->disable) {
+ /* Unconditionally disable the clock in hardware */
+ clk->disable(clk);
+ /* recursively disable parents */
+ if (clk->parent)
+ __clk_disable(clk->parent);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->refcount++ == 0 && clk->enable) {
+ if (clk->parent)
+ ret = __clk_enable(clk->parent);
+ if (ret)
+ return ret;
+ else
+ return clk->enable(clk);
+ }
+
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!clk)
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (!clk)
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (!clk)
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk)
+ return 0;
+ if (!clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_rate || !rate)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk *old;
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_parent || !parent)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ old = clk->parent;
+ if (clk->refcount)
+ __clk_enable(parent);
+ ret = clk->set_parent(clk, parent);
+ if (ret)
+ old = parent;
+ if (clk->refcount)
+ __clk_disable(old);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return NULL;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
--- /dev/null
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
--- /dev/null
+/*
+ * Low level clock header file for Telechips TCC architecture
+ * (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_TCC_CLOCK_H__
+#define __ASM_ARCH_TCC_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+
+struct clk {
+ struct clk *parent;
+ /* id number of a root clock, 0 for normal clocks */
+ int root_id;
+ /* Reference count of clock enable/disable */
+ int refcount;
+ /* Address of associated BCLKCTRx register. Must be set. */
+ void __iomem *bclkctr;
+ /* Bit position for BCLKCTRx. Must be set. */
+ int bclk_shift;
+ /* Address of ACLKxxx register, if any. */
+ void __iomem *aclkreg;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
--- /dev/null
+/*
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+ .macro addruart,rx,tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x90000000 @ physical base address
+ movne \rx, #0xF1000000 @ virtual base
+ orr \rx, \rx, #0x00007000 @ UART0
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #0x44]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1001:
+ ldr \rd, [\rx, #0x14]
+ tst \rd, #0x20
+
+ beq 1001b
+ .endm
--- /dev/null
+/*
+ * include/asm-arm/arch-tcc83x/entry-macro.S
+ *
+ * Author : <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: Low-level IRQ helper macros for Telechips-based platforms
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * 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 <mach/hardware.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \base, =0xF2003000 @ base address of PIC registers
+
+ @@ read MREQ register of PIC0
+
+ mov \irqnr, #0
+ ldr \irqstat, [\base, #0x00000014 ] @ lower 32 interrupts
+ cmp \irqstat, #0
+ bne 1001f
+
+ @@ read MREQ register of PIC1
+
+ ldr \irqstat, [\base, #0x00000094] @ upper 32 interrupts
+ cmp \irqstat, #0
+ beq 1002f
+ mov \irqnr, #0x20
+
+1001:
+ movs \tmp, \irqstat, lsl #16
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #16
+
+ movs \tmp, \irqstat, lsl #8
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #8
+
+ movs \tmp, \irqstat, lsl #4
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #4
+
+ movs \tmp, \irqstat, lsl #2
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #2
+
+ movs \tmp, \irqstat, lsl #1
+ addeq \irqnr, \irqnr, #1
+ orrs \base, \base, #1
+1002:
+ @@ exit here, Z flag unset if IRQ
+
+ .endm
--- /dev/null
+/*
+ * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ * and Dirk Behme <dirk.behme@de.bosch.com>
+ * Rewritten by: <linux@telechips.com>
+ * Description: Hardware definitions for TCC8300 processors and boards
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Modifications for mainline (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Pulic License version 2.
+ */
+
+#ifndef __ASM_ARCH_TCC_HARDWARE_H
+#define __ASM_ARCH_TCC_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#endif
+#include <mach/io.h>
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_BASE 0xfffece00
+#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
+
+/* DPLL control registers */
+#define DPLL_CTL 0xfffecf00
+
+#endif /* __ASM_ARCH_TCC_HARDWARE_H */
--- /dev/null
+/*
+ * IO definitions for TCC8000 processors and boards
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Public License version 2.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
--- /dev/null
+/*
+ * IRQ definitions for TCC8xxx
+ *
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_TCC_IRQS_H
+#define __ASM_ARCH_TCC_IRQS_H
+
+#define NR_IRQS 64
+
+/* PIC0 interrupts */
+#define INT_ADMA1 0
+#define INT_BDMA 1
+#define INT_ADMA0 2
+#define INT_GDMA1 3
+#define INT_I2S0RX 4
+#define INT_I2S0TX 5
+#define INT_TC 6
+#define INT_UART0 7
+#define INT_USBD 8
+#define INT_SPI0TX 9
+#define INT_UDMA 10
+#define INT_LIRQ 11
+#define INT_GDMA2 12
+#define INT_GDMA0 13
+#define INT_TC32 14
+#define INT_LCD 15
+#define INT_ADC 16
+#define INT_I2C 17
+#define INT_RTCP 18
+#define INT_RTCA 19
+#define INT_NFC 20
+#define INT_SD0 21
+#define INT_GSB0 22
+#define INT_PK 23
+#define INT_USBH0 24
+#define INT_USBH1 25
+#define INT_G2D 26
+#define INT_ECC 27
+#define INT_SPI0RX 28
+#define INT_UART1 29
+#define INT_MSCL 30
+#define INT_GSB1 31
+/* PIC1 interrupts */
+#define INT_E0 32
+#define INT_E1 33
+#define INT_E2 34
+#define INT_E3 35
+#define INT_E4 36
+#define INT_E5 37
+#define INT_E6 38
+#define INT_E7 39
+#define INT_UART2 40
+#define INT_UART3 41
+#define INT_SPI1TX 42
+#define INT_SPI1RX 43
+#define INT_GSB2 44
+#define INT_SPDIF 45
+#define INT_CDIF 46
+#define INT_VBON 47
+#define INT_VBOFF 48
+#define INT_SD1 49
+#define INT_UART4 50
+#define INT_GDMA3 51
+#define INT_I2S1RX 52
+#define INT_I2S1TX 53
+#define INT_CAN0 54
+#define INT_CAN1 55
+#define INT_GSB3 56
+#define INT_KRST 57
+#define INT_UNUSED 58
+#define INT_SD0D3 59
+#define INT_SD1D3 60
+#define INT_GPS0 61
+#define INT_GPS1 62
+#define INT_GPS2 63
+
+#endif /* ASM_ARCH_TCC_IRQS_H */
--- /dev/null
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET UL(0x20000000)
+
+#endif
--- /dev/null
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: LINUX SYSTEM FUNCTIONS for TCC83x
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+extern void plat_tcc_reboot(void);
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ plat_tcc_reboot();
+}
+
+#endif
--- /dev/null
+/*
+ * Telechips TCC8000 register definitions
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPLv2.
+ */
+
+#ifndef TCC8K_REGS_H
+#define TCC8K_REGS_H
+
+#include <linux/types.h>
+
+#define EXT_SDRAM_BASE 0x20000000
+#define INT_SRAM_BASE 0x30000000
+#define INT_SRAM_SIZE SZ_32K
+#define CS0_BASE 0x40000000
+#define CS1_BASE 0x50000000
+#define CS1_SIZE SZ_64K
+#define CS2_BASE 0x60000000
+#define CS3_BASE 0x70000000
+#define AHB_PERI_BASE 0x80000000
+#define AHB_PERI_SIZE SZ_64K
+#define APB0_PERI_BASE 0x90000000
+#define APB0_PERI_SIZE SZ_128K
+#define APB1_PERI_BASE 0x98000000
+#define APB1_PERI_SIZE SZ_128K
+#define DATA_TCM_BASE 0xa0000000
+#define DATA_TCM_SIZE SZ_8K
+#define EXT_MEM_CTRL_BASE 0xf0000000
+#define EXT_MEM_CTRL_SIZE SZ_4K
+
+#define CS1_BASE_VIRT (void __iomem *)0xf7000000
+#define AHB_PERI_BASE_VIRT (void __iomem *)0xf4000000
+#define APB0_PERI_BASE_VIRT (void __iomem *)0xf1000000
+#define APB1_PERI_BASE_VIRT (void __iomem *)0xf2000000
+#define EXT_MEM_CTRL_BASE_VIRT (void __iomem *)0xf3000000
+#define INT_SRAM_BASE_VIRT (void __iomem *)0xf5000000
+#define DATA_TCM_BASE_VIRT (void __iomem *)0xf6000000
+
+#define __REG(x) (*((volatile u32 *)(x)))
+
+/* USB Device Controller Registers */
+#define UDC_BASE (AHB_PERI_BASE_VIRT + 0x8000)
+#define UDC_BASE_PHYS (AHB_PERI_BASE + 0x8000)
+
+#define UDC_IR_OFFS 0x00
+#define UDC_EIR_OFFS 0x04
+#define UDC_EIER_OFFS 0x08
+#define UDC_FAR_OFFS 0x0c
+#define UDC_FNR_OFFS 0x10
+#define UDC_EDR_OFFS 0x14
+#define UDC_RT_OFFS 0x18
+#define UDC_SSR_OFFS 0x1c
+#define UDC_SCR_OFFS 0x20
+#define UDC_EP0SR_OFFS 0x24
+#define UDC_EP0CR_OFFS 0x28
+
+#define UDC_ESR_OFFS 0x2c
+#define UDC_ECR_OFFS 0x30
+#define UDC_BRCR_OFFS 0x34
+#define UDC_BWCR_OFFS 0x38
+#define UDC_MPR_OFFS 0x3c
+#define UDC_DCR_OFFS 0x40
+#define UDC_DTCR_OFFS 0x44
+#define UDC_DFCR_OFFS 0x48
+#define UDC_DTTCR1_OFFS 0x4c
+#define UDC_DTTCR2_OFFS 0x50
+#define UDC_ESR2_OFFS 0x54
+
+#define UDC_SCR2_OFFS 0x58
+#define UDC_EP0BUF_OFFS 0x60
+#define UDC_EP1BUF_OFFS 0x64
+#define UDC_EP2BUF_OFFS 0x68
+#define UDC_EP3BUF_OFFS 0x6c
+#define UDC_PLICR_OFFS 0xa0
+#define UDC_PCR_OFFS 0xa4
+
+#define UDC_UPCR0_OFFS 0xc8
+#define UDC_UPCR1_OFFS 0xcc
+#define UDC_UPCR2_OFFS 0xd0
+#define UDC_UPCR3_OFFS 0xd4
+
+/* Bits in UDC_EIR */
+#define UDC_EIR_EP0I (1 << 0)
+#define UDC_EIR_EP1I (1 << 1)
+#define UDC_EIR_EP2I (1 << 2)
+#define UDC_EIR_EP3I (1 << 3)
+#define UDC_EIR_EPI_MASK 0x0f
+
+/* Bits in UDC_EIER */
+#define UDC_EIER_EP0IE (1 << 0)
+#define UDC_EIER_EP1IE (1 << 1)
+#define UDC_EIER_EP2IE (1 << 2)
+#define UDC_EIER_EP3IE (1 << 3)
+
+/* Bits in UDC_FNR */
+#define UDC_FNR_FN_MASK 0x7ff
+#define UDC_FNR_SM (1 << 13)
+#define UDC_FNR_FTL (1 << 14)
+
+/* Bits in UDC_SSR */
+#define UDC_SSR_HFRES (1 << 0)
+#define UDC_SSR_HFSUSP (1 << 1)
+#define UDC_SSR_HFRM (1 << 2)
+#define UDC_SSR_SDE (1 << 3)
+#define UDC_SSR_HSP (1 << 4)
+#define UDC_SSR_DM (1 << 5)
+#define UDC_SSR_DP (1 << 6)
+#define UDC_SSR_TBM (1 << 7)
+#define UDC_SSR_VBON (1 << 8)
+#define UDC_SSR_VBOFF (1 << 9)
+#define UDC_SSR_EOERR (1 << 10)
+#define UDC_SSR_DCERR (1 << 11)
+#define UDC_SSR_TCERR (1 << 12)
+#define UDC_SSR_BSERR (1 << 13)
+#define UDC_SSR_TMERR (1 << 14)
+#define UDC_SSR_BAERR (1 << 15)
+
+/* Bits in UDC_SCR */
+#define UDC_SCR_HRESE (1 << 0)
+#define UDC_SCR_HSSPE (1 << 1)
+#define UDC_SCR_RRDE (1 << 5)
+#define UDC_SCR_SPDEN (1 << 6)
+#define UDC_SCR_DIEN (1 << 12)
+
+/* Bits in UDC_EP0SR */
+#define UDC_EP0SR_RSR (1 << 0)
+#define UDC_EP0SR_TST (1 << 1)
+#define UDC_EP0SR_SHT (1 << 4)
+#define UDC_EP0SR_LWO (1 << 6)
+
+/* Bits in UDC_EP0CR */
+#define UDC_EP0CR_ESS (1 << 1)
+
+/* Bits in UDC_ESR */
+#define UDC_ESR_RPS (1 << 0)
+#define UDC_ESR_TPS (1 << 1)
+#define UDC_ESR_LWO (1 << 4)
+#define UDC_ESR_FFS (1 << 6)
+
+/* Bits in UDC_ECR */
+#define UDC_ECR_ESS (1 << 1)
+#define UDC_ECR_CDP (1 << 2)
+
+#define UDC_ECR_FLUSH (1 << 6)
+#define UDC_ECR_DUEN (1 << 7)
+
+/* Bits in UDC_UPCR0 */
+#define UDC_UPCR0_VBD (1 << 1)
+#define UDC_UPCR0_VBDS (1 << 6)
+#define UDC_UPCR0_RCD_12 (0x0 << 9)
+#define UDC_UPCR0_RCD_24 (0x1 << 9)
+#define UDC_UPCR0_RCD_48 (0x2 << 9)
+#define UDC_UPCR0_RCS_EXT (0x1 << 11)
+#define UDC_UPCR0_RCS_XTAL (0x0 << 11)
+
+/* Bits in UDC_UPCR1 */
+#define UDC_UPCR1_CDT(x) ((x) << 0)
+#define UDC_UPCR1_OTGT(x) ((x) << 3)
+#define UDC_UPCR1_SQRXT(x) ((x) << 8)
+#define UDC_UPCR1_TXFSLST(x) ((x) << 12)
+
+/* Bits in UDC_UPCR2 */
+#define UDC_UPCR2_TP (1 << 0)
+#define UDC_UPCR2_TXRT(x) ((x) << 2)
+#define UDC_UPCR2_TXVRT(x) ((x) << 5)
+#define UDC_UPCR2_OPMODE(x) ((x) << 9)
+#define UDC_UPCR2_XCVRSEL(x) ((x) << 12)
+#define UDC_UPCR2_TM (1 << 14)
+
+/* USB Host Controller registers */
+#define USBH0_BASE (AHB_PERI_BASE_VIRT + 0xb000)
+#define USBH1_BASE (AHB_PERI_BASE_VIRT + 0xb800)
+
+#define OHCI_INT_ENABLE_OFFS 0x10
+
+#define RH_DESCRIPTOR_A_OFFS 0x48
+#define RH_DESCRIPTOR_B_OFFS 0x4c
+
+#define USBHTCFG0_OFFS 0x100
+#define USBHHCFG0_OFFS 0x104
+#define USBHHCFG1_OFFS 0x104
+
+/* DMA controller registers */
+#define DMAC0_BASE (AHB_PERI_BASE + 0x4000)
+#define DMAC1_BASE (AHB_PERI_BASE + 0xa000)
+#define DMAC2_BASE (AHB_PERI_BASE + 0x4800)
+#define DMAC3_BASE (AHB_PERI_BASE + 0xa800)
+
+#define DMAC_CH_OFFSET(ch) (ch * 0x30)
+
+#define ST_SADR_OFFS 0x00
+#define SPARAM_OFFS 0x04
+#define C_SADR_OFFS 0x0c
+#define ST_DADR_OFFS 0x10
+#define DPARAM_OFFS 0x14
+#define C_DADR_OFFS 0x1c
+#define HCOUNT_OFFS 0x20
+#define CHCTRL_OFFS 0x24
+#define RPTCTRL_OFFS 0x28
+#define EXTREQ_A_OFFS 0x2c
+
+/* Bits in CHCTRL register */
+#define CHCTRL_EN (1 << 0)
+
+#define CHCTRL_IEN (1 << 2)
+#define CHCTRL_FLAG (1 << 3)
+#define CHCTRL_WSIZE8 (0 << 4)
+#define CHCTRL_WSIZE16 (1 << 4)
+#define CHCTRL_WSIZE32 (2 << 4)
+
+#define CHCTRL_BSIZE1 (0 << 6)
+#define CHCTRL_BSIZE2 (1 << 6)
+#define CHCTRL_BSIZE4 (2 << 6)
+#define CHCTRL_BSIZE8 (3 << 6)
+
+#define CHCTRL_TYPE_SINGLE_E (0 << 8)
+#define CHCTRL_TYPE_HW (1 << 8)
+#define CHCTRL_TYPE_SW (2 << 8)
+#define CHCTRL_TYPE_SINGLE_L (3 << 8)
+
+#define CHCTRL_BST (1 << 10)
+
+/* Use DMA controller 0, channel 2 for USB */
+#define USB_DMA_BASE (DMAC0_BASE + DMAC_CH_OFFSET(2))
+
+/* NAND flash controller registers */
+#define NFC_BASE (AHB_PERI_BASE_VIRT + 0xd000)
+#define NFC_BASE_PHYS (AHB_PERI_BASE + 0xd000)
+
+#define NFC_CMD_OFFS 0x00
+#define NFC_LADDR_OFFS 0x04
+#define NFC_BADDR_OFFS 0x08
+#define NFC_SADDR_OFFS 0x0c
+#define NFC_WDATA_OFFS 0x10
+#define NFC_LDATA_OFFS 0x20
+#define NFC_SDATA_OFFS 0x40
+#define NFC_CTRL_OFFS 0x50
+#define NFC_PSTART_OFFS 0x54
+#define NFC_RSTART_OFFS 0x58
+#define NFC_DSIZE_OFFS 0x5c
+#define NFC_IREQ_OFFS 0x60
+#define NFC_RST_OFFS 0x64
+#define NFC_CTRL1_OFFS 0x68
+#define NFC_MDATA_OFFS 0x70
+
+#define NFC_WDATA_PHYS_ADDR (NFC_BASE_PHYS + NFC_WDATA_OFFS)
+
+/* Bits in NFC_CTRL */
+#define NFC_CTRL_BHLD_MASK (0xf << 0)
+#define NFC_CTRL_BPW_MASK (0xf << 4)
+#define NFC_CTRL_BSTP_MASK (0xf << 8)
+#define NFC_CTRL_CADDR_MASK (0x7 << 12)
+#define NFC_CTRL_CADDR_1 (0x0 << 12)
+#define NFC_CTRL_CADDR_2 (0x1 << 12)
+#define NFC_CTRL_CADDR_3 (0x2 << 12)
+#define NFC_CTRL_CADDR_4 (0x3 << 12)
+#define NFC_CTRL_CADDR_5 (0x4 << 12)
+#define NFC_CTRL_MSK (1 << 15)
+#define NFC_CTRL_PSIZE256 (0 << 16)
+#define NFC_CTRL_PSIZE512 (1 << 16)
+#define NFC_CTRL_PSIZE1024 (2 << 16)
+#define NFC_CTRL_PSIZE2048 (3 << 16)
+#define NFC_CTRL_PSIZE4096 (4 << 16)
+#define NFC_CTRL_PSIZE_MASK (7 << 16)
+#define NFC_CTRL_BSIZE1 (0 << 19)
+#define NFC_CTRL_BSIZE2 (1 << 19)
+#define NFC_CTRL_BSIZE4 (2 << 19)
+#define NFC_CTRL_BSIZE8 (3 << 19)
+#define NFC_CTRL_BSIZE_MASK (3 << 19)
+#define NFC_CTRL_RDY (1 << 21)
+#define NFC_CTRL_CS0SEL (1 << 22)
+#define NFC_CTRL_CS1SEL (1 << 23)
+#define NFC_CTRL_CS2SEL (1 << 24)
+#define NFC_CTRL_CS3SEL (1 << 25)
+#define NFC_CTRL_CSMASK (0xf << 22)
+#define NFC_CTRL_BW (1 << 26)
+#define NFC_CTRL_FS (1 << 27)
+#define NFC_CTRL_DEN (1 << 28)
+#define NFC_CTRL_READ_IEN (1 << 29)
+#define NFC_CTRL_PROG_IEN (1 << 30)
+#define NFC_CTRL_RDY_IEN (1 << 31)
+
+/* Bits in NFC_IREQ */
+#define NFC_IREQ_IRQ0 (1 << 0)
+#define NFC_IREQ_IRQ1 (1 << 1)
+#define NFC_IREQ_IRQ2 (1 << 2)
+
+#define NFC_IREQ_FLAG0 (1 << 4)
+#define NFC_IREQ_FLAG1 (1 << 5)
+#define NFC_IREQ_FLAG2 (1 << 6)
+
+/* MMC controller registers */
+#define MMC0_BASE (AHB_PERI_BASE_VIRT + 0xe000)
+#define MMC1_BASE (AHB_PERI_BASE_VIRT + 0xe800)
+
+/* UART base addresses */
+
+#define UART0_BASE (APB0_PERI_BASE_VIRT + 0x07000)
+#define UART0_BASE_PHYS (APB0_PERI_BASE + 0x07000)
+#define UART1_BASE (APB0_PERI_BASE_VIRT + 0x08000)
+#define UART1_BASE_PHYS (APB0_PERI_BASE + 0x08000)
+#define UART2_BASE (APB0_PERI_BASE_VIRT + 0x09000)
+#define UART2_BASE_PHYS (APB0_PERI_BASE + 0x09000)
+#define UART3_BASE (APB0_PERI_BASE_VIRT + 0x0a000)
+#define UART3_BASE_PHYS (APB0_PERI_BASE + 0x0a000)
+#define UART4_BASE (APB0_PERI_BASE_VIRT + 0x15000)
+#define UART4_BASE_PHYS (APB0_PERI_BASE + 0x15000)
+
+#define UART_BASE UART0_BASE
+#define UART_BASE_PHYS UART0_BASE_PHYS
+
+/* ECC controller */
+#define ECC_CTR_BASE (APB0_PERI_BASE_VIRT + 0xd000)
+
+#define ECC_CTRL_OFFS 0x00
+#define ECC_BASE_OFFS 0x04
+#define ECC_MASK_OFFS 0x08
+#define ECC_CLEAR_OFFS 0x0c
+#define ECC4_0_OFFS 0x10
+#define ECC4_1_OFFS 0x14
+
+#define ECC_EADDR0_OFFS 0x50
+
+#define ECC_ERRNUM_OFFS 0x90
+#define ECC_IREQ_OFFS 0x94
+
+/* Bits in ECC_CTRL */
+#define ECC_CTRL_ECC4_DIEN (1 << 28)
+#define ECC_CTRL_ECC8_DIEN (1 << 29)
+#define ECC_CTRL_ECC12_DIEN (1 << 30)
+#define ECC_CTRL_ECC_DISABLE 0x0
+#define ECC_CTRL_ECC_SLC_ENC 0x8
+#define ECC_CTRL_ECC_SLC_DEC 0x9
+#define ECC_CTRL_ECC4_ENC 0xa
+#define ECC_CTRL_ECC4_DEC 0xb
+#define ECC_CTRL_ECC8_ENC 0xc
+#define ECC_CTRL_ECC8_DEC 0xd
+#define ECC_CTRL_ECC12_ENC 0xe
+#define ECC_CTRL_ECC12_DEC 0xf
+
+/* Bits in ECC_IREQ */
+#define ECC_IREQ_E4DI (1 << 4)
+
+#define ECC_IREQ_E4DF (1 << 20)
+#define ECC_IREQ_E4EF (1 << 21)
+
+/* Interrupt controller */
+
+#define PIC0_BASE (APB1_PERI_BASE_VIRT + 0x3000)
+#define PIC0_BASE_PHYS (APB1_PERI_BASE + 0x3000)
+
+#define PIC0_IEN_OFFS 0x00
+#define PIC0_CREQ_OFFS 0x04
+#define PIC0_IREQ_OFFS 0x08
+#define PIC0_IRQSEL_OFFS 0x0c
+#define PIC0_SRC_OFFS 0x10
+#define PIC0_MREQ_OFFS 0x14
+#define PIC0_TSTREQ_OFFS 0x18
+#define PIC0_POL_OFFS 0x1c
+#define PIC0_IRQ_OFFS 0x20
+#define PIC0_FIQ_OFFS 0x24
+#define PIC0_MIRQ_OFFS 0x28
+#define PIC0_MFIQ_OFFS 0x2c
+#define PIC0_TMODE_OFFS 0x30
+#define PIC0_SYNC_OFFS 0x34
+#define PIC0_WKUP_OFFS 0x38
+#define PIC0_TMODEA_OFFS 0x3c
+#define PIC0_INTOEN_OFFS 0x40
+#define PIC0_MEN0_OFFS 0x44
+#define PIC0_MEN_OFFS 0x48
+
+#define PIC0_IEN __REG(PIC0_BASE + PIC0_IEN_OFFS)
+#define PIC0_IEN_PHYS __REG(PIC0_BASE_PHYS + PIC0_IEN_OFFS)
+#define PIC0_CREQ __REG(PIC0_BASE + PIC0_CREQ_OFFS)
+#define PIC0_CREQ_PHYS __REG(PIC0_BASE_PHYS + PIC0_CREQ_OFFS)
+#define PIC0_IREQ __REG(PIC0_BASE + PIC0_IREQ_OFFS)
+#define PIC0_IRQSEL __REG(PIC0_BASE + PIC0_IRQSEL_OFFS)
+#define PIC0_IRQSEL_PHYS __REG(PIC0_BASE_PHYS + PIC0_IRQSEL_OFFS)
+#define PIC0_SRC __REG(PIC0_BASE + PIC0_SRC_OFFS)
+#define PIC0_MREQ __REG(PIC0_BASE + PIC0_MREQ_OFFS)
+#define PIC0_TSTREQ __REG(PIC0_BASE + PIC0_TSTREQ_OFFS)
+#define PIC0_POL __REG(PIC0_BASE + PIC0_POL_OFFS)
+#define PIC0_IRQ __REG(PIC0_BASE + PIC0_IRQ_OFFS)
+#define PIC0_FIQ __REG(PIC0_BASE + PIC0_FIQ_OFFS)
+#define PIC0_MIRQ __REG(PIC0_BASE + PIC0_MIRQ_OFFS)
+#define PIC0_MFIQ __REG(PIC0_BASE + PIC0_MFIQ_OFFS)
+#define PIC0_TMODE __REG(PIC0_BASE + PIC0_TMODE_OFFS)
+#define PIC0_TMODE_PHYS __REG(PIC0_BASE_PHYS + PIC0_TMODE_OFFS)
+#define PIC0_SYNC __REG(PIC0_BASE + PIC0_SYNC_OFFS)
+#define PIC0_WKUP __REG(PIC0_BASE + PIC0_WKUP_OFFS)
+#define PIC0_TMODEA __REG(PIC0_BASE + PIC0_TMODEA_OFFS)
+#define PIC0_INTOEN __REG(PIC0_BASE + PIC0_INTOEN_OFFS)
+#define PIC0_MEN0 __REG(PIC0_BASE + PIC0_MEN0_OFFS)
+#define PIC0_MEN __REG(PIC0_BASE + PIC0_MEN_OFFS)
+
+#define PIC1_BASE (APB1_PERI_BASE_VIRT + 0x3080)
+
+#define PIC1_IEN_OFFS 0x00
+#define PIC1_CREQ_OFFS 0x04
+#define PIC1_IREQ_OFFS 0x08
+#define PIC1_IRQSEL_OFFS 0x0c
+#define PIC1_SRC_OFFS 0x10
+#define PIC1_MREQ_OFFS 0x14
+#define PIC1_TSTREQ_OFFS 0x18
+#define PIC1_POL_OFFS 0x1c
+#define PIC1_IRQ_OFFS 0x20
+#define PIC1_FIQ_OFFS 0x24
+#define PIC1_MIRQ_OFFS 0x28
+#define PIC1_MFIQ_OFFS 0x2c
+#define PIC1_TMODE_OFFS 0x30
+#define PIC1_SYNC_OFFS 0x34
+#define PIC1_WKUP_OFFS 0x38
+#define PIC1_TMODEA_OFFS 0x3c
+#define PIC1_INTOEN_OFFS 0x40
+#define PIC1_MEN1_OFFS 0x44
+#define PIC1_MEN_OFFS 0x48
+
+#define PIC1_IEN __REG(PIC1_BASE + PIC1_IEN_OFFS)
+#define PIC1_CREQ __REG(PIC1_BASE + PIC1_CREQ_OFFS)
+#define PIC1_IREQ __REG(PIC1_BASE + PIC1_IREQ_OFFS)
+#define PIC1_IRQSEL __REG(PIC1_BASE + PIC1_IRQSEL_OFFS)
+#define PIC1_SRC __REG(PIC1_BASE + PIC1_SRC_OFFS)
+#define PIC1_MREQ __REG(PIC1_BASE + PIC1_MREQ_OFFS)
+#define PIC1_TSTREQ __REG(PIC1_BASE + PIC1_TSTREQ_OFFS)
+#define PIC1_POL __REG(PIC1_BASE + PIC1_POL_OFFS)
+#define PIC1_IRQ __REG(PIC1_BASE + PIC1_IRQ_OFFS)
+#define PIC1_FIQ __REG(PIC1_BASE + PIC1_FIQ_OFFS)
+#define PIC1_MIRQ __REG(PIC1_BASE + PIC1_MIRQ_OFFS)
+#define PIC1_MFIQ __REG(PIC1_BASE + PIC1_MFIQ_OFFS)
+#define PIC1_TMODE __REG(PIC1_BASE + PIC1_TMODE_OFFS)
+#define PIC1_SYNC __REG(PIC1_BASE + PIC1_SYNC_OFFS)
+#define PIC1_WKUP __REG(PIC1_BASE + PIC1_WKUP_OFFS)
+#define PIC1_TMODEA __REG(PIC1_BASE + PIC1_TMODEA_OFFS)
+#define PIC1_INTOEN __REG(PIC1_BASE + PIC1_INTOEN_OFFS)
+#define PIC1_MEN1 __REG(PIC1_BASE + PIC1_MEN1_OFFS)
+#define PIC1_MEN __REG(PIC1_BASE + PIC1_MEN_OFFS)
+
+/* Timer registers */
+#define TIMER_BASE (APB1_PERI_BASE_VIRT + 0x4000)
+#define TIMER_BASE_PHYS (APB1_PERI_BASE + 0x4000)
+
+#define TWDCFG_OFFS 0x70
+
+#define TC32EN_OFFS 0x80
+#define TC32LDV_OFFS 0x84
+#define TC32CMP0_OFFS 0x88
+#define TC32CMP1_OFFS 0x8c
+#define TC32PCNT_OFFS 0x90
+#define TC32MCNT_OFFS 0x94
+#define TC32IRQ_OFFS 0x98
+
+/* Bits in TC32EN */
+#define TC32EN_PRESCALE_MASK 0x00ffffff
+#define TC32EN_ENABLE (1 << 24)
+#define TC32EN_LOADZERO (1 << 25)
+#define TC32EN_STOPMODE (1 << 26)
+#define TC32EN_LDM0 (1 << 28)
+#define TC32EN_LDM1 (1 << 29)
+
+/* Bits in TC32IRQ */
+#define TC32IRQ_MSTAT_MASK 0x0000001f
+#define TC32IRQ_RSTAT_MASK (0x1f << 8)
+#define TC32IRQ_IRQEN0 (1 << 16)
+#define TC32IRQ_IRQEN1 (1 << 17)
+#define TC32IRQ_IRQEN2 (1 << 18)
+#define TC32IRQ_IRQEN3 (1 << 19)
+#define TC32IRQ_IRQEN4 (1 << 20)
+#define TC32IRQ_RSYNC (1 << 30)
+#define TC32IRQ_IRQCLR (1 << 31)
+
+/* GPIO registers */
+#define GPIOPD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPD_DAT_OFFS 0x00
+#define GPIOPD_DOE_OFFS 0x04
+#define GPIOPD_FS0_OFFS 0x08
+#define GPIOPD_FS1_OFFS 0x0c
+#define GPIOPD_FS2_OFFS 0x10
+#define GPIOPD_RPU_OFFS 0x30
+#define GPIOPD_RPD_OFFS 0x34
+#define GPIOPD_DV0_OFFS 0x38
+#define GPIOPD_DV1_OFFS 0x3c
+
+#define GPIOPS_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPS_DAT_OFFS 0x40
+#define GPIOPS_DOE_OFFS 0x44
+#define GPIOPS_FS0_OFFS 0x48
+#define GPIOPS_FS1_OFFS 0x4c
+#define GPIOPS_FS2_OFFS 0x50
+#define GPIOPS_FS3_OFFS 0x54
+#define GPIOPS_RPU_OFFS 0x70
+#define GPIOPS_RPD_OFFS 0x74
+#define GPIOPS_DV0_OFFS 0x78
+#define GPIOPS_DV1_OFFS 0x7c
+
+#define GPIOPS_FS1_SDH0_BITS 0x000000ff
+#define GPIOPS_FS1_SDH1_BITS 0x0000ff00
+
+#define GPIOPU_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPU_DAT_OFFS 0x80
+#define GPIOPU_DOE_OFFS 0x84
+#define GPIOPU_FS0_OFFS 0x88
+#define GPIOPU_FS1_OFFS 0x8c
+#define GPIOPU_FS2_OFFS 0x90
+#define GPIOPU_RPU_OFFS 0xb0
+#define GPIOPU_RPD_OFFS 0xb4
+#define GPIOPU_DV0_OFFS 0xb8
+#define GPIOPU_DV1_OFFS 0xbc
+
+#define GPIOPU_FS0_TXD0 (1 << 0)
+#define GPIOPU_FS0_RXD0 (1 << 1)
+#define GPIOPU_FS0_CTS0 (1 << 2)
+#define GPIOPU_FS0_RTS0 (1 << 3)
+#define GPIOPU_FS0_TXD1 (1 << 4)
+#define GPIOPU_FS0_RXD1 (1 << 5)
+#define GPIOPU_FS0_CTS1 (1 << 6)
+#define GPIOPU_FS0_RTS1 (1 << 7)
+#define GPIOPU_FS0_TXD2 (1 << 8)
+#define GPIOPU_FS0_RXD2 (1 << 9)
+#define GPIOPU_FS0_CTS2 (1 << 10)
+#define GPIOPU_FS0_RTS2 (1 << 11)
+#define GPIOPU_FS0_TXD3 (1 << 12)
+#define GPIOPU_FS0_RXD3 (1 << 13)
+#define GPIOPU_FS0_CTS3 (1 << 14)
+#define GPIOPU_FS0_RTS3 (1 << 15)
+#define GPIOPU_FS0_TXD4 (1 << 16)
+#define GPIOPU_FS0_RXD4 (1 << 17)
+#define GPIOPU_FS0_CTS4 (1 << 18)
+#define GPIOPU_FS0_RTS4 (1 << 19)
+
+#define GPIOFC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFC_DAT_OFFS 0xc0
+#define GPIOFC_DOE_OFFS 0xc4
+#define GPIOFC_FS0_OFFS 0xc8
+#define GPIOFC_FS1_OFFS 0xcc
+#define GPIOFC_FS2_OFFS 0xd0
+#define GPIOFC_FS3_OFFS 0xd4
+#define GPIOFC_RPU_OFFS 0xf0
+#define GPIOFC_RPD_OFFS 0xf4
+#define GPIOFC_DV0_OFFS 0xf8
+#define GPIOFC_DV1_OFFS 0xfc
+
+#define GPIOFD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFD_DAT_OFFS 0x100
+#define GPIOFD_DOE_OFFS 0x104
+#define GPIOFD_FS0_OFFS 0x108
+#define GPIOFD_FS1_OFFS 0x10c
+#define GPIOFD_FS2_OFFS 0x110
+#define GPIOFD_RPU_OFFS 0x130
+#define GPIOFD_RPD_OFFS 0x134
+#define GPIOFD_DV0_OFFS 0x138
+#define GPIOFD_DV1_OFFS 0x13c
+
+#define GPIOLC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLC_DAT_OFFS 0x140
+#define GPIOLC_DOE_OFFS 0x144
+#define GPIOLC_FS0_OFFS 0x148
+#define GPIOLC_FS1_OFFS 0x14c
+#define GPIOLC_RPU_OFFS 0x170
+#define GPIOLC_RPD_OFFS 0x174
+#define GPIOLC_DV0_OFFS 0x178
+#define GPIOLC_DV1_OFFS 0x17c
+
+#define GPIOLD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLD_DAT_OFFS 0x180
+#define GPIOLD_DOE_OFFS 0x184
+#define GPIOLD_FS0_OFFS 0x188
+#define GPIOLD_FS1_OFFS 0x18c
+#define GPIOLD_FS2_OFFS 0x190
+#define GPIOLD_RPU_OFFS 0x1b0
+#define GPIOLD_RPD_OFFS 0x1b4
+#define GPIOLD_DV0_OFFS 0x1b8
+#define GPIOLD_DV1_OFFS 0x1bc
+
+#define GPIOAD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOAD_DAT_OFFS 0x1c0
+#define GPIOAD_DOE_OFFS 0x1c4
+#define GPIOAD_FS0_OFFS 0x1c8
+#define GPIOAD_RPU_OFFS 0x1f0
+#define GPIOAD_RPD_OFFS 0x1f4
+#define GPIOAD_DV0_OFFS 0x1f8
+#define GPIOAD_DV1_OFFS 0x1fc
+
+#define GPIOXC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXC_DAT_OFFS 0x200
+#define GPIOXC_DOE_OFFS 0x204
+#define GPIOXC_FS0_OFFS 0x208
+#define GPIOXC_RPU_OFFS 0x230
+#define GPIOXC_RPD_OFFS 0x234
+#define GPIOXC_DV0_OFFS 0x238
+#define GPIOXC_DV1_OFFS 0x23c
+
+#define GPIOXC_FS0 __REG(GPIOXC_BASE + GPIOXC_FS0_OFFS)
+
+#define GPIOXC_FS0_CS0 (1 << 26)
+#define GPIOXC_FS0_CS1 (1 << 27)
+
+#define GPIOXD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXD_DAT_OFFS 0x240
+#define GPIOXD_FS0_OFFS 0x248
+#define GPIOXD_RPU_OFFS 0x270
+#define GPIOXD_RPD_OFFS 0x274
+#define GPIOXD_DV0_OFFS 0x278
+#define GPIOXD_DV1_OFFS 0x27c
+
+#define GPIOPK_BASE (APB1_PERI_BASE_VIRT + 0x1c000)
+
+#define GPIOPK_RST_OFFS 0x008
+#define GPIOPK_DAT_OFFS 0x100
+#define GPIOPK_DOE_OFFS 0x104
+#define GPIOPK_FS0_OFFS 0x108
+#define GPIOPK_FS1_OFFS 0x10c
+#define GPIOPK_FS2_OFFS 0x110
+#define GPIOPK_IRQST_OFFS 0x210
+#define GPIOPK_IRQEN_OFFS 0x214
+#define GPIOPK_IRQPOL_OFFS 0x218
+#define GPIOPK_IRQTM0_OFFS 0x21c
+#define GPIOPK_IRQTM1_OFFS 0x220
+#define GPIOPK_CTL_OFFS 0x22c
+
+#define PMGPIO_BASE (APB1_PERI_BASE_VIRT + 0x10000)
+#define BACKUP_RAM_BASE PMGPIO_BASE
+
+#define PMGPIO_DAT_OFFS 0x800
+#define PMGPIO_DOE_OFFS 0x804
+#define PMGPIO_FS0_OFFS 0x808
+#define PMGPIO_RPU_OFFS 0x810
+#define PMGPIO_RPD_OFFS 0x814
+#define PMGPIO_DV0_OFFS 0x818
+#define PMGPIO_DV1_OFFS 0x81c
+#define PMGPIO_EE0_OFFS 0x820
+#define PMGPIO_EE1_OFFS 0x824
+#define PMGPIO_CTL_OFFS 0x828
+#define PMGPIO_DI_OFFS 0x82c
+#define PMGPIO_STR_OFFS 0x830
+#define PMGPIO_STF_OFFS 0x834
+#define PMGPIO_POL_OFFS 0x838
+#define PMGPIO_APB_OFFS 0x800
+
+/* Clock controller registers */
+#define CKC_BASE ((void __iomem *)(APB1_PERI_BASE_VIRT + 0x6000))
+
+#define CLKCTRL_OFFS 0x00
+#define PLL0CFG_OFFS 0x04
+#define PLL1CFG_OFFS 0x08
+#define CLKDIVC0_OFFS 0x0c
+
+#define BCLKCTR0_OFFS 0x14
+#define SWRESET0_OFFS 0x18
+
+#define BCLKCTR1_OFFS 0x60
+#define SWRESET1_OFFS 0x64
+#define PWDCTL_OFFS 0x68
+#define PLL2CFG_OFFS 0x6c
+#define CLKDIVC1_OFFS 0x70
+
+#define ACLKREF_OFFS 0x80
+#define ACLKI2C_OFFS 0x84
+#define ACLKSPI0_OFFS 0x88
+#define ACLKSPI1_OFFS 0x8c
+#define ACLKUART0_OFFS 0x90
+#define ACLKUART1_OFFS 0x94
+#define ACLKUART2_OFFS 0x98
+#define ACLKUART3_OFFS 0x9c
+#define ACLKUART4_OFFS 0xa0
+#define ACLKTCT_OFFS 0xa4
+#define ACLKTCX_OFFS 0xa8
+#define ACLKTCZ_OFFS 0xac
+#define ACLKADC_OFFS 0xb0
+#define ACLKDAI0_OFFS 0xb4
+#define ACLKDAI1_OFFS 0xb8
+#define ACLKLCD_OFFS 0xbc
+#define ACLKSPDIF_OFFS 0xc0
+#define ACLKUSBH_OFFS 0xc4
+#define ACLKSDH0_OFFS 0xc8
+#define ACLKSDH1_OFFS 0xcc
+#define ACLKC3DEC_OFFS 0xd0
+#define ACLKEXT_OFFS 0xd4
+#define ACLKCAN0_OFFS 0xd8
+#define ACLKCAN1_OFFS 0xdc
+#define ACLKGSB0_OFFS 0xe0
+#define ACLKGSB1_OFFS 0xe4
+#define ACLKGSB2_OFFS 0xe8
+#define ACLKGSB3_OFFS 0xec
+
+#define PLLxCFG_PD (1 << 31)
+
+/* CLKCTRL bits */
+#define CLKCTRL_XE (1 << 31)
+
+/* CLKDIVCx bits */
+#define CLKDIVC0_XTE (1 << 7)
+#define CLKDIVC0_XE (1 << 15)
+#define CLKDIVC0_P1E (1 << 23)
+#define CLKDIVC0_P0E (1 << 31)
+
+#define CLKDIVC1_P2E (1 << 7)
+
+/* BCLKCTR0 clock bits */
+#define BCLKCTR0_USBD (1 << 4)
+#define BCLKCTR0_ECC (1 << 9)
+#define BCLKCTR0_USBH0 (1 << 11)
+#define BCLKCTR0_NFC (1 << 16)
+
+/* BCLKCTR1 clock bits */
+#define BCLKCTR1_USBH1 (1 << 20)
+
+/* SWRESET0 bits */
+#define SWRESET0_USBD (1 << 4)
+#define SWRESET0_USBH0 (1 << 11)
+
+/* SWRESET1 bits */
+#define SWRESET1_USBH1 (1 << 20)
+
+/* System clock sources.
+ * Note: These are the clock sources that serve as parents for
+ * all other clocks. They have no parents themselves.
+ *
+ * These values are used for struct clk->root_id. All clocks
+ * that are not system clock sources have this value set to
+ * CLK_SRC_NOROOT.
+ * The values for system clocks start with CLK_SRC_PLL0 == 0
+ * because this gives us exactly the values needed for the lower
+ * 4 bits of ACLK_* registers. Therefore, CLK_SRC_NOROOT is
+ * defined as -1 to not disturb the order.
+ */
+enum root_clks {
+ CLK_SRC_NOROOT = -1,
+ CLK_SRC_PLL0 = 0,
+ CLK_SRC_PLL1,
+ CLK_SRC_PLL0DIV,
+ CLK_SRC_PLL1DIV,
+ CLK_SRC_XI,
+ CLK_SRC_XIDIV,
+ CLK_SRC_XTI,
+ CLK_SRC_XTIDIV,
+ CLK_SRC_PLL2,
+ CLK_SRC_PLL2DIV,
+ CLK_SRC_PK0,
+ CLK_SRC_PK1,
+ CLK_SRC_PK2,
+ CLK_SRC_PK3,
+ CLK_SRC_PK4,
+ CLK_SRC_48MHZ
+};
+
+#define CLK_SRC_MASK 0xf
+
+/* Bits in ACLK* registers */
+#define ACLK_EN (1 << 28)
+#define ACLK_SEL_SHIFT 24
+#define ACLK_SEL_MASK 0x0f000000
+#define ACLK_DIV_MASK 0x00000fff
+
+/* System configuration registers */
+
+#define SCFG_BASE (APB1_PERI_BASE_VIRT + 0x13000)
+
+#define BMI_OFFS 0x00
+#define AHBCON0_OFFS 0x04
+#define APBPWE_OFFS 0x08
+#define DTCMWAIT_OFFS 0x0c
+#define ECCSEL_OFFS 0x10
+#define AHBCON1_OFFS 0x14
+#define SDHCFG_OFFS 0x18
+#define REMAP_OFFS 0x20
+#define LCDSIAE_OFFS 0x24
+#define XMCCFG_OFFS 0xe0
+#define IMCCFG_OFFS 0xe4
+
+/* Values for ECCSEL */
+#define ECCSEL_EXTMEM 0x0
+#define ECCSEL_DTCM 0x1
+#define ECCSEL_INT_SRAM 0x2
+#define ECCSEL_AHB 0x3
+
+/* Bits in XMCCFG */
+#define XMCCFG_NFCE (1 << 1)
+#define XMCCFG_FDXD (1 << 2)
+
+/* External memory controller registers */
+
+#define EMC_BASE EXT_MEM_CTRL_BASE
+
+#define SDCFG_OFFS 0x00
+#define SDFSM_OFFS 0x04
+#define MCFG_OFFS 0x08
+
+#define CSCFG0_OFFS 0x10
+#define CSCFG1_OFFS 0x14
+#define CSCFG2_OFFS 0x18
+#define CSCFG3_OFFS 0x1c
+
+#define MCFG_SDEN (1 << 4)
+
+#endif /* TCC8K_REGS_H */
--- /dev/null
+/*
+ * A definition needed by arch core code.
+ *
+ */
+#define CLOCK_TICK_RATE (HZ * 100000UL)
--- /dev/null
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This file is licensed under the terms of the GPL version 2.
+ */
+
+#include <linux/serial_reg.h>
+#include <linux/types.h>
+
+#include <mach/tcc8k-regs.h>
+
+unsigned int system_rev;
+
+#define ID_MASK 0x7fff
+
+static void putc(int c)
+{
+ u32 *uart_lsr = (u32 *)(UART_BASE_PHYS + (UART_LSR << 2));
+ u32 *uart_tx = (u32 *)(UART_BASE_PHYS + (UART_TX << 2));
+
+ while (!(*uart_lsr & UART_LSR_THRE))
+ barrier();
+ *uart_tx = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
--- /dev/null
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ *
+ * Copyright (C) 2000 Russell King.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+#define VMALLOC_END 0xf0000000UL
--- /dev/null
+/*
+ * System functions for Telechips TCCxxxx SoCs
+ *
+ * Copyright (C) Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#include <linux/io.h>
+
+#include <mach/tcc8k-regs.h>
+
+/* System reboot */
+void plat_tcc_reboot(void)
+{
+ /* Make sure clocks are on */
+ __raw_writel(0xffffffff, CKC_BASE + BCLKCTR0_OFFS);
+
+ /* Enable watchdog reset */
+ __raw_writel(0x49, TIMER_BASE + TWDCFG_OFFS);
+ /* Wait for reset */
+ while(1)
+ ;
+}
select ARCH_REQUIRE_GPIOLIB
select GENERIC_ALLOCATOR
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
#
# CPU types
vfree(module->arch.syminfo);
module->arch.syminfo = NULL;
- return module_bug_finalize(hdr, sechdrs, module);
+ return 0;
}
void module_arch_cleanup(struct module *module)
{
- module_bug_cleanup(module);
}
const Elf_Shdr *sechdrs,
struct module *me)
{
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
#undef __HAVE_ARCH_SIG_BITOPS
struct pt_regs;
-extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __IGNORE_lchown
#define __IGNORE_setuid
work_notifysig: ; deal with pending signals and
; notify-resume requests
mv r0, sp ; arg1 : struct pt_regs *regs
- ldi r1, #0 ; arg2 : sigset_t *oldset
- mv r2, r9 ; arg3 : __u32 thread_info_flags
+ mv r1, r9 ; arg2 : __u32 thread_info_flags
bl do_notify_resume
- bra restore_all
+ bra resume_userspace
; perform syscall exit tracing
ALIGN
if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
!= sizeof(insn))
- break;
+ return -EIO;
compute_next_pc(insn, pc, &next_pc, child);
if (next_pc & 0x80000000)
- break;
+ return -EIO;
if (embed_debug_trap(child, next_pc))
- break;
+ return -EIO;
invalidate_cache();
+ return 0;
}
void user_disable_single_step(struct task_struct *child)
#define DEBUG_SIG 0
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-int do_signal(struct pt_regs *, sigset_t *);
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
- unsigned long r2, unsigned long r3, unsigned long r4,
- unsigned long r5, unsigned long r6, struct pt_regs *regs)
-{
- sigset_t newset;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&newset, unewset, sizeof(newset)))
- return -EFAULT;
- sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
-
- spin_lock_irq(¤t->sighand->siglock);
- current->saved_sigmask = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- set_thread_flag(TIF_RESTORE_SIGMASK);
- return -ERESTARTNOHAND;
-}
-
asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r2, unsigned long r3, unsigned long r4,
return (void __user *)((sp - frame_size) & -8ul);
}
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
current->comm, current->pid, frame, regs->pc);
#endif
- return;
+ return 0;
give_sigsegv:
force_sigsegv(sig, current);
+ return -EFAULT;
+}
+
+static int prev_insn(struct pt_regs *regs)
+{
+ u16 inst;
+ if (get_user(&inst, (u16 __user *)(regs->bpc - 2)))
+ return -EFAULT;
+ if ((inst & 0xfff0) == 0x10f0) /* trap ? */
+ regs->bpc -= 2;
+ else
+ regs->bpc -= 4;
+ regs->syscall_nr = -1;
+ return 0;
}
/*
* OK, we're invoking a handler
*/
-static void
+static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
- unsigned short inst;
-
/* Are we from a system call? */
if (regs->syscall_nr >= 0) {
/* If so, check system call restarting.. */
/* fallthrough */
case -ERESTARTNOINTR:
regs->r0 = regs->orig_r0;
- inst = *(unsigned short *)(regs->bpc - 2);
- if ((inst & 0xfff0) == 0x10f0) /* trap ? */
- regs->bpc -= 2;
- else
- regs->bpc -= 4;
+ if (prev_insn(regs) < 0)
+ return -EFAULT;
}
}
/* Set up the stack frame */
- setup_rt_frame(sig, ka, info, oldset, regs);
+ if (setup_rt_frame(sig, ka, info, oldset, regs))
+ return -EFAULT;
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
sigaddset(¤t->blocked,sig);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
+ return 0;
}
/*
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static void do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
- unsigned short inst;
+ sigset_t *oldset;
/*
* We want the common case to go fast, which
* if so.
*/
if (!user_mode(regs))
- return 1;
+ return;
if (try_to_freeze())
goto no_signal;
- if (!oldset)
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = ¤t->saved_sigmask;
+ else
oldset = ¤t->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
*/
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, oldset, regs);
- return 1;
+ if (handle_signal(signr, &ka, &info, oldset, regs) == 0)
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+ return;
}
no_signal:
regs->r0 == -ERESTARTSYS ||
regs->r0 == -ERESTARTNOINTR) {
regs->r0 = regs->orig_r0;
- inst = *(unsigned short *)(regs->bpc - 2);
- if ((inst & 0xfff0) == 0x10f0) /* trap ? */
- regs->bpc -= 2;
- else
- regs->bpc -= 4;
- }
- if (regs->r0 == -ERESTART_RESTARTBLOCK){
+ prev_insn(regs);
+ } else if (regs->r0 == -ERESTART_RESTARTBLOCK){
regs->r0 = regs->orig_r0;
regs->r7 = __NR_restart_syscall;
- inst = *(unsigned short *)(regs->bpc - 2);
- if ((inst & 0xfff0) == 0x10f0) /* trap ? */
- regs->bpc -= 2;
- else
- regs->bpc -= 4;
+ prev_insn(regs);
}
}
- return 0;
+ 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
*/
-void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
- __u32 thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
{
/* Pending single-step? */
if (thread_info_flags & _TIF_SINGLESTEP)
/* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING)
- do_signal(regs,oldset);
+ do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
void mac_mksound( unsigned int freq, unsigned int length )
{
__u32 cfreq = ( freq << 5 ) / 468;
- __u32 flags;
+ unsigned long flags;
int i;
if ( mac_special_bell == NULL )
*/
static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume )
{
- __u32 flags;
+ unsigned long flags;
/* if the bell is already ringing, ring longer */
if ( mac_bell_duration > 0 )
static void mac_quadra_ring_bell( unsigned long ignored )
{
int i, count = mac_asc_samplespersec / HZ;
- __u32 flags;
+ unsigned long flags;
/*
* we neither want a sound buffer overflow nor underflow, so we need to match
select HAVE_KPROBES
select HAVE_KRETPROBES
select RTC_LIB if !MACH_LOONGSON
+ select GENERIC_ATOMIC64 if !64BIT
mainmenu "Linux/MIPS Kernel Configuration"
select SYS_SUPPORTS_SMP
select SMP_UP
help
- This is a kernel model which is also known a VSMP or lately
- has been marketesed into SMVP.
+ This is a kernel model which is known a VSMP but lately has been
+ marketesed into SMVP.
+ Virtual SMP uses the processor's VPEs to implement virtual
+ processors. In currently available configuration of the 34K processor
+ this allows for a dual processor. Both processors will share the same
+ primary caches; each will obtain the half of the TLB for it's own
+ exclusive use. For a layman this model can be described as similar to
+ what Intel calls Hyperthreading.
+
+ For further information see http://www.linux-mips.org/wiki/34K#VSMP
config MIPS_MT_SMTC
bool "SMTC: Use all TCs on all VPEs for SMP"
help
This is a kernel model which is known a SMTC or lately has been
marketesed into SMVP.
+ is presenting the available TC's of the core as processors to Linux.
+ On currently available 34K processors this means a Linux system will
+ see up to 5 processors. The implementation of the SMTC kernel differs
+ significantly from VSMP and cannot efficiently coexist in the same
+ kernel binary so the choice between VSMP and SMTC is a compile time
+ decision.
+
+ For further information see http://www.linux-mips.org/wiki/34K#SMTC
endchoice
char **prom_argv;
char **prom_envp;
-void prom_init_cmdline(void)
+void __init prom_init_cmdline(void)
{
int i;
}
}
-int prom_get_ethernet_addr(char *ethernet_addr)
+int __init prom_get_ethernet_addr(char *ethernet_addr)
{
char *ethaddr_str;
return 0;
}
-EXPORT_SYMBOL(prom_get_ethernet_addr);
void __init prom_free_prom_memory(void)
{
hostprogs-y := calc_vmlinuz_load_addr
VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
- $(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS))
+ $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
vmlinuzobjs-y += $(obj)/piggy.o
def_bool y
select SPARSEMEM_STATIC
depends on CPU_CAVIUM_OCTEON
+
+config CAVIUM_OCTEON_HELPER
+ def_bool y
+ depends on OCTEON_ETHERNET || PCI
return NOTIFY_OK; /* Let default notifier send signals */
}
-static int cnmips_cu2_setup(void)
+static int __init cnmips_cu2_setup(void)
{
return cu2_notifier(cnmips_cu2_call, 0);
}
obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
-obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o
+obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o
*/
#define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
+#else /* !CONFIG_64BIT */
+
+#include <asm-generic/atomic64.h>
+
#endif /* CONFIG_64BIT */
/*
#define cu2_notifier(fn, pri) \
({ \
- static struct notifier_block fn##_nb __cpuinitdata = { \
+ static struct notifier_block fn##_nb = { \
.notifier_call = fn, \
.priority = pri \
}; \
*/
struct gic_intr_map {
unsigned int cpunum; /* Directed to this CPU */
+#define GIC_UNUSED 0xdead /* Dummy data */
unsigned int pin; /* Directed to this Pin */
unsigned int polarity; /* Polarity : +/- */
unsigned int trigtype; /* Trigger : Edge/Levl */
#ifndef __ASM_MACH_TX49XX_KMALLOC_H
#define __ASM_MACH_TX49XX_KMALLOC_H
-#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
#endif /* __ASM_MACH_TX49XX_KMALLOC_H */
#define GIC_EXT_INTR(x) x
-/* Dummy data */
-#define X 0xdead
-
/* External Interrupts used for IPI */
#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16
#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
#endif
#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+
+/*
+ * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad
+ * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org). The
+ * discussion can be found in lkml posting
+ * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is
+ * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html
+ *
+ * It is unclear if the misscompilations mentioned in
+ * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one
+ * until GCC 3.x has been retired before we can apply
+ * https://patchwork.linux-mips.org/patch/1541/
+ */
+
#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
/* work to do on interrupt/exception return */
-#define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)
+#define _TIF_WORK_MASK (0x0000ffef & \
+ ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
/* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP)
#define __NR_perf_event_open (__NR_Linux + 333)
#define __NR_accept4 (__NR_Linux + 334)
#define __NR_recvmmsg (__NR_Linux + 335)
+#define __NR_fanotify_init (__NR_Linux + 336)
+#define __NR_fanotify_mark (__NR_Linux + 337)
+#define __NR_prlimit64 (__NR_Linux + 338)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 335
+#define __NR_Linux_syscalls 338
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 335
+#define __NR_O32_Linux_syscalls 338
#if _MIPS_SIM == _MIPS_SIM_ABI64
#define __NR_perf_event_open (__NR_Linux + 292)
#define __NR_accept4 (__NR_Linux + 293)
#define __NR_recvmmsg (__NR_Linux + 294)
+#define __NR_fanotify_init (__NR_Linux + 295)
+#define __NR_fanotify_mark (__NR_Linux + 296)
+#define __NR_prlimit64 (__NR_Linux + 297)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 294
+#define __NR_Linux_syscalls 297
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 294
+#define __NR_64_Linux_syscalls 297
#if _MIPS_SIM == _MIPS_SIM_NABI32
#define __NR_accept4 (__NR_Linux + 297)
#define __NR_recvmmsg (__NR_Linux + 298)
#define __NR_getdents64 (__NR_Linux + 299)
+#define __NR_fanotify_init (__NR_Linux + 300)
+#define __NR_fanotify_mark (__NR_Linux + 301)
+#define __NR_prlimit64 (__NR_Linux + 302)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 299
+#define __NR_Linux_syscalls 302
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 299
+#define __NR_N32_Linux_syscalls 302
#ifdef __KERNEL__
#include <asm/io.h>
#include <asm/gic.h>
#include <asm/gcmpregs.h>
-#include <asm/mips-boards/maltaint.h>
#include <asm/irq.h>
#include <linux/hardirq.h>
#include <asm-generic/bitops/find.h>
int i;
irq -= _irqbase;
- pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq);
+ pr_debug("%s(%d) called\n", __func__, irq);
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp))
return -1;
/* Setup specifics */
for (i = 0; i < mapsize; i++) {
cpu = intrmap[i].cpunum;
- if (cpu == X)
+ if (cpu == GIC_UNUSED)
continue;
if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
continue;
struct pt_regs *regs = args->regs;
int trap = (regs->cp0_cause & 0x7c) >> 2;
- /* Userpace events, ignore. */
+ /* Userspace events, ignore. */
if (user_mode(regs))
return NOTIFY_DONE;
memset(&tz, 0, sizeof(tz));
if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
(int)&tz, 0, 0)) == 0)
- ret.retval = tv.tv_sec;
+ ret.retval = tv.tv_sec;
break;
case MTSP_SYSCALL_EXIT:
{
return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
}
+
+SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags,
+ u64, a3, u64, a4, int, dfd, const char __user *, pathname)
+{
+ return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4),
+ dfd, pathname);
+}
sys sys_rt_tgsigqueueinfo 4
sys sys_perf_event_open 5
sys sys_accept4 4
- sys sys_recvmmsg 5
+ sys sys_recvmmsg 5 /* 4335 */
+ sys sys_fanotify_init 2
+ sys sys_fanotify_mark 6
+ sys sys_prlimit64 4
.endm
/* We pre-compute the number of _instruction_ bytes needed to
PTR sys_pipe2
PTR sys_inotify_init1
PTR sys_preadv
- PTR sys_pwritev /* 5390 */
+ PTR sys_pwritev /* 5290 */
PTR sys_rt_tgsigqueueinfo
PTR sys_perf_event_open
PTR sys_accept4
- PTR sys_recvmmsg
+ PTR sys_recvmmsg
+ PTR sys_fanotify_init /* 5295 */
+ PTR sys_fanotify_mark
+ PTR sys_prlimit64
.size sys_call_table,.-sys_call_table
PTR sys_perf_event_open
PTR sys_accept4
PTR compat_sys_recvmmsg
- PTR sys_getdents
+ PTR sys_getdents64
+ PTR sys_fanotify_init /* 6300 */
+ PTR sys_fanotify_mark
+ PTR sys_prlimit64
.size sysn32_call_table,.-sysn32_call_table
PTR compat_sys_rt_tgsigqueueinfo
PTR sys_perf_event_open
PTR sys_accept4
- PTR compat_sys_recvmmsg
+ PTR compat_sys_recvmmsg /* 4335 */
+ PTR sys_fanotify_init
+ PTR sys_32_fanotify_mark
+ PTR sys_prlimit64
.size sys_call_table,.-sys_call_table
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
{
+ gfp_t dma_flag;
+
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ISA
if (dev == NULL)
- gfp |= __GFP_DMA;
- else if (dev->coherent_dma_mask < DMA_BIT_MASK(24))
- gfp |= __GFP_DMA;
+ dma_flag = __GFP_DMA;
else
#endif
-#ifdef CONFIG_ZONE_DMA32
+#if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA)
if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
- gfp |= __GFP_DMA32;
+ dma_flag = __GFP_DMA;
+ else if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA32;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA32;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA;
else
#endif
- ;
+ dma_flag = 0;
/* Don't invoke OOM killer */
gfp |= __GFP_NORETRY;
- return gfp;
+ return gfp | dma_flag;
}
void *dma_alloc_noncoherent(struct device *dev, size_t size,
#define tc_lsize 32
extern unsigned long icache_way_size, dcache_way_size;
-unsigned long tcache_size;
+static unsigned long tcache_size;
#include <asm/r4kcache.h>
*/
#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
+#define X GIC_UNUSED
+
static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
{ X, X, X, X, 0 },
{ X, X, X, X, 0 },
{ X, X, X, X, 0 },
/* The remainder of this table is initialised by fill_ipi_map */
};
+#undef X
/*
* GCMP needs to be detected before any SMP initialisation
if (!((pcicvalue == PCIM_H_EA) ||
(pcicvalue == PCIM_H_IA_FIX) ||
(pcicvalue == PCIM_H_IA_RR))) {
- pr_err(KERN_ERR "PCI init error!!!\n");
+ pr_err("PCI init error!!!\n");
/* Not in Host Mode, return ERROR */
return -1;
}
*/
#include <linux/kernel.h>
+#include <asm/processor.h>
#include <asm/reboot.h>
#include <glb.h>
void pnx8550_machine_restart(char *command)
{
- char head[] = "************* Machine restart *************";
- char foot[] = "*******************************************";
-
- printk("\n\n");
- printk("%s\n", head);
- if (command != NULL)
- printk("* %s\n", command);
- printk("%s\n", foot);
-
PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
}
void pnx8550_machine_halt(void)
{
- printk("*** Machine halt. (Not implemented) ***\n");
-}
-
-void pnx8550_machine_power_off(void)
-{
- printk("*** Machine power off. (Not implemented) ***\n");
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
}
extern void __init board_setup(void);
extern void pnx8550_machine_restart(char *);
extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
extern struct resource ioport_resource;
extern struct resource iomem_resource;
extern char *prom_getcmdline(void);
_machine_restart = pnx8550_machine_restart;
_machine_halt = pnx8550_machine_halt;
- pm_power_off = pnx8550_machine_power_off;
+ pm_power_off = pnx8550_machine_halt;
/* Clear the Global 2 Register, PCI Inta Output Enable Registers
Bit 1:Enable DAC Powerdown
config MN10300
def_bool y
select HAVE_OPROFILE
- select HAVE_ARCH_TRACEHOOK
config AM33
def_bool y
choice
prompt "GDB stub port"
- default GDBSTUB_TTYSM0
+ default GDBSTUB_ON_TTYSM0
depends on GDBSTUB
help
Select the serial port used for GDB-stub.
#include <asm-generic/bitops/hweight.h>
#define ext2_set_bit_atomic(lock, nr, addr) \
- test_and_set_bit((nr) ^ 0x18, (addr))
+ test_and_set_bit((nr), (addr))
#define ext2_clear_bit_atomic(lock, nr, addr) \
- test_and_clear_bit((nr) ^ 0x18, (addr))
+ test_and_clear_bit((nr), (addr))
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/minix-le.h>
/* These should not be considered constants from userland. */
#define SIGRTMIN 32
-#define SIGRTMAX (_NSIG-1)
+#define SIGRTMAX _NSIG
/*
* SA_FLAGS values:
const Elf_Shdr *sechdrs,
struct module *me)
{
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
/*
*/
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
}
if (!ret && oact) {
if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
{
unsigned int err = 0;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
if (is_using_fpu(current))
fpu_kill_state(current);
regs->d0 = sig;
regs->d1 = (unsigned long) &frame->sc;
- set_fs(USER_DS);
-
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
return 0;
give_sigsegv:
- force_sig(SIGSEGV, current);
+ force_sigsegv(sig, current);
return -EFAULT;
}
regs->d0 = sig;
regs->d1 = (long) &frame->info;
- set_fs(USER_DS);
-
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
return 0;
give_sigsegv:
- force_sig(SIGSEGV, current);
+ force_sigsegv(sig, current);
return -EFAULT;
}
+static inline void stepback(struct pt_regs *regs)
+{
+ regs->pc -= 2;
+ regs->orig_d0 = -1;
+}
+
/*
* handle the actual delivery of a signal to userspace
*/
/* fallthrough */
case -ERESTARTNOINTR:
regs->d0 = regs->orig_d0;
- regs->pc -= 2;
+ stepback(regs);
}
}
case -ERESTARTSYS:
case -ERESTARTNOINTR:
regs->d0 = regs->orig_d0;
- regs->pc -= 2;
+ stepback(regs);
break;
case -ERESTART_RESTARTBLOCK:
regs->d0 = __NR_restart_syscall;
- regs->pc -= 2;
+ stepback(regs);
break;
}
}
# Makefile for the MN10300-specific memory management code
#
+cacheflush-y := cache.o cache-mn10300.o
+cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o
+
+cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o
+
obj-y := \
init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \
- misalignment.o dma-alloc.o
-
-ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y)
-obj-y += cache.o cache-mn10300.o
-ifeq ($(CONFIG_MN10300_CACHE_WBACK),y)
-obj-y += cache-flush-mn10300.o
-endif
-endif
+ misalignment.o dma-alloc.o $(cacheflush-y)
--- /dev/null
+/* Handle the cache being disabled
+ *
+ * Copyright (C) 2010 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 <linux/mm.h>
+
+/*
+ * allow userspace to flush the instruction cache
+ */
+asmlinkage long sys_cacheflush(unsigned long start, unsigned long end)
+{
+ if (end < start)
+ return -EINVAL;
+ return 0;
+}
void flush_icache_range(unsigned long start, unsigned long end)
{
#ifdef CONFIG_MN10300_CACHE_WBACK
- unsigned long addr, size, off;
+ unsigned long addr, size, base, off;
struct page *page;
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ppte, pte;
+ if (end > 0x80000000UL) {
+ /* addresses above 0xa0000000 do not go through the cache */
+ if (end > 0xa0000000UL) {
+ end = 0xa0000000UL;
+ if (start >= end)
+ return;
+ }
+
+ /* kernel addresses between 0x80000000 and 0x9fffffff do not
+ * require page tables, so we just map such addresses directly */
+ base = (start >= 0x80000000UL) ? start : 0x80000000UL;
+ mn10300_dcache_flush_range(base, end);
+ if (base == start)
+ goto invalidate;
+ end = base;
+ }
+
for (; start < end; start += size) {
/* work out how much of the page to flush */
off = start & (PAGE_SIZE - 1);
}
#endif
+invalidate:
mn10300_icache_inv();
}
EXPORT_SYMBOL(flush_icache_range);
nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
DEBUGP("NEW num_symtab %lu\n", nsyms);
symhdr->sh_size = nsyms * sizeof(Elf_Sym);
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
deregister_unwind_table(mod);
- module_bug_cleanup(mod);
}
const Elf_Shdr *sechdrs, struct module *me)
{
const Elf_Shdr *sect;
- int err;
-
- err = module_bug_finalize(hdr, sechdrs, me);
- if (err)
- return err;
/* Apply feature fixups */
sect = find_section(hdr, sechdrs, "__ftr_fixup");
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
}
+ regs->trap = 0;
return 0; /* no signals delivered */
}
ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
}
+ regs->trap = 0;
if (ret) {
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked, ¤t->blocked,
if (!sig)
save_r2 = (unsigned int)regs->gpr[2];
err = restore_general_regs(regs, sr);
+ regs->trap = 0;
err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
if (!sig)
regs->gpr[2] = (unsigned long) save_r2;
regs->nip = (unsigned long) ka->sa.sa_handler;
/* enter the signal handler in big-endian mode */
regs->msr &= ~MSR_LE;
- regs->trap = 0;
return 1;
badframe:
regs->nip = (unsigned long) ka->sa.sa_handler;
/* enter the signal handler in big-endian mode */
regs->msr &= ~MSR_LE;
- regs->trap = 0;
return 1;
err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
/* skip SOFTE */
- err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
+ regs->trap = 0;
err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
int id_match = 0;
if (dev == NULL || id == NULL)
- return NULL;
+ return clk;
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (bus_range == NULL || len < 2 * sizeof(int)) {
printk(KERN_WARNING EFIKA_PLATFORM_NAME
": Can't get bus-range for %s\n", pcictrl->full_name);
- return;
+ goto out_put;
}
if (bus_range[1] == bus_range[0])
printk(" controlled by %s\n", pcictrl->full_name);
printk("\n");
- hose = pcibios_alloc_controller(of_node_get(pcictrl));
+ hose = pcibios_alloc_controller(pcictrl);
if (!hose) {
printk(KERN_WARNING EFIKA_PLATFORM_NAME
": Can't allocate PCI controller structure for %s\n",
pcictrl->full_name);
- return;
+ goto out_put;
}
hose->first_busno = bus_range[0];
hose->ops = &rtas_pci_ops;
pci_process_bridge_OF_ranges(hose, pcictrl, 0);
+ return;
+out_put:
+ of_node_put(pcictrl);
}
#else
clrbits32(&simple_gpio->simple_dvo, sync | out);
clrbits8(&wkup_gpio->wkup_dvo, reset);
- /* wait at lease 1 us */
- udelay(2);
+ /* wait for 1 us */
+ udelay(1);
/* Deassert reset */
setbits8(&wkup_gpio->wkup_dvo, reset);
+ /* wait at least 200ns */
+ /* 7 ~= (200ns * timebase) / ns2sec */
+ __delay(7);
+
/* Restore pin-muxing */
out_be32(&simple_gpio->port_config, mux);
{
vfree(me->arch.syminfo);
me->arch.syminfo = NULL;
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
int ret = 0;
ret |= module_dwarf_finalize(hdr, sechdrs, me);
- ret |= module_bug_finalize(hdr, sechdrs, me);
return ret;
}
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
module_dwarf_cleanup(mod);
}
if (atomic_read(&nmi_active) < 0)
return -ENODEV;
+ pmap = NULL;
if (attr->type == PERF_TYPE_HARDWARE) {
if (attr->config >= sparc_pmu->max_events)
return -EINVAL;
pmap = sparc_map_cache_event(attr->config);
if (IS_ERR(pmap))
return PTR_ERR(pmap);
- } else
+ } else if (attr->type != PERF_TYPE_RAW)
return -EOPNOTSUPP;
+ if (pmap) {
+ hwc->event_base = perf_event_encode(pmap);
+ } else {
+ /* User gives us "(encoding << 16) | pic_mask" for
+ * PERF_TYPE_RAW events.
+ */
+ hwc->event_base = attr->config;
+ }
+
/* We save the enable bits in the config_base. */
hwc->config_base = sparc_pmu->irq_bit;
if (!attr->exclude_user)
if (!attr->exclude_hv)
hwc->config_base |= sparc_pmu->hv_bit;
- hwc->event_base = perf_event_encode(pmap);
-
n = 0;
if (event->group_leader != event) {
n = collect_events(event->group_leader,
return err;
}
-static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset)
+/* The I-cache flush instruction only works in the primary ASI, which
+ * right now is the nucleus, aka. kernel space.
+ *
+ * Therefore we have to kick the instructions out using the kernel
+ * side linear mapping of the physical address backing the user
+ * instructions.
+ */
+static void flush_signal_insns(unsigned long address)
+{
+ unsigned long pstate, paddr;
+ pte_t *ptep, pte;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+
+ /* Commit all stores of the instructions we are about to flush. */
+ wmb();
+
+ /* Disable cross-call reception. In this way even a very wide
+ * munmap() on another cpu can't tear down the page table
+ * hierarchy from underneath us, since that can't complete
+ * until the IPI tlb flush returns.
+ */
+
+ __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+ __asm__ __volatile__("wrpr %0, %1, %%pstate"
+ : : "r" (pstate), "i" (PSTATE_IE));
+
+ pgdp = pgd_offset(current->mm, address);
+ if (pgd_none(*pgdp))
+ goto out_irqs_on;
+ pudp = pud_offset(pgdp, address);
+ if (pud_none(*pudp))
+ goto out_irqs_on;
+ pmdp = pmd_offset(pudp, address);
+ if (pmd_none(*pmdp))
+ goto out_irqs_on;
+
+ ptep = pte_offset_map(pmdp, address);
+ pte = *ptep;
+ if (!pte_present(pte))
+ goto out_unmap;
+
+ paddr = (unsigned long) page_address(pte_page(pte));
+
+ __asm__ __volatile__("flush %0 + %1"
+ : /* no outputs */
+ : "r" (paddr),
+ "r" (address & (PAGE_SIZE - 1))
+ : "memory");
+
+out_unmap:
+ pte_unmap(ptep);
+out_irqs_on:
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
+
+}
+
+static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+ int signo, sigset_t *oldset)
{
struct signal_frame32 __user *sf;
int sigframe_size;
if (ka->ka_restorer) {
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
} else {
- /* Flush instruction space. */
unsigned long address = ((unsigned long)&(sf->insns[0]));
- pgd_t *pgdp = pgd_offset(current->mm, address);
- pud_t *pudp = pud_offset(pgdp, address);
- pmd_t *pmdp = pmd_offset(pudp, address);
- pte_t *ptep;
- pte_t pte;
regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
if (err)
goto sigsegv;
- preempt_disable();
- ptep = pte_offset_map(pmdp, address);
- pte = *ptep;
- if (pte_present(pte)) {
- unsigned long page = (unsigned long)
- page_address(pte_page(pte));
-
- wmb();
- __asm__ __volatile__("flush %0 + %1"
- : /* no outputs */
- : "r" (page),
- "r" (address & (PAGE_SIZE - 1))
- : "memory");
- }
- pte_unmap(ptep);
- preempt_enable();
+ flush_signal_insns(address);
}
- return;
+ return 0;
sigill:
do_exit(SIGILL);
+ return -EINVAL;
+
sigsegv:
force_sigsegv(signo, current);
+ return -EFAULT;
}
-static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
- unsigned long signr, sigset_t *oldset,
- siginfo_t *info)
+static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+ unsigned long signr, sigset_t *oldset,
+ siginfo_t *info)
{
struct rt_signal_frame32 __user *sf;
int sigframe_size;
if (ka->ka_restorer)
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
else {
- /* Flush instruction space. */
unsigned long address = ((unsigned long)&(sf->insns[0]));
- pgd_t *pgdp = pgd_offset(current->mm, address);
- pud_t *pudp = pud_offset(pgdp, address);
- pmd_t *pmdp = pmd_offset(pudp, address);
- pte_t *ptep;
regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
if (err)
goto sigsegv;
- preempt_disable();
- ptep = pte_offset_map(pmdp, address);
- if (pte_present(*ptep)) {
- unsigned long page = (unsigned long)
- page_address(pte_page(*ptep));
-
- wmb();
- __asm__ __volatile__("flush %0 + %1"
- : /* no outputs */
- : "r" (page),
- "r" (address & (PAGE_SIZE - 1))
- : "memory");
- }
- pte_unmap(ptep);
- preempt_enable();
+ flush_signal_insns(address);
}
- return;
+ return 0;
sigill:
do_exit(SIGILL);
+ return -EINVAL;
+
sigsegv:
force_sigsegv(signr, current);
+ return -EFAULT;
}
-static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
- siginfo_t *info,
- sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
+ siginfo_t *info,
+ sigset_t *oldset, struct pt_regs *regs)
{
+ int err;
+
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame32(ka, regs, signr, oldset, info);
+ err = setup_rt_frame32(ka, regs, signr, oldset, info);
else
- setup_frame32(ka, regs, signr, oldset);
+ err = setup_frame32(ka, regs, signr, oldset);
+
+ if (err)
+ return err;
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
sigaddset(¤t->blocked,signr);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
+
+ tracehook_signal_handler(signr, info, ka, regs, 0);
+
+ return 0;
}
static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
if (signr > 0) {
if (restart_syscall)
syscall_restart32(orig_i0, regs, &ka.sa);
- handle_signal32(signr, &ka, &info, oldset, regs);
-
- /* 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 TS_RESTORE_SIGMASK flag.
- */
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
- tracehook_signal_handler(signr, &info, &ka, regs, 0);
+ if (handle_signal32(signr, &ka, &info, oldset, regs) == 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 TS_RESTORE_SIGMASK flag.
+ */
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ }
return;
}
if (restart_syscall &&
regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4;
regs->tnpc -= 4;
+ pt_regs_clear_syscall(regs);
}
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
regs->tnpc -= 4;
+ pt_regs_clear_syscall(regs);
}
/* If there's no signal to deliver, we just put the saved sigmask
return err;
}
-static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset)
+static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
+ int signo, sigset_t *oldset)
{
struct signal_frame __user *sf;
int sigframe_size, err;
/* Flush instruction space. */
flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
}
- return;
+ return 0;
sigill_and_return:
do_exit(SIGILL);
+ return -EINVAL;
+
sigsegv:
force_sigsegv(signo, current);
+ return -EFAULT;
}
-static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset, siginfo_t *info)
+static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
+ int signo, sigset_t *oldset, siginfo_t *info)
{
struct rt_signal_frame __user *sf;
int sigframe_size;
/* Flush instruction space. */
flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
}
- return;
+ return 0;
sigill:
do_exit(SIGILL);
+ return -EINVAL;
+
sigsegv:
force_sigsegv(signo, current);
+ return -EFAULT;
}
-static inline void
+static inline int
handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
+ int err;
+
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(ka, regs, signr, oldset, info);
+ err = setup_rt_frame(ka, regs, signr, oldset, info);
else
- setup_frame(ka, regs, signr, oldset);
+ err = setup_frame(ka, regs, signr, oldset);
+
+ if (err)
+ return err;
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
sigaddset(¤t->blocked, signr);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
+
+ tracehook_signal_handler(signr, info, ka, regs, 0);
+
+ return 0;
}
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
if (signr > 0) {
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
- handle_signal(signr, &ka, &info, oldset, regs);
-
- /* 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);
+ if (handle_signal(signr, &ka, &info, oldset, regs) == 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);
+ }
return;
}
if (restart_syscall &&
regs->u_regs[UREG_I0] = orig_i0;
regs->pc -= 4;
regs->npc -= 4;
+ pt_regs_clear_syscall(regs);
}
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->pc -= 4;
regs->npc -= 4;
+ pt_regs_clear_syscall(regs);
}
/* if there's no signal to deliver, we just put the saved sigmask
return (void __user *) sp;
}
-static inline void
+static inline int
setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
{
}
/* 4. return to kernel instructions */
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
- return;
+ return 0;
sigill:
do_exit(SIGILL);
+ return -EINVAL;
+
sigsegv:
force_sigsegv(signo, current);
+ return -EFAULT;
}
-static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
- siginfo_t *info,
- sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
+ siginfo_t *info,
+ sigset_t *oldset, struct pt_regs *regs)
{
- setup_rt_frame(ka, regs, signr, oldset,
- (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
+ int err;
+
+ err = setup_rt_frame(ka, regs, signr, oldset,
+ (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
+ if (err)
+ return err;
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
sigaddset(¤t->blocked,signr);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
+
+ tracehook_signal_handler(signr, info, ka, regs, 0);
+
+ return 0;
}
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
if (signr > 0) {
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
- handle_signal(signr, &ka, &info, oldset, regs);
-
- /* 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 TS_RESTORE_SIGMASK flag.
- */
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
- tracehook_signal_handler(signr, &info, &ka, regs, 0);
+ if (handle_signal(signr, &ka, &info, oldset, regs) == 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 TS_RESTORE_SIGMASK flag.
+ */
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ }
return;
}
if (restart_syscall &&
regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4;
regs->tnpc -= 4;
+ pt_regs_clear_syscall(regs);
}
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
regs->tnpc -= 4;
+ pt_regs_clear_syscall(regs);
}
/* If there's no signal to deliver, we just put the saved sigmask
}
STD_ENDPROC(handle_ill)
- .pushsection .rodata, "a"
- .align 8
-bpt_code:
- bpt
- ENDPROC(bpt_code)
- .popsection
-
/* Various stub interrupt handlers and syscall handlers */
STD_ENTRY_LOCAL(_kernel_double_fault)
netif_wake_queue(dev);
}
-static int uml_net_set_mac(struct net_device *dev, void *addr)
-{
- struct uml_net_private *lp = netdev_priv(dev);
- struct sockaddr *hwaddr = addr;
-
- spin_lock_irq(&lp->lock);
- eth_mac_addr(dev, hwaddr->sa_data);
- spin_unlock_irq(&lp->lock);
-
- return 0;
-}
-
static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
{
dev->mtu = new_mtu;
.ndo_start_xmit = uml_net_start_xmit,
.ndo_set_multicast_list = uml_net_set_multicast_list,
.ndo_tx_timeout = uml_net_tx_timeout,
- .ndo_set_mac_address = uml_net_set_mac,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = uml_net_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};
((*transport->user->init)(&lp->user, dev) != 0))
goto out_unregister;
- eth_mac_addr(dev, device->mac);
+ /* don't use eth_mac_addr, it will not work here */
+ memcpy(dev->dev_addr, device->mac, ETH_ALEN);
dev->mtu = transport->user->mtu;
dev->netdev_ops = ¨_netdev_ops;
dev->ethtool_ops = ¨_net_ethtool_ops;
return error;
}
-long um_execve(const char *file, char __user *__user *argv, char __user *__user *env)
+long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
{
long err;
return err;
}
-long sys_execve(const char __user *file, char __user *__user *argv,
- char __user *__user *env)
+long sys_execve(const char __user *file, const char __user *const __user *argv,
+ const char __user *const __user *env)
{
long error;
char *filename;
-extern long um_execve(const char *file, char __user *__user *argv, char __user *__user *env);
+extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env);
fs = get_fs();
set_fs(KERNEL_DS);
- ret = um_execve(filename, (char __user *__user *)argv,
- (char __user *__user *) envp);
+ ret = um_execve(filename, (const char __user *const __user *)argv,
+ (const char __user *const __user *) envp);
set_fs(fs);
return ret;
if (arg[pos] == ',')
pos++;
- if (!strncmp(arg, "ttyS", 4)) {
+ /*
+ * make sure we have
+ * "serial,0x3f8,115200"
+ * "serial,ttyS0,115200"
+ * "ttyS0,115200"
+ */
+ if (pos == 7 && !strncmp(arg + pos, "0x", 2)) {
+ port = simple_strtoull(arg + pos, &e, 16);
+ if (port == 0 || arg + pos == e)
+ port = DEFAULT_SERIAL_PORT;
+ else
+ pos = e - arg;
+ } else if (!strncmp(arg + pos, "ttyS", 4)) {
static const int bases[] = { 0x3f8, 0x2f8 };
int idx = 0;
#endif /* !CONFIG_AMD_IOMMU_STATS */
+static inline bool is_rd890_iommu(struct pci_dev *pdev)
+{
+ return (pdev->vendor == PCI_VENDOR_ID_ATI) &&
+ (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
+}
+
#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
/* capabilities of that IOMMU read from ACPI */
u32 cap;
+ /* flags read from acpi table */
+ u8 acpi_flags;
+
/*
* Capability pointer. There could be more than one IOMMU per PCI
* device function if there are more than one AMD IOMMU capability
/* default dma_ops domain for that IOMMU */
struct dma_ops_domain *default_dom;
+
+ /*
+ * This array is required to work around a potential BIOS bug.
+ * The BIOS may miss to restore parts of the PCI configuration
+ * space when the system resumes from S3. The result is that the
+ * IOMMU does not execute commands anymore which leads to system
+ * failure.
+ */
+ u32 cache_cfg[4];
};
/*
static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
{
return ((1UL << (nr % BITS_PER_LONG)) &
- (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
+ (addr[nr / BITS_PER_LONG])) != 0;
}
static inline int variable_test_bit(int nr, volatile const unsigned long *addr)
#define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */
#define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */
#define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */
+#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */
/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
#include <linux/list.h>
/* Available HW breakpoint length encodings */
-#define X86_BREAKPOINT_LEN_X 0x00
+#define X86_BREAKPOINT_LEN_X 0x40
#define X86_BREAKPOINT_LEN_1 0x40
#define X86_BREAKPOINT_LEN_2 0x44
#define X86_BREAKPOINT_LEN_4 0x4c
CFLAGS_REMOVE_tsc.o = -pg
CFLAGS_REMOVE_rtc.o = -pg
CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
+CFLAGS_REMOVE_pvclock.o = -pg
+CFLAGS_REMOVE_kvmclock.o = -pg
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_early_printk.o = -pg
endif
unsigned int ecx;
} states[ACPI_PROCESSOR_MAX_POWER];
};
-static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */
+static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */
static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
size_t size,
int dir)
{
+ dma_addr_t flush_addr;
dma_addr_t i, start;
unsigned int pages;
(dma_addr + size > dma_dom->aperture_size))
return;
+ flush_addr = dma_addr;
pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
dma_addr &= PAGE_MASK;
start = dma_addr;
dma_ops_free_addresses(dma_dom, dma_addr, pages);
if (amd_iommu_unmap_flush || dma_dom->need_flush) {
- iommu_flush_pages(&dma_dom->domain, dma_addr, size);
+ iommu_flush_pages(&dma_dom->domain, flush_addr, size);
dma_dom->need_flush = false;
}
}
iommu->last_device = calc_devid(MMIO_GET_BUS(range),
MMIO_GET_LD(range));
iommu->evt_msi_num = MMIO_MSI_NUM(misc);
+
+ if (is_rd890_iommu(iommu->dev)) {
+ pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]);
+ pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]);
+ pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]);
+ pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]);
+ }
}
/*
struct ivhd_entry *e;
/*
- * First set the recommended feature enable bits from ACPI
- * into the IOMMU control registers
+ * First save the recommended feature enable bits from ACPI
*/
- h->flags & IVHD_FLAG_HT_TUN_EN_MASK ?
- iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
- iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
-
- h->flags & IVHD_FLAG_PASSPW_EN_MASK ?
- iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
- iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
-
- h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
- iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
- iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
-
- h->flags & IVHD_FLAG_ISOC_EN_MASK ?
- iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
- iommu_feature_disable(iommu, CONTROL_ISOC_EN);
-
- /*
- * make IOMMU memory accesses cache coherent
- */
- iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
+ iommu->acpi_flags = h->flags;
/*
* Done. Now parse the device entries
}
}
+static void iommu_init_flags(struct amd_iommu *iommu)
+{
+ iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
+ iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
+ iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
+
+ iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ?
+ iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
+ iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
+
+ iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
+ iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
+ iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
+
+ iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ?
+ iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
+ iommu_feature_disable(iommu, CONTROL_ISOC_EN);
+
+ /*
+ * make IOMMU memory accesses cache coherent
+ */
+ iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
+}
+
+static void iommu_apply_quirks(struct amd_iommu *iommu)
+{
+ if (is_rd890_iommu(iommu->dev)) {
+ pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]);
+ pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]);
+ pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]);
+ pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]);
+ }
+}
+
/*
* This function finally enables all IOMMUs found in the system after
* they have been initialized
for_each_iommu(iommu) {
iommu_disable(iommu);
+ iommu_apply_quirks(iommu);
+ iommu_init_flags(iommu);
iommu_set_device_table(iommu);
iommu_enable_command_buffer(iommu);
iommu_enable_event_buffer(iommu);
old_cfg = old_desc->chip_data;
- memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
+ cfg->vector = old_cfg->vector;
+ cfg->move_in_progress = old_cfg->move_in_progress;
+ cpumask_copy(cfg->domain, old_cfg->domain);
+ cpumask_copy(cfg->old_domain, old_cfg->old_domain);
init_copy_irq_2_pin(old_cfg, cfg, node);
}
-static void free_irq_cfg(struct irq_cfg *old_cfg)
+static void free_irq_cfg(struct irq_cfg *cfg)
{
- kfree(old_cfg);
+ free_cpumask_var(cfg->domain);
+ free_cpumask_var(cfg->old_domain);
+ kfree(cfg);
}
void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
}
}
-static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
{
u32 tfms, xlvl;
u32 ebx;
*const __x86_cpu_dev_end[];
extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
+extern void get_cpu_cap(struct cpuinfo_x86 *c);
#endif
return -ENODEV;
out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER)
- return -ENODEV;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
- if (errors)
- return -ENODEV;
+ if (errors) {
+ ret = -ENODEV;
+ goto out_free;
+ }
supported = *((u32 *)(out_obj->buffer.pointer + 4));
- if (!(supported & 0x1))
- return -ENODEV;
+ if (!(supported & 0x1)) {
+ ret = -ENODEV;
+ goto out_free;
+ }
out_free:
kfree(output.pointer);
misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
c->cpuid_level = cpuid_eax(0);
+ get_cpu_cap(c);
}
}
*/
struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
int enabled;
int n_events;
x86_perf_event_set_period(event);
cpuc->events[idx] = event;
__set_bit(idx, cpuc->active_mask);
+ __set_bit(idx, cpuc->running);
x86_pmu.enable(event);
perf_event_update_userpage(event);
cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- if (!test_bit(idx, cpuc->active_mask))
+ if (!test_bit(idx, cpuc->active_mask)) {
+ /*
+ * Though we deactivated the counter some cpus
+ * might still deliver spurious interrupts still
+ * in flight. Catch them:
+ */
+ if (__test_and_clear_bit(idx, cpuc->running))
+ handled++;
continue;
+ }
event = cpuc->events[idx];
hwc = &event->hw;
for (idx = 0; idx < x86_pmu.num_counters; idx++) {
int overflow;
- if (!test_bit(idx, cpuc->active_mask))
+ if (!test_bit(idx, cpuc->active_mask)) {
+ /* catch in-flight IRQs */
+ if (__test_and_clear_bit(idx, cpuc->running))
+ handled++;
continue;
+ }
event = cpuc->events[idx];
hwc = &event->hw;
const struct cpuid_bit *cb;
static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
+ { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 },
{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 },
{ X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 },
{ X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 },
{
unsigned int irq;
- irq = create_irq();
+ irq = create_irq_nr(0, -1);
if (!irq)
return -EINVAL;
int arch_bp_generic_fields(int x86_len, int x86_type,
int *gen_len, int *gen_type)
{
- /* Len */
- switch (x86_len) {
- case X86_BREAKPOINT_LEN_X:
+ /* Type */
+ switch (x86_type) {
+ case X86_BREAKPOINT_EXECUTE:
+ if (x86_len != X86_BREAKPOINT_LEN_X)
+ return -EINVAL;
+
+ *gen_type = HW_BREAKPOINT_X;
*gen_len = sizeof(long);
+ return 0;
+ case X86_BREAKPOINT_WRITE:
+ *gen_type = HW_BREAKPOINT_W;
break;
+ case X86_BREAKPOINT_RW:
+ *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Len */
+ switch (x86_len) {
case X86_BREAKPOINT_LEN_1:
*gen_len = HW_BREAKPOINT_LEN_1;
break;
return -EINVAL;
}
- /* Type */
- switch (x86_type) {
- case X86_BREAKPOINT_EXECUTE:
- *gen_type = HW_BREAKPOINT_X;
- break;
- case X86_BREAKPOINT_WRITE:
- *gen_type = HW_BREAKPOINT_W;
- break;
- case X86_BREAKPOINT_RW:
- *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
- break;
- default:
- return -EINVAL;
- }
-
return 0;
}
ret = -EINVAL;
switch (info->len) {
- case X86_BREAKPOINT_LEN_X:
- align = sizeof(long) -1;
- break;
case X86_BREAKPOINT_LEN_1:
align = 0;
break;
apply_paravirt(pseg, pseg + para->sh_size);
}
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
alternatives_smp_module_del(mod);
- module_bug_cleanup(mod);
}
}
/*
- * For a single GDT entry which changes, we do the lazy thing: alter our GDT,
- * then tell the Host to reload the entire thing. This operation is so rare
- * that this naive implementation is reasonable.
+ * For a single GDT entry which changes, we simply change our copy and
+ * then tell the host about it.
*/
static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
const void *desc, int type)
}
/*
- * OK, I lied. There are three "thread local storage" GDT entries which change
+ * There are three "thread local storage" GDT entries which change
* on every context switch (these three entries are how glibc implements
- * __thread variables). So we have a hypercall specifically for this case.
+ * __thread variables). As an optimization, we have a hypercall
+ * specifically for this case.
+ *
+ * Wouldn't it be nicer to have a general LOAD_GDT_ENTRIES hypercall
+ * which took a range of entries?
*/
static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
{
case 14:
*cpu_type = "i386/core";
break;
- case 15: case 23:
+ case 0x0f:
+ case 0x16:
+ case 0x17:
+ case 0x1d:
*cpu_type = "i386/core_2";
break;
case 0x1a:
__init void xen_hvm_init_time_ops(void)
{
/* vector callback is needed otherwise we cannot receive interrupts
- * on cpu > 0 */
- if (!xen_have_vector_callback && num_present_cpus() > 1)
+ * on cpu > 0 and at this point we don't know how many cpus are
+ * available */
+ if (!xen_have_vector_callback)
return;
if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
return PTR_ERR(bio);
if (rq_data_dir(rq) == WRITE)
- bio->bi_rw |= (1 << REQ_WRITE);
+ bio->bi_rw |= REQ_WRITE;
if (do_copy)
rq->cmd_flags |= REQ_COPY_USER;
if (!rq_mergeable(req) || !rq_mergeable(next))
return 0;
+ /*
+ * Don't merge file system requests and discard requests
+ */
+ if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
+ return 0;
+
+ /*
+ * Don't merge discard requests and secure discard requests
+ */
+ if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
+ return 0;
+
/*
* not contiguous
*/
*/
atomic_set(&cfqg->ref, 1);
- /* Add group onto cgroup list */
- sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
- cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
+ /*
+ * Add group onto cgroup list. It might happen that bdi->dev is
+ * not initiliazed yet. Initialize this new group without major
+ * and minor info and this info will be filled in once a new thread
+ * comes for IO. See code above.
+ */
+ if (bdi->dev) {
+ sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+ cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
MKDEV(major, minor));
+ } else
+ cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
+ 0);
+
cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev);
/* Add group on cfqd list */
Be aware that using this interface can confuse your Embedded
Controller in a way that a normal reboot is not enough. You then
- have to power of your system, and remove the laptop battery for
+ have to power off your system, and remove the laptop battery for
some seconds.
An Embedded Controller typically is available on laptops and reads
sensor values like battery state and temperature.
device_remove_file(&device->dev, &dev_attr_rrtime);
}
-/* Query firmware how many CPUs should be idle */
-static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
+/*
+ * Query firmware how many CPUs should be idle
+ * return -1 on failure
+ */
+static int acpi_pad_pur(acpi_handle handle)
{
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *package;
- int rev, num, ret = -EINVAL;
+ int num = -1;
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
- return -EINVAL;
+ return num;
if (!buffer.length || !buffer.pointer)
- return -EINVAL;
+ return num;
package = buffer.pointer;
- if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
- goto out;
- rev = package->package.elements[0].integer.value;
- num = package->package.elements[1].integer.value;
- if (rev != 1 || num < 0)
- goto out;
- *num_cpus = num;
- ret = 0;
-out:
+
+ if (package->type == ACPI_TYPE_PACKAGE &&
+ package->package.count == 2 &&
+ package->package.elements[0].integer.value == 1) /* rev 1 */
+
+ num = package->package.elements[1].integer.value;
+
kfree(buffer.pointer);
- return ret;
+ return num;
}
/* Notify firmware how many CPUs are idle */
uint32_t idle_cpus;
mutex_lock(&isolated_cpus_lock);
- if (acpi_pad_pur(handle, &num_cpus)) {
+ num_cpus = acpi_pad_pur(handle);
+ if (num_cpus < 0) {
mutex_unlock(&isolated_cpus_lock);
return;
}
ACPI_BITMASK_POWER_BUTTON_STATUS | \
ACPI_BITMASK_SLEEP_BUTTON_STATUS | \
ACPI_BITMASK_RT_CLOCK_STATUS | \
+ ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \
ACPI_BITMASK_WAKE_STATUS)
#define ACPI_BITMASK_TIMER_ENABLE 0x0001
*
* DESCRIPTION: Reacquire the interpreter execution region from within the
* interpreter code. Failure to enter the interpreter region is a
- * fatal system error. Used in conjuction with
+ * fatal system error. Used in conjunction with
* relinquish_interpreter
*
******************************************************************************/
/*
* 16-, 32-, and 64-bit cases must use the move macros that perform
- * endian conversion and/or accomodate hardware that cannot perform
+ * endian conversion and/or accommodate hardware that cannot perform
* misaligned memory transfers
*/
case ACPI_RSC_MOVE16:
depends on ACPI_APEI
help
ERST is a way provided by APEI to save and retrieve hardware
- error infomation to and from a persistent store. Enable this
+ error information to and from a persistent store. Enable this
if you want to debugging and testing the ERST kernel support
and firmware implementation.
int apei_resources_request(struct apei_resources *resources,
const char *desc)
{
- struct apei_res *res, *res_bak;
+ struct apei_res *res, *res_bak = NULL;
struct resource *r;
+ int rc;
- apei_resources_sub(resources, &apei_resources_all);
+ rc = apei_resources_sub(resources, &apei_resources_all);
+ if (rc)
+ return rc;
+ rc = -EINVAL;
list_for_each_entry(res, &resources->iomem, list) {
r = request_mem_region(res->start, res->end - res->start,
desc);
}
}
- apei_resources_merge(&apei_resources_all, resources);
+ rc = apei_resources_merge(&apei_resources_all, resources);
+ if (rc) {
+ pr_err(APEI_PFX "Fail to merge resources!\n");
+ goto err_unmap_ioport;
+ }
return 0;
err_unmap_ioport:
break;
release_mem_region(res->start, res->end - res->start);
}
- return -EINVAL;
+ return rc;
}
EXPORT_SYMBOL_GPL(apei_resources_request);
void apei_resources_release(struct apei_resources *resources)
{
+ int rc;
struct apei_res *res;
list_for_each_entry(res, &resources->iomem, list)
list_for_each_entry(res, &resources->ioport, list)
release_region(res->start, res->end - res->start);
- apei_resources_sub(&apei_resources_all, resources);
+ rc = apei_resources_sub(&apei_resources_all, resources);
+ if (rc)
+ pr_err(APEI_PFX "Fail to sub resources!\n");
}
EXPORT_SYMBOL_GPL(apei_resources_release);
static int einj_check_table(struct acpi_table_einj *einj_tab)
{
- if (einj_tab->header_length != sizeof(struct acpi_table_einj))
+ if ((einj_tab->header_length !=
+ (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header)))
+ && (einj_tab->header_length != sizeof(struct acpi_table_einj)))
return -EINVAL;
if (einj_tab->header.length < sizeof(struct acpi_table_einj))
return -EINVAL;
* APEI Error Record Serialization Table debug support
*
* ERST is a way provided by APEI to save and retrieve hardware error
- * infomation to and from a persistent store. This file provide the
+ * information to and from a persistent store. This file provide the
* debugging/testing support for ERST kernel support and firmware
* implementation.
*
goto out;
}
if (len > erst_dbg_buf_len) {
- kfree(erst_dbg_buf);
+ void *p;
rc = -ENOMEM;
- erst_dbg_buf = kmalloc(len, GFP_KERNEL);
- if (!erst_dbg_buf)
+ p = kmalloc(len, GFP_KERNEL);
+ if (!p)
goto out;
+ kfree(erst_dbg_buf);
+ erst_dbg_buf = p;
erst_dbg_buf_len = len;
goto retry;
}
if (mutex_lock_interruptible(&erst_dbg_mutex))
return -EINTR;
if (usize > erst_dbg_buf_len) {
- kfree(erst_dbg_buf);
+ void *p;
rc = -ENOMEM;
- erst_dbg_buf = kmalloc(usize, GFP_KERNEL);
- if (!erst_dbg_buf)
+ p = kmalloc(usize, GFP_KERNEL);
+ if (!p)
goto out;
+ kfree(erst_dbg_buf);
+ erst_dbg_buf = p;
erst_dbg_buf_len = usize;
}
rc = copy_from_user(erst_dbg_buf, ubuf, usize);
* APEI Error Record Serialization Table support
*
* ERST is a way provided by APEI to save and retrieve hardware error
- * infomation to and from a persistent store.
+ * information to and from a persistent store.
*
* For more information about ERST, please refer to ACPI Specification
* version 4.0, section 17.4.
{
int rc;
u64 offset;
+ void *src, *dst;
+
+ /* ioremap does not work in interrupt context */
+ if (in_interrupt()) {
+ pr_warning(ERST_PFX
+ "MOVE_DATA can not be used in interrupt context");
+ return -EBUSY;
+ }
rc = __apei_exec_read_register(entry, &offset);
if (rc)
return rc;
- memmove((void *)ctx->dst_base + offset,
- (void *)ctx->src_base + offset,
- ctx->var2);
+
+ src = ioremap(ctx->src_base + offset, ctx->var2);
+ if (!src)
+ return -ENOMEM;
+ dst = ioremap(ctx->dst_base + offset, ctx->var2);
+ if (!dst)
+ return -ENOMEM;
+
+ memmove(dst, src, ctx->var2);
+
+ iounmap(src);
+ iounmap(dst);
return 0;
}
static int erst_check_table(struct acpi_table_erst *erst_tab)
{
- if (erst_tab->header_length != sizeof(struct acpi_table_erst))
+ if ((erst_tab->header_length !=
+ (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header)))
+ && (erst_tab->header_length != sizeof(struct acpi_table_einj)))
return -EINVAL;
if (erst_tab->header.length < sizeof(struct acpi_table_erst))
return -EINVAL;
struct ghes *ghes = NULL;
int rc = -EINVAL;
- generic = ghes_dev->dev.platform_data;
+ generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
if (!generic->enabled)
return -ENODEV;
static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
{
- struct acpi_hest_generic *generic;
struct platform_device *ghes_dev;
struct ghes_arr *ghes_arr = data;
int rc;
if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR)
return 0;
- generic = (struct acpi_hest_generic *)hest_hdr;
- if (!generic->enabled)
+
+ if (!((struct acpi_hest_generic *)hest_hdr)->enabled)
return 0;
ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id);
if (!ghes_dev)
return -ENOMEM;
- ghes_dev->dev.platform_data = generic;
+
+ rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *));
+ if (rc)
+ goto err;
+
rc = platform_device_add(ghes_dev);
if (rc)
goto err;
list_add_tail_rcu(&map->list, &acpi_iomaps);
spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
- return vaddr + (paddr - pg_off);
+ return map->vaddr + (paddr - map->paddr);
err_unmap:
iounmap(vaddr);
return NULL;
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_POWER_NOW,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
{
printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
acpi_osi_setup("!Windows 2006");
+ acpi_osi_setup("!Windows 2006 SP1");
+ acpi_osi_setup("!Windows 2006 SP2");
return 0;
}
static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
},
},
{
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba Satellite L355",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
+ },
+ },
+ {
.callback = dmi_disable_osi_win7,
.ident = "ASUS K50IJ",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
},
},
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba P305D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
+ },
+ },
/*
* BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
static int set_power_nocheck(const struct dmi_system_id *id)
{
printk(KERN_NOTICE PREFIX "%s detected - "
- "disable power check in power transistion\n", id->ident);
+ "disable power check in power transition\n", id->ident);
acpi_power_nocheck = 1;
return 0;
}
static struct dmi_system_id dsdt_dmi_table[] __initdata = {
/*
- * Insyde BIOS on some TOSHIBA machines corrupt the DSDT.
+ * Invoke DSDT corruption work-around on all Toshiba Satellite.
* https://bugzilla.kernel.org/show_bug.cgi?id=14679
*/
{
.callback = set_copy_dsdt,
- .ident = "TOSHIBA Satellite A505",
+ .ident = "TOSHIBA Satellite",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"),
- },
- },
- {
- .callback = set_copy_dsdt,
- .ident = "TOSHIBA Satellite L505D",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
},
},
{}
/*
* If the laptop falls into the DMI check table, the power state check
- * will be disabled in the course of device power transistion.
+ * will be disabled in the course of device power transition.
*/
dmi_check_system(power_nocheck_dmi_table);
acpi_bus_unregister_driver(&acpi_fan_driver);
+#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
+#endif
return;
}
}
static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
- {
- set_no_mwait, "IFL91 board", {
- DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
- DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
- DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
{
set_no_mwait, "Extensa 5220", {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
acpi_idle_driver.name);
} else {
- printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s",
+ printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n",
cpuidle_get_driver()->name);
}
if (!try_module_get(calling_module))
return -EINVAL;
- /* is_done is set to negative if an error occured,
- * and to postitive if _no_ error occured, but SMM
+ /* is_done is set to negative if an error occurred,
+ * and to postitive if _no_ error occurred, but SMM
* was already notified. This avoids double notification
* which might lead to unexpected results...
*/
return 0;
}
+static int __init init_nvs_nosave(const struct dmi_system_id *d)
+{
+ acpi_nvs_nosave();
+ return 0;
+}
+
static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
{
.callback = init_old_suspend_ordering,
DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
},
},
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-SR11M",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Everex StepNote Series",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
};
-static int param_get_debug_layer(char *buffer, struct kernel_param *kp)
+static int param_get_debug_layer(char *buffer, const struct kernel_param *kp)
{
int result = 0;
int i;
return result;
}
-static int param_get_debug_level(char *buffer, struct kernel_param *kp)
+static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
{
int result = 0;
int i;
return result;
}
-module_param_call(debug_layer, param_set_uint, param_get_debug_layer,
- &acpi_dbg_layer, 0644);
-module_param_call(debug_level, param_set_uint, param_get_debug_level,
- &acpi_dbg_level, 0644);
+static struct kernel_param_ops param_ops_debug_layer = {
+ .set = param_set_uint,
+ .get = param_get_debug_layer,
+};
+
+static struct kernel_param_ops param_ops_debug_level = {
+ .set = param_set_uint,
+ .get = param_get_debug_level,
+};
+
+module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644);
+module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644);
static char trace_method_name[6];
module_param_string(trace_method_name, trace_method_name, 6, 0644);
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
- printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
- "control misses _BQC function\n");
+ printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
+ "cannot determine initial brightness\n");
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
static int ahci_pci_device_resume(struct pci_dev *pdev);
#endif
+static struct scsi_host_template ahci_sht = {
+ AHCI_SHT("ahci"),
+};
+
static struct ata_port_operations ahci_vt8251_ops = {
.inherits = &ahci_ops,
.hardreset = ahci_vt8251_hardreset,
extern int ahci_ignore_sss;
-extern struct scsi_host_template ahci_sht;
+extern struct device_attribute *ahci_shost_attrs[];
+extern struct device_attribute *ahci_sdev_attrs[];
+
+#define AHCI_SHT(drv_name) \
+ ATA_NCQ_SHT(drv_name), \
+ .can_queue = AHCI_MAX_CMDS - 1, \
+ .sg_tablesize = AHCI_MAX_SG, \
+ .dma_boundary = AHCI_DMA_BOUNDARY, \
+ .shost_attrs = ahci_shost_attrs, \
+ .sdev_attrs = ahci_sdev_attrs
+
extern struct ata_port_operations ahci_ops;
void ahci_save_initial_config(struct device *dev,
#include <linux/ahci_platform.h>
#include "ahci.h"
+static struct scsi_host_template ahci_platform_sht = {
+ AHCI_SHT("ahci_platform"),
+};
+
static int __init ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
ahci_print_info(host, "platform");
rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
- &ahci_sht);
+ &ahci_platform_sht);
if (rc)
goto err0;
static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
ahci_read_em_buffer, ahci_store_em_buffer);
-static struct device_attribute *ahci_shost_attrs[] = {
+struct device_attribute *ahci_shost_attrs[] = {
&dev_attr_link_power_management_policy,
&dev_attr_em_message_type,
&dev_attr_em_message,
&dev_attr_em_buffer,
NULL
};
+EXPORT_SYMBOL_GPL(ahci_shost_attrs);
-static struct device_attribute *ahci_sdev_attrs[] = {
+struct device_attribute *ahci_sdev_attrs[] = {
&dev_attr_sw_activity,
&dev_attr_unload_heads,
NULL
};
-
-struct scsi_host_template ahci_sht = {
- ATA_NCQ_SHT("ahci"),
- .can_queue = AHCI_MAX_CMDS - 1,
- .sg_tablesize = AHCI_MAX_SG,
- .dma_boundary = AHCI_DMA_BOUNDARY,
- .shost_attrs = ahci_shost_attrs,
- .sdev_attrs = ahci_sdev_attrs,
-};
-EXPORT_SYMBOL_GPL(ahci_sht);
+EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
struct ata_port_operations ahci_ops = {
.inherits = &sata_pmp_port_ops,
clean4:
kfree(h->cmd_pool_bits);
/* Free up sg elements */
- for (k = 0; k < h->nr_cmds; k++)
+ for (k-- ; k >= 0; k--)
kfree(h->scatter_list[k]);
kfree(h->scatter_list);
cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
pkt_shrink_pktlist(pd);
}
-static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
+static struct pktcdvd_device *pkt_find_dev_from_minor(unsigned int dev_minor)
{
if (dev_minor >= MAX_WRITERS)
return NULL;
"G45/G43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG,
"B43", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_B43_1_HB, PCI_DEVICE_ID_INTEL_B43_1_IG,
+ "B43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG,
"G41", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG,
#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2
#define PCI_DEVICE_ID_INTEL_B43_HB 0x2E40
#define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42
+#define PCI_DEVICE_ID_INTEL_B43_1_HB 0x2E90
+#define PCI_DEVICE_ID_INTEL_B43_1_IG 0x2E92
#define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40
#define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42
#define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00
#ifdef CONFIG_PCI
static int pci_registered;
#endif
+#ifdef CONFIG_ACPI
+static int pnp_registered;
+#endif
#ifdef CONFIG_PPC_OF
static int of_registered;
#endif
{
struct acpi_device *acpi_dev;
struct smi_info *info;
- struct resource *res;
+ struct resource *res, *res_second;
acpi_handle handle;
acpi_status status;
unsigned long long tmp;
info->io.addr_data = res->start;
info->io.regspacing = DEFAULT_REGSPACING;
- res = pnp_get_resource(dev,
+ res_second = pnp_get_resource(dev,
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ?
IORESOURCE_IO : IORESOURCE_MEM,
1);
- if (res) {
- if (res->start > info->io.addr_data)
- info->io.regspacing = res->start - info->io.addr_data;
+ if (res_second) {
+ if (res_second->start > info->io.addr_data)
+ info->io.regspacing = res_second->start - info->io.addr_data;
}
info->io.regsize = DEFAULT_REGSPACING;
info->io.regshift = 0;
#ifdef CONFIG_ACPI
pnp_register_driver(&ipmi_pnp_driver);
+ pnp_registered = 1;
#endif
#ifdef CONFIG_DMI
pci_unregister_driver(&ipmi_pci_driver);
#endif
#ifdef CONFIG_ACPI
- pnp_unregister_driver(&ipmi_pnp_driver);
+ if (pnp_registered)
+ pnp_unregister_driver(&ipmi_pnp_driver);
#endif
#ifdef CONFIG_PPC_OF
/*
* capabilities for /dev/zero
* - permits private mappings, "copies" are taken of the source of zeros
+ * - no writeback happens
*/
static struct backing_dev_info zero_bdi = {
.name = "char/mem",
- .capabilities = BDI_CAP_MAP_COPY,
+ .capabilities = BDI_CAP_MAP_COPY | BDI_CAP_NO_ACCT_AND_WRITEBACK,
};
static const struct file_operations full_fops = {
ssize_t ret;
bool nonblock;
+ /* Userspace could be out to fool us */
+ if (!count)
+ return 0;
+
port = filp->private_data;
nonblock = filp->f_flags & O_NONBLOCK;
poll_wait(filp, &port->waitqueue, wait);
ret = 0;
- if (port->inbuf)
+ if (!will_read_block(port))
ret |= POLLIN | POLLRDNORM;
if (!will_write_block(port))
ret |= POLLOUT;
* Limiting Performance Impact
* ---------------------------
* C states, especially those with large exit latencies, can have a real
- * noticable impact on workloads, which is not acceptable for most sysadmins,
+ * noticeable impact on workloads, which is not acceptable for most sysadmins,
* and in addition, less performance has a power price of its own.
*
* As a general rule of thumb, menu assumes that the following heuristic
static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan)
{
- u32 val = (1 << (1 + (chan->idx * 16)));
+ u32 val = ~(1 << (chan->idx * 16));
dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val);
__raw_writel(val, XOR_INTR_CAUSE(chan));
}
sh_chan = to_sh_chan(chan);
param = chan->private;
- slave_addr = param->config->addr;
/* Someone calling slave DMA on a public channel? */
if (!param || !sg_len) {
return NULL;
}
+ slave_addr = param->config->addr;
+
/*
* if (param != NULL), this is a successfully requested slave channel,
* therefore param->config != NULL too.
{
int status;
+ if (mci->op_state != OP_RUNNING_POLL)
+ return;
+
status = cancel_delayed_work(&mci->work);
if (status == 0) {
debugf0("%s() not canceled, flush the queue\n",
ATTR_COUNTER(0),
ATTR_COUNTER(1),
ATTR_COUNTER(2),
+ { .attr = { .name = NULL } }
};
static struct mcidev_sysfs_group i7core_udimm_counters = {
* user_data: A pointer the data that is copied to the buffer.
* size: The Number of bytes to copy.
*/
-extern int drm_buffer_copy_from_user(struct drm_buffer *buf,
- void __user *user_data, int size)
+int drm_buffer_copy_from_user(struct drm_buffer *buf,
+ void __user *user_data, int size)
{
int nr_pages = size / PAGE_SIZE + 1;
int idx;
{
int idx = drm_buffer_index(buf);
int page = drm_buffer_page(buf);
- void *obj = 0;
+ void *obj = NULL;
if (idx + objsize <= PAGE_SIZE) {
obj = &buf->data[page][idx];
return -ENOMEM;
kref_init(&obj->refcount);
- kref_init(&obj->handlecount);
+ atomic_set(&obj->handle_count, 0);
obj->size = size;
atomic_inc(&dev->object_count);
}
EXPORT_SYMBOL(drm_gem_object_free);
-/**
- * Called after the last reference to the object has been lost.
- * Must be called without holding struct_mutex
- *
- * Frees the object
- */
-void
-drm_gem_object_free_unlocked(struct kref *kref)
-{
- struct drm_gem_object *obj = (struct drm_gem_object *) kref;
- struct drm_device *dev = obj->dev;
-
- if (dev->driver->gem_free_object_unlocked != NULL)
- dev->driver->gem_free_object_unlocked(obj);
- else if (dev->driver->gem_free_object != NULL) {
- mutex_lock(&dev->struct_mutex);
- dev->driver->gem_free_object(obj);
- mutex_unlock(&dev->struct_mutex);
- }
-}
-EXPORT_SYMBOL(drm_gem_object_free_unlocked);
-
static void drm_gem_object_ref_bug(struct kref *list_kref)
{
BUG();
* called before drm_gem_object_free or we'll be touching
* freed memory
*/
-void
-drm_gem_object_handle_free(struct kref *kref)
+void drm_gem_object_handle_free(struct drm_gem_object *obj)
{
- struct drm_gem_object *obj = container_of(kref,
- struct drm_gem_object,
- handlecount);
struct drm_device *dev = obj->dev;
/* Remove any name for this object */
struct drm_gem_object *obj = vma->vm_private_data;
drm_gem_object_reference(obj);
+
+ mutex_lock(&obj->dev->struct_mutex);
+ drm_vm_open_locked(vma);
+ mutex_unlock(&obj->dev->struct_mutex);
}
EXPORT_SYMBOL(drm_gem_vm_open);
{
struct drm_gem_object *obj = vma->vm_private_data;
- drm_gem_object_unreference_unlocked(obj);
+ mutex_lock(&obj->dev->struct_mutex);
+ drm_vm_close_locked(vma);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&obj->dev->struct_mutex);
}
EXPORT_SYMBOL(drm_gem_vm_close);
seq_printf(m, "%6d %8zd %7d %8d\n",
obj->name, obj->size,
- atomic_read(&obj->handlecount.refcount),
+ atomic_read(&obj->handle_count),
atomic_read(&obj->refcount.refcount));
return 0;
}
mutex_unlock(&dev->struct_mutex);
}
-/**
- * \c close method for all virtual memory types.
- *
- * \param vma virtual memory area.
- *
- * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
- * free it.
- */
-static void drm_vm_close(struct vm_area_struct *vma)
+void drm_vm_close_locked(struct vm_area_struct *vma)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
vma->vm_start, vma->vm_end - vma->vm_start);
atomic_dec(&dev->vma_count);
- mutex_lock(&dev->struct_mutex);
list_for_each_entry_safe(pt, temp, &dev->vmalist, head) {
if (pt->vma == vma) {
list_del(&pt->head);
break;
}
}
+}
+
+/**
+ * \c close method for all virtual memory types.
+ *
+ * \param vma virtual memory area.
+ *
+ * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
+ * free it.
+ */
+static void drm_vm_close(struct vm_area_struct *vma)
+{
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->minor->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ drm_vm_close_locked(vma);
mutex_unlock(&dev->struct_mutex);
}
static const struct file_operations i810_buffer_fops = {
.open = drm_open,
.release = drm_release,
- .unlocked_ioctl = drm_ioctl,
+ .unlocked_ioctl = i810_ioctl,
.mmap = i810_mmap_buffers,
.fasync = drm_fasync,
};
static const struct file_operations i830_buffer_fops = {
.open = drm_open,
.release = drm_release,
- .unlocked_ioctl = drm_ioctl,
+ .unlocked_ioctl = i830_ioctl,
.mmap = i830_mmap_buffers,
.fasync = drm_fasync,
};
}
}
- div_u64(diff, diff1);
+ diff = div_u64(diff, diff1);
ret = ((m * diff) + c);
- div_u64(ret, 10);
+ ret = div_u64(ret, 10);
dev_priv->last_count1 = total_count;
dev_priv->last_time1 = now;
/* More magic constants... */
diff = diff * 1181;
- div_u64(diff, diffms * 10);
+ diff = div_u64(diff, diffms * 10);
dev_priv->gfx_power = diff;
}
INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */
INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */
INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */
+ INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */
INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
return -ENOMEM;
ret = drm_gem_handle_create(file_priv, obj, &handle);
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
return ret;
}
- /* Sink the floating reference from kref_init(handlecount) */
- drm_gem_object_handle_unreference_unlocked(obj);
-
args->handle = handle;
return 0;
}
return -ENOENT;
obj_priv = to_intel_bo(obj);
- /* Bounds check source.
- *
- * XXX: This could use review for overflow issues...
- */
- if (args->offset > obj->size || args->size > obj->size ||
- args->offset + args->size > obj->size) {
- drm_gem_object_unreference_unlocked(obj);
- return -EINVAL;
+ /* Bounds check source. */
+ if (args->offset > obj->size || args->size > obj->size - args->offset) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (!access_ok(VERIFY_WRITE,
+ (char __user *)(uintptr_t)args->data_ptr,
+ args->size)) {
+ ret = -EFAULT;
+ goto err;
}
if (i915_gem_object_needs_bit17_swizzle(obj)) {
file_priv);
}
+err:
drm_gem_object_unreference_unlocked(obj);
-
return ret;
}
user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size;
- if (!access_ok(VERIFY_READ, user_data, remain))
- return -EFAULT;
mutex_lock(&dev->struct_mutex);
return -ENOENT;
obj_priv = to_intel_bo(obj);
- /* Bounds check destination.
- *
- * XXX: This could use review for overflow issues...
- */
- if (args->offset > obj->size || args->size > obj->size ||
- args->offset + args->size > obj->size) {
- drm_gem_object_unreference_unlocked(obj);
- return -EINVAL;
+ /* Bounds check destination. */
+ if (args->offset > obj->size || args->size > obj->size - args->offset) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (!access_ok(VERIFY_READ,
+ (char __user *)(uintptr_t)args->data_ptr,
+ args->size)) {
+ ret = -EFAULT;
+ goto err;
}
/* We can only do the GTT pwrite on untiled buffers, as otherwise
DRM_INFO("pwrite failed %d\n", ret);
#endif
+err:
drm_gem_object_unreference_unlocked(obj);
-
return ret;
}
reg->obj = obj;
- if (IS_GEN6(dev))
+ switch (INTEL_INFO(dev)->gen) {
+ case 6:
sandybridge_write_fence_reg(reg);
- else if (IS_I965G(dev))
+ break;
+ case 5:
+ case 4:
i965_write_fence_reg(reg);
- else if (IS_I9XX(dev))
+ break;
+ case 3:
i915_write_fence_reg(reg);
- else
+ break;
+ case 2:
i830_write_fence_reg(reg);
+ break;
+ }
trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
obj_priv->tiling_mode);
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct drm_i915_fence_reg *reg =
&dev_priv->fence_regs[obj_priv->fence_reg];
+ uint32_t fence_reg;
- if (IS_GEN6(dev)) {
+ switch (INTEL_INFO(dev)->gen) {
+ case 6:
I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
(obj_priv->fence_reg * 8), 0);
- } else if (IS_I965G(dev)) {
+ break;
+ case 5:
+ case 4:
I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
- } else {
- uint32_t fence_reg;
-
- if (obj_priv->fence_reg < 8)
- fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
+ break;
+ case 3:
+ if (obj_priv->fence_reg >= 8)
+ fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4;
else
- fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg -
- 8) * 4;
+ case 2:
+ fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
I915_WRITE(fence_reg, 0);
+ break;
}
reg->obj = NULL;
(int) reloc->offset,
reloc->read_domains,
reloc->write_domain);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
return -EINVAL;
}
if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
struct list_head *unwind)
{
list_add(&obj_priv->evict_list, unwind);
+ drm_gem_object_reference(&obj_priv->base);
return drm_mm_scan_add_block(obj_priv->gtt_space);
}
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct list_head eviction_list, unwind_list;
- struct drm_i915_gem_object *obj_priv, *tmp_obj_priv;
+ struct drm_i915_gem_object *obj_priv;
struct list_head *render_iter, *bsd_iter;
int ret = 0;
list_for_each_entry(obj_priv, &unwind_list, evict_list) {
ret = drm_mm_scan_remove_block(obj_priv->gtt_space);
BUG_ON(ret);
+ drm_gem_object_unreference(&obj_priv->base);
}
/* We expect the caller to unpin, evict all and try again, or give up.
return -ENOSPC;
found:
+ /* drm_mm doesn't allow any other other operations while
+ * scanning, therefore store to be evicted objects on a
+ * temporary list. */
INIT_LIST_HEAD(&eviction_list);
- list_for_each_entry_safe(obj_priv, tmp_obj_priv,
- &unwind_list, evict_list) {
+ while (!list_empty(&unwind_list)) {
+ obj_priv = list_first_entry(&unwind_list,
+ struct drm_i915_gem_object,
+ evict_list);
if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
- /* drm_mm doesn't allow any other other operations while
- * scanning, therefore store to be evicted objects on a
- * temporary list. */
list_move(&obj_priv->evict_list, &eviction_list);
+ continue;
}
+ list_del(&obj_priv->evict_list);
+ drm_gem_object_unreference(&obj_priv->base);
}
/* Unbinding will emit any required flushes */
- list_for_each_entry_safe(obj_priv, tmp_obj_priv,
- &eviction_list, evict_list) {
-#if WATCH_LRU
- DRM_INFO("%s: evicting %p\n", __func__, obj);
-#endif
- ret = i915_gem_object_unbind(&obj_priv->base);
- if (ret)
- return ret;
+ while (!list_empty(&eviction_list)) {
+ obj_priv = list_first_entry(&eviction_list,
+ struct drm_i915_gem_object,
+ evict_list);
+ if (ret == 0)
+ ret = i915_gem_object_unbind(&obj_priv->base);
+ list_del(&obj_priv->evict_list);
+ drm_gem_object_unreference(&obj_priv->base);
}
- /* The just created free hole should be on the top of the free stack
- * maintained by drm_mm, so this BUG_ON actually executes in O(1).
- * Furthermore all accessed data has just recently been used, so it
- * should be really fast, too. */
- BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size,
- alignment, 0));
-
- return 0;
+ return ret;
}
int
dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
/* Fences */
- if (IS_I965G(dev)) {
+ switch (INTEL_INFO(dev)->gen) {
+ case 6:
+ for (i = 0; i < 16; i++)
+ dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
+ break;
+ case 5:
+ case 4:
for (i = 0; i < 16; i++)
dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
- } else {
- for (i = 0; i < 8; i++)
- dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
-
+ break;
+ case 3:
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
for (i = 0; i < 8; i++)
dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
+ case 2:
+ for (i = 0; i < 8; i++)
+ dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
+ break;
+
}
return 0;
I915_WRITE(HWS_PGA, dev_priv->saveHWS);
/* Fences */
- if (IS_I965G(dev)) {
+ switch (INTEL_INFO(dev)->gen) {
+ case 6:
+ for (i = 0; i < 16; i++)
+ I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
+ break;
+ case 5:
+ case 4:
for (i = 0; i < 16; i++)
I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
- } else {
- for (i = 0; i < 8; i++)
- I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
+ break;
+ case 3:
+ case 2:
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
for (i = 0; i < 8; i++)
I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
+ for (i = 0; i < 8; i++)
+ I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
+ break;
}
i915_restore_display(dev);
if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
1000, 1))
- DRM_ERROR("timed out waiting for FORCE_TRIGGER");
+ DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
if (turn_off_dac) {
I915_WRITE(PCH_ADPA, temp);
if (wait_for((I915_READ(PORT_HOTPLUG_EN) &
CRT_HOTPLUG_FORCE_DETECT) == 0,
1000, 1))
- DRM_ERROR("timed out waiting for FORCE_DETECT to go off");
+ DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off");
}
stat = I915_READ(PORT_HOTPLUG_STAT);
DRM_DEBUG_KMS("vblank wait timed out\n");
}
-/**
- * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
+/*
+ * intel_wait_for_pipe_off - wait for pipe to turn off
* @dev: drm device
* @pipe: pipe to wait for
*
* spinning on the vblank interrupt status bit, since we won't actually
* see an interrupt when the pipe is disabled.
*
- * So this function waits for the display line value to settle (it
- * usually ends up stopping at the start of the next frame).
+ * On Gen4 and above:
+ * wait for the pipe register state bit to turn off
+ *
+ * Otherwise:
+ * wait for the display line value to settle (it usually
+ * ends up stopping at the start of the next frame).
+ *
*/
-void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
+static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
- unsigned long timeout = jiffies + msecs_to_jiffies(100);
- u32 last_line;
-
- /* Wait for the display line to settle */
- do {
- last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
- mdelay(5);
- } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
- time_after(timeout, jiffies));
-
- if (time_after(jiffies, timeout))
- DRM_DEBUG_KMS("vblank wait timed out\n");
+
+ if (INTEL_INFO(dev)->gen >= 4) {
+ int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF);
+
+ /* Wait for the Pipe State to go off */
+ if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0,
+ 100, 0))
+ DRM_DEBUG_KMS("pipe_off wait timed out\n");
+ } else {
+ u32 last_line;
+ int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+ /* Wait for the display line to settle */
+ do {
+ last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
+ mdelay(5);
+ } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
+ time_after(timeout, jiffies));
+ if (time_after(jiffies, timeout))
+ DRM_DEBUG_KMS("pipe_off wait timed out\n");
+ }
}
/* Parameters have changed, update FBC info */
I915_READ(dspbase_reg);
}
- /* Wait for vblank for the disable to take effect */
- intel_wait_for_vblank_off(dev, pipe);
-
/* Don't disable pipe A or pipe A PLLs if needed */
if (pipeconf_reg == PIPEACONF &&
- (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+ (dev_priv->quirks & QUIRK_PIPEA_FORCE)) {
+ /* Wait for vblank for the disable to take effect */
+ intel_wait_for_vblank(dev, pipe);
goto skip_pipe_off;
+ }
/* Next, disable display pipes */
temp = I915_READ(pipeconf_reg);
I915_READ(pipeconf_reg);
}
- /* Wait for vblank for the disable to take effect. */
- intel_wait_for_vblank_off(dev, pipe);
+ /* Wait for the pipe to turn off */
+ intel_wait_for_pipe_off(dev, pipe);
temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) != 0) {
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = crtc->dev;
+
if (HAS_PCH_SPLIT(dev)) {
/* FDI link clock is fixed at 2.7G */
if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
return false;
}
+
+ /* XXX some encoders set the crtcinfo, others don't.
+ * Obviously we need some form of conflict resolution here...
+ */
+ if (adjusted_mode->crtc_htotal == 0)
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
return true;
}
intel_dp_set_link_train(struct intel_dp *intel_dp,
uint32_t dp_reg_value,
uint8_t dp_train_pat,
- uint8_t train_set[4],
- bool first)
+ uint8_t train_set[4])
{
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
int ret;
I915_WRITE(intel_dp->output_reg, dp_reg_value);
POSTING_READ(intel_dp->output_reg);
- if (first)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
intel_dp_aux_native_write_1(intel_dp,
DP_TRAINING_PATTERN_SET,
uint8_t voltage;
bool clock_recovery = false;
bool channel_eq = false;
- bool first = true;
int tries;
u32 reg;
uint32_t DP = intel_dp->DP;
+ struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
+
+ /* Enable output, wait for it to become active */
+ I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+ POSTING_READ(intel_dp->output_reg);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
/* Write the link configuration data */
intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
reg = DP | DP_LINK_TRAIN_PAT_1;
if (!intel_dp_set_link_train(intel_dp, reg,
- DP_TRAINING_PATTERN_1, train_set, first))
+ DP_TRAINING_PATTERN_1, train_set))
break;
- first = false;
/* Set training pattern 1 */
udelay(100);
/* channel eq pattern */
if (!intel_dp_set_link_train(intel_dp, reg,
- DP_TRAINING_PATTERN_2, train_set,
- false))
+ DP_TRAINING_PATTERN_2, train_set))
break;
udelay(400);
struct drm_crtc *crtc);
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
drm_fb_helper_fini(&ifbdev->helper);
drm_framebuffer_cleanup(&ifb->base);
- if (ifb->obj)
+ if (ifb->obj) {
+ drm_gem_object_handle_unreference(ifb->obj);
drm_gem_object_unreference(ifb->obj);
+ }
return 0;
}
return true;
err:
- intel_sdvo_destroy_enhance_property(connector);
- kfree(intel_sdvo_connector);
+ intel_sdvo_destroy(connector);
return false;
}
return true;
err:
- intel_sdvo_destroy_enhance_property(connector);
- kfree(intel_sdvo_connector);
+ intel_sdvo_destroy(connector);
return false;
}
uint16_t response;
} enhancements;
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
- &enhancements, sizeof(enhancements)))
- return false;
-
+ enhancements.response = 0;
+ intel_sdvo_get_value(intel_sdvo,
+ SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+ &enhancements, sizeof(enhancements));
if (enhancements.response == 0) {
DRM_DEBUG_KMS("No enhancement is supported\n");
return true;
if (nv_encoder->dcb->type == OUTPUT_LVDS &&
(nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
- nv_connector->native_mode = drm_mode_create(dev);
- nouveau_bios_fp_mode(dev, nv_connector->native_mode);
+ struct drm_display_mode mode;
+
+ nouveau_bios_fp_mode(dev, &mode);
+ nv_connector->native_mode = drm_mode_duplicate(dev, &mode);
}
/* Find the native mode if this is a digital panel, if we didn't
if (nouveau_fb->nvbo) {
nouveau_bo_unmap(nouveau_fb->nvbo);
+ drm_gem_object_handle_unreference_unlocked(nouveau_fb->nvbo->gem);
drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
nouveau_fb->nvbo = NULL;
}
goto out;
ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(nvbo->gem);
out:
- drm_gem_object_handle_unreference_unlocked(nvbo->gem);
-
- if (ret)
- drm_gem_object_unreference_unlocked(nvbo->gem);
return ret;
}
mutex_lock(&dev->struct_mutex);
nouveau_bo_unpin(chan->notifier_bo);
mutex_unlock(&dev->struct_mutex);
+ drm_gem_object_handle_unreference_unlocked(chan->notifier_bo->gem);
drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
drm_mm_takedown(&chan->notifier_heap);
}
#define SW_I2C_CNTL_WRITE1BIT 6
//==============================VESA definition Portion===============================
-#define VESA_OEM_PRODUCT_REV '01.00'
+#define VESA_OEM_PRODUCT_REV "01.00"
#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support
#define VESA_MODE_WIN_ATTRIBUTE 7
#define VESA_WIN_SIZE 64
if (i < rdev->usec_timeout) {
DRM_INFO("ib test succeeded in %u usecs\n", i);
} else {
- DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
+ DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n",
scratch, tmp);
r = -EINVAL;
}
/* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
* rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
*/
- if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+ rdev->vram_scratch.ptr) {
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
u32 tmp;
*connector_type = DRM_MODE_CONNECTOR_DVID;
}
+ /* MSI K9A2GM V2/V3 board has no HDMI or DVI */
+ if ((dev->pdev->device == 0x796e) &&
+ (dev->pdev->subsystem_vendor == 0x1462) &&
+ (dev->pdev->subsystem_device == 0x7302)) {
+ if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) ||
+ (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
+ return false;
+ }
+
/* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */
if ((dev->pdev->device == 0x7941) &&
(dev->pdev->subsystem_vendor == 0x147b) &&
DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP5_SUPPORT)
DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]);
+ if (devices & ATOM_DEVICE_DFP6_SUPPORT)
+ DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]);
if (devices & ATOM_DEVICE_TV1_SUPPORT)
DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]);
if (devices & ATOM_DEVICE_CV_SUPPORT)
{
struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
- if (radeon_fb->obj)
+ if (radeon_fb->obj) {
drm_gem_object_unreference_unlocked(radeon_fb->obj);
+ }
drm_framebuffer_cleanup(fb);
kfree(radeon_fb);
}
ret = radeon_bo_reserve(rbo, false);
if (likely(ret == 0)) {
radeon_bo_kunmap(rbo);
+ radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
}
+ drm_gem_object_handle_unreference(gobj);
drm_gem_object_unreference_unlocked(gobj);
}
{
struct fb_info *info;
struct radeon_framebuffer *rfb = &rfbdev->rfb;
- struct radeon_bo *rbo;
- int r;
if (rfbdev->helper.fbdev) {
info = rfbdev->helper.fbdev;
}
if (rfb->obj) {
- rbo = rfb->obj->driver_private;
- r = radeon_bo_reserve(rbo, false);
- if (likely(r == 0)) {
- radeon_bo_kunmap(rbo);
- radeon_bo_unpin(rbo);
- radeon_bo_unreserve(rbo);
- }
- drm_gem_object_unreference_unlocked(rfb->obj);
+ radeonfb_destroy_pinned_object(rfb->obj);
+ rfb->obj = NULL;
}
drm_fb_helper_fini(&rfbdev->helper);
drm_framebuffer_cleanup(&rfb->base);
return r;
}
r = drm_gem_handle_create(filp, gobj, &handle);
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(gobj);
if (r) {
- drm_gem_object_unreference_unlocked(gobj);
return r;
}
- drm_gem_object_handle_unreference_unlocked(gobj);
args->handle = handle;
return 0;
}
*/
int radeon_driver_firstopen_kms(struct drm_device *dev)
{
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (rdev->powered_down)
+ return -EINVAL;
return 0;
}
INIT_LIST_HEAD(&fbo->lru);
INIT_LIST_HEAD(&fbo->swap);
fbo->vm_node = NULL;
+ atomic_set(&fbo->cpu_writers, 0);
fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
kref_init(&fbo->list_kref);
spinlock_t lock;
bool fill_lock;
struct list_head list;
- int gfp_flags;
+ gfp_t gfp_flags;
unsigned npages;
char *name;
unsigned long nfrees;
* This function is reentrant if caller updates count depending on number of
* pages returned in pages array.
*/
-static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags,
+static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags,
int ttm_flags, enum ttm_caching_state cstate, unsigned count)
{
struct page **caching_array;
{
struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
struct page *p = NULL;
- int gfp_flags = GFP_USER;
+ gfp_t gfp_flags = GFP_USER;
int r;
/* set zero flag for page allocation if required */
return 0;
}
-void ttm_page_alloc_fini()
+void ttm_page_alloc_fini(void)
{
int i;
{0, 0, 0}
};
-static char *vmw_devname = "vmwgfx";
+static int enable_fbdev;
static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
static void vmw_master_init(struct vmw_master *);
static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
void *ptr);
+MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
+module_param_named(enable_fbdev, enable_fbdev, int, 0600);
+
static void vmw_print_capabilities(uint32_t capabilities)
{
DRM_INFO("Capabilities:\n");
{
int ret;
- vmw_kms_save_vga(dev_priv);
-
ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
if (unlikely(ret != 0)) {
DRM_ERROR("Unable to initialize FIFO.\n");
static void vmw_release_device(struct vmw_private *dev_priv)
{
vmw_fifo_release(dev_priv, &dev_priv->fifo);
- vmw_kms_restore_vga(dev_priv);
}
+int vmw_3d_resource_inc(struct vmw_private *dev_priv)
+{
+ int ret = 0;
+
+ mutex_lock(&dev_priv->release_mutex);
+ if (unlikely(dev_priv->num_3d_resources++ == 0)) {
+ ret = vmw_request_device(dev_priv);
+ if (unlikely(ret != 0))
+ --dev_priv->num_3d_resources;
+ }
+ mutex_unlock(&dev_priv->release_mutex);
+ return ret;
+}
+
+
+void vmw_3d_resource_dec(struct vmw_private *dev_priv)
+{
+ int32_t n3d;
+
+ mutex_lock(&dev_priv->release_mutex);
+ if (unlikely(--dev_priv->num_3d_resources == 0))
+ vmw_release_device(dev_priv);
+ n3d = (int32_t) dev_priv->num_3d_resources;
+ mutex_unlock(&dev_priv->release_mutex);
+
+ BUG_ON(n3d < 0);
+}
static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
{
dev_priv->last_read_sequence = (uint32_t) -100;
mutex_init(&dev_priv->hw_mutex);
mutex_init(&dev_priv->cmdbuf_mutex);
+ mutex_init(&dev_priv->release_mutex);
rwlock_init(&dev_priv->resource_lock);
idr_init(&dev_priv->context_idr);
idr_init(&dev_priv->surface_idr);
dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
+ dev_priv->enable_fb = enable_fbdev;
+
mutex_lock(&dev_priv->hw_mutex);
vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
dev->dev_private = dev_priv;
- if (!dev->devname)
- dev->devname = vmw_devname;
-
- if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
- ret = drm_irq_install(dev);
- if (unlikely(ret != 0)) {
- DRM_ERROR("Failed installing irq: %d\n", ret);
- goto out_no_irq;
- }
- }
-
ret = pci_request_regions(dev->pdev, "vmwgfx probe");
dev_priv->stealth = (ret != 0);
if (dev_priv->stealth) {
goto out_no_device;
}
}
- ret = vmw_request_device(dev_priv);
+ ret = vmw_kms_init(dev_priv);
if (unlikely(ret != 0))
- goto out_no_device;
- vmw_kms_init(dev_priv);
+ goto out_no_kms;
vmw_overlay_init(dev_priv);
- vmw_fb_init(dev_priv);
+ if (dev_priv->enable_fb) {
+ ret = vmw_3d_resource_inc(dev_priv);
+ if (unlikely(ret != 0))
+ goto out_no_fifo;
+ vmw_kms_save_vga(dev_priv);
+ vmw_fb_init(dev_priv);
+ DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ?
+ "Detected device 3D availability.\n" :
+ "Detected no device 3D availability.\n");
+ } else {
+ DRM_INFO("Delayed 3D detection since we're not "
+ "running the device in SVGA mode yet.\n");
+ }
+
+ if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
+ ret = drm_irq_install(dev);
+ if (unlikely(ret != 0)) {
+ DRM_ERROR("Failed installing irq: %d\n", ret);
+ goto out_no_irq;
+ }
+ }
dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
register_pm_notifier(&dev_priv->pm_nb);
- DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n");
-
return 0;
-out_no_device:
- if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
- drm_irq_uninstall(dev_priv->dev);
- if (dev->devname == vmw_devname)
- dev->devname = NULL;
out_no_irq:
+ if (dev_priv->enable_fb) {
+ vmw_fb_close(dev_priv);
+ vmw_kms_restore_vga(dev_priv);
+ vmw_3d_resource_dec(dev_priv);
+ }
+out_no_fifo:
+ vmw_overlay_close(dev_priv);
+ vmw_kms_close(dev_priv);
+out_no_kms:
+ if (dev_priv->stealth)
+ pci_release_region(dev->pdev, 2);
+ else
+ pci_release_regions(dev->pdev);
+out_no_device:
ttm_object_device_release(&dev_priv->tdev);
out_err4:
iounmap(dev_priv->mmio_virt);
unregister_pm_notifier(&dev_priv->pm_nb);
- vmw_fb_close(dev_priv);
+ if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
+ drm_irq_uninstall(dev_priv->dev);
+ if (dev_priv->enable_fb) {
+ vmw_fb_close(dev_priv);
+ vmw_kms_restore_vga(dev_priv);
+ vmw_3d_resource_dec(dev_priv);
+ }
vmw_kms_close(dev_priv);
vmw_overlay_close(dev_priv);
- vmw_release_device(dev_priv);
if (dev_priv->stealth)
pci_release_region(dev->pdev, 2);
else
pci_release_regions(dev->pdev);
- if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
- drm_irq_uninstall(dev_priv->dev);
- if (dev->devname == vmw_devname)
- dev->devname = NULL;
ttm_object_device_release(&dev_priv->tdev);
iounmap(dev_priv->mmio_virt);
drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
struct drm_ioctl_desc *ioctl =
&vmw_ioctls[nr - DRM_COMMAND_BASE];
- if (unlikely(ioctl->cmd != cmd)) {
+ if (unlikely(ioctl->cmd_drv != cmd)) {
DRM_ERROR("Invalid command format, ioctl %d\n",
nr - DRM_COMMAND_BASE);
return -EINVAL;
struct vmw_master *vmaster = vmw_master(file_priv->master);
int ret = 0;
+ if (!dev_priv->enable_fb) {
+ ret = vmw_3d_resource_inc(dev_priv);
+ if (unlikely(ret != 0))
+ return ret;
+ vmw_kms_save_vga(dev_priv);
+ mutex_lock(&dev_priv->hw_mutex);
+ vmw_write(dev_priv, SVGA_REG_TRACES, 0);
+ mutex_unlock(&dev_priv->hw_mutex);
+ }
+
if (active) {
BUG_ON(active != &dev_priv->fbdev_master);
ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
return 0;
out_no_active_lock:
- vmw_release_device(dev_priv);
+ if (!dev_priv->enable_fb) {
+ mutex_lock(&dev_priv->hw_mutex);
+ vmw_write(dev_priv, SVGA_REG_TRACES, 1);
+ mutex_unlock(&dev_priv->hw_mutex);
+ vmw_kms_restore_vga(dev_priv);
+ vmw_3d_resource_dec(dev_priv);
+ }
return ret;
}
ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
+ if (!dev_priv->enable_fb) {
+ ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
+ if (unlikely(ret != 0))
+ DRM_ERROR("Unable to clean VRAM on master drop.\n");
+ mutex_lock(&dev_priv->hw_mutex);
+ vmw_write(dev_priv, SVGA_REG_TRACES, 1);
+ mutex_unlock(&dev_priv->hw_mutex);
+ vmw_kms_restore_vga(dev_priv);
+ vmw_3d_resource_dec(dev_priv);
+ }
+
dev_priv->active_master = &dev_priv->fbdev_master;
ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
ttm_vt_unlock(&dev_priv->fbdev_master.lock);
- vmw_fb_on(dev_priv);
+ if (dev_priv->enable_fb)
+ vmw_fb_on(dev_priv);
}
.irq_postinstall = vmw_irq_postinstall,
.irq_uninstall = vmw_irq_uninstall,
.irq_handler = vmw_irq_handler,
+ .get_vblank_counter = vmw_get_vblank_counter,
.reclaim_buffers_locked = NULL,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
bool stealth;
bool is_opened;
+ bool enable_fb;
/**
* Master management.
struct vmw_master *active_master;
struct vmw_master fbdev_master;
struct notifier_block pm_nb;
+
+ struct mutex release_mutex;
+ uint32_t num_3d_resources;
};
static inline struct vmw_private *vmw_priv(struct drm_device *dev)
return val;
}
+int vmw_3d_resource_inc(struct vmw_private *dev_priv);
+void vmw_3d_resource_dec(struct vmw_private *dev_priv);
+
/**
* GMR utilities - vmwgfx_gmr.c
*/
unsigned bbp, unsigned depth);
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);
/**
* Overlay control - vmwgfx_overlay.c
if (unlikely(ret != 0))
goto err_unlock;
+ if (bo->mem.mem_type == TTM_PL_VRAM &&
+ bo->mem.mm_node->start < bo->num_pages)
+ (void) ttm_bo_validate(bo, &vmw_sys_placement, false,
+ false, false);
+
ret = ttm_bo_validate(bo, &ne_placement, false, false, false);
/* Could probably bug on */
mutex_lock(&dev_priv->hw_mutex);
dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
+ dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
min = 4;
dev_priv->config_done_state);
vmw_write(dev_priv, SVGA_REG_ENABLE,
dev_priv->enable_state);
+ vmw_write(dev_priv, SVGA_REG_TRACES,
+ dev_priv->traces_state);
mutex_unlock(&dev_priv->hw_mutex);
vmw_fence_queue_takedown(&fifo->fence_queue);
save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+ if (i == 0 && vmw_priv->num_displays == 1 &&
+ save->width == 0 && save->height == 0) {
+
+ /*
+ * It should be fairly safe to assume that these
+ * values are uninitialized.
+ */
+
+ save->width = vmw_priv->vga_width - save->pos_x;
+ save->height = vmw_priv->vga_height - save->pos_y;
+ }
}
+
return 0;
}
ttm_read_unlock(&vmaster->lock);
return ret;
}
+
+u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ return 0;
+}
#include "vmwgfx_kms.h"
+#define VMWGFX_LDU_NUM_DU 8
+
#define vmw_crtc_to_ldu(x) \
container_of(x, struct vmw_legacy_display_unit, base.crtc)
#define vmw_encoder_to_ldu(x) \
int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
+ int i;
+ int ret;
+
if (dev_priv->ldu_priv) {
DRM_INFO("ldu system already on\n");
return -EINVAL;
drm_mode_create_dirty_info_property(dev_priv->dev);
- vmw_ldu_init(dev_priv, 0);
- /* for old hardware without multimon only enable one display */
if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
- vmw_ldu_init(dev_priv, 1);
- vmw_ldu_init(dev_priv, 2);
- vmw_ldu_init(dev_priv, 3);
- vmw_ldu_init(dev_priv, 4);
- vmw_ldu_init(dev_priv, 5);
- vmw_ldu_init(dev_priv, 6);
- vmw_ldu_init(dev_priv, 7);
+ for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i)
+ vmw_ldu_init(dev_priv, i);
+ ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU);
+ } else {
+ /* for old hardware without multimon only enable one display */
+ vmw_ldu_init(dev_priv, 0);
+ ret = drm_vblank_init(dev, 1);
}
- return 0;
+ return ret;
}
int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
+
+ drm_vblank_cleanup(dev);
if (!dev_priv->ldu_priv)
return -ENOSYS;
cmd->body.cid = cpu_to_le32(res->id);
vmw_fifo_commit(dev_priv, sizeof(*cmd));
+ vmw_3d_resource_dec(dev_priv);
}
static int vmw_context_init(struct vmw_private *dev_priv,
cmd->body.cid = cpu_to_le32(res->id);
vmw_fifo_commit(dev_priv, sizeof(*cmd));
+ (void) vmw_3d_resource_inc(dev_priv);
vmw_resource_activate(res, vmw_hw_context_destroy);
return 0;
}
cmd->body.sid = cpu_to_le32(res->id);
vmw_fifo_commit(dev_priv, sizeof(*cmd));
+ vmw_3d_resource_dec(dev_priv);
}
void vmw_surface_res_free(struct vmw_resource *res)
}
vmw_fifo_commit(dev_priv, submit_size);
+ (void) vmw_3d_resource_inc(dev_priv);
vmw_resource_activate(res, vmw_hw_surface_destroy);
return 0;
}
pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count);
}
-void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
+static void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
{
struct vga_device *vgadev;
unsigned long flags;
config SENSORS_PKGTEMP
tristate "Intel processor package temperature sensor"
- depends on X86 && PCI && EXPERIMENTAL
+ depends on X86 && EXPERIMENTAL
help
If you say yes here you get support for the package level temperature
sensor inside your CPU. Check documentation/driver for details.
#include <linux/pci.h>
#include <asm/msr.h>
#include <asm/processor.h>
+#include <asm/smp.h>
#define DRVNAME "coretemp"
int err;
struct platform_device *pdev;
struct pdev_entry *pdev_entry;
-#ifdef CONFIG_SMP
struct cpuinfo_x86 *c = &cpu_data(cpu);
-#endif
+
+ /*
+ * CPUID.06H.EAX[0] indicates whether the CPU has thermal
+ * sensors. We check this bit only, all the early CPUs
+ * without thermal sensors will be filtered out.
+ */
+ if (!cpu_has(c, X86_FEATURE_DTS)) {
+ printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
+ " has no thermal sensor.\n", c->x86_model);
+ return 0;
+ }
mutex_lock(&pdev_list_mutex);
static void coretemp_device_remove(unsigned int cpu)
{
- struct pdev_entry *p, *n;
+ struct pdev_entry *p;
+ unsigned int i;
+
mutex_lock(&pdev_list_mutex);
- list_for_each_entry_safe(p, n, &pdev_list, list) {
- if (p->cpu == cpu) {
- platform_device_unregister(p->pdev);
- list_del(&p->list);
- kfree(p);
- }
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu != cpu)
+ continue;
+
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ for_each_cpu(i, cpu_sibling_mask(cpu))
+ if (i != cpu && !coretemp_device_add(i))
+ break;
+ return;
}
mutex_unlock(&pdev_list_mutex);
}
if (err)
goto exit;
- for_each_online_cpu(i) {
- struct cpuinfo_x86 *c = &cpu_data(i);
- /*
- * CPUID.06H.EAX[0] indicates whether the CPU has thermal
- * sensors. We check this bit only, all the early CPUs
- * without thermal sensors will be filtered out.
- */
- if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01))
- coretemp_device_add(i);
- else {
- printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
- " has no thermal sensor.\n", c->x86_model);
- }
- }
+ for_each_online_cpu(i)
+ coretemp_device_add(i);
+
+#ifndef CONFIG_HOTPLUG_CPU
if (list_empty(&pdev_list)) {
err = -ENODEV;
goto exit_driver_unreg;
}
+#endif
register_hotcpu_notifier(&coretemp_cpu_notifier);
return 0;
-exit_driver_unreg:
#ifndef CONFIG_HOTPLUG_CPU
+exit_driver_unreg:
platform_driver_unregister(&coretemp_driver);
#endif
exit:
/* Super-I/O Function prototypes */
static inline int superio_inb(int base, int reg);
static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
static inline void superio_select(int base, int ld);
static inline void superio_exit(int base);
return val;
}
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
{
+ /* Don't step on other drivers' I/O space by accident */
+ if (!request_muxed_region(base, 2, DRVNAME)) {
+ printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+ base);
+ return -EBUSY;
+ }
+
/* according to the datasheet the key must be send twice! */
outb(SIO_UNLOCK_KEY, base);
outb(SIO_UNLOCK_KEY, base);
+
+ return 0;
}
static inline void superio_select(int base, int ld)
static inline void superio_exit(int base)
{
outb(SIO_LOCK_KEY, base);
+ release_region(base, 2);
}
static inline int fan_from_reg(u16 reg)
static int __init f71882fg_find(int sioaddr, unsigned short *address,
struct f71882fg_sio_data *sio_data)
{
- int err = -ENODEV;
u16 devid;
-
- /* Don't step on other drivers' I/O space by accident */
- if (!request_region(sioaddr, 2, DRVNAME)) {
- printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
- (int)sioaddr);
- return -EBUSY;
- }
-
- superio_enter(sioaddr);
+ int err = superio_enter(sioaddr);
+ if (err)
+ return err;
devid = superio_inw(sioaddr, SIO_REG_MANID);
if (devid != SIO_FINTEK_ID) {
pr_debug(DRVNAME ": Not a Fintek device\n");
+ err = -ENODEV;
goto exit;
}
default:
printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
(unsigned int)devid);
+ err = -ENODEV;
goto exit;
}
if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
printk(KERN_WARNING DRVNAME ": Device not activated\n");
+ err = -ENODEV;
goto exit;
}
*address = superio_inw(sioaddr, SIO_REG_ADDR);
if (*address == 0) {
printk(KERN_WARNING DRVNAME ": Base address not set\n");
+ err = -ENODEV;
goto exit;
}
*address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
(int)superio_inb(sioaddr, SIO_REG_DEVREV));
exit:
superio_exit(sioaddr);
- release_region(sioaddr, 2);
return err;
}
wake_up_interruptible(&lis3_dev.misc_wait);
kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
out:
- if (lis3_dev.whoami == WAI_8B && lis3_dev.idev &&
+ if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev &&
lis3_dev.idev->input->users)
return IRQ_WAKE_THREAD;
return IRQ_HANDLED;
* io-apic is not configurable (and generates a warning) but I keep it
* in case of support for other hardware.
*/
- if (dev->whoami == WAI_8B)
+ if (dev->pdata && dev->whoami == WAI_8B)
thread_fn = lis302dl_interrupt_thread1_8b;
else
thread_fn = NULL;
#include <linux/list.h>
#include <linux/platform_device.h>
#include <linux/cpu.h>
-#include <linux/pci.h>
#include <asm/msr.h>
#include <asm/processor.h>
err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group);
if (err)
- goto exit_free;
+ goto exit_dev;
data->hwmon_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(data->hwmon_dev)) {
exit_class:
sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
+exit_dev:
+ device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
exit_free:
kfree(data);
exit:
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
+ device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
platform_set_drvdata(pdev, NULL);
kfree(data);
return 0;
int err;
struct platform_device *pdev;
struct pdev_entry *pdev_entry;
-#ifdef CONFIG_SMP
struct cpuinfo_x86 *c = &cpu_data(cpu);
-#endif
+
+ if (!cpu_has(c, X86_FEATURE_PTS))
+ return 0;
mutex_lock(&pdev_list_mutex);
#ifdef CONFIG_HOTPLUG_CPU
static void pkgtemp_device_remove(unsigned int cpu)
{
- struct pdev_entry *p, *n;
+ struct pdev_entry *p;
unsigned int i;
int err;
mutex_lock(&pdev_list_mutex);
- list_for_each_entry_safe(p, n, &pdev_list, list) {
+ list_for_each_entry(p, &pdev_list, list) {
if (p->cpu != cpu)
continue;
platform_device_unregister(p->pdev);
list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
kfree(p);
for_each_cpu(i, cpu_core_mask(cpu)) {
if (i != cpu) {
break;
}
}
- break;
+ return;
}
mutex_unlock(&pdev_list_mutex);
}
goto exit;
for_each_online_cpu(i) {
- struct cpuinfo_x86 *c = &cpu_data(i);
-
- if (!cpu_has(c, X86_FEATURE_PTS))
- continue;
-
err = pkgtemp_device_add(i);
if (err)
goto exit_devices_unreg;
dev->terminate = 0;
- /* write the data into mode register */
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-
/*
* First byte should be set here, not after interrupt,
* because transmit-data-ready interrupt can come before
dev->buf_len--;
}
+ /* write the data into mode register; start transmitting */
+ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
dev->adapter.timeout);
if (r == 0) {
return result;
} else if (result == 0) {
dev_dbg(i2c->dev, "%s: timeout\n", __func__);
- result = -ETIMEDOUT;
+ return -ETIMEDOUT;
}
return 0;
if (r == 0)
r = num;
+
+ omap_i2c_wait_for_bb(dev);
out:
omap_i2c_idle(dev);
return r;
unsigned long sda_delay;
if (pdata->sda_delay) {
- sda_delay = (freq / 1000) * pdata->sda_delay;
- sda_delay /= 1000000;
+ sda_delay = clkin * pdata->sda_delay;
+ sda_delay = DIV_ROUND_UP(sda_delay, 1000000);
sda_delay = DIV_ROUND_UP(sda_delay, 5);
if (sda_delay > 3)
sda_delay = 3;
/* Reliable LAPIC Timer States, bit 1 for C1 etc. */
static unsigned int lapic_timer_reliable_states;
-static struct cpuidle_device *intel_idle_cpuidle_devices;
+static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
static struct cpuidle_state *cpuidle_state_table;
.name = "NHM-C3",
.desc = "MWAIT 0x10",
.driver_data = (void *) 0x10,
- .flags = CPUIDLE_FLAG_TIME_VALID,
+ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 20,
.power_usage = 500,
.target_residency = 80,
.name = "NHM-C6",
.desc = "MWAIT 0x20",
.driver_data = (void *) 0x20,
- .flags = CPUIDLE_FLAG_TIME_VALID,
+ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 200,
.power_usage = 350,
.target_residency = 800,
.name = "ATM-C4",
.desc = "MWAIT 0x30",
.driver_data = (void *) 0x30,
- .flags = CPUIDLE_FLAG_TIME_VALID,
+ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.power_usage = 250,
.target_residency = 400,
.name = "ATM-C6",
.desc = "MWAIT 0x40",
.driver_data = (void *) 0x40,
- .flags = CPUIDLE_FLAG_TIME_VALID,
+ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 200,
.power_usage = 150,
.target_residency = 800,
local_irq_disable();
+ /*
+ * If the state flag indicates that the TLB will be flushed or if this
+ * is the deepest c-state supported, do a voluntary leave mm to avoid
+ * costly and mostly unnecessary wakeups for flushing the user TLB's
+ * associated with the active mm.
+ */
+ if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED ||
+ (&dev->states[dev->state_count - 1] == state))
+ leave_mm(cpu);
+
if (!(lapic_timer_reliable_states & (1 << (cstate))))
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
V_MSS_IDX(mtu_idx) |
V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx);
opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10);
- opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor);
+ opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) |
+ V_CONG_CONTROL_FLAVOR(cong_flavor);
skb->priority = CPL_PRIORITY_SETUP;
set_arp_failure_handler(skb, act_open_req_arp_failure);
V_MSS_IDX(mtu_idx) |
V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx);
opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10);
- opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor);
+ opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) |
+ V_CONG_CONTROL_FLAVOR(cong_flavor);
rpl = cplhdr(skb);
rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
config KEYBOARD_PXA27x
tristate "PXA27x/PXA3xx keypad support"
- depends on PXA27x || PXA3xx
+ depends on PXA27x || PXA3xx || ARCH_MMP
help
Enable support for PXA27x/PXA3xx keypad controller.
#include <asm/mach/map.h>
#include <mach/hardware.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
/*
* Keypad Controller registers
*/
keypad->direct_key_state = new_state;
}
+static void clear_wakeup_event(struct pxa27x_keypad *keypad)
+{
+ struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+
+ if (pdata->clear_wakeup_event)
+ (pdata->clear_wakeup_event)();
+}
+
static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
{
struct pxa27x_keypad *keypad = dev_id;
unsigned long kpc = keypad_readl(KPC);
+ clear_wakeup_event(keypad);
+
if (kpc & KPC_DI)
pxa27x_keypad_scan_direct(keypad);
config LEDS_NS2
tristate "LED support for Network Space v2 GPIO LEDs"
- depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2
+ depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
default y
help
This option enable support for the dual-GPIO LED found on the
Network Space v2 board (and parents). This include Internet Space v2,
Network Space (Max) v2 and d2 Network v2 boards.
+config LEDS_NETXBIG
+ tristate "LED support for Big Network series LEDs"
+ depends on MACH_NET2BIG_V2 || MACH_NET5BIG_V2
+ default y
+ help
+ This option enable support for LEDs found on the LaCie 2Big
+ and 5Big Network v2 boards. The LEDs are wired to a CPLD and are
+ controlled through a GPIO extension bus.
+
config LEDS_TRIGGERS
bool "LED Trigger support"
help
obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o
obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
+obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
--- /dev/null
+/*
+ * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs
+ *
+ * Copyright (C) 2010 LaCie
+ *
+ * Author: Simon Guinot <sguinot@lacie.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <mach/leds-netxbig.h>
+
+/*
+ * GPIO extension bus.
+ */
+
+static DEFINE_SPINLOCK(gpio_ext_lock);
+
+static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr)
+{
+ int pin;
+
+ for (pin = 0; pin < gpio_ext->num_addr; pin++)
+ gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1);
+}
+
+static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data)
+{
+ int pin;
+
+ for (pin = 0; pin < gpio_ext->num_data; pin++)
+ gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1);
+}
+
+static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext)
+{
+ /* Enable select is done on the raising edge. */
+ gpio_set_value(gpio_ext->enable, 0);
+ gpio_set_value(gpio_ext->enable, 1);
+}
+
+static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
+ int addr, int value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_ext_lock, flags);
+ gpio_ext_set_addr(gpio_ext, addr);
+ gpio_ext_set_data(gpio_ext, value);
+ gpio_ext_enable_select(gpio_ext);
+ spin_unlock_irqrestore(&gpio_ext_lock, flags);
+}
+
+static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
+{
+ int err;
+ int i;
+
+ if (unlikely(!gpio_ext))
+ return -EINVAL;
+
+ /* Configure address GPIOs. */
+ for (i = 0; i < gpio_ext->num_addr; i++) {
+ err = gpio_request(gpio_ext->addr[i], "GPIO extension addr");
+ if (err)
+ goto err_free_addr;
+ err = gpio_direction_output(gpio_ext->addr[i], 0);
+ if (err) {
+ gpio_free(gpio_ext->addr[i]);
+ goto err_free_addr;
+ }
+ }
+ /* Configure data GPIOs. */
+ for (i = 0; i < gpio_ext->num_data; i++) {
+ err = gpio_request(gpio_ext->data[i], "GPIO extension data");
+ if (err)
+ goto err_free_data;
+ err = gpio_direction_output(gpio_ext->data[i], 0);
+ if (err) {
+ gpio_free(gpio_ext->data[i]);
+ goto err_free_data;
+ }
+ }
+ /* Configure "enable select" GPIO. */
+ err = gpio_request(gpio_ext->enable, "GPIO extension enable");
+ if (err)
+ goto err_free_data;
+ err = gpio_direction_output(gpio_ext->enable, 0);
+ if (err) {
+ gpio_free(gpio_ext->enable);
+ goto err_free_data;
+ }
+
+ return 0;
+
+err_free_data:
+ for (i = i - 1; i >= 0; i--)
+ gpio_free(gpio_ext->data[i]);
+ i = gpio_ext->num_addr;
+err_free_addr:
+ for (i = i - 1; i >= 0; i--)
+ gpio_free(gpio_ext->addr[i]);
+
+ return err;
+}
+
+static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext)
+{
+ int i;
+
+ gpio_free(gpio_ext->enable);
+ for (i = gpio_ext->num_addr - 1; i >= 0; i--)
+ gpio_free(gpio_ext->addr[i]);
+ for (i = gpio_ext->num_data - 1; i >= 0; i--)
+ gpio_free(gpio_ext->data[i]);
+}
+
+/*
+ * Class LED driver.
+ */
+
+struct netxbig_led_data {
+ struct netxbig_gpio_ext *gpio_ext;
+ struct led_classdev cdev;
+ int mode_addr;
+ int *mode_val;
+ int bright_addr;
+ int bright_max;
+ struct netxbig_led_timer *timer;
+ int num_timer;
+ enum netxbig_led_mode mode;
+ int sata;
+ spinlock_t lock;
+};
+
+static int netxbig_led_get_timer_mode(enum netxbig_led_mode *mode,
+ unsigned long delay_on,
+ unsigned long delay_off,
+ struct netxbig_led_timer *timer,
+ int num_timer)
+{
+ int i;
+
+ for (i = 0; i < num_timer; i++) {
+ if (timer[i].delay_on == delay_on &&
+ timer[i].delay_off == delay_off) {
+ *mode = timer[i].mode;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static int netxbig_led_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct netxbig_led_data *led_dat =
+ container_of(led_cdev, struct netxbig_led_data, cdev);
+ enum netxbig_led_mode mode;
+ int mode_val;
+ int ret;
+
+ /* Look for a LED mode with the requested timer frequency. */
+ ret = netxbig_led_get_timer_mode(&mode, *delay_on, *delay_off,
+ led_dat->timer, led_dat->num_timer);
+ if (ret < 0)
+ return ret;
+
+ mode_val = led_dat->mode_val[mode];
+ if (mode_val == NETXBIG_LED_INVALID_MODE)
+ return -EINVAL;
+
+ spin_lock_irq(&led_dat->lock);
+
+ gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
+ led_dat->mode = mode;
+
+ spin_unlock_irq(&led_dat->lock);
+
+ return 0;
+}
+
+static void netxbig_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct netxbig_led_data *led_dat =
+ container_of(led_cdev, struct netxbig_led_data, cdev);
+ enum netxbig_led_mode mode;
+ int mode_val, bright_val;
+ int set_brightness = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&led_dat->lock, flags);
+
+ if (value == LED_OFF) {
+ mode = NETXBIG_LED_OFF;
+ set_brightness = 0;
+ } else {
+ if (led_dat->sata)
+ mode = NETXBIG_LED_SATA;
+ else if (led_dat->mode == NETXBIG_LED_OFF)
+ mode = NETXBIG_LED_ON;
+ else /* Keep 'timer' mode. */
+ mode = led_dat->mode;
+ }
+ mode_val = led_dat->mode_val[mode];
+
+ gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
+ led_dat->mode = mode;
+ /*
+ * Note that the brightness register is shared between all the
+ * SATA LEDs. So, change the brightness setting for a single
+ * SATA LED will affect all the others.
+ */
+ if (set_brightness) {
+ bright_val = DIV_ROUND_UP(value * led_dat->bright_max,
+ LED_FULL);
+ gpio_ext_set_value(led_dat->gpio_ext,
+ led_dat->bright_addr, bright_val);
+ }
+
+ spin_unlock_irqrestore(&led_dat->lock, flags);
+}
+
+static ssize_t netxbig_led_sata_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buff, size_t count)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct netxbig_led_data *led_dat =
+ container_of(led_cdev, struct netxbig_led_data, cdev);
+ unsigned long enable;
+ enum netxbig_led_mode mode;
+ int mode_val;
+ int ret;
+
+ ret = strict_strtoul(buff, 10, &enable);
+ if (ret < 0)
+ return ret;
+
+ enable = !!enable;
+
+ spin_lock_irq(&led_dat->lock);
+
+ if (led_dat->sata == enable) {
+ ret = count;
+ goto exit_unlock;
+ }
+
+ if (led_dat->mode != NETXBIG_LED_ON &&
+ led_dat->mode != NETXBIG_LED_SATA)
+ mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */
+ else if (enable)
+ mode = NETXBIG_LED_SATA;
+ else
+ mode = NETXBIG_LED_ON;
+
+ mode_val = led_dat->mode_val[mode];
+ if (mode_val == NETXBIG_LED_INVALID_MODE) {
+ ret = -EINVAL;
+ goto exit_unlock;
+ }
+
+ gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
+ led_dat->mode = mode;
+ led_dat->sata = enable;
+
+ ret = count;
+
+exit_unlock:
+ spin_unlock_irq(&led_dat->lock);
+
+ return ret;
+}
+
+static ssize_t netxbig_led_sata_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct netxbig_led_data *led_dat =
+ container_of(led_cdev, struct netxbig_led_data, cdev);
+
+ return sprintf(buf, "%d\n", led_dat->sata);
+}
+
+static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
+
+static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat)
+{
+ if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
+ device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
+ led_classdev_unregister(&led_dat->cdev);
+}
+
+static int __devinit
+create_netxbig_led(struct platform_device *pdev,
+ struct netxbig_led_data *led_dat,
+ const struct netxbig_led *template)
+{
+ struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
+ int ret;
+
+ spin_lock_init(&led_dat->lock);
+ led_dat->gpio_ext = pdata->gpio_ext;
+ led_dat->cdev.name = template->name;
+ led_dat->cdev.default_trigger = template->default_trigger;
+ led_dat->cdev.blink_set = netxbig_led_blink_set;
+ led_dat->cdev.brightness_set = netxbig_led_set;
+ /*
+ * Because the GPIO extension bus don't allow to read registers
+ * value, there is no way to probe the LED initial state.
+ * So, the initial sysfs LED value for the "brightness" and "sata"
+ * attributes are inconsistent.
+ *
+ * Note that the initial LED state can't be reconfigured.
+ * The reason is that the LED behaviour must stay uniform during
+ * the whole boot process (bootloader+linux).
+ */
+ led_dat->sata = 0;
+ led_dat->cdev.brightness = LED_OFF;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+ led_dat->mode_addr = template->mode_addr;
+ led_dat->mode_val = template->mode_val;
+ led_dat->bright_addr = template->bright_addr;
+ led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
+ led_dat->timer = pdata->timer;
+ led_dat->num_timer = pdata->num_timer;
+
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * If available, expose the SATA activity blink capability through
+ * a "sata" sysfs attribute.
+ */
+ if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) {
+ ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
+ if (ret)
+ led_classdev_unregister(&led_dat->cdev);
+ }
+
+ return ret;
+}
+
+static int __devinit netxbig_led_probe(struct platform_device *pdev)
+{
+ struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
+ struct netxbig_led_data *leds_data;
+ int i;
+ int ret;
+
+ if (!pdata)
+ return -EINVAL;
+
+ leds_data = kzalloc(sizeof(struct netxbig_led_data) * pdata->num_leds,
+ GFP_KERNEL);
+ if (!leds_data)
+ return -ENOMEM;
+
+ ret = gpio_ext_init(pdata->gpio_ext);
+ if (ret < 0)
+ goto err_free_data;
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
+ if (ret < 0)
+ goto err_free_leds;
+ }
+
+ platform_set_drvdata(pdev, leds_data);
+
+ return 0;
+
+err_free_leds:
+ for (i = i - 1; i >= 0; i--)
+ delete_netxbig_led(&leds_data[i]);
+
+ gpio_ext_free(pdata->gpio_ext);
+err_free_data:
+ kfree(leds_data);
+
+ return ret;
+}
+
+static int __devexit netxbig_led_remove(struct platform_device *pdev)
+{
+ struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
+ struct netxbig_led_data *leds_data;
+ int i;
+
+ leds_data = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_netxbig_led(&leds_data[i]);
+
+ gpio_ext_free(pdata->gpio_ext);
+ kfree(leds_data);
+
+ return 0;
+}
+
+static struct platform_driver netxbig_led_driver = {
+ .probe = netxbig_led_probe,
+ .remove = __devexit_p(netxbig_led_remove),
+ .driver = {
+ .name = "leds-netxbig",
+ .owner = THIS_MODULE,
+ },
+};
+MODULE_ALIAS("platform:leds-netxbig");
+
+static int __init netxbig_led_init(void)
+{
+ return platform_driver_register(&netxbig_led_driver);
+}
+
+static void __exit netxbig_led_exit(void)
+{
+ platform_driver_unregister(&netxbig_led_driver);
+}
+
+module_init(netxbig_led_init);
+module_exit(netxbig_led_exit);
+
+MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
+MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards");
+MODULE_LICENSE("GPL");
int cmd_level;
int slow_level;
- read_lock(&led_dat->rw_lock);
+ read_lock_irq(&led_dat->rw_lock);
cmd_level = gpio_get_value(led_dat->cmd);
slow_level = gpio_get_value(led_dat->slow);
}
}
- read_unlock(&led_dat->rw_lock);
+ read_unlock_irq(&led_dat->rw_lock);
return ret;
}
enum ns2_led_modes mode)
{
int i;
+ unsigned long flags;
- write_lock(&led_dat->rw_lock);
+ write_lock_irqsave(&led_dat->rw_lock, flags);
for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
if (mode == ns2_led_modval[i].mode) {
}
}
- write_unlock(&led_dat->rw_lock);
+ write_unlock_irqrestore(&led_dat->rw_lock, flags);
}
static void ns2_led_set(struct led_classdev *led_cdev,
struct device_attribute *attr,
const char *buff, size_t count)
{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct ns2_led_data *led_dat =
+ container_of(led_cdev, struct ns2_led_data, cdev);
int ret;
unsigned long enable;
enum ns2_led_modes mode;
- struct ns2_led_data *led_dat = dev_get_drvdata(dev);
ret = strict_strtoul(buff, 10, &enable);
if (ret < 0)
static ssize_t ns2_led_sata_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct ns2_led_data *led_dat = dev_get_drvdata(dev);
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct ns2_led_data *led_dat =
+ container_of(led_cdev, struct ns2_led_data, cdev);
return sprintf(buf, "%d\n", led_dat->sata);
}
if (ret < 0)
goto err_free_slow;
- dev_set_drvdata(led_dat->cdev.dev, led_dat);
ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
if (ret < 0)
goto err_free_cdev;
irq_tsc = cache_tsc;
for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
irq_data = &max8925_irqs[i];
+ /* 1 -- disable, 0 -- enable */
switch (irq_data->mask_reg) {
case MAX8925_CHG_IRQ1_MASK:
- irq_chg[0] &= irq_data->enable;
+ irq_chg[0] &= ~irq_data->enable;
break;
case MAX8925_CHG_IRQ2_MASK:
- irq_chg[1] &= irq_data->enable;
+ irq_chg[1] &= ~irq_data->enable;
break;
case MAX8925_ON_OFF_IRQ1_MASK:
- irq_on[0] &= irq_data->enable;
+ irq_on[0] &= ~irq_data->enable;
break;
case MAX8925_ON_OFF_IRQ2_MASK:
- irq_on[1] &= irq_data->enable;
+ irq_on[1] &= ~irq_data->enable;
break;
case MAX8925_RTC_IRQ_MASK:
- irq_rtc &= irq_data->enable;
+ irq_rtc &= ~irq_data->enable;
break;
case MAX8925_TSC_IRQ_MASK:
- irq_tsc &= irq_data->enable;
+ irq_tsc &= ~irq_data->enable;
break;
default:
dev_err(chip->dev, "wrong IRQ\n");
irq = irq - wm831x->irq_base;
- if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11)
- return -EINVAL;
+ if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
+ /* Ignore internal-only IRQs */
+ if (irq >= 0 && irq < WM831X_NUM_IRQS)
+ return 0;
+ else
+ return -EINVAL;
+ }
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
If unsure, say N.
To compile this driver as a module, choose M here: the
- module will be called vmware_balloon.
+ module will be called vmw_balloon.
config ARM_CHARLCD
bool "ARM Ltd. Character LCD Driver"
obj-$(CONFIG_HMC6352) += hmc6352.o
obj-y += eeprom/
obj-y += cb710/
-obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o
+obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
{
struct sdhci_host *host = platform_get_drvdata(dev);
+ unsigned long flags;
+
if (host) {
- spin_lock(&host->lock);
+ spin_lock_irqsave(&host->lock, flags);
if (state) {
dev_dbg(&dev->dev, "card inserted.\n");
host->flags &= ~SDHCI_DEVICE_DEAD;
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
tasklet_schedule(&host->card_tasklet);
- spin_unlock(&host->lock);
+ spin_unlock_irqrestore(&host->lock, flags);
}
}
sdhci_remove_host(host, 1);
for (ptr = 0; ptr < 3; ptr++) {
- clk_disable(sc->clk_bus[ptr]);
- clk_put(sc->clk_bus[ptr]);
+ if (sc->clk_bus[ptr]) {
+ clk_disable(sc->clk_bus[ptr]);
+ clk_put(sc->clk_bus[ptr]);
+ }
}
clk_disable(sc->clk_io);
clk_put(sc->clk_io);
prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT);
} while (prefetch_status);
/* disable and stop the PFPW engine */
- gpmc_prefetch_reset();
+ gpmc_prefetch_reset(info->gpmc_cs);
dma_unmap_single(&info->pdev->dev, dma_addr, len, dir);
return 0;
{
struct vortex_private *vp = netdev_priv(dev);
+ if (!VORTEX_PCI(vp))
+ return;
+
wol->supported = WAKE_MAGIC;
wol->wolopts = 0;
static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct vortex_private *vp = netdev_priv(dev);
+
+ if (!VORTEX_PCI(vp))
+ return -EOPNOTSUPP;
+
if (wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
return;
}
+ if (VORTEX_PCI(vp)->current_state < PCI_D3hot)
+ return;
+
/* Change the power state to D3; RxEnable doesn't take effect. */
pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
}
# Network device configuration
#
+config HAVE_NET_MACB
+ bool
+
menuconfig NETDEVICES
default y if UML
depends on NET
config MACB
tristate "Atmel MACB support"
- depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9
+ depends on HAVE_NET_MACB
select PHYLIB
help
The Atmel MACB ethernet interface is found on many AT32 and AT91
rrd_ring->desc = NULL;
rrd_ring->dma = 0;
+
+ adapter->cmb.dma = 0;
+ adapter->cmb.cmb = NULL;
+
+ adapter->smb.dma = 0;
+ adapter->smb.smb = NULL;
}
static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
pci_enable_wake(pdev, PCI_D3cold, 0);
atl1_reset_hw(&adapter->hw);
- adapter->cmb.cmb->int_stats = 0;
- if (netif_running(netdev))
+ if (netif_running(netdev)) {
+ adapter->cmb.cmb->int_stats = 0;
atl1_up(adapter);
+ }
netif_device_attach(netdev);
return 0;
E1000_SCTL = 0x00024, /* SerDes Control - RW */
E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */
E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */
+ E1000_FEXTNVM4 = 0x00024, /* Future Extended NVM 4 - RW */
E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */
E1000_FCT = 0x00030, /* Flow Control Type - RW */
E1000_VET = 0x00038, /* VLAN Ether Type - RW */
#define E1000_FEXTNVM_SW_CONFIG 1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
+#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
+#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
+#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
+
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
/* SMBus Address Phy Register */
#define HV_SMB_ADDR PHY_REG(768, 26)
+#define HV_SMB_ADDR_MASK 0x007F
#define HV_SMB_ADDR_PEC_EN 0x0200
#define HV_SMB_ADDR_VALID 0x0080
static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
+static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
+static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
{
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- u32 ctrl;
+ u32 ctrl, fwsm;
s32 ret_val = 0;
phy->addr = 1;
* disabled, then toggle the LANPHYPC Value bit to force
* the interconnect to PCIe mode.
*/
- if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+ fwsm = er32(FWSM);
+ if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
ctrl = er32(CTRL);
ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
ew32(CTRL, ctrl);
msleep(50);
+
+ /*
+ * Gate automatic PHY configuration by hardware on
+ * non-managed 82579
+ */
+ if (hw->mac.type == e1000_pch2lan)
+ e1000_gate_hw_phy_config_ich8lan(hw, true);
}
/*
if (ret_val)
goto out;
+ /* Ungate automatic PHY configuration on non-managed 82579 */
+ if ((hw->mac.type == e1000_pch2lan) &&
+ !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
+ msleep(10);
+ e1000_gate_hw_phy_config_ich8lan(hw, false);
+ }
+
phy->id = e1000_phy_unknown;
ret_val = e1000e_get_phy_id(hw);
if (ret_val)
if (mac->type == e1000_ich8lan)
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
- /* Disable PHY configuration by hardware, config by software */
- if (mac->type == e1000_pch2lan) {
- u32 extcnf_ctrl = er32(EXTCNF_CTRL);
-
- extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- }
+ /* Gate automatic PHY configuration by hardware on managed 82579 */
+ if ((mac->type == e1000_pch2lan) &&
+ (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+ e1000_gate_hw_phy_config_ich8lan(hw, true);
return 0;
}
goto out;
}
+ if (hw->mac.type == e1000_pch2lan) {
+ ret_val = e1000_k1_workaround_lv(hw);
+ if (ret_val)
+ goto out;
+ }
+
/*
* Check if there was DownShift, must be checked
* immediately after link-up
return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET;
}
+/**
+ * e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states
+ * @hw: pointer to the HW structure
+ *
+ * Assumes semaphore already acquired.
+ *
+ **/
+static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
+{
+ u16 phy_data;
+ u32 strap = er32(STRAP);
+ s32 ret_val = 0;
+
+ strap &= E1000_STRAP_SMBUS_ADDRESS_MASK;
+
+ ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data);
+ if (ret_val)
+ goto out;
+
+ phy_data &= ~HV_SMB_ADDR_MASK;
+ phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
+ phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
+ ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
+
+out:
+ return ret_val;
+}
+
/**
* e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
* @hw: pointer to the HW structure
**/
static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
{
- struct e1000_adapter *adapter = hw->adapter;
struct e1000_phy_info *phy = &hw->phy;
u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
s32 ret_val = 0;
if (phy->type != e1000_phy_igp_3)
return ret_val;
- if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) {
+ if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
+ (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
break;
}
cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
- if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
- ((hw->mac.type == e1000_pchlan) ||
- (hw->mac.type == e1000_pch2lan))) {
+ if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
+ (hw->mac.type == e1000_pchlan)) ||
+ (hw->mac.type == e1000_pch2lan)) {
/*
* HW configures the SMBus address and LEDs when the
* OEM and LCD Write Enable bits are set in the NVM.
* When both NVM bits are cleared, SW will configure
* them instead.
*/
- data = er32(STRAP);
- data &= E1000_STRAP_SMBUS_ADDRESS_MASK;
- reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT;
- reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
- ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR,
- reg_data);
+ ret_val = e1000_write_smbus_addr(hw);
if (ret_val)
goto out;
goto out;
/* Enable jumbo frame workaround in the PHY */
- e1e_rphy(hw, PHY_REG(769, 20), &data);
- ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
- if (ret_val)
- goto out;
e1e_rphy(hw, PHY_REG(769, 23), &data);
data &= ~(0x7F << 5);
data |= (0x37 << 5);
goto out;
e1e_rphy(hw, PHY_REG(769, 16), &data);
data &= ~(1 << 13);
- data |= (1 << 12);
ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
if (ret_val)
goto out;
mac_reg = er32(RCTL);
mac_reg &= ~E1000_RCTL_SECRC;
- ew32(FFLT_DBG, mac_reg);
+ ew32(RCTL, mac_reg);
ret_val = e1000e_read_kmrn_reg(hw,
E1000_KMRNCTRLSTA_CTRL_OFFSET,
goto out;
/* Write PHY register values back to h/w defaults */
- e1e_rphy(hw, PHY_REG(769, 20), &data);
- ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
- if (ret_val)
- goto out;
e1e_rphy(hw, PHY_REG(769, 23), &data);
data &= ~(0x7F << 5);
ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
if (ret_val)
goto out;
e1e_rphy(hw, PHY_REG(769, 16), &data);
- data &= ~(1 << 12);
data |= (1 << 13);
ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
if (ret_val)
return ret_val;
}
+/**
+ * e1000_k1_gig_workaround_lv - K1 Si workaround
+ * @hw: pointer to the HW structure
+ *
+ * Workaround to set the K1 beacon duration for 82579 parts
+ **/
+static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
+{
+ s32 ret_val = 0;
+ u16 status_reg = 0;
+ u32 mac_reg;
+
+ if (hw->mac.type != e1000_pch2lan)
+ goto out;
+
+ /* Set K1 beacon duration based on 1Gbps speed or otherwise */
+ ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
+ if (ret_val)
+ goto out;
+
+ if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
+ == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
+ mac_reg = er32(FEXTNVM4);
+ mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
+
+ if (status_reg & HV_M_STATUS_SPEED_1000)
+ mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
+ else
+ mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
+
+ ew32(FEXTNVM4, mac_reg);
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware
+ * @hw: pointer to the HW structure
+ * @gate: boolean set to true to gate, false to ungate
+ *
+ * Gate/ungate the automatic PHY configuration via hardware; perform
+ * the configuration via software instead.
+ **/
+static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
+{
+ u32 extcnf_ctrl;
+
+ if (hw->mac.type != e1000_pch2lan)
+ return;
+
+ extcnf_ctrl = er32(EXTCNF_CTRL);
+
+ if (gate)
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
+ else
+ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG;
+
+ ew32(EXTCNF_CTRL, extcnf_ctrl);
+ return;
+}
+
/**
* e1000_lan_init_done_ich8lan - Check for PHY config completion
* @hw: pointer to the HW structure
if (e1000_check_reset_block(hw))
goto out;
+ /* Allow time for h/w to get to quiescent state after reset */
+ msleep(10);
+
/* Perform any necessary post-reset workarounds */
switch (hw->mac.type) {
case e1000_pchlan:
/* Configure the LCD with the OEM bits in NVM */
ret_val = e1000_oem_bits_config_ich8lan(hw, true);
+ /* Ungate automatic PHY configuration on non-managed 82579 */
+ if ((hw->mac.type == e1000_pch2lan) &&
+ !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+ msleep(10);
+ e1000_gate_hw_phy_config_ich8lan(hw, false);
+ }
+
out:
return ret_val;
}
{
s32 ret_val = 0;
+ /* Gate automatic PHY configuration by hardware on non-managed 82579 */
+ if ((hw->mac.type == e1000_pch2lan) &&
+ !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+ e1000_gate_hw_phy_config_ich8lan(hw, true);
+
ret_val = e1000e_phy_hw_reset_generic(hw);
if (ret_val)
goto out;
* external PHY is reset.
*/
ctrl |= E1000_CTRL_PHY_RST;
+
+ /*
+ * Gate automatic PHY configuration by hardware on
+ * non-managed 82579
+ */
+ if ((hw->mac.type == e1000_pch2lan) &&
+ !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+ e1000_gate_hw_phy_config_ich8lan(hw, true);
}
ret_val = e1000_acquire_swflag_ich8lan(hw);
e_dbg("Issuing a global reset to ich8lan\n");
void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
{
u32 phy_ctrl;
+ s32 ret_val;
phy_ctrl = er32(PHY_CTRL);
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE;
ew32(PHY_CTRL, phy_ctrl);
- if (hw->mac.type >= e1000_pchlan)
- e1000_phy_hw_reset_ich8lan(hw);
+ if (hw->mac.type >= e1000_pchlan) {
+ e1000_oem_bits_config_ich8lan(hw, true);
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return;
+ e1000_write_smbus_addr(hw);
+ hw->phy.ops.release(hw);
+ }
}
/**
u32 psrctl = 0;
u32 pages = 0;
+ /* Workaround Si errata on 82579 - configure jumbo frame flow */
+ if (hw->mac.type == e1000_pch2lan) {
+ s32 ret_val;
+
+ if (adapter->netdev->mtu > ETH_DATA_LEN)
+ ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
+ else
+ ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
+ }
+
/* Program MC offset vector base */
rctl = er32(RCTL);
rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
e1e_wphy(hw, 22, phy_data);
}
- /* Workaround Si errata on 82579 - configure jumbo frame flow */
- if (hw->mac.type == e1000_pch2lan) {
- s32 ret_val;
-
- if (rctl & E1000_RCTL_LPE)
- ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
- else
- ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
- }
-
/* Setup buffer sizes */
rctl &= ~E1000_RCTL_SZ_4096;
rctl |= E1000_RCTL_BSEX;
return -EINVAL;
}
+ /* Jumbo frame workaround on 82579 requires CRC be stripped */
+ if ((adapter->hw.mac.type == e1000_pch2lan) &&
+ !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
+ (new_mtu > ETH_DATA_LEN)) {
+ e_err("Jumbo Frames not supported on 82579 when CRC "
+ "stripping is disabled.\n");
+ return -EINVAL;
+ }
+
/* 82573 Errata 17 */
if (((adapter->hw.mac.type == e1000_82573) ||
(adapter->hw.mac.type == e1000_82574)) &&
if (dev->emac_irq != NO_IRQ)
irq_dispose_mapping(dev->emac_irq);
err_free:
- kfree(ndev);
+ free_netdev(ndev);
err_gone:
/* if we were on the bootlist, remove us as we won't show up and
* wake up all waiters to notify them in case they were waiting
if (dev->emac_irq != NO_IRQ)
irq_dispose_mapping(dev->emac_irq);
- kfree(dev->ndev);
+ free_netdev(dev->ndev);
return 0;
}
if (pkt_offset)
skb_pull(skb, pkt_offset);
- skb->truesize = skb->len + sizeof(struct sk_buff);
skb->protocol = eth_type_trans(skb, netdev);
napi_gro_receive(&sds_ring->napi, skb);
skb_put(skb, lro_length + data_offset);
- skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
-
skb_pull(skb, l2_hdr_offset);
skb->protocol = eth_type_trans(skb, netdev);
return -ENOMEM;
}
- skb_reserve(skb, 2);
+ skb_reserve(skb, NET_IP_ALIGN);
dma = pci_map_single(pdev, skb->data,
rds_ring->dma_size, PCI_DMA_FROMDEVICE);
if (pkt_offset)
skb_pull(skb, pkt_offset);
- skb->truesize = skb->len + sizeof(struct sk_buff);
skb->protocol = eth_type_trans(skb, netdev);
napi_gro_receive(&sds_ring->napi, skb);
skb_put(skb, lro_length + data_offset);
- skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
-
skb_pull(skb, l2_hdr_offset);
skb->protocol = eth_type_trans(skb, netdev);
if (pkt_offset)
skb_pull(skb, pkt_offset);
- skb->truesize = skb->len + sizeof(struct sk_buff);
-
if (!qlcnic_check_loopback_buff(skb->data))
adapter->diag_cnt++;
free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
__ilog2(sizeof(void *)) + 4 : 0);
unregister_netdev(ndev);
- kfree(ndev);
+ free_netdev(ndev);
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
list_del(&peer->node);
err_out_free_page:
free_page((unsigned long) sp->srings);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out:
return err;
MODULE_LICENSE("GPL");
MODULE_VERSION(SMSC_DRV_VERSION);
+MODULE_ALIAS("platform:smsc911x");
#if USE_DEBUG > 0
static int debug = 16;
NWayState = (1 << 14) | (1 << 13) | (1 << 12),
NWayRestart = (1 << 12),
NonselPortActive = (1 << 9),
+ SelPortActive = (1 << 8),
LinkFailStatus = (1 << 2),
NetCxnErr = (1 << 1),
};
/* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/
static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
-static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, };
+static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
+/* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */
+static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
unsigned int carrier;
unsigned long flags;
+ /* clear port active bits */
+ dw32(SIAStatus, NonselPortActive | SelPortActive);
+
carrier = (status & NetCxnErr) ? 0 : 1;
if (carrier) {
static void de_media_interrupt (struct de_private *de, u32 status)
{
if (status & LinkPass) {
+ /* Ignore if current media is AUI or BNC and we can't use TP */
+ if ((de->media_type == DE_MEDIA_AUI ||
+ de->media_type == DE_MEDIA_BNC) &&
+ (de->media_lock ||
+ !de_ok_to_advertise(de, DE_MEDIA_TP_AUTO)))
+ return;
+ /* If current media is not TP, change it to TP */
+ if ((de->media_type == DE_MEDIA_AUI ||
+ de->media_type == DE_MEDIA_BNC)) {
+ de->media_type = DE_MEDIA_TP_AUTO;
+ de_stop_rxtx(de);
+ de_set_media(de);
+ de_start_rxtx(de);
+ }
de_link_up(de);
mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK);
return;
}
BUG_ON(!(status & LinkFail));
-
- if (netif_carrier_ok(de->dev)) {
+ /* Mark the link as down only if current media is TP */
+ if (netif_carrier_ok(de->dev) && de->media_type != DE_MEDIA_AUI &&
+ de->media_type != DE_MEDIA_BNC) {
de_link_down(de);
mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
}
if (de->de21040)
return;
+ dw32(CSR13, 0); /* Reset phy */
pci_read_config_dword(de->pdev, PCIPM, &pmctl);
pmctl |= PM_Sleep;
pci_write_config_dword(de->pdev, PCIPM, pmctl);
return 0; /* nothing to change */
de_link_down(de);
+ mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
de_stop_rxtx(de);
de->media_type = new_media;
de->media_lock = media_lock;
de->media_advertise = ecmd->advertising;
de_set_media(de);
+ if (netif_running(de->dev))
+ de_start_rxtx(de);
return 0;
}
for (i = 0; i < DE_MAX_MEDIA; i++) {
if (de->media[i].csr13 == 0xffff)
de->media[i].csr13 = t21041_csr13[i];
- if (de->media[i].csr14 == 0xffff)
- de->media[i].csr14 = t21041_csr14[i];
+ if (de->media[i].csr14 == 0xffff) {
+ /* autonegotiation is broken at least on some chip
+ revisions - rev. 0x21 works, 0x11 does not */
+ if (de->pdev->revision < 0x20)
+ de->media[i].csr14 = t21041_csr14_brk[i];
+ else
+ de->media[i].csr14 = t21041_csr14[i];
+ }
if (de->media[i].csr15 == 0xffff)
de->media[i].csr15 = t21041_csr15[i];
}
dev_err(&dev->dev, "pci_enable_device failed in resume\n");
goto out;
}
+ pci_set_master(pdev);
+ de_init_rings(de);
de_init_hw(de);
out_attach:
netif_device_attach(dev);
clear_bit(STATUS_SCAN_HW, &priv->status);
clear_bit(STATUS_SCANNING, &priv->status);
/* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
+ queue_work(priv->workqueue, &priv->abort_scan);
}
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return -EINVAL;
+ if (test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_INFO(priv, "scan in progress.\n");
+ return -EINVAL;
+ }
+
if (mode >= IWL_MAX_FORCE_RESET) {
IWL_DEBUG_INFO(priv, "invalid reset request.\n");
return -EINVAL;
clear_bit(STATUS_SCANNING, &priv->status);
/* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
+ queue_work(priv->workqueue, &priv->abort_scan);
}
static void iwl3945_bg_restart(struct work_struct *data)
#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
+/* page table handling */
+#define LEVEL_STRIDE (9)
+#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
+
+static inline int agaw_to_level(int agaw)
+{
+ return agaw + 2;
+}
+
+static inline int agaw_to_width(int agaw)
+{
+ return 30 + agaw * LEVEL_STRIDE;
+}
+
+static inline int width_to_agaw(int width)
+{
+ return (width - 30) / LEVEL_STRIDE;
+}
+
+static inline unsigned int level_to_offset_bits(int level)
+{
+ return (level - 1) * LEVEL_STRIDE;
+}
+
+static inline int pfn_level_offset(unsigned long pfn, int level)
+{
+ return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
+}
+
+static inline unsigned long level_mask(int level)
+{
+ return -1UL << level_to_offset_bits(level);
+}
+
+static inline unsigned long level_size(int level)
+{
+ return 1UL << level_to_offset_bits(level);
+}
+
+static inline unsigned long align_to_level(unsigned long pfn, int level)
+{
+ return (pfn + level_size(level) - 1) & level_mask(level);
+}
/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
are never going to work. */
}
-static inline int width_to_agaw(int width);
-
static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
{
unsigned long sagaw;
spin_unlock_irqrestore(&iommu->lock, flags);
}
-/* page table handling */
-#define LEVEL_STRIDE (9)
-#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
-
-static inline int agaw_to_level(int agaw)
-{
- return agaw + 2;
-}
-
-static inline int agaw_to_width(int agaw)
-{
- return 30 + agaw * LEVEL_STRIDE;
-
-}
-
-static inline int width_to_agaw(int width)
-{
- return (width - 30) / LEVEL_STRIDE;
-}
-
-static inline unsigned int level_to_offset_bits(int level)
-{
- return (level - 1) * LEVEL_STRIDE;
-}
-
-static inline int pfn_level_offset(unsigned long pfn, int level)
-{
- return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
-}
-
-static inline unsigned long level_mask(int level)
-{
- return -1UL << level_to_offset_bits(level);
-}
-
-static inline unsigned long level_size(int level)
-{
- return 1UL << level_to_offset_bits(level);
-}
-
-static inline unsigned long align_to_level(unsigned long pfn, int level)
-{
- return (pfn + level_size(level) - 1) & level_mask(level);
-}
-
static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
unsigned long pfn)
{
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
+#define GGC 0x52
+#define GGC_MEMORY_SIZE_MASK (0xf << 8)
+#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
+#define GGC_MEMORY_SIZE_1M (0x1 << 8)
+#define GGC_MEMORY_SIZE_2M (0x3 << 8)
+#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
+#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
+#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
+#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
+
+static void __devinit quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
+{
+ unsigned short ggc;
+
+ if (pci_read_config_word(dev, GGC, &ggc))
+ return;
+
+ if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
+ printk(KERN_INFO "DMAR: BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
+ dmar_map_gfx = 0;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
+
/* On Tylersburg chipsets, some BIOSes have been known to enable the
ISOCH DMAR unit for the Azalia sound device, but not give it any
TLB entries, which causes it to deadlock. Check for that. We do
* the VF BAR size multiplied by the number of VFs. The alignment
* is just the VF BAR size.
*/
-int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
+resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
{
struct resource tmp;
enum pci_bar_type type;
extern void pci_iov_release(struct pci_dev *dev);
extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
enum pci_bar_type *type);
-extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
+extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev,
+ int resno);
extern void pci_restore_iov_state(struct pci_dev *dev);
extern int pci_iov_bus_range(struct pci_bus *bus);
}
#endif /* CONFIG_PCI_IOV */
-static inline int pci_resource_alignment(struct pci_dev *dev,
+static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
struct resource *res)
{
#ifdef CONFIG_PCI_IOV
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs);
+/*
+ * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear
+ * for some HT machines to use C4 w/o hanging.
+ */
+static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev)
+{
+ u32 pmbase;
+ u16 pm1a;
+
+ pci_read_config_dword(dev, 0x40, &pmbase);
+ pmbase = pmbase & 0xff80;
+ pm1a = inw(pmbase);
+
+ if (pm1a & 0x10) {
+ dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
+ outw(0x10, pmbase);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts);
+
/*
* Chipsets where PCI->PCI transfers vanish or hang
*/
if (c->io[1].end) {
ret = alloc_io_space(s, &c->io[1], p_dev->io_lines);
if (ret) {
+ struct resource tmp = c->io[0];
+ /* release the previously allocated resource */
release_io_space(s, &c->io[0]);
+ /* but preserve the settings, for they worked... */
+ c->io[0].end = resource_size(&tmp);
+ c->io[0].start = tmp.start;
+ c->io[0].flags = tmp.flags;
goto out;
}
} else
if (!pci_resource_start(dev, 0)) {
dev_warn(&dev->dev, "refusing to load the driver as the "
"io_base is NULL.\n");
- goto err_out_free_mem;
+ goto err_out_disable;
}
dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
};
-typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
+typedef u16 tpacpi_keymap_entry_t;
+typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
static int __init hotkey_init(struct ibm_init_struct *iibm)
{
};
#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t)
-#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0])
+#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_entry_t)
int res, i;
int status;
constraints->min_uA != constraints->max_uA) {
ret = _regulator_get_current_limit(rdev);
if (ret > 0)
- count += sprintf(buf + count, "at %d uA ", ret / 1000);
+ count += sprintf(buf + count, "at %d mA ", ret / 1000);
}
if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
dev_set_name(&rdev->dev, "regulator.%d",
atomic_inc_return(®ulator_no) - 1);
ret = device_register(&rdev->dev);
- if (ret != 0)
+ if (ret != 0) {
+ put_device(&rdev->dev);
goto clean;
+ }
dev_set_drvdata(&rdev->dev, rdev);
/* set external clock frequency */
info->extclk_freq = pdata->extclk_freq;
max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK,
- info->extclk_freq);
+ info->extclk_freq << 6);
}
if (pdata->ramp_timing) {
err = PTR_ERR(rtc);
return err;
}
+ platform_set_drvdata(pdev, rtc);
return 0;
}
struct rtc_device *rtc = platform_get_drvdata(pdev);
rtc_device_unregister(rtc);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
s3c_rtc_setaie(alrm->enabled);
- if (alrm->enabled)
- enable_irq_wake(s3c_rtc_alarmno);
- else
- disable_irq_wake(s3c_rtc_alarmno);
-
return 0;
}
ticnt_en_save &= S3C64XX_RTCCON_TICEN;
}
s3c_rtc_enable(pdev, 0);
+
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(s3c_rtc_alarmno);
+
return 0;
}
tmp = readb(s3c_rtc_base + S3C2410_RTCCON);
writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON);
}
+
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(s3c_rtc_alarmno);
+
return 0;
}
#else
dev_fsm, dev_fsm_len, GFP_KERNEL);
if (priv->fsm == NULL) {
CTCMY_DBF_DEV(SETUP, dev, "init_fsm error");
- kfree(dev);
+ free_netdev(dev);
return NULL;
}
fsm_newstate(priv->fsm, DEV_STATE_STOPPED);
grp = ctcmpc_init_mpc_group(priv);
if (grp == NULL) {
MPC_DBF_DEV(SETUP, dev, "init_mpc_group error");
- kfree(dev);
+ free_netdev(dev);
return NULL;
}
tasklet_init(&grp->mpc_tasklet2,
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
+#include <linux/slab.h>
#include <linux/serial_reg.h>
#include <linux/circ_buf.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/ioport.h>
+#include <linux/irq.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
GPIO operations, you should be able to leverage that for better
speed with a custom version of this driver; see the source code.
+config SPI_IMX_VER_IMX1
+ def_bool y if SOC_IMX1
+
+config SPI_IMX_VER_0_0
+ def_bool y if SOC_IMX21 || SOC_IMX27
+
+config SPI_IMX_VER_0_4
+ def_bool y if ARCH_MX31
+
+config SPI_IMX_VER_0_7
+ def_bool y if ARCH_MX25 || ARCH_MX35 || ARCH_MX51
+
+config SPI_IMX_VER_2_3
+ def_bool y if ARCH_MX51
+
config SPI_IMX
tristate "Freescale i.MX SPI controllers"
depends on ARCH_MXC
select SPI_BITBANG
+ default m if IMX_HAVE_PLATFORM_SPI_IMX
help
This enables using the Freescale i.MX SPI controllers in master
mode.
#include <linux/init.h>
#include <linux/cache.h>
#include <linux/mutex.h>
+#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
const struct spi_device *spi = to_spi_device(dev);
const struct spi_driver *sdrv = to_spi_driver(drv);
+ /* Attempt an OF style match */
+ if (of_driver_match_device(dev, drv))
+ return 1;
+
if (sdrv->id_table)
return !!spi_match_id(sdrv->id_table, spi);
spi_gpio->bitbang.master = spi_master_get(master);
spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
- if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) {
+ if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
unsigned int speed_hz;
unsigned int bpw;
unsigned int mode;
- int cs;
+ u8 cs;
+};
+
+enum spi_imx_devtype {
+ SPI_IMX_VER_IMX1,
+ SPI_IMX_VER_0_0,
+ SPI_IMX_VER_0_4,
+ SPI_IMX_VER_0_5,
+ SPI_IMX_VER_0_7,
+ SPI_IMX_VER_2_3,
+ SPI_IMX_VER_AUTODETECT,
+};
+
+struct spi_imx_data;
+
+struct spi_imx_devtype_data {
+ void (*intctrl)(struct spi_imx_data *, int);
+ int (*config)(struct spi_imx_data *, struct spi_imx_config *);
+ void (*trigger)(struct spi_imx_data *);
+ int (*rx_available)(struct spi_imx_data *);
+ void (*reset)(struct spi_imx_data *);
+ unsigned int fifosize;
};
struct spi_imx_data {
const void *tx_buf;
unsigned int txfifo; /* number of words pushed in tx FIFO */
- /* SoC specific functions */
- void (*intctrl)(struct spi_imx_data *, int);
- int (*config)(struct spi_imx_data *, struct spi_imx_config *);
- void (*trigger)(struct spi_imx_data *);
- int (*rx_available)(struct spi_imx_data *);
+ struct spi_imx_devtype_data devtype_data;
};
#define MXC_SPI_BUF_RX(type) \
return max;
}
-/* MX1, MX31, MX35 */
+/* MX1, MX31, MX35, MX51 CSPI */
static unsigned int spi_imx_clkdiv_2(unsigned int fin,
unsigned int fspi)
{
return 7;
}
+#define SPI_IMX2_3_CTRL 0x08
+#define SPI_IMX2_3_CTRL_ENABLE (1 << 0)
+#define SPI_IMX2_3_CTRL_XCH (1 << 2)
+#define SPI_IMX2_3_CTRL_MODE(cs) (1 << ((cs) + 4))
+#define SPI_IMX2_3_CTRL_POSTDIV_OFFSET 8
+#define SPI_IMX2_3_CTRL_PREDIV_OFFSET 12
+#define SPI_IMX2_3_CTRL_CS(cs) ((cs) << 18)
+#define SPI_IMX2_3_CTRL_BL_OFFSET 20
+
+#define SPI_IMX2_3_CONFIG 0x0c
+#define SPI_IMX2_3_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0))
+#define SPI_IMX2_3_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4))
+#define SPI_IMX2_3_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8))
+#define SPI_IMX2_3_CONFIG_SSBPOL(cs) (1 << ((cs) + 12))
+
+#define SPI_IMX2_3_INT 0x10
+#define SPI_IMX2_3_INT_TEEN (1 << 0)
+#define SPI_IMX2_3_INT_RREN (1 << 3)
+
+#define SPI_IMX2_3_STAT 0x18
+#define SPI_IMX2_3_STAT_RR (1 << 3)
+
+/* MX51 eCSPI */
+static unsigned int spi_imx2_3_clkdiv(unsigned int fin, unsigned int fspi)
+{
+ /*
+ * there are two 4-bit dividers, the pre-divider divides by
+ * $pre, the post-divider by 2^$post
+ */
+ unsigned int pre, post;
+
+ if (unlikely(fspi > fin))
+ return 0;
+
+ post = fls(fin) - fls(fspi);
+ if (fin > fspi << post)
+ post++;
+
+ /* now we have: (fin <= fspi << post) with post being minimal */
+
+ post = max(4U, post) - 4;
+ if (unlikely(post > 0xf)) {
+ pr_err("%s: cannot set clock freq: %u (base freq: %u)\n",
+ __func__, fspi, fin);
+ return 0xff;
+ }
+
+ pre = DIV_ROUND_UP(fin, fspi << post) - 1;
+
+ pr_debug("%s: fin: %u, fspi: %u, post: %u, pre: %u\n",
+ __func__, fin, fspi, post, pre);
+ return (pre << SPI_IMX2_3_CTRL_PREDIV_OFFSET) |
+ (post << SPI_IMX2_3_CTRL_POSTDIV_OFFSET);
+}
+
+static void __maybe_unused spi_imx2_3_intctrl(struct spi_imx_data *spi_imx, int enable)
+{
+ unsigned val = 0;
+
+ if (enable & MXC_INT_TE)
+ val |= SPI_IMX2_3_INT_TEEN;
+
+ if (enable & MXC_INT_RR)
+ val |= SPI_IMX2_3_INT_RREN;
+
+ writel(val, spi_imx->base + SPI_IMX2_3_INT);
+}
+
+static void __maybe_unused spi_imx2_3_trigger(struct spi_imx_data *spi_imx)
+{
+ u32 reg;
+
+ reg = readl(spi_imx->base + SPI_IMX2_3_CTRL);
+ reg |= SPI_IMX2_3_CTRL_XCH;
+ writel(reg, spi_imx->base + SPI_IMX2_3_CTRL);
+}
+
+static int __maybe_unused spi_imx2_3_config(struct spi_imx_data *spi_imx,
+ struct spi_imx_config *config)
+{
+ u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0;
+
+ /* set master mode */
+ ctrl |= SPI_IMX2_3_CTRL_MODE(config->cs);
+
+ /* set clock speed */
+ ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz);
+
+ /* set chip select to use */
+ ctrl |= SPI_IMX2_3_CTRL_CS(config->cs);
+
+ ctrl |= (config->bpw - 1) << SPI_IMX2_3_CTRL_BL_OFFSET;
+
+ cfg |= SPI_IMX2_3_CONFIG_SBBCTRL(config->cs);
+
+ if (config->mode & SPI_CPHA)
+ cfg |= SPI_IMX2_3_CONFIG_SCLKPHA(config->cs);
+
+ if (config->mode & SPI_CPOL)
+ cfg |= SPI_IMX2_3_CONFIG_SCLKPOL(config->cs);
+
+ if (config->mode & SPI_CS_HIGH)
+ cfg |= SPI_IMX2_3_CONFIG_SSBPOL(config->cs);
+
+ writel(ctrl, spi_imx->base + SPI_IMX2_3_CTRL);
+ writel(cfg, spi_imx->base + SPI_IMX2_3_CONFIG);
+
+ return 0;
+}
+
+static int __maybe_unused spi_imx2_3_rx_available(struct spi_imx_data *spi_imx)
+{
+ return readl(spi_imx->base + SPI_IMX2_3_STAT) & SPI_IMX2_3_STAT_RR;
+}
+
+static void __maybe_unused spi_imx2_3_reset(struct spi_imx_data *spi_imx)
+{
+ /* drain receive buffer */
+ while (spi_imx2_3_rx_available(spi_imx))
+ readl(spi_imx->base + MXC_CSPIRXDATA);
+}
+
#define MX31_INTREG_TEEN (1 << 0)
#define MX31_INTREG_RREN (1 << 3)
* the i.MX35 has a slightly different register layout for bits
* we do not use here.
*/
-static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable)
+static void __maybe_unused mx31_intctrl(struct spi_imx_data *spi_imx, int enable)
{
unsigned int val = 0;
writel(val, spi_imx->base + MXC_CSPIINT);
}
-static void mx31_trigger(struct spi_imx_data *spi_imx)
+static void __maybe_unused mx31_trigger(struct spi_imx_data *spi_imx)
{
unsigned int reg;
writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx31_config(struct spi_imx_data *spi_imx,
+static int __maybe_unused spi_imx0_4_config(struct spi_imx_data *spi_imx,
struct spi_imx_config *config)
{
unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
+ int cs = spi_imx->chipselect[config->cs];
reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
MX31_CSPICTRL_DR_SHIFT;
- if (cpu_is_mx31())
- reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT;
- else if (cpu_is_mx25() || cpu_is_mx35()) {
- reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT;
- reg |= MX31_CSPICTRL_SSCTL;
- }
+ reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT;
if (config->mode & SPI_CPHA)
reg |= MX31_CSPICTRL_PHA;
reg |= MX31_CSPICTRL_POL;
if (config->mode & SPI_CS_HIGH)
reg |= MX31_CSPICTRL_SSPOL;
- if (config->cs < 0) {
- if (cpu_is_mx31())
- reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT;
- else if (cpu_is_mx25() || cpu_is_mx35())
- reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
- }
+ if (cs < 0)
+ reg |= (cs + 32) << MX31_CSPICTRL_CS_SHIFT;
+
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
+
+ return 0;
+}
+
+static int __maybe_unused spi_imx0_7_config(struct spi_imx_data *spi_imx,
+ struct spi_imx_config *config)
+{
+ unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
+ int cs = spi_imx->chipselect[config->cs];
+
+ reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
+ MX31_CSPICTRL_DR_SHIFT;
+
+ reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT;
+ reg |= MX31_CSPICTRL_SSCTL;
+
+ if (config->mode & SPI_CPHA)
+ reg |= MX31_CSPICTRL_PHA;
+ if (config->mode & SPI_CPOL)
+ reg |= MX31_CSPICTRL_POL;
+ if (config->mode & SPI_CS_HIGH)
+ reg |= MX31_CSPICTRL_SSPOL;
+ if (cs < 0)
+ reg |= (cs + 32) << MX35_CSPICTRL_CS_SHIFT;
writel(reg, spi_imx->base + MXC_CSPICTRL);
return 0;
}
-static int mx31_rx_available(struct spi_imx_data *spi_imx)
+static int __maybe_unused mx31_rx_available(struct spi_imx_data *spi_imx)
{
return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
}
+static void __maybe_unused spi_imx0_4_reset(struct spi_imx_data *spi_imx)
+{
+ /* drain receive buffer */
+ while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR)
+ readl(spi_imx->base + MXC_CSPIRXDATA);
+}
+
#define MX27_INTREG_RR (1 << 4)
#define MX27_INTREG_TEEN (1 << 9)
#define MX27_INTREG_RREN (1 << 13)
#define MX27_CSPICTRL_DR_SHIFT 14
#define MX27_CSPICTRL_CS_SHIFT 19
-static void mx27_intctrl(struct spi_imx_data *spi_imx, int enable)
+static void __maybe_unused mx27_intctrl(struct spi_imx_data *spi_imx, int enable)
{
unsigned int val = 0;
writel(val, spi_imx->base + MXC_CSPIINT);
}
-static void mx27_trigger(struct spi_imx_data *spi_imx)
+static void __maybe_unused mx27_trigger(struct spi_imx_data *spi_imx)
{
unsigned int reg;
writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx27_config(struct spi_imx_data *spi_imx,
+static int __maybe_unused mx27_config(struct spi_imx_data *spi_imx,
struct spi_imx_config *config)
{
unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER;
+ int cs = spi_imx->chipselect[config->cs];
reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz) <<
MX27_CSPICTRL_DR_SHIFT;
reg |= MX27_CSPICTRL_POL;
if (config->mode & SPI_CS_HIGH)
reg |= MX27_CSPICTRL_SSPOL;
- if (config->cs < 0)
- reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT;
+ if (cs < 0)
+ reg |= (cs + 32) << MX27_CSPICTRL_CS_SHIFT;
writel(reg, spi_imx->base + MXC_CSPICTRL);
return 0;
}
-static int mx27_rx_available(struct spi_imx_data *spi_imx)
+static int __maybe_unused mx27_rx_available(struct spi_imx_data *spi_imx)
{
return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR;
}
+static void __maybe_unused spi_imx0_0_reset(struct spi_imx_data *spi_imx)
+{
+ writel(1, spi_imx->base + MXC_RESET);
+}
+
#define MX1_INTREG_RR (1 << 3)
#define MX1_INTREG_TEEN (1 << 8)
#define MX1_INTREG_RREN (1 << 11)
#define MX1_CSPICTRL_MASTER (1 << 10)
#define MX1_CSPICTRL_DR_SHIFT 13
-static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable)
+static void __maybe_unused mx1_intctrl(struct spi_imx_data *spi_imx, int enable)
{
unsigned int val = 0;
writel(val, spi_imx->base + MXC_CSPIINT);
}
-static void mx1_trigger(struct spi_imx_data *spi_imx)
+static void __maybe_unused mx1_trigger(struct spi_imx_data *spi_imx)
{
unsigned int reg;
writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx1_config(struct spi_imx_data *spi_imx,
+static int __maybe_unused mx1_config(struct spi_imx_data *spi_imx,
struct spi_imx_config *config)
{
unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER;
return 0;
}
-static int mx1_rx_available(struct spi_imx_data *spi_imx)
+static int __maybe_unused mx1_rx_available(struct spi_imx_data *spi_imx)
{
return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR;
}
+static void __maybe_unused mx1_reset(struct spi_imx_data *spi_imx)
+{
+ writel(1, spi_imx->base + MXC_RESET);
+}
+
+/*
+ * These version numbers are taken from the Freescale driver. Unfortunately it
+ * doesn't support i.MX1, so this entry doesn't match the scheme. :-(
+ */
+static struct spi_imx_devtype_data spi_imx_devtype_data[] __devinitdata = {
+#ifdef CONFIG_SPI_IMX_VER_IMX1
+ [SPI_IMX_VER_IMX1] = {
+ .intctrl = mx1_intctrl,
+ .config = mx1_config,
+ .trigger = mx1_trigger,
+ .rx_available = mx1_rx_available,
+ .reset = mx1_reset,
+ .fifosize = 8,
+ },
+#endif
+#ifdef CONFIG_SPI_IMX_VER_0_0
+ [SPI_IMX_VER_0_0] = {
+ .intctrl = mx27_intctrl,
+ .config = mx27_config,
+ .trigger = mx27_trigger,
+ .rx_available = mx27_rx_available,
+ .reset = spi_imx0_0_reset,
+ .fifosize = 8,
+ },
+#endif
+#ifdef CONFIG_SPI_IMX_VER_0_4
+ [SPI_IMX_VER_0_4] = {
+ .intctrl = mx31_intctrl,
+ .config = spi_imx0_4_config,
+ .trigger = mx31_trigger,
+ .rx_available = mx31_rx_available,
+ .reset = spi_imx0_4_reset,
+ .fifosize = 8,
+ },
+#endif
+#ifdef CONFIG_SPI_IMX_VER_0_7
+ [SPI_IMX_VER_0_7] = {
+ .intctrl = mx31_intctrl,
+ .config = spi_imx0_7_config,
+ .trigger = mx31_trigger,
+ .rx_available = mx31_rx_available,
+ .reset = spi_imx0_4_reset,
+ .fifosize = 8,
+ },
+#endif
+#ifdef CONFIG_SPI_IMX_VER_2_3
+ [SPI_IMX_VER_2_3] = {
+ .intctrl = spi_imx2_3_intctrl,
+ .config = spi_imx2_3_config,
+ .trigger = spi_imx2_3_trigger,
+ .rx_available = spi_imx2_3_rx_available,
+ .reset = spi_imx2_3_reset,
+ .fifosize = 64,
+ },
+#endif
+};
+
static void spi_imx_chipselect(struct spi_device *spi, int is_active)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
static void spi_imx_push(struct spi_imx_data *spi_imx)
{
- while (spi_imx->txfifo < 8) {
+ while (spi_imx->txfifo < spi_imx->devtype_data.fifosize) {
if (!spi_imx->count)
break;
spi_imx->tx(spi_imx);
spi_imx->txfifo++;
}
- spi_imx->trigger(spi_imx);
+ spi_imx->devtype_data.trigger(spi_imx);
}
static irqreturn_t spi_imx_isr(int irq, void *dev_id)
{
struct spi_imx_data *spi_imx = dev_id;
- while (spi_imx->rx_available(spi_imx)) {
+ while (spi_imx->devtype_data.rx_available(spi_imx)) {
spi_imx->rx(spi_imx);
spi_imx->txfifo--;
}
/* No data left to push, but still waiting for rx data,
* enable receive data available interrupt.
*/
- spi_imx->intctrl(spi_imx, MXC_INT_RR);
+ spi_imx->devtype_data.intctrl(
+ spi_imx, MXC_INT_RR);
return IRQ_HANDLED;
}
- spi_imx->intctrl(spi_imx, 0);
+ spi_imx->devtype_data.intctrl(spi_imx, 0);
complete(&spi_imx->xfer_done);
return IRQ_HANDLED;
config.bpw = t ? t->bits_per_word : spi->bits_per_word;
config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
config.mode = spi->mode;
- config.cs = spi_imx->chipselect[spi->chip_select];
+ config.cs = spi->chip_select;
if (!config.speed_hz)
config.speed_hz = spi->max_speed_hz;
} else
BUG();
- spi_imx->config(spi_imx, &config);
+ spi_imx->devtype_data.config(spi_imx, &config);
return 0;
}
spi_imx_push(spi_imx);
- spi_imx->intctrl(spi_imx, MXC_INT_TE);
+ spi_imx->devtype_data.intctrl(spi_imx, MXC_INT_TE);
wait_for_completion(&spi_imx->xfer_done);
{
}
+static struct platform_device_id spi_imx_devtype[] = {
+ {
+ .name = DRIVER_NAME,
+ .driver_data = SPI_IMX_VER_AUTODETECT,
+ }, {
+ .name = "imx1-cspi",
+ .driver_data = SPI_IMX_VER_IMX1,
+ }, {
+ .name = "imx21-cspi",
+ .driver_data = SPI_IMX_VER_0_0,
+ }, {
+ .name = "imx25-cspi",
+ .driver_data = SPI_IMX_VER_0_7,
+ }, {
+ .name = "imx27-cspi",
+ .driver_data = SPI_IMX_VER_0_0,
+ }, {
+ .name = "imx31-cspi",
+ .driver_data = SPI_IMX_VER_0_4,
+ }, {
+ .name = "imx35-cspi",
+ .driver_data = SPI_IMX_VER_0_7,
+ }, {
+ .name = "imx51-cspi",
+ .driver_data = SPI_IMX_VER_0_7,
+ }, {
+ .name = "imx51-ecspi",
+ .driver_data = SPI_IMX_VER_2_3,
+ }, {
+ /* sentinel */
+ }
+};
+
static int __devinit spi_imx_probe(struct platform_device *pdev)
{
struct spi_imx_master *mxc_platform_info;
init_completion(&spi_imx->xfer_done);
+ if (pdev->id_entry->driver_data == SPI_IMX_VER_AUTODETECT) {
+ if (cpu_is_mx25() || cpu_is_mx35())
+ spi_imx->devtype_data =
+ spi_imx_devtype_data[SPI_IMX_VER_0_7];
+ else if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35())
+ spi_imx->devtype_data =
+ spi_imx_devtype_data[SPI_IMX_VER_0_4];
+ else if (cpu_is_mx27() || cpu_is_mx21())
+ spi_imx->devtype_data =
+ spi_imx_devtype_data[SPI_IMX_VER_0_0];
+ else if (cpu_is_mx1())
+ spi_imx->devtype_data =
+ spi_imx_devtype_data[SPI_IMX_VER_IMX1];
+ else
+ BUG();
+ } else
+ spi_imx->devtype_data =
+ spi_imx_devtype_data[pdev->id_entry->driver_data];
+
+ if (!spi_imx->devtype_data.intctrl) {
+ dev_err(&pdev->dev, "no support for this device compiled in\n");
+ ret = -ENODEV;
+ goto out_gpio_free;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "can't get platform resource\n");
goto out_iounmap;
}
- if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) {
- spi_imx->intctrl = mx31_intctrl;
- spi_imx->config = mx31_config;
- spi_imx->trigger = mx31_trigger;
- spi_imx->rx_available = mx31_rx_available;
- } else if (cpu_is_mx27() || cpu_is_mx21()) {
- spi_imx->intctrl = mx27_intctrl;
- spi_imx->config = mx27_config;
- spi_imx->trigger = mx27_trigger;
- spi_imx->rx_available = mx27_rx_available;
- } else if (cpu_is_mx1()) {
- spi_imx->intctrl = mx1_intctrl;
- spi_imx->config = mx1_config;
- spi_imx->trigger = mx1_trigger;
- spi_imx->rx_available = mx1_rx_available;
- } else
- BUG();
-
spi_imx->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(spi_imx->clk)) {
dev_err(&pdev->dev, "unable to get clock\n");
clk_enable(spi_imx->clk);
spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
- if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
- writel(1, spi_imx->base + MXC_RESET);
-
- /* drain receive buffer */
- if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35())
- while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR)
- readl(spi_imx->base + MXC_CSPIRXDATA);
+ spi_imx->devtype_data.reset(spi_imx);
- spi_imx->intctrl(spi_imx, 0);
+ spi_imx->devtype_data.intctrl(spi_imx, 0);
ret = spi_bitbang_start(&spi_imx->bitbang);
if (ret) {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
+ .id_table = spi_imx_devtype,
.probe = spi_imx_probe,
.remove = __devexit_p(spi_imx_remove),
};
xfer_ofs = mspi->xfer_in_progress->len - mspi->count;
- out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs);
+ if (mspi->rx_dma == mspi->dma_dummy_rx)
+ out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma);
+ else
+ out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs);
out_be16(&rx_bd->cbd_datlen, 0);
out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP);
- out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs);
+ if (mspi->tx_dma == mspi->dma_dummy_tx)
+ out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma);
+ else
+ out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs);
out_be16(&tx_bd->cbd_datlen, xfer_len);
out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP |
BD_SC_LAST);
extern long st_register(struct st_proto_s *);
extern long st_unregister(enum proto_type);
-extern struct platform_device *st_get_plat_device(void);
#endif /* ST_H */
#include "st_ll.h"
#include "st.h"
-#define VERBOSE
/* strings to be used for rfkill entries and by
* ST Core to be used for sysfs debug entry
*/
long err = 0;
unsigned long flags = 0;
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
pr_info("%s(%d) ", __func__, new_proto->type);
if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
|| new_proto->reg_complete_cb == NULL) {
pr_debug("%s: %d ", __func__, type);
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
if (type < ST_BT || type >= ST_MAX) {
pr_err(" protocol %d not supported", type);
return -EPROTONOSUPPORT;
#endif
long len;
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
if (unlikely(skb == NULL || st_gdata == NULL
|| st_gdata->tty == NULL)) {
pr_err("data/tty unavailable to perform write");
struct st_data_s *st_gdata;
pr_info("%s ", __func__);
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
st_gdata->tty = tty;
tty->disc_data = st_gdata;
void st_core_exit(struct st_data_s *);
/* ask for reference from KIM */
-void st_kim_ref(struct st_data_s **);
+void st_kim_ref(struct st_data_s **, int);
#define GPS_STUB_TEST
#ifdef GPS_STUB_TEST
PROTO_ENTRY(ST_GPS, "GPS"),
};
+#define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */
+struct platform_device *st_kim_devices[MAX_ST_DEVICES];
/**********************************************************************/
/* internal functions */
+/**
+ * st_get_plat_device -
+ * function which returns the reference to the platform device
+ * requested by id. As of now only 1 such device exists (id=0)
+ * the context requesting for reference can get the id to be
+ * requested by a. The protocol driver which is registering or
+ * b. the tty device which is opened.
+ */
+static struct platform_device *st_get_plat_device(int id)
+{
+ return st_kim_devices[id];
+}
+
/**
* validate_firmware_response -
* function to return whether the firmware response was proper
struct kim_data_s *kim_gdata;
pr_info(" %s ", __func__);
- kim_pdev = st_get_plat_device();
+ kim_pdev = st_get_plat_device(0);
kim_gdata = dev_get_drvdata(&kim_pdev->dev);
if (kim_gdata->gpios[type] == -1) {
* This would enable multiple such platform devices to exist
* on a given platform
*/
-void st_kim_ref(struct st_data_s **core_data)
+void st_kim_ref(struct st_data_s **core_data, int id)
{
struct platform_device *pdev;
struct kim_data_s *kim_gdata;
/* get kim_gdata reference from platform device */
- pdev = st_get_plat_device();
+ pdev = st_get_plat_device(id);
kim_gdata = dev_get_drvdata(&pdev->dev);
*core_data = kim_gdata->core_data;
}
long *gpios = pdev->dev.platform_data;
struct kim_data_s *kim_gdata;
+ st_kim_devices[pdev->id] = pdev;
kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
if (!kim_gdata) {
pr_err("no mem to allocate");
If you are unsure about this, say N here.
config USB_SUSPEND
- bool "USB runtime power management (suspend/resume and wakeup)"
+ bool "USB runtime power management (autosuspend) and wakeup"
depends on USB && PM_RUNTIME
help
If you say Y here, you can use driver calls or the sysfs
- "power/level" file to suspend or resume individual USB
- peripherals and to enable or disable autosuspend (see
+ "power/control" file to enable or disable autosuspend for
+ individual USB peripherals (see
Documentation/usb/power-management.txt for more details).
Also, USB "remote wakeup" signaling is supported, whereby some
int usb_register_dev(struct usb_interface *intf,
struct usb_class_driver *class_driver)
{
- int retval = -EINVAL;
+ int retval;
int minor_base = class_driver->minor_base;
- int minor = 0;
+ int minor;
char name[20];
char *temp;
*/
minor_base = 0;
#endif
- intf->minor = -1;
-
- dbg ("looking for a minor, starting at %d", minor_base);
if (class_driver->fops == NULL)
- goto exit;
+ return -EINVAL;
+ if (intf->minor >= 0)
+ return -EADDRINUSE;
+
+ retval = init_usb_class();
+ if (retval)
+ return retval;
+
+ dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);
down_write(&minor_rwsem);
for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
continue;
usb_minors[minor] = class_driver->fops;
-
- retval = 0;
+ intf->minor = minor;
break;
}
up_write(&minor_rwsem);
-
- if (retval)
- goto exit;
-
- retval = init_usb_class();
- if (retval)
- goto exit;
-
- intf->minor = minor;
+ if (intf->minor < 0)
+ return -EXFULL;
/* create a usb class device for this usb interface */
snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
"%s", temp);
if (IS_ERR(intf->usb_dev)) {
down_write(&minor_rwsem);
- usb_minors[intf->minor] = NULL;
+ usb_minors[minor] = NULL;
+ intf->minor = -1;
up_write(&minor_rwsem);
retval = PTR_ERR(intf->usb_dev);
}
-exit:
return retval;
}
EXPORT_SYMBOL_GPL(usb_register_dev);
intf->dev.groups = usb_interface_groups;
intf->dev.dma_mask = dev->dev.dma_mask;
INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
+ intf->minor = -1;
device_initialize(&intf->dev);
dev_set_name(&intf->dev, "%d-%s:%d.%d",
dev->bus->busnum, dev->devpath,
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <mach/ohci.h>
+#include <mach/pxa3xx-u2d.h>
/*
* UHC: USB Host Controller (OHCI-like) register definitions
if (retval < 0)
return retval;
+ if (cpu_is_pxa3xx())
+ pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
+
uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
__raw_writel(uhchr, ohci->mmio_base + UHCHR);
__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
inf = dev->platform_data;
+ if (cpu_is_pxa3xx())
+ pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
+
if (inf->exit)
inf->exit(dev);
index, transmit ? 'T' : 'R', cppi_ch);
cppi_ch->hw_ep = ep;
cppi_ch->channel.status = MUSB_DMA_STATUS_FREE;
+ cppi_ch->channel.max_len = 0x7fffffff;
DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R');
return &cppi_ch->channel;
#ifndef CONFIG_MUSB_PIO_ONLY
if (is_dma_capable() && musb_ep->dma) {
struct dma_controller *c = musb->dma_controller;
+ size_t request_size;
+
+ /* setup DMA, then program endpoint CSR */
+ request_size = min_t(size_t, request->length - request->actual,
+ musb_ep->dma->max_len);
use_dma = (request->dma != DMA_ADDR_INVALID);
#ifdef CONFIG_USB_INVENTRA_DMA
{
- size_t request_size;
-
- /* setup DMA, then program endpoint CSR */
- request_size = min_t(size_t, request->length,
- musb_ep->dma->max_len);
if (request_size < musb_ep->packet_sz)
musb_ep->dma->desired_mode = 0;
else
use_dma = use_dma && c->channel_program(
musb_ep->dma, musb_ep->packet_sz,
0,
- request->dma,
- request->length);
+ request->dma + request->actual,
+ request_size);
if (!use_dma) {
c->channel_release(musb_ep->dma);
musb_ep->dma = NULL;
use_dma = use_dma && c->channel_program(
musb_ep->dma, musb_ep->packet_sz,
request->zero,
- request->dma,
- request->length);
+ request->dma + request->actual,
+ request_size);
#endif
}
#endif
request->zero = 0;
}
- /* ... or if not, then complete it. */
- musb_g_giveback(musb_ep, request, 0);
-
- /*
- * Kickstart next transfer if appropriate;
- * the packet that just completed might not
- * be transmitted for hours or days.
- * REVISIT for double buffering...
- * FIXME revisit for stalls too...
- */
- musb_ep_select(mbase, epnum);
- csr = musb_readw(epio, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_FIFONOTEMPTY)
- return;
-
- request = musb_ep->desc ? next_request(musb_ep) : NULL;
- if (!request) {
- DBG(4, "%s idle now\n",
- musb_ep->end_point.name);
- return;
+ if (request->actual == request->length) {
+ musb_g_giveback(musb_ep, request, 0);
+ request = musb_ep->desc ? next_request(musb_ep) : NULL;
+ if (!request) {
+ DBG(4, "%s idle now\n",
+ musb_ep->end_point.name);
+ return;
+ }
}
}
{
const u8 epnum = req->epnum;
struct usb_request *request = &req->request;
- struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
+ struct musb_ep *musb_ep;
void __iomem *epio = musb->endpoints[epnum].regs;
unsigned fifo_count = 0;
- u16 len = musb_ep->packet_sz;
+ u16 len;
u16 csr = musb_readw(epio, MUSB_RXCSR);
+ struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
+
+ if (hw_ep->is_shared_fifo)
+ musb_ep = &hw_ep->ep_in;
+ else
+ musb_ep = &hw_ep->ep_out;
+
+ len = musb_ep->packet_sz;
/* We shouldn't get here while DMA is active, but we do... */
if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
*/
csr |= MUSB_RXCSR_DMAENAB;
-#ifdef USE_MODE1
csr |= MUSB_RXCSR_AUTOCLEAR;
+#ifdef USE_MODE1
/* csr |= MUSB_RXCSR_DMAMODE; */
/* this special sequence (enabling and then
if (request->actual < request->length) {
int transfer_size = 0;
#ifdef USE_MODE1
- transfer_size = min(request->length,
+ transfer_size = min(request->length - request->actual,
channel->max_len);
#else
- transfer_size = len;
+ transfer_size = min(request->length - request->actual,
+ (unsigned)len);
#endif
if (transfer_size <= musb_ep->packet_sz)
musb_ep->dma->desired_mode = 0;
u16 csr;
struct usb_request *request;
void __iomem *mbase = musb->mregs;
- struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
+ struct musb_ep *musb_ep;
void __iomem *epio = musb->endpoints[epnum].regs;
struct dma_channel *dma;
+ struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
+
+ if (hw_ep->is_shared_fifo)
+ musb_ep = &hw_ep->ep_in;
+ else
+ musb_ep = &hw_ep->ep_out;
musb_ep_select(mbase, epnum);
/*
* Context: controller locked, IRQs blocked.
*/
-static void musb_ep_restart(struct musb *musb, struct musb_request *req)
+void musb_ep_restart(struct musb *musb, struct musb_request *req)
{
DBG(3, "<== %s request %p len %u on hw_ep%d\n",
req->tx ? "TX/IN" : "RX/OUT",
extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
+extern void musb_ep_restart(struct musb *, struct musb_request *);
+
#endif /* __MUSB_GADGET_H */
ctrlrequest->wIndex & 0x0f;
struct musb_ep *musb_ep;
struct musb_hw_ep *ep;
+ struct musb_request *request;
void __iomem *regs;
int is_in;
u16 csr;
musb_writew(regs, MUSB_RXCSR, csr);
}
+ /* Maybe start the first request in the queue */
+ request = to_musb_request(
+ next_request(musb_ep));
+ if (!musb_ep->busy && request) {
+ DBG(3, "restarting the request\n");
+ musb_ep_restart(musb, request);
+ }
+
/* select ep0 again */
musb_ep_select(mbase, 0);
} break;
qh->segsize = length;
+ /*
+ * Ensure the data reaches to main memory before starting
+ * DMA transfer
+ */
+ wmb();
+
if (!dma->channel_program(channel, pkt_size, mode,
urb->transfer_dma + offset, length)) {
dma->channel_release(channel);
int r, nlogs = 0;
while (datalen > 0) {
- if (unlikely(headcount >= VHOST_NET_MAX_SG)) {
+ if (unlikely(seg >= VHOST_NET_MAX_SG)) {
r = -ENOBUFS;
goto err;
}
if (r < 0)
return r;
len -= l;
- if (!len)
+ if (!len) {
+ if (vq->log_ctx)
+ eventfd_signal(vq->log_ctx, 1);
return 0;
+ }
}
- if (vq->log_ctx)
- eventfd_signal(vq->log_ctx, 1);
/* Length written exceeds what we have stored. This is a bug. */
BUG();
return 0;
softback_buf = 0UL;
for (i = 0; i < FB_MAX; i++) {
- int pending;
+ int pending = 0;
mapped = 0;
info = registered_fb[i];
if (info == NULL)
continue;
- pending = cancel_work_sync(&info->queue);
+ if (info->queue.func)
+ pending = cancel_work_sync(&info->queue);
DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" :
"no"));
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/dmi.h>
-
+#include <linux/pci.h>
#include <video/vga.h>
static struct fb_var_screeninfo efifb_defined __devinitdata = {
M_I20, /* 20-Inch iMac */
M_I20_SR, /* 20-Inch iMac (Santa Rosa) */
M_I24, /* 24-Inch iMac */
+ M_I24_8_1, /* 24-Inch iMac, 8,1th gen */
+ M_I24_10_1, /* 24-Inch iMac, 10,1th gen */
+ M_I27_11_1, /* 27-Inch iMac, 11,1th gen */
M_MINI, /* Mac Mini */
+ M_MINI_3_1, /* Mac Mini, 3,1th gen */
+ M_MINI_4_1, /* Mac Mini, 4,1th gen */
M_MB, /* MacBook */
M_MB_2, /* MacBook, 2nd rev. */
M_MB_3, /* MacBook, 3rd rev. */
+ M_MB_5_1, /* MacBook, 5th rev. */
+ M_MB_6_1, /* MacBook, 6th rev. */
+ M_MB_7_1, /* MacBook, 7th rev. */
M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
M_MBA, /* MacBook Air */
M_MBP, /* MacBook Pro */
M_MBP_2, /* MacBook Pro 2nd gen */
+ M_MBP_2_2, /* MacBook Pro 2,2nd gen */
M_MBP_SR, /* MacBook Pro (Santa Rosa) */
M_MBP_4, /* MacBook Pro, 4th gen */
M_MBP_5_1, /* MacBook Pro, 5,1th gen */
+ M_MBP_5_2, /* MacBook Pro, 5,2th gen */
+ M_MBP_5_3, /* MacBook Pro, 5,3rd gen */
+ M_MBP_6_1, /* MacBook Pro, 6,1th gen */
+ M_MBP_6_2, /* MacBook Pro, 6,2th gen */
+ M_MBP_7_1, /* MacBook Pro, 7,1th gen */
M_UNKNOWN /* placeholder */
};
[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
+ [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 },
+ [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 },
+ [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 },
[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
+ [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 },
+ [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 },
[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
+ [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 },
+ [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 },
+ [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 },
[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
+ [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 },
[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
+ [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 },
+ [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 },
+ [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 },
+ [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 },
+ [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 },
[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
};
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1),
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1),
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
/* At least one of these two will be right; maybe both? */
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
{},
};
{
struct efifb_dmi_info *info = id->driver_data;
if (info->base == 0)
- return -ENODEV;
+ return 0;
printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
"(%dx%d, stride %d)\n", id->ident,
info->stride);
/* Trust the bootloader over the DMI tables */
- if (screen_info.lfb_base == 0)
+ if (screen_info.lfb_base == 0) {
+#if defined(CONFIG_PCI)
+ struct pci_dev *dev = NULL;
+ int found_bar = 0;
+#endif
screen_info.lfb_base = info->base;
- if (screen_info.lfb_linelength == 0)
- screen_info.lfb_linelength = info->stride;
- if (screen_info.lfb_width == 0)
- screen_info.lfb_width = info->width;
- if (screen_info.lfb_height == 0)
- screen_info.lfb_height = info->height;
- if (screen_info.orig_video_isVGA == 0)
- screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
- return 0;
+#if defined(CONFIG_PCI)
+ /* make sure that the address in the table is actually on a
+ * VGA device's PCI BAR */
+
+ for_each_pci_dev(dev) {
+ int i;
+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ continue;
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ resource_size_t start, end;
+
+ start = pci_resource_start(dev, i);
+ if (start == 0)
+ break;
+ end = pci_resource_end(dev, i);
+ if (screen_info.lfb_base >= start &&
+ screen_info.lfb_base < end) {
+ found_bar = 1;
+ }
+ }
+ }
+ if (!found_bar)
+ screen_info.lfb_base = 0;
+#endif
+ }
+ if (screen_info.lfb_base) {
+ if (screen_info.lfb_linelength == 0)
+ screen_info.lfb_linelength = info->stride;
+ if (screen_info.lfb_width == 0)
+ screen_info.lfb_width = info->width;
+ if (screen_info.lfb_height == 0)
+ screen_info.lfb_height = info->height;
+ if (screen_info.orig_video_isVGA == 0)
+ screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
+ } else {
+ screen_info.lfb_linelength = 0;
+ screen_info.lfb_width = 0;
+ screen_info.lfb_height = 0;
+ screen_info.orig_video_isVGA = 0;
+ return 0;
+ }
+ return 1;
}
static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
* Set bit to enable graphics DMA.
*/
x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
- x |= fbi->active ? 0x00000100 : 0;
- fbi->active = 0;
+ x &= ~CFG_GRA_ENA_MASK;
+ x |= fbi->active ? CFG_GRA_ENA(1) : CFG_GRA_ENA(0);
/*
* If we are in a pseudo-color mode, we need to enable
return ret;
}
+static int __devexit pxa168fb_remove(struct platform_device *pdev)
+{
+ struct pxa168fb_info *fbi = platform_get_drvdata(pdev);
+ struct fb_info *info;
+ int irq;
+ unsigned int data;
+
+ if (!fbi)
+ return 0;
+
+ /* disable DMA transfer */
+ data = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
+ data &= ~CFG_GRA_ENA_MASK;
+ writel(data, fbi->reg_base + LCD_SPU_DMA_CTRL0);
+
+ info = fbi->info;
+
+ unregister_framebuffer(info);
+
+ writel(GRA_FRAME_IRQ0_ENA(0x0), fbi->reg_base + SPU_IRQ_ENA);
+
+ if (info->cmap.len)
+ fb_dealloc_cmap(&info->cmap);
+
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq, fbi);
+
+ dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+ info->screen_base, info->fix.smem_start);
+
+ iounmap(fbi->reg_base);
+
+ clk_disable(fbi->clk);
+ clk_put(fbi->clk);
+
+ framebuffer_release(info);
+
+ return 0;
+}
+
static struct platform_driver pxa168fb_driver = {
.driver = {
.name = "pxa168-fb",
.owner = THIS_MODULE,
},
.probe = pxa168fb_probe,
+ .remove = __devexit_p(pxa168fb_remove),
};
static int __init pxa168fb_init(void)
}
module_init(pxa168fb_init);
+static void __exit pxa168fb_exit(void)
+{
+ platform_driver_unregister(&pxa168fb_driver);
+}
+module_exit(pxa168fb_exit);
+
MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com> "
"Green Wan <gwan@marvell.com>");
MODULE_DESCRIPTION("Framebuffer driver for PXA168/910");
break;
case FBIOGET_VBLANK:
+
+ memset(&sisvbblank, 0, sizeof(struct fb_vblank));
+
sisvbblank.count = 0;
sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
{
int ret = 0;
- blocking_notifier_chain_register(&xenstore_chain, nb);
+ if (xenstored_ready > 0)
+ ret = nb->notifier_call(nb, 0, NULL);
+ else
+ blocking_notifier_chain_register(&xenstore_chain, nb);
return ret;
}
void xenbus_probe(struct work_struct *unused)
{
- BUG_ON((xenstored_ready <= 0));
+ xenstored_ready = 1;
/* Enumerate devices in xenstore and watch for changes. */
xenbus_probe_devices(&xenbus_frontend);
xen_store_evtchn = xen_start_info->store_evtchn;
xen_store_mfn = xen_start_info->store_mfn;
xen_store_interface = mfn_to_virt(xen_store_mfn);
+ xenstored_ready = 1;
}
- xenstored_ready = 1;
}
/* Initialize the interface to xenstore. */
*/
ret = retry(iocb);
- if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED)
+ if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
+ /*
+ * There's no easy way to restart the syscall since other AIO's
+ * may be already running. Just fail this IO with EINTR.
+ */
+ if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR ||
+ ret == -ERESTARTNOHAND || ret == -ERESTART_RESTARTBLOCK))
+ ret = -EINTR;
aio_complete(iocb, ret, 0);
+ }
out:
spin_lock_irq(&ctx->ctx_lock);
depends on INET && EXPERIMENTAL
select LIBCRC32C
select CRYPTO_AES
+ select CRYPTO
help
Choose Y or M here to include support for mounting the
experimental Ceph distributed file system. Ceph is an extremely
if (i_size < page_off + len)
len = i_size - page_off;
- dout("writepage %p page %p index %lu on %llu~%u\n",
- inode, page, page->index, page_off, len);
+ dout("writepage %p page %p index %lu on %llu~%u snapc %p\n",
+ inode, page, page->index, page_off, len, snapc);
writeback_stat = atomic_long_inc_return(&client->writeback_count);
if (writeback_stat >
/* ok */
if (locked_pages == 0) {
/* prepare async write request */
- offset = page->index << PAGE_CACHE_SHIFT;
+ offset = (unsigned long long)page->index
+ << PAGE_CACHE_SHIFT;
len = wsize;
req = ceph_osdc_new_request(&client->osdc,
&ci->i_layout,
used |= CEPH_CAP_PIN;
if (ci->i_rd_ref)
used |= CEPH_CAP_FILE_RD;
- if (ci->i_rdcache_ref || ci->i_rdcache_gen)
+ if (ci->i_rdcache_ref || ci->vfs_inode.i_data.nrpages)
used |= CEPH_CAP_FILE_CACHE;
if (ci->i_wr_ref)
used |= CEPH_CAP_FILE_WR;
* asynchronously back to the MDS once sync writes complete and dirty
* data is written out.
*
+ * Unless @again is true, skip cap_snaps that were already sent to
+ * the MDS (i.e., during this session).
+ *
* Called under i_lock. Takes s_mutex as needed.
*/
void __ceph_flush_snaps(struct ceph_inode_info *ci,
- struct ceph_mds_session **psession)
+ struct ceph_mds_session **psession,
+ int again)
__releases(ci->vfs_inode->i_lock)
__acquires(ci->vfs_inode->i_lock)
{
* pages to be written out.
*/
if (capsnap->dirty_pages || capsnap->writing)
- continue;
+ break;
/*
* if cap writeback already occurred, we should have dropped
dout("no auth cap (migrating?), doing nothing\n");
goto out;
}
+
+ /* only flush each capsnap once */
+ if (!again && !list_empty(&capsnap->flushing_item)) {
+ dout("already flushed %p, skipping\n", capsnap);
+ continue;
+ }
+
mds = ci->i_auth_cap->session->s_mds;
mseq = ci->i_auth_cap->mseq;
&session->s_cap_snaps_flushing);
spin_unlock(&inode->i_lock);
- dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
- inode, capsnap, next_follows, capsnap->size);
+ dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n",
+ inode, capsnap, capsnap->follows, capsnap->flush_tid);
send_cap_msg(session, ceph_vino(inode).ino, 0,
CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
struct inode *inode = &ci->vfs_inode;
spin_lock(&inode->i_lock);
- __ceph_flush_snaps(ci, NULL);
+ __ceph_flush_snaps(ci, NULL, 0);
spin_unlock(&inode->i_lock);
}
/* flush snaps first time around only */
if (!list_empty(&ci->i_cap_snaps))
- __ceph_flush_snaps(ci, &session);
+ __ceph_flush_snaps(ci, &session, 0);
goto retry_locked;
retry:
spin_lock(&inode->i_lock);
if (cap && cap->session == session) {
dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
cap, capsnap);
- __ceph_flush_snaps(ci, &session);
+ __ceph_flush_snaps(ci, &session, 1);
} else {
pr_err("%p auth cap %p not mds%d ???\n", inode,
cap, session->s_mds);
static void ceph_dentry_release(struct dentry *dentry)
{
struct ceph_dentry_info *di = ceph_dentry(dentry);
- struct inode *parent_inode = dentry->d_parent->d_inode;
- u64 snapid = ceph_snap(parent_inode);
+ struct inode *parent_inode = NULL;
+ u64 snapid = CEPH_NOSNAP;
+ if (!IS_ROOT(dentry)) {
+ parent_inode = dentry->d_parent->d_inode;
+ if (parent_inode)
+ snapid = ceph_snap(parent_inode);
+ }
dout("dentry_release %p parent %p\n", dentry, parent_inode);
-
if (parent_inode && snapid != CEPH_SNAPDIR) {
struct ceph_inode_info *ci = ceph_inode(parent_inode);
* the caller) if we fail.
*/
static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
- bool *prehash)
+ bool *prehash, bool set_offset)
{
struct dentry *realdn;
}
if ((!prehash || *prehash) && d_unhashed(dn))
d_rehash(dn);
- ceph_set_dentry_offset(dn);
+ if (set_offset)
+ ceph_set_dentry_offset(dn);
out:
return dn;
}
d_delete(dn);
goto done;
}
- dn = splice_dentry(dn, in, &have_lease);
+ dn = splice_dentry(dn, in, &have_lease, true);
if (IS_ERR(dn)) {
err = PTR_ERR(dn);
goto done;
goto done;
}
dout(" linking snapped dir %p to dn %p\n", in, dn);
- dn = splice_dentry(dn, in, NULL);
+ dn = splice_dentry(dn, in, NULL, true);
if (IS_ERR(dn)) {
err = PTR_ERR(dn);
goto done;
err = PTR_ERR(in);
goto out;
}
- dn = splice_dentry(dn, in, NULL);
+ dn = splice_dentry(dn, in, NULL, false);
if (IS_ERR(dn))
dn = NULL;
}
num_fcntl_locks,
num_flock_locks);
unlock_kernel();
+ } else {
+ err = ceph_pagelist_append(pagelist, &rec, reclen);
}
out_free:
#include "pagelist.h"
+static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl)
+{
+ struct page *page = list_entry(pl->head.prev, struct page,
+ lru);
+ kunmap(page);
+}
+
int ceph_pagelist_release(struct ceph_pagelist *pl)
{
if (pl->mapped_tail)
- kunmap(pl->mapped_tail);
+ ceph_pagelist_unmap_tail(pl);
+
while (!list_empty(&pl->head)) {
struct page *page = list_first_entry(&pl->head, struct page,
lru);
pl->room += PAGE_SIZE;
list_add_tail(&page->lru, &pl->head);
if (pl->mapped_tail)
- kunmap(pl->mapped_tail);
+ ceph_pagelist_unmap_tail(pl);
pl->mapped_tail = kmap(page);
return 0;
}
INIT_LIST_HEAD(&realm->children);
INIT_LIST_HEAD(&realm->child_item);
INIT_LIST_HEAD(&realm->empty_item);
+ INIT_LIST_HEAD(&realm->dirty_item);
INIT_LIST_HEAD(&realm->inodes_with_caps);
spin_lock_init(&realm->inodes_with_caps_lock);
__insert_snap_realm(&mdsc->snap_realms, realm);
INIT_LIST_HEAD(&capsnap->ci_item);
INIT_LIST_HEAD(&capsnap->flushing_item);
- capsnap->follows = snapc->seq - 1;
+ capsnap->follows = snapc->seq;
capsnap->issued = __ceph_caps_issued(ci, NULL);
capsnap->dirty = dirty;
struct ceph_snap_realm *realm;
int invalidate = 0;
int err = -ENOMEM;
+ LIST_HEAD(dirty_realms);
dout("update_snap_trace deletion=%d\n", deletion);
more:
}
}
- if (le64_to_cpu(ri->seq) > realm->seq) {
- dout("update_snap_trace updating %llx %p %lld -> %lld\n",
- realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
- /*
- * if the realm seq has changed, queue a cap_snap for every
- * inode with open caps. we do this _before_ we update
- * the realm info so that we prepare for writeback under the
- * _previous_ snap context.
- *
- * ...unless it's a snap deletion!
- */
- if (!deletion)
- queue_realm_cap_snaps(realm);
- } else {
- dout("update_snap_trace %llx %p seq %lld unchanged\n",
- realm->ino, realm, realm->seq);
- }
-
/* ensure the parent is correct */
err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent));
if (err < 0)
invalidate += err;
if (le64_to_cpu(ri->seq) > realm->seq) {
+ dout("update_snap_trace updating %llx %p %lld -> %lld\n",
+ realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
/* update realm parameters, snap lists */
realm->seq = le64_to_cpu(ri->seq);
realm->created = le64_to_cpu(ri->created);
if (err < 0)
goto fail;
+ /* queue realm for cap_snap creation */
+ list_add(&realm->dirty_item, &dirty_realms);
+
invalidate = 1;
} else if (!realm->cached_context) {
+ dout("update_snap_trace %llx %p seq %lld new\n",
+ realm->ino, realm, realm->seq);
invalidate = 1;
+ } else {
+ dout("update_snap_trace %llx %p seq %lld unchanged\n",
+ realm->ino, realm, realm->seq);
}
dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino,
if (invalidate)
rebuild_snap_realms(realm);
+ /*
+ * queue cap snaps _after_ we've built the new snap contexts,
+ * so that i_head_snapc can be set appropriately.
+ */
+ list_for_each_entry(realm, &dirty_realms, dirty_item) {
+ queue_realm_cap_snaps(realm);
+ }
+
__cleanup_empty_realms(mdsc);
return 0;
igrab(inode);
spin_unlock(&mdsc->snap_flush_lock);
spin_lock(&inode->i_lock);
- __ceph_flush_snaps(ci, &session);
+ __ceph_flush_snaps(ci, &session, 0);
spin_unlock(&inode->i_lock);
iput(inode);
spin_lock(&mdsc->snap_flush_lock);
};
struct inode *inode = ceph_find_inode(sb, vino);
struct ceph_inode_info *ci;
+ struct ceph_snap_realm *oldrealm;
if (!inode)
continue;
dout(" will move %p to split realm %llx %p\n",
inode, realm->ino, realm);
/*
- * Remove the inode from the realm's inode
- * list, but don't add it to the new realm
- * yet. We don't want the cap_snap to be
- * queued (again) by ceph_update_snap_trace()
- * below. Queue it _now_, under the old context.
+ * Move the inode to the new realm
*/
spin_lock(&realm->inodes_with_caps_lock);
list_del_init(&ci->i_snap_realm_item);
+ list_add(&ci->i_snap_realm_item,
+ &realm->inodes_with_caps);
+ oldrealm = ci->i_snap_realm;
+ ci->i_snap_realm = realm;
spin_unlock(&realm->inodes_with_caps_lock);
spin_unlock(&inode->i_lock);
- ceph_queue_cap_snap(ci);
+ ceph_get_snap_realm(mdsc, realm);
+ ceph_put_snap_realm(mdsc, oldrealm);
iput(inode);
continue;
ceph_update_snap_trace(mdsc, p, e,
op == CEPH_SNAP_OP_DESTROY);
- if (op == CEPH_SNAP_OP_SPLIT) {
- /*
- * ok, _now_ add the inodes into the new realm.
- */
- for (i = 0; i < num_split_inos; i++) {
- struct ceph_vino vino = {
- .ino = le64_to_cpu(split_inos[i]),
- .snap = CEPH_NOSNAP,
- };
- struct inode *inode = ceph_find_inode(sb, vino);
- struct ceph_inode_info *ci;
-
- if (!inode)
- continue;
- ci = ceph_inode(inode);
- spin_lock(&inode->i_lock);
- if (list_empty(&ci->i_snap_realm_item)) {
- struct ceph_snap_realm *oldrealm =
- ci->i_snap_realm;
-
- dout(" moving %p to split realm %llx %p\n",
- inode, realm->ino, realm);
- spin_lock(&realm->inodes_with_caps_lock);
- list_add(&ci->i_snap_realm_item,
- &realm->inodes_with_caps);
- ci->i_snap_realm = realm;
- spin_unlock(&realm->inodes_with_caps_lock);
- ceph_get_snap_realm(mdsc, realm);
- ceph_put_snap_realm(mdsc, oldrealm);
- }
- spin_unlock(&inode->i_lock);
- iput(inode);
- }
-
+ if (op == CEPH_SNAP_OP_SPLIT)
/* we took a reference when we created the realm, above */
ceph_put_snap_realm(mdsc, realm);
- }
__cleanup_empty_realms(mdsc);
struct list_head empty_item; /* if i have ref==0 */
+ struct list_head dirty_item; /* if realm needs new context */
+
/* the current set of snaps for this realm */
struct ceph_snap_context *cached_context;
extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
struct ceph_snap_context *snapc);
extern void __ceph_flush_snaps(struct ceph_inode_info *ci,
- struct ceph_mds_session **psession);
+ struct ceph_mds_session **psession,
+ int again);
extern void ceph_check_caps(struct ceph_inode_info *ci, int flags,
struct ceph_mds_session *session);
extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc);
#endif
/* permit direct mmap, for read, write or exec */
BDI_CAP_MAP_DIRECT |
- BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP),
+ BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP |
+ /* no writeback happens */
+ BDI_CAP_NO_ACCT_AND_WRITEBACK),
};
static struct kobj_map *cdev_map;
small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
void **request_buf)
{
- int rc = 0;
+ int rc;
rc = cifs_reconnect_tcon(tcon, smb_command);
if (rc)
if (tcon != NULL)
cifs_stats_inc(&tcon->num_smbs_sent);
- return rc;
+ return 0;
}
int
/* If the return code is zero, this function must fill in request_buf pointer */
static int
-smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
- void **request_buf /* returned */ ,
- void **response_buf /* returned */ )
+__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+ void **request_buf, void **response_buf)
{
- int rc = 0;
-
- rc = cifs_reconnect_tcon(tcon, smb_command);
- if (rc)
- return rc;
-
*request_buf = cifs_buf_get();
if (*request_buf == NULL) {
/* BB should we add a retry in here if not a writepage? */
if (tcon != NULL)
cifs_stats_inc(&tcon->num_smbs_sent);
- return rc;
+ return 0;
+}
+
+/* If the return code is zero, this function must fill in request_buf pointer */
+static int
+smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+ void **request_buf, void **response_buf)
+{
+ int rc;
+
+ rc = cifs_reconnect_tcon(tcon, smb_command);
+ if (rc)
+ return rc;
+
+ return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
+}
+
+static int
+smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
+ void **request_buf, void **response_buf)
+{
+ if (tcon->ses->need_reconnect || tcon->need_reconnect)
+ return -EHOSTDOWN;
+
+ return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
}
static int validate_t2(struct smb_t2_rsp *pSMB)
cFYI(1, "In QFSUnixInfo");
QFSUnixRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
+ rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
+ (void **) &pSMB, (void **) &pSMBr);
if (rc)
return rc;
cFYI(1, "In SETFSUnixInfo");
SETFSUnixRetry:
/* BB switch to small buf init to save memory */
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
+ rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
+ (void **) &pSMB, (void **) &pSMBr);
if (rc)
return rc;
inode->i_flags |= S_NOATIME | S_NOCMTIME;
if (inode->i_state & I_NEW) {
inode->i_ino = hash;
+ if (S_ISREG(inode->i_mode))
+ inode->i_data.backing_dev_info = sb->s_bdi;
#ifdef CONFIG_CIFS_FSCACHE
/* initialize per-inode cache cookie pointer */
CIFS_I(inode)->fscache = NULL;
{
compat_ssize_t tot_len;
struct iovec iovstack[UIO_FASTIOV];
- struct iovec *iov;
+ struct iovec *iov = iovstack;
ssize_t ret;
io_fn_t fn;
iov_fn_t fnv;
#define CREATE_TRACE_POINTS
#include <trace/events/writeback.h>
-#define inode_to_bdi(inode) ((inode)->i_mapping->backing_dev_info)
-
/*
* We don't actually have pdflush, but this one is exported though /proc...
*/
return test_bit(BDI_writeback_running, &bdi->state);
}
+static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+
+ if (strcmp(sb->s_type->name, "bdev") == 0)
+ return inode->i_mapping->backing_dev_info;
+
+ return sb->s_bdi;
+}
+
static void bdi_queue_work(struct backing_dev_info *bdi,
struct wb_writeback_work *work)
{
loff_t file_size;
unsigned int num;
unsigned int offset;
- size_t total_len;
+ size_t total_len = 0;
req = fuse_get_req(fc);
if (IS_ERR(req))
}
inode->i_mode = new_mode;
+ inode->i_ctime = CURRENT_TIME;
di->i_mode = cpu_to_le16(inode->i_mode);
+ di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
+ di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
ocfs2_journal_dirty(handle, di_bh);
int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
size_t caller_veclen, u8 target_node, int *status)
{
- int ret;
+ int ret = 0;
struct o2net_msg *msg = NULL;
size_t veclen, caller_bytes = 0;
struct kvec *vec = NULL;
goto out_commit;
}
+ cpos = split_hash;
+ ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle,
+ data_ac, meta_ac, new_dx_leaves,
+ num_dx_leaves);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
for (i = 0; i < num_dx_leaves; i++) {
ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir),
orig_dx_leaves[i],
mlog_errno(ret);
goto out_commit;
}
- }
- cpos = split_hash;
- ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle,
- data_ac, meta_ac, new_dx_leaves,
- num_dx_leaves);
- if (ret) {
- mlog_errno(ret);
- goto out_commit;
+ ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir),
+ new_dx_leaves[i],
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
}
ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf,
struct dlm_lock_resource *res);
void dlm_clean_master_list(struct dlm_ctxt *dlm,
u8 dead_node);
+void dlm_force_free_mles(struct dlm_ctxt *dlm);
int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
int __dlm_lockres_has_locks(struct dlm_lock_resource *res);
int __dlm_lockres_unused(struct dlm_lock_resource *res);
spin_lock(&dlm->track_lock);
if (oldres)
track_list = &oldres->tracking;
- else
+ else {
track_list = &dlm->tracking_list;
+ if (list_empty(track_list)) {
+ dl = NULL;
+ spin_unlock(&dlm->track_lock);
+ goto bail;
+ }
+ }
list_for_each_entry(res, track_list, tracking) {
if (&res->tracking == &dlm->tracking_list)
} else
dl = NULL;
+bail:
/* passed to seq_show */
return dl;
}
dlm_mark_domain_leaving(dlm);
dlm_leave_domain(dlm);
+ dlm_force_free_mles(dlm);
dlm_complete_dlm_shutdown(dlm);
}
dlm_put(dlm);
wake_up(&res->wq);
wake_up(&dlm->migration_wq);
}
+
+void dlm_force_free_mles(struct dlm_ctxt *dlm)
+{
+ int i;
+ struct hlist_head *bucket;
+ struct dlm_master_list_entry *mle;
+ struct hlist_node *tmp, *list;
+
+ /*
+ * We notified all other nodes that we are exiting the domain and
+ * marked the dlm state to DLM_CTXT_LEAVING. If any mles are still
+ * around we force free them and wake any processes that are waiting
+ * on the mles
+ */
+ spin_lock(&dlm->spinlock);
+ spin_lock(&dlm->master_lock);
+
+ BUG_ON(dlm->dlm_state != DLM_CTXT_LEAVING);
+ BUG_ON((find_next_bit(dlm->domain_map, O2NM_MAX_NODES, 0) < O2NM_MAX_NODES));
+
+ for (i = 0; i < DLM_HASH_BUCKETS; i++) {
+ bucket = dlm_master_hash(dlm, i);
+ hlist_for_each_safe(list, tmp, bucket) {
+ mle = hlist_entry(list, struct dlm_master_list_entry,
+ master_hash_node);
+ if (mle->type != DLM_MLE_BLOCK) {
+ mlog(ML_ERROR, "bad mle: %p\n", mle);
+ dlm_print_one_mle(mle);
+ }
+ atomic_set(&mle->woken, 1);
+ wake_up(&mle->wq);
+
+ __dlm_unlink_mle(dlm, mle);
+ __dlm_mle_detach_hb_events(dlm, mle);
+ __dlm_put_mle(mle);
+ }
+ }
+ spin_unlock(&dlm->master_lock);
+ spin_unlock(&dlm->spinlock);
+}
OI_LS_PARENT,
OI_LS_RENAME1,
OI_LS_RENAME2,
+ OI_LS_REFLINK_TARGET,
};
int ocfs2_dlm_init(struct ocfs2_super *osb);
#define OCFS2_HAS_REFCOUNT_FL (0x0010)
/* Inode attributes, keep in sync with EXT2 */
-#define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */
-#define OCFS2_UNRM_FL (0x00000002) /* Undelete */
-#define OCFS2_COMPR_FL (0x00000004) /* Compress file */
-#define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */
-#define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */
-#define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */
-#define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */
-#define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */
-#define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */
-
-#define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */
-#define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */
+#define OCFS2_SECRM_FL FS_SECRM_FL /* Secure deletion */
+#define OCFS2_UNRM_FL FS_UNRM_FL /* Undelete */
+#define OCFS2_COMPR_FL FS_COMPR_FL /* Compress file */
+#define OCFS2_SYNC_FL FS_SYNC_FL /* Synchronous updates */
+#define OCFS2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */
+#define OCFS2_APPEND_FL FS_APPEND_FL /* writes to file may only append */
+#define OCFS2_NODUMP_FL FS_NODUMP_FL /* do not dump file */
+#define OCFS2_NOATIME_FL FS_NOATIME_FL /* do not update atime */
+/* Reserved for compression usage... */
+#define OCFS2_DIRTY_FL FS_DIRTY_FL
+#define OCFS2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */
+#define OCFS2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */
+#define OCFS2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */
+/* End compression flags --- maybe not all used */
+#define OCFS2_BTREE_FL FS_BTREE_FL /* btree format dir */
+#define OCFS2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */
+#define OCFS2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */
+#define OCFS2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */
+#define OCFS2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
+#define OCFS2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
+#define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
+#define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
+
+#define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
+#define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
/*
* Extent record flags (e_node.leaf.flags)
/*
* ioctl commands
*/
-#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long)
-#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long)
-#define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int)
-#define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int)
+#define OCFS2_IOC_GETFLAGS FS_IOC_GETFLAGS
+#define OCFS2_IOC_SETFLAGS FS_IOC_SETFLAGS
+#define OCFS2_IOC32_GETFLAGS FS_IOC32_GETFLAGS
+#define OCFS2_IOC32_SETFLAGS FS_IOC32_SETFLAGS
/*
* Space reservation / allocation / free ioctls and argument structure
goto out;
}
- mutex_lock(&new_inode->i_mutex);
- ret = ocfs2_inode_lock(new_inode, &new_bh, 1);
+ mutex_lock_nested(&new_inode->i_mutex, I_MUTEX_CHILD);
+ ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1,
+ OI_LS_REFLINK_TARGET);
if (ret) {
mlog_errno(ret);
goto out_unlock;
struct ocfs2_alloc_reservation *resv,
int *cstart, int *clen)
{
- unsigned int wanted = *clen;
-
if (resv == NULL || ocfs2_resmap_disabled(resmap))
return -ENOSPC;
spin_lock(&resv_lock);
- /*
- * We don't want to over-allocate for temporary
- * windows. Otherwise, we run the risk of fragmenting the
- * allocation space.
- */
- wanted = ocfs2_resv_window_bits(resmap, resv);
- if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen)
- wanted = *clen;
-
if (ocfs2_resv_empty(resv)) {
- mlog(0, "empty reservation, find new window\n");
+ /*
+ * We don't want to over-allocate for temporary
+ * windows. Otherwise, we run the risk of fragmenting the
+ * allocation space.
+ */
+ unsigned int wanted = ocfs2_resv_window_bits(resmap, resv);
+ if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen)
+ wanted = *clen;
+
+ mlog(0, "empty reservation, find new window\n");
/*
* Try to get a window here. If it works, we must fall
* through and test the bitmap . This avoids some
static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb,
struct ocfs2_group_desc *bg,
struct ocfs2_chain_list *cl,
- u64 p_blkno, u32 clusters)
+ u64 p_blkno, unsigned int clusters)
{
struct ocfs2_extent_list *el = &bg->bg_list;
struct ocfs2_extent_rec *rec;
rec->e_blkno = cpu_to_le64(p_blkno);
rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) /
le16_to_cpu(cl->cl_bpc));
- rec->e_leaf_clusters = cpu_to_le32(clusters);
+ rec->e_leaf_clusters = cpu_to_le16(clusters);
le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc));
le16_add_cpu(&bg->bg_free_bits_count,
clusters * le16_to_cpu(cl->cl_bpc));
}
/* Fast symlinks can't be large */
- len = strlen(target);
+ len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb));
link = kzalloc(len + 1, GFP_NOFS);
if (!link) {
status = -ENOMEM;
xis.inode_bh = xbs.inode_bh = di_bh;
di = (struct ocfs2_dinode *)di_bh->b_data;
- down_read(&oi->ip_xattr_sem);
ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer,
buffer_size, &xis);
if (ret == -ENODATA && di->i_xattr_loc)
ret = ocfs2_xattr_block_get(inode, name_index, name, buffer,
buffer_size, &xbs);
- up_read(&oi->ip_xattr_sem);
return ret;
}
mlog_errno(ret);
return ret;
}
+ down_read(&OCFS2_I(inode)->ip_xattr_sem);
ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index,
name, buffer, buffer_size);
+ up_read(&OCFS2_I(inode)->ip_xattr_sem);
ocfs2_inode_unlock(inode, 0);
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUSR, proc_pid_personality),
- INF("limits", S_IRUSR, proc_pid_limits),
+ INF("limits", S_IRUGO, proc_pid_limits),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUSR, proc_pid_personality),
- INF("limits", S_IRUSR, proc_pid_limits),
+ INF("limits", S_IRUGO, proc_pid_limits),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
mss->referenced += PAGE_SIZE;
mapcount = page_mapcount(page);
if (mapcount >= 2) {
- if (pte_dirty(ptent))
+ if (pte_dirty(ptent) || PageDirty(page))
mss->shared_dirty += PAGE_SIZE;
else
mss->shared_clean += PAGE_SIZE;
mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount;
} else {
- if (pte_dirty(ptent))
+ if (pte_dirty(ptent) || PageDirty(page))
mss->private_dirty += PAGE_SIZE;
else
mss->private_clean += PAGE_SIZE;
static const struct file_operations proc_vmcore_operations = {
.read = read_vmcore,
- .llseek = generic_file_llseek,
+ .llseek = default_llseek,
};
static struct vmcore* __init get_new_element(void)
int reiserfs_unpack(struct inode *inode, struct file *filp)
{
int retval = 0;
+ int depth;
int index;
struct page *page;
struct address_space *mapping;
/* we need to make sure nobody is changing the file size beneath
** us
*/
- mutex_lock(&inode->i_mutex);
- reiserfs_write_lock(inode->i_sb);
+ reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb);
+ depth = reiserfs_write_lock_once(inode->i_sb);
write_from = inode->i_size & (blocksize - 1);
/* if we are on a block boundary, we are already unpacked. */
out:
mutex_unlock(&inode->i_mutex);
- reiserfs_write_unlock(inode->i_sb);
+ reiserfs_write_unlock_once(inode->i_sb, depth);
return retval;
}
new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS);
new_ctx->ticket = xlog_cil_ticket_alloc(log);
- /* lock out transaction commit, but don't block on background push */
+ /*
+ * Lock out transaction commit, but don't block for background pushes
+ * unless we are well over the CIL space limit. See the definition of
+ * XLOG_CIL_HARD_SPACE_LIMIT() for the full explanation of the logic
+ * used here.
+ */
if (!down_write_trylock(&cil->xc_ctx_lock)) {
- if (!push_seq)
+ if (!push_seq &&
+ cil->xc_ctx->space_used < XLOG_CIL_HARD_SPACE_LIMIT(log))
goto out_free_ticket;
down_write(&cil->xc_ctx_lock);
}
goto out_skip;
/* check for a previously pushed seqeunce */
- if (push_seq < cil->xc_ctx->sequence)
+ if (push_seq && push_seq < cil->xc_ctx->sequence)
goto out_skip;
/*
};
/*
- * The amount of log space we should the CIL to aggregate is difficult to size.
- * Whatever we chose we have to make we can get a reservation for the log space
- * effectively, that it is large enough to capture sufficient relogging to
- * reduce log buffer IO significantly, but it is not too large for the log or
- * induces too much latency when writing out through the iclogs. We track both
- * space consumed and the number of vectors in the checkpoint context, so we
- * need to decide which to use for limiting.
+ * The amount of log space we allow the CIL to aggregate is difficult to size.
+ * Whatever we choose, we have to make sure we can get a reservation for the
+ * log space effectively, that it is large enough to capture sufficient
+ * relogging to reduce log buffer IO significantly, but it is not too large for
+ * the log or induces too much latency when writing out through the iclogs. We
+ * track both space consumed and the number of vectors in the checkpoint
+ * context, so we need to decide which to use for limiting.
*
* Every log buffer we write out during a push needs a header reserved, which
* is at least one sector and more for v2 logs. Hence we need a reservation of
* checkpoint transaction ticket is specific to the checkpoint context, rather
* than the CIL itself.
*
- * With dynamic reservations, we can basically make up arbitrary limits for the
- * checkpoint size so long as they don't violate any other size rules. Hence
- * the initial maximum size for the checkpoint transaction will be set to a
- * quarter of the log or 8MB, which ever is smaller. 8MB is an arbitrary limit
- * right now based on the latency of writing out a large amount of data through
- * the circular iclog buffers.
+ * With dynamic reservations, we can effectively make up arbitrary limits for
+ * the checkpoint size so long as they don't violate any other size rules.
+ * Recovery imposes a rule that no transaction exceed half the log, so we are
+ * limited by that. Furthermore, the log transaction reservation subsystem
+ * tries to keep 25% of the log free, so we need to keep below that limit or we
+ * risk running out of free log space to start any new transactions.
+ *
+ * In order to keep background CIL push efficient, we will set a lower
+ * threshold at which background pushing is attempted without blocking current
+ * transaction commits. A separate, higher bound defines when CIL pushes are
+ * enforced to ensure we stay within our maximum checkpoint size bounds.
+ * threshold, yet give us plenty of space for aggregation on large logs.
*/
-
-#define XLOG_CIL_SPACE_LIMIT(log) \
- (min((log->l_logsize >> 2), (8 * 1024 * 1024)))
+#define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3)
+#define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4))
/*
* The reservation head lsn is not made up of a cycle number and block number.
extern u8 acpi_gbl_permanent_mmap;
/*
- * Globals that are publically available, allowing for
+ * Globals that are publicly available, allowing for
* run time configuration
*/
extern u32 acpi_dbg_level;
struct kref refcount;
/** Handle count of this object. Each handle also holds a reference */
- struct kref handlecount;
+ atomic_t handle_count; /* number of handles on this object */
/** Related drm device */
struct drm_device *dev;
*/
int (*gem_init_object) (struct drm_gem_object *obj);
void (*gem_free_object) (struct drm_gem_object *obj);
- void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
/* vga arb irq handler */
void (*vgaarb_irq)(struct drm_device *dev, bool state);
extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma);
extern void drm_vm_open_locked(struct vm_area_struct *vma);
+extern void drm_vm_close_locked(struct vm_area_struct *vma);
extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map);
extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev);
extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
void drm_gem_destroy(struct drm_device *dev);
void drm_gem_object_release(struct drm_gem_object *obj);
void drm_gem_object_free(struct kref *kref);
-void drm_gem_object_free_unlocked(struct kref *kref);
struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
size_t size);
int drm_gem_object_init(struct drm_device *dev,
struct drm_gem_object *obj, size_t size);
-void drm_gem_object_handle_free(struct kref *kref);
+void drm_gem_object_handle_free(struct drm_gem_object *obj);
void drm_gem_vm_open(struct vm_area_struct *vma);
void drm_gem_vm_close(struct vm_area_struct *vma);
int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
static inline void
drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
{
- if (obj != NULL)
- kref_put(&obj->refcount, drm_gem_object_free_unlocked);
+ if (obj != NULL) {
+ struct drm_device *dev = obj->dev;
+ mutex_lock(&dev->struct_mutex);
+ kref_put(&obj->refcount, drm_gem_object_free);
+ mutex_unlock(&dev->struct_mutex);
+ }
}
int drm_gem_handle_create(struct drm_file *file_priv,
drm_gem_object_handle_reference(struct drm_gem_object *obj)
{
drm_gem_object_reference(obj);
- kref_get(&obj->handlecount);
+ atomic_inc(&obj->handle_count);
}
static inline void
if (obj == NULL)
return;
+ if (atomic_read(&obj->handle_count) == 0)
+ return;
/*
* Must bump handle count first as this may be the last
* ref, in which case the object would disappear before we
* checked for a name
*/
- kref_put(&obj->handlecount, drm_gem_object_handle_free);
+ if (atomic_dec_and_test(&obj->handle_count))
+ drm_gem_object_handle_free(obj);
drm_gem_object_unreference(obj);
}
if (obj == NULL)
return;
+ if (atomic_read(&obj->handle_count) == 0)
+ return;
+
/*
* Must bump handle count first as this may be the last
* ref, in which case the object would disappear before we
* checked for a name
*/
- kref_put(&obj->handlecount, drm_gem_object_handle_free);
+
+ if (atomic_dec_and_test(&obj->handle_count))
+ drm_gem_object_handle_free(obj);
drm_gem_object_unreference_unlocked(obj);
}
{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
- {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
{0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
{0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
{0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
#define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */
#define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */
#define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */
+#define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */
#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
return DMA_BIT_MASK(32);
}
+#ifdef ARCH_HAS_DMA_SET_COHERENT_MASK
+int dma_set_coherent_mask(struct device *dev, u64 mask);
+#else
static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
{
if (!dma_supported(dev, mask))
dev->coherent_dma_mask = mask;
return 0;
}
+#endif
extern u64 dma_get_required_mask(struct device *dev);
return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE;
}
-static unsigned short dma_dev_to_maxpq(struct dma_device *dma)
+static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma)
{
return dma->max_pq & ~DMA_HAS_PQ_CONTINUE;
}
#include <linux/fcntl.h>
+/* temporary stubs for BKL removal */
+#define lock_flocks() lock_kernel()
+#define unlock_flocks() unlock_kernel()
+
extern void send_sigio(struct fown_struct *fown, int fd, int band);
#ifdef CONFIG_FILE_LOCKING
#ifdef CONFIG_GENERIC_BUG
-int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *,
struct module *);
void module_bug_cleanup(struct module *);
#else /* !CONFIG_GENERIC_BUG */
-static inline int module_bug_finalize(const Elf_Ehdr *hdr,
+static inline void module_bug_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *mod)
{
- return 0;
}
static inline void module_bug_cleanup(struct module *mod) {}
#endif /* CONFIG_GENERIC_BUG */
#define MAX_LINKS 32
-struct net;
-
struct sockaddr_nl {
sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* zero */
#include <linux/capability.h>
#include <linux/skbuff.h>
+struct net;
+
static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
{
return (struct nlmsghdr *)skb->data;
#define PCI_DEVICE_ID_VLSI_82C147 0x0105
#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702
+/* AMD RD890 Chipset */
+#define PCI_DEVICE_ID_RD890_IOMMU 0x5a23
+
#define PCI_VENDOR_ID_ADL 0x1005
#define PCI_DEVICE_ID_ADL_2301 0x2301
* Makes rcu_dereference_check() do the dirty work.
*/
#define rcu_dereference_bh(p) \
- rcu_dereference_check(p, rcu_read_lock_bh_held())
+ rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled())
/**
* rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched
int offset,
unsigned int len, __wsum *csump);
-extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
+extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
int offset, int len);
(wait)->private = current; \
(wait)->func = autoremove_wake_function; \
INIT_LIST_HEAD(&(wait)->task_list); \
+ (wait)->flags = 0; \
} while (0)
/**
* IPv6 Address Label subsystem (addrlabel.c)
*/
extern int ipv6_addr_label_init(void);
+extern void ipv6_addr_label_cleanup(void);
extern void ipv6_addr_label_rtnl_register(void);
extern u32 ipv6_addr_label(struct net *net,
const struct in6_addr *addr,
dev->stats.rx_packets++;
dev->stats.rx_bytes += skb->len;
skb->rxhash = 0;
+ skb_set_queue_mapping(skb, 0);
skb_dst_drop(skb);
nf_reset(skb);
}
fl.fl_ip_sport = sport;
fl.fl_ip_dport = dport;
fl.proto = protocol;
+ if (inet_sk(sk)->transparent)
+ fl.flags |= FLOWI_FLAG_ANYSRC;
ip_rt_put(*rp);
*rp = NULL;
security_sk_classify_flow(sk, &fl);
const struct xfrm_type *type_map[IPPROTO_MAX];
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
int (*init_flags)(struct xfrm_state *x);
- void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
+ void (*init_tempsel)(struct xfrm_selector *sel, struct flowi *fl);
+ void (*init_temprop)(struct xfrm_state *x, struct xfrm_tmpl *tmpl,
xfrm_address_t *daddr, xfrm_address_t *saddr);
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
{
struct semid_ds out;
+ memset(&out, 0, sizeof(out));
+
ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm);
out.sem_otime = in->sem_otime;
if (IS_ERR(pol))
goto fail_nomem_policy;
vma_set_policy(tmp, pol);
+ tmp->vm_mm = mm;
if (anon_vma_fork(tmp, mpnt))
goto fail_nomem_anon_vma_fork;
tmp->vm_flags &= ~VM_LOCKED;
- tmp->vm_mm = mm;
tmp->vm_next = tmp->vm_prev = NULL;
file = tmp->vm_file;
if (file) {
perf_overflow_handler_t triggered,
struct task_struct *tsk)
{
- return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered);
+ return perf_event_create_kernel_counter(attr, -1, task_pid_vnr(tsk),
+ triggered);
}
EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
n = setup_sgl_buf(sgl, fifo->data + off, nents, l);
n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l);
- if (n)
- sg_mark_end(sgl + n - 1);
return n;
}
{
struct module *mod = _mod;
list_del(&mod->list);
+ module_bug_cleanup(mod);
return 0;
}
if (err < 0)
goto ddebug;
+ module_bug_finalize(info.hdr, info.sechdrs, mod);
list_add_rcu(&mod->list, &modules);
mutex_unlock(&module_mutex);
mutex_lock(&module_mutex);
/* Unlink carefully: kallsyms could be walking list. */
list_del_rcu(&mod->list);
+ module_bug_cleanup(mod);
+
ddebug:
if (!mod->taints)
dynamic_debug_remove(info.debug);
rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
if (total) {
- u64 temp;
+ u64 temp = rtime;
- temp = (u64)(rtime * utime);
+ temp *= utime;
do_div(temp, total);
utime = (cputime_t)temp;
} else
rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
if (total) {
- u64 temp;
+ u64 temp = rtime;
- temp = (u64)(rtime * cputime.utime);
+ temp *= cputime.utime;
do_div(temp, total);
utime = (cputime_t)temp;
} else
if (time_before(now, nohz.next_balance))
return 0;
- if (!rq->nr_running)
+ if (rq->idle_at_tick)
return 0;
first_pick_cpu = atomic_read(&nohz.first_pick_cpu);
EXPORT_SYMBOL_GPL(smp_call_function_any);
/**
- * __smp_call_function_single(): Run a function on another CPU
+ * __smp_call_function_single(): Run a function on a specific CPU
* @cpu: The CPU to run on.
* @data: Pre-allocated and setup data structure
+ * @wait: If true, wait until function has completed on specified CPU.
*
* Like smp_call_function_single(), but allow caller to pass in a
* pre-allocated data structure. Useful for embedding @data inside
void __smp_call_function_single(int cpu, struct call_single_data *data,
int wait)
{
- csd_lock(data);
+ unsigned int this_cpu;
+ unsigned long flags;
+ this_cpu = get_cpu();
/*
* Can deadlock when called with interrupts disabled.
* We allow cpu's that are not yet online though, as no one else can
WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled()
&& !oops_in_progress);
- generic_exec_single(cpu, data, wait);
+ if (cpu == this_cpu) {
+ local_irq_save(flags);
+ data->func(data->info);
+ local_irq_restore(flags);
+ } else {
+ csd_lock(data);
+ generic_exec_single(cpu, data, wait);
+ }
+ put_cpu();
}
/**
return NULL;
}
-int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
- struct module *mod)
+void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ struct module *mod)
{
char *secstrings;
unsigned int i;
* could potentially lead to deadlock and thus be counter-productive.
*/
list_add(&mod->bug_list, &module_bug_list);
-
- return 0;
}
void module_bug_cleanup(struct module *mod)
* element comparison is needed, so the client's cmp()
* routine can invoke cond_resched() periodically.
*/
- (*cmp)(priv, tail, tail);
+ (*cmp)(priv, tail->next, tail->next);
tail->next->prev = tail;
tail = tail->next;
struct backing_dev_info noop_backing_dev_info = {
.name = "noop",
+ .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
};
EXPORT_SYMBOL_GPL(noop_backing_dev_info);
err = bdi_init(&default_backing_dev_info);
if (!err)
bdi_register(&default_backing_dev_info, NULL, "default");
+ err = bdi_init(&noop_backing_dev_info);
return err;
}
{
struct mm_struct *mm = current->mm;
struct address_space *mapping;
- unsigned long end = start + size;
struct vm_area_struct *vma;
int err = -EINVAL;
int has_write_lock = 0;
if (start + size <= start)
return err;
+ /* Does pgoff wrap? */
+ if (pgoff + (size >> PAGE_SHIFT) < pgoff)
+ return err;
+
/* Can we represent this offset inside this architecture's pte's? */
#if PTE_FILE_MAX_BITS < BITS_PER_LONG
if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS))
if (!(vma->vm_flags & VM_CAN_NONLINEAR))
goto out;
- if (end <= start || start < vma->vm_start || end > vma->vm_end)
+ if (start < vma->vm_start || start + size > vma->vm_end)
goto out;
/* Must set VM_NONLINEAR before any pages are populated. */
* and just make the page writable */
avoidcopy = (page_mapcount(old_page) == 1);
if (avoidcopy) {
- if (!trylock_page(old_page)) {
- if (PageAnon(old_page))
- page_move_anon_rmap(old_page, vma, address);
- } else
- unlock_page(old_page);
+ if (PageAnon(old_page))
+ page_move_anon_rmap(old_page, vma, address);
set_huge_ptep_writable(vma, address, ptep);
return 0;
}
set_huge_pte_at(mm, address, ptep,
make_huge_pte(vma, new_page, 1));
page_remove_rmap(old_page);
- hugepage_add_anon_rmap(new_page, vma, address);
+ hugepage_add_new_anon_rmap(new_page, vma, address);
/* Make the old page be freed below */
new_page = old_page;
mmu_notifier_invalidate_range_end(mm,
vma, address);
}
- if (!pagecache_page) {
- page = pte_page(entry);
+ /*
+ * hugetlb_cow() requires page locks of pte_page(entry) and
+ * pagecache_page, so here we need take the former one
+ * when page != pagecache_page or !pagecache_page.
+ * Note that locking order is always pagecache_page -> page,
+ * so no worry about deadlock.
+ */
+ page = pte_page(entry);
+ if (page != pagecache_page)
lock_page(page);
- }
spin_lock(&mm->page_table_lock);
/* Check for a racing update before calling hugetlb_cow */
if (pagecache_page) {
unlock_page(pagecache_page);
put_page(pagecache_page);
- } else {
- unlock_page(page);
}
+ unlock_page(page);
out_mutex:
mutex_unlock(&hugetlb_instantiation_mutex);
if (!ptep)
goto out;
- if (pte_write(*ptep)) {
+ if (pte_write(*ptep) || pte_dirty(*ptep)) {
pte_t entry;
swapped = PageSwapCache(page);
set_pte_at(mm, addr, ptep, entry);
goto out_unlock;
}
- entry = pte_wrprotect(entry);
+ if (pte_dirty(entry))
+ set_page_dirty(page);
+ entry = pte_mkclean(pte_wrprotect(entry));
set_pte_at_notify(mm, addr, ptep, entry);
}
*orig_pte = *ptep;
removed_exe_file_vma(mm);
fput(new->vm_file);
}
+ unlink_anon_vmas(new);
out_free_mpol:
mpol_put(pol);
out_free_vma:
}
/* return true if the task is not adequate as candidate victim task. */
-static bool oom_unkillable_task(struct task_struct *p, struct mem_cgroup *mem,
- const nodemask_t *nodemask)
+static bool oom_unkillable_task(struct task_struct *p,
+ const struct mem_cgroup *mem, const nodemask_t *nodemask)
{
if (is_global_init(p))
return true;
*/
points += p->signal->oom_score_adj;
- if (points < 0)
- return 0;
+ /*
+ * Never return 0 for an eligible task that may be killed since it's
+ * possible that no single user task uses more than 0.1% of memory and
+ * no single admin tasks uses more than 3.0%.
+ */
+ if (points <= 0)
+ return 1;
return (points < 1000) ? points : 1000;
}
/**
* dump_tasks - dump current memory state of all system tasks
* @mem: current's memory controller, if constrained
+ * @nodemask: nodemask passed to page allocator for mempolicy ooms
*
- * Dumps the current memory state of all system tasks, excluding kernel threads.
+ * Dumps the current memory state of all eligible tasks. Tasks not in the same
+ * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes
+ * are not shown.
* State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj
* value, oom_score_adj value, and name.
*
- * If the actual is non-NULL, only tasks that are a member of the mem_cgroup are
- * shown.
- *
* Call with tasklist_lock read-locked.
*/
-static void dump_tasks(const struct mem_cgroup *mem)
+static void dump_tasks(const struct mem_cgroup *mem, const nodemask_t *nodemask)
{
struct task_struct *p;
struct task_struct *task;
pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n");
for_each_process(p) {
- if (p->flags & PF_KTHREAD)
- continue;
- if (mem && !task_in_mem_cgroup(p, mem))
+ if (oom_unkillable_task(p, mem, nodemask))
continue;
task = find_lock_task_mm(p);
}
static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
- struct mem_cgroup *mem)
+ struct mem_cgroup *mem, const nodemask_t *nodemask)
{
task_lock(current);
pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
mem_cgroup_print_oom_info(mem, p);
show_mem();
if (sysctl_oom_dump_tasks)
- dump_tasks(mem);
+ dump_tasks(mem, nodemask);
}
#define K(x) ((x) << (PAGE_SHIFT-10))
unsigned int victim_points = 0;
if (printk_ratelimit())
- dump_header(p, gfp_mask, order, mem);
+ dump_header(p, gfp_mask, order, mem, nodemask);
/*
* If the task is already exiting, don't alarm the sysadmin or kill
* Determines whether the kernel must panic because of the panic_on_oom sysctl.
*/
static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask,
- int order)
+ int order, const nodemask_t *nodemask)
{
if (likely(!sysctl_panic_on_oom))
return;
return;
}
read_lock(&tasklist_lock);
- dump_header(NULL, gfp_mask, order, NULL);
+ dump_header(NULL, gfp_mask, order, NULL, nodemask);
read_unlock(&tasklist_lock);
panic("Out of memory: %s panic_on_oom is enabled\n",
sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide");
unsigned int points = 0;
struct task_struct *p;
- check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0);
+ check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL);
limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT;
read_lock(&tasklist_lock);
retry:
void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
int order, nodemask_t *nodemask)
{
+ const nodemask_t *mpol_mask;
struct task_struct *p;
unsigned long totalpages;
unsigned long freed = 0;
*/
constraint = constrained_alloc(zonelist, gfp_mask, nodemask,
&totalpages);
- check_panic_on_oom(constraint, gfp_mask, order);
+ mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL;
+ check_panic_on_oom(constraint, gfp_mask, order, mpol_mask);
read_lock(&tasklist_lock);
if (sysctl_oom_kill_allocating_task &&
}
retry:
- p = select_bad_process(&points, totalpages, NULL,
- constraint == CONSTRAINT_MEMORY_POLICY ? nodemask :
- NULL);
+ p = select_bad_process(&points, totalpages, NULL, mpol_mask);
if (PTR_ERR(p) == -1UL)
goto out;
/* Found nothing?!?! Either we hang forever, or we panic. */
if (!p) {
- dump_header(NULL, gfp_mask, order, NULL);
+ dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
read_unlock(&tasklist_lock);
panic("Out of memory and no killable processes...\n");
}
if (pcpu_first_unit_cpu == NR_CPUS)
pcpu_first_unit_cpu = cpu;
+ pcpu_last_unit_cpu = cpu;
}
}
- pcpu_last_unit_cpu = cpu;
pcpu_nr_units = unit;
for_each_possible_cpu(cpu)
unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
{
if (PageAnon(page)) {
- if (vma->anon_vma->root != page_anon_vma(page)->root)
+ struct anon_vma *page__anon_vma = page_anon_vma(page);
+ /*
+ * Note: swapoff's unuse_vma() is more efficient with this
+ * check, and needs it to match anon_vma when KSM is active.
+ */
+ if (!vma->anon_vma || !page__anon_vma ||
+ vma->anon_vma->root != page__anon_vma->root)
return -EFAULT;
} else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
if (!vma->vm_file ||
struct vm_area_struct *vma, unsigned long address, int exclusive)
{
struct anon_vma *anon_vma = vma->anon_vma;
+
BUG_ON(!anon_vma);
- if (!exclusive) {
- struct anon_vma_chain *avc;
- avc = list_entry(vma->anon_vma_chain.prev,
- struct anon_vma_chain, same_vma);
- anon_vma = avc->anon_vma;
- }
+
+ if (PageAnon(page))
+ return;
+ if (!exclusive)
+ anon_vma = anon_vma->root;
+
anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
page->mapping = (struct address_space *) anon_vma;
page->index = linear_page_index(vma, address);
{
struct anon_vma *anon_vma = vma->anon_vma;
int first;
+
+ BUG_ON(!PageLocked(page));
BUG_ON(!anon_vma);
BUG_ON(address < vma->vm_start || address >= vma->vm_end);
first = atomic_inc_and_test(&page->_mapcount);
* If a zone is deemed to be full of pinned pages then just give it a light
* scan then give up on it.
*/
-static bool shrink_zones(int priority, struct zonelist *zonelist,
+static void shrink_zones(int priority, struct zonelist *zonelist,
struct scan_control *sc)
{
struct zoneref *z;
struct zone *zone;
- bool all_unreclaimable = true;
for_each_zone_zonelist_nodemask(zone, z, zonelist,
gfp_zone(sc->gfp_mask), sc->nodemask) {
}
shrink_zone(priority, zone, sc);
- all_unreclaimable = false;
}
+}
+
+static bool zone_reclaimable(struct zone *zone)
+{
+ return zone->pages_scanned < zone_reclaimable_pages(zone) * 6;
+}
+
+/*
+ * As hibernation is going on, kswapd is freezed so that it can't mark
+ * the zone into all_unreclaimable. It can't handle OOM during hibernation.
+ * So let's check zone's unreclaimable in direct reclaim as well as kswapd.
+ */
+static bool all_unreclaimable(struct zonelist *zonelist,
+ struct scan_control *sc)
+{
+ struct zoneref *z;
+ struct zone *zone;
+ bool all_unreclaimable = true;
+
+ for_each_zone_zonelist_nodemask(zone, z, zonelist,
+ gfp_zone(sc->gfp_mask), sc->nodemask) {
+ if (!populated_zone(zone))
+ continue;
+ if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
+ continue;
+ if (zone_reclaimable(zone)) {
+ all_unreclaimable = false;
+ break;
+ }
+ }
+
return all_unreclaimable;
}
struct scan_control *sc)
{
int priority;
- bool all_unreclaimable;
unsigned long total_scanned = 0;
struct reclaim_state *reclaim_state = current->reclaim_state;
struct zoneref *z;
sc->nr_scanned = 0;
if (!priority)
disable_swap_token();
- all_unreclaimable = shrink_zones(priority, zonelist, sc);
+ shrink_zones(priority, zonelist, sc);
/*
* Don't shrink slabs when reclaiming memory from
* over limit cgroups
return sc->nr_reclaimed;
/* top priority shrink_zones still had more to do? don't OOM, then */
- if (scanning_global_lru(sc) && !all_unreclaimable)
+ if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc))
return 1;
return 0;
total_scanned += sc.nr_scanned;
if (zone->all_unreclaimable)
continue;
- if (nr_slab == 0 &&
- zone->pages_scanned >= (zone_reclaimable_pages(zone) * 6))
+ if (nr_slab == 0 && !zone_reclaimable(zone))
zone->all_unreclaimable = 1;
/*
* If we've done a decent amount of scanning and
if (vlan_dev)
skb->dev = vlan_dev;
- else if (vlan_id)
- goto drop;
+ else if (vlan_id) {
+ if (!(skb->dev->flags & IFF_PROMISC))
+ goto drop;
+ skb->pkt_type = PACKET_OTHERHOST;
+ }
return (polling ? netif_receive_skb(skb) : netif_rx(skb));
if (vlan_dev)
skb->dev = vlan_dev;
- else if (vlan_id)
- goto drop;
+ else if (vlan_id) {
+ if (!(skb->dev->flags & IFF_PROMISC))
+ goto drop;
+ skb->pkt_type = PACKET_OTHERHOST;
+ }
for (p = napi->gro_list; p; p = p->next) {
NAPI_GRO_CB(p)->same_flow =
/* Allocate an fcall for the reply */
rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL);
- if (!rpl_context)
+ if (!rpl_context) {
+ err = -ENOMEM;
goto err_close;
+ }
/*
* If the request has a buffer, steal it, otherwise
}
rpl_context->rc = req->rc;
if (!rpl_context->rc) {
- kfree(rpl_context);
- goto err_close;
+ err = -ENOMEM;
+ goto err_free2;
}
/*
*/
if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) {
err = post_recv(client, rpl_context);
- if (err) {
- kfree(rpl_context->rc);
- kfree(rpl_context);
- goto err_close;
- }
+ if (err)
+ goto err_free1;
} else
atomic_dec(&rdma->rq_count);
/* Post the request */
c = kmalloc(sizeof *c, GFP_KERNEL);
- if (!c)
- goto err_close;
+ if (!c) {
+ err = -ENOMEM;
+ goto err_free1;
+ }
c->req = req;
c->busa = ib_dma_map_single(rdma->cm_id->device,
return ib_post_send(rdma->qp, &wr, &bad_wr);
error:
+ kfree(c);
+ kfree(rpl_context->rc);
+ kfree(rpl_context);
P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n");
return -EIO;
-
+ err_free1:
+ kfree(rpl_context->rc);
+ err_free2:
+ kfree(rpl_context);
err_close:
spin_lock_irqsave(&rdma->req_lock, flags);
if (rdma->state < P9_RDMA_CLOSING) {
mutex_lock(&virtio_9p_lock);
list_for_each_entry(chan, &virtio_chan_list, chan_list) {
- if (!strncmp(devname, chan->tag, chan->tag_len)) {
+ if (!strncmp(devname, chan->tag, chan->tag_len) &&
+ strlen(devname) == chan->tag_len) {
if (!chan->inuse) {
chan->inuse = true;
found = 1;
unregister_netdev(net_dev);
free_netdev(net_dev);
}
- read_lock_irq(&devs_lock);
- if (list_empty(&br2684_devs)) {
- /* last br2684 device */
- unregister_atmdevice_notifier(&atm_dev_notifier);
- }
- read_unlock_irq(&devs_lock);
return;
}
if (list_empty(&br2684_devs)) {
/* 1st br2684 device */
- register_atmdevice_notifier(&atm_dev_notifier);
brdev->number = 1;
} else
brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
return -ENOMEM;
#endif
register_atm_ioctl(&br2684_ioctl_ops);
+ register_atmdevice_notifier(&atm_dev_notifier);
return 0;
}
#endif
- /* if not already empty */
- if (!list_empty(&br2684_devs))
- unregister_atmdevice_notifier(&atm_dev_notifier);
+ unregister_atmdevice_notifier(&atm_dev_notifier);
while (!list_empty(&br2684_devs)) {
net_dev = list_entry_brdev(br2684_devs.next);
* in any case.
*/
-int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
+long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
{
- int size, err, ct;
+ int size, ct;
+ long err;
if (m->msg_namelen) {
if (mode == VERIFY_READ) {
{
int uid;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0;
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
return uid;
}
EXPORT_SYMBOL(sock_i_uid);
{
unsigned long ino;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
return ino;
}
EXPORT_SYMBOL(sock_i_ino);
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
+ depends on IPV6 || IPV6=n
help
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <net/ipv6.h>
#include <net/ip6_fib.h>
#include <net/ip6_route.h>
if ((dst = rt->rt_gateway) == 0)
goto tx_error_icmp;
}
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6)) {
struct in6_addr *addr6;
int addr_type;
goto tx_error;
}
}
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6)) {
struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
if ((iph->ttl = tiph->ttl) == 0) {
if (skb->protocol == htons(ETH_P_IP))
iph->ttl = old_iph->ttl;
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6))
iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit;
#endif
* we can switch to copy when see the first bad fragment.
*/
if (skb_has_frags(skb)) {
- struct sk_buff *frag;
+ struct sk_buff *frag, *frag2;
int first_len = skb_pagelen(skb);
- int truesizes = 0;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
if (frag->len > mtu ||
((frag->len & 7) && frag->next) ||
skb_headroom(frag) < hlen)
- goto slow_path;
+ goto slow_path_clean;
/* Partially cloned skb? */
if (skb_shared(frag))
- goto slow_path;
+ goto slow_path_clean;
BUG_ON(frag->sk);
if (skb->sk) {
frag->sk = skb->sk;
frag->destructor = sock_wfree;
}
- truesizes += frag->truesize;
+ skb->truesize -= frag->truesize;
}
/* Everything is OK. Generate! */
frag = skb_shinfo(skb)->frag_list;
skb_frag_list_init(skb);
skb->data_len = first_len - skb_headlen(skb);
- skb->truesize -= truesizes;
skb->len = first_len;
iph->tot_len = htons(first_len);
iph->frag_off = htons(IP_MF);
}
IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
return err;
+
+slow_path_clean:
+ skb_walk_frags(skb, frag2) {
+ if (frag2 == frag)
+ break;
+ frag2->sk = NULL;
+ frag2->destructor = NULL;
+ skb->truesize += frag2->truesize;
+ }
}
slow_path:
/* ip_route_me_harder expects skb->dst to be set */
skb_dst_set_noref(nskb, skb_dst(oldskb));
+ nskb->protocol = htons(ETH_P_IP);
if (ip_route_me_harder(nskb, addr_type))
goto free_nskb;
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(skb->sk);
- if (inet && inet->nodefrag)
+ if (sk && (sk->sk_family == PF_INET) &&
+ inet->nodefrag)
return NF_ACCEPT;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
unsigned char s[4];
if (offset & 1) {
- s[0] = s[2] = 0;
+ s[0] = ~0;
s[1] = ~*optr;
+ s[2] = 0;
s[3] = *nptr;
} else {
- s[1] = s[3] = 0;
s[0] = ~*optr;
+ s[1] = ~0;
s[2] = *nptr;
+ s[3] = 0;
}
*csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
}
if (net_ratelimit())
- printk(KERN_WARNING "Neighbour table overflow.\n");
+ printk(KERN_WARNING "ipv4: Neighbour table overflow.\n");
rt_drop(rt);
return -ENOBUFS;
}
*/
mask = 0;
- if (sk->sk_err)
- mask = POLLERR;
/*
* POLLHUP is certainly not done right. But poll() doesn't
if (tp->urg_data & TCP_URG_VALID)
mask |= POLLPRI;
}
+ /* This barrier is coupled with smp_wmb() in tcp_reset() */
+ smp_rmb();
+ if (sk->sk_err)
+ mask |= POLLERR;
+
return mask;
}
EXPORT_SYMBOL(tcp_poll);
sg = sk->sk_route_caps & NETIF_F_SG;
while (--iovlen >= 0) {
- int seglen = iov->iov_len;
+ size_t seglen = iov->iov_len;
unsigned char __user *from = iov->iov_base;
iov++;
cnt += tcp_skb_pcount(skb);
if (cnt > packets) {
- if (tcp_is_sack(tp) || (oldcnt >= packets))
+ if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) ||
+ (oldcnt >= packets))
break;
mss = skb_shinfo(skb)->gso_size;
default:
sk->sk_err = ECONNRESET;
}
+ /* This barrier is coupled with smp_rmb() in tcp_poll() */
+ smp_wmb();
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_error_report(sk);
/* This function calculates a "timeout" which is equivalent to the timeout of a
* TCP connection after "boundary" unsuccessful, exponentially backed-off
- * retransmissions with an initial RTO of TCP_RTO_MIN.
+ * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if
+ * syn_set flag is set.
*/
static bool retransmits_timed_out(struct sock *sk,
- unsigned int boundary)
+ unsigned int boundary,
+ bool syn_set)
{
unsigned int timeout, linear_backoff_thresh;
unsigned int start_ts;
+ unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN;
if (!inet_csk(sk)->icsk_retransmits)
return false;
else
start_ts = tcp_sk(sk)->retrans_stamp;
- linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN);
+ linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
if (boundary <= linear_backoff_thresh)
- timeout = ((2 << boundary) - 1) * TCP_RTO_MIN;
+ timeout = ((2 << boundary) - 1) * rto_base;
else
- timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN +
+ timeout = ((2 << linear_backoff_thresh) - 1) * rto_base +
(boundary - linear_backoff_thresh) * TCP_RTO_MAX;
return (tcp_time_stamp - start_ts) >= timeout;
{
struct inet_connection_sock *icsk = inet_csk(sk);
int retry_until;
- bool do_reset;
+ bool do_reset, syn_set = 0;
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
if (icsk->icsk_retransmits)
dst_negative_advice(sk);
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
+ syn_set = 1;
} else {
- if (retransmits_timed_out(sk, sysctl_tcp_retries1)) {
+ if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);
retry_until = tcp_orphan_retries(sk, alive);
do_reset = alive ||
- !retransmits_timed_out(sk, retry_until);
+ !retransmits_timed_out(sk, retry_until, 0);
if (tcp_out_of_resources(sk, do_reset))
return 1;
}
}
- if (retransmits_timed_out(sk, retry_until)) {
+ if (retransmits_timed_out(sk, retry_until, syn_set)) {
/* Has it gone just too far? */
tcp_write_err(sk);
return 1;
icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
}
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
- if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1))
+ if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0))
__sk_dst_reset(sk);
out:;
static int xfrm4_get_tos(struct flowi *fl)
{
- return fl->fl4_tos;
+ return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */
}
static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
}
static void
-__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
- xfrm_address_t *daddr, xfrm_address_t *saddr)
+__xfrm4_init_tempsel(struct xfrm_selector *sel, struct flowi *fl)
+{
+ sel->daddr.a4 = fl->fl4_dst;
+ sel->saddr.a4 = fl->fl4_src;
+ sel->dport = xfrm_flowi_dport(fl);
+ sel->dport_mask = htons(0xffff);
+ sel->sport = xfrm_flowi_sport(fl);
+ sel->sport_mask = htons(0xffff);
+ sel->family = AF_INET;
+ sel->prefixlen_d = 32;
+ sel->prefixlen_s = 32;
+ sel->proto = fl->proto;
+ sel->ifindex = fl->oif;
+}
+
+static void
+xfrm4_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl,
+ xfrm_address_t *daddr, xfrm_address_t *saddr)
{
- x->sel.daddr.a4 = fl->fl4_dst;
- x->sel.saddr.a4 = fl->fl4_src;
- x->sel.dport = xfrm_flowi_dport(fl);
- x->sel.dport_mask = htons(0xffff);
- x->sel.sport = xfrm_flowi_sport(fl);
- x->sel.sport_mask = htons(0xffff);
- x->sel.family = AF_INET;
- x->sel.prefixlen_d = 32;
- x->sel.prefixlen_s = 32;
- x->sel.proto = fl->proto;
- x->sel.ifindex = fl->oif;
x->id = tmpl->id;
if (x->id.daddr.a4 == 0)
x->id.daddr.a4 = daddr->a4;
.owner = THIS_MODULE,
.init_flags = xfrm4_init_flags,
.init_tempsel = __xfrm4_init_tempsel,
+ .init_temprop = xfrm4_init_temprop,
.output = xfrm4_output,
.extract_input = xfrm4_extract_input,
.extract_output = xfrm4_extract_output,
if (err < 0) {
printk(KERN_CRIT "IPv6 Addrconf:"
" cannot initialize default policy table: %d.\n", err);
- return err;
+ goto out;
}
- register_pernet_subsys(&addrconf_ops);
+ err = register_pernet_subsys(&addrconf_ops);
+ if (err < 0)
+ goto out_addrlabel;
/* The addrconf netdev notifier requires that loopback_dev
* has it's ipv6 private information allocated and setup
unregister_netdevice_notifier(&ipv6_dev_notf);
errlo:
unregister_pernet_subsys(&addrconf_ops);
-
+out_addrlabel:
+ ipv6_addr_label_cleanup();
+out:
return err;
}
unregister_netdevice_notifier(&ipv6_dev_notf);
unregister_pernet_subsys(&addrconf_ops);
+ ipv6_addr_label_cleanup();
rtnl_lock();
return register_pernet_subsys(&ipv6_addr_label_ops);
}
+void ipv6_addr_label_cleanup(void)
+{
+ unregister_pernet_subsys(&ipv6_addr_label_ops);
+}
+
static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
[IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), },
[IFAL_LABEL] = { .len = sizeof(u32), },
if (skb_has_frags(skb)) {
int first_len = skb_pagelen(skb);
- int truesizes = 0;
+ struct sk_buff *frag2;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
if (frag->len > mtu ||
((frag->len & 7) && frag->next) ||
skb_headroom(frag) < hlen)
- goto slow_path;
+ goto slow_path_clean;
/* Partially cloned skb? */
if (skb_shared(frag))
- goto slow_path;
+ goto slow_path_clean;
BUG_ON(frag->sk);
if (skb->sk) {
frag->sk = skb->sk;
frag->destructor = sock_wfree;
- truesizes += frag->truesize;
}
+ skb->truesize -= frag->truesize;
}
err = 0;
first_len = skb_pagelen(skb);
skb->data_len = first_len - skb_headlen(skb);
- skb->truesize -= truesizes;
skb->len = first_len;
ipv6_hdr(skb)->payload_len = htons(first_len -
sizeof(struct ipv6hdr));
IPSTATS_MIB_FRAGFAILS);
dst_release(&rt->dst);
return err;
+
+slow_path_clean:
+ skb_walk_frags(skb, frag2) {
+ if (frag2 == frag)
+ break;
+ frag2->sk = NULL;
+ frag2->destructor = NULL;
+ skb->truesize += frag2->truesize;
+ }
}
slow_path:
if (net_ratelimit())
printk(KERN_WARNING
- "Neighbour table overflow.\n");
+ "ipv6: Neighbour table overflow.\n");
dst_free(&rt->dst);
return NULL;
}
#include <net/addrconf.h>
static void
-__xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
- xfrm_address_t *daddr, xfrm_address_t *saddr)
+__xfrm6_init_tempsel(struct xfrm_selector *sel, struct flowi *fl)
{
/* Initialize temporary selector matching only
* to current session. */
- ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
- ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
- x->sel.dport = xfrm_flowi_dport(fl);
- x->sel.dport_mask = htons(0xffff);
- x->sel.sport = xfrm_flowi_sport(fl);
- x->sel.sport_mask = htons(0xffff);
- x->sel.family = AF_INET6;
- x->sel.prefixlen_d = 128;
- x->sel.prefixlen_s = 128;
- x->sel.proto = fl->proto;
- x->sel.ifindex = fl->oif;
+ ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst);
+ ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src);
+ sel->dport = xfrm_flowi_dport(fl);
+ sel->dport_mask = htons(0xffff);
+ sel->sport = xfrm_flowi_sport(fl);
+ sel->sport_mask = htons(0xffff);
+ sel->family = AF_INET6;
+ sel->prefixlen_d = 128;
+ sel->prefixlen_s = 128;
+ sel->proto = fl->proto;
+ sel->ifindex = fl->oif;
+}
+
+static void
+xfrm6_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl,
+ xfrm_address_t *daddr, xfrm_address_t *saddr)
+{
x->id = tmpl->id;
if (ipv6_addr_any((struct in6_addr*)&x->id.daddr))
memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr));
.eth_proto = htons(ETH_P_IPV6),
.owner = THIS_MODULE,
.init_tempsel = __xfrm6_init_tempsel,
+ .init_temprop = xfrm6_init_temprop,
.tmpl_sort = __xfrm6_tmpl_sort,
.state_sort = __xfrm6_state_sort,
.output = xfrm6_output,
struct net_device *prev_dev = NULL;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
- if (status->flag & RX_FLAG_INTERNAL_CMTR)
- goto out_free_skb;
-
if (skb_headroom(skb) < sizeof(*rthdr) &&
pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
goto out_free_skb;
} else
goto out_free_skb;
- status->flag |= RX_FLAG_INTERNAL_CMTR;
return;
out_free_skb:
{
unsigned int off, len;
struct nf_ct_ext_type *t;
+ size_t alloc_size;
rcu_read_lock();
t = rcu_dereference(nf_ct_ext_types[id]);
BUG_ON(t == NULL);
off = ALIGN(sizeof(struct nf_ct_ext), t->align);
len = off + t->len;
+ alloc_size = t->alloc_size;
rcu_read_unlock();
- *ext = kzalloc(t->alloc_size, gfp);
+ *ext = kzalloc(alloc_size, gfp);
if (!*ext)
return NULL;
unsigned int msglen, origlen;
const char *dptr, *end;
s16 diff, tdiff = 0;
- int ret;
+ int ret = NF_ACCEPT;
typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
if (ctinfo != IP_CT_ESTABLISHED &&
int
nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
{
- if (inet_sk(sk)->transparent) {
+ bool transparent = (sk->sk_state == TCP_TIME_WAIT) ?
+ inet_twsk(sk)->tw_transparent :
+ inet_sk(sk)->transparent;
+
+ if (transparent) {
skb_orphan(skb);
skb->sk = sk;
skb->destructor = nf_tproxy_destructor;
static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb)
{
struct pep_sock *pn = pep_sk(sk);
- struct pnpipehdr *hdr = pnp_hdr(skb);
+ struct pnpipehdr *hdr;
int wake = 0;
if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
return -EINVAL;
+ hdr = pnp_hdr(skb);
if (hdr->data[0] != PN_PEP_TYPE_COMMON) {
LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n",
(unsigned)hdr->data[0]);
struct rds_connection *conn;
struct rds_tcp_connection *tc;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
conn = sk->sk_user_data;
if (conn == NULL) {
state_change = sk->sk_state_change;
break;
}
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
state_change(sk);
}
rdsdebug("listen data ready sk %p\n", sk);
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
ready = sk->sk_user_data;
if (ready == NULL) { /* check for teardown race */
ready = sk->sk_data_ready;
queue_work(rds_wq, &rds_tcp_listen_work);
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
ready(sk, bytes);
}
rdsdebug("data ready sk %p bytes %d\n", sk, bytes);
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
conn = sk->sk_user_data;
if (conn == NULL) { /* check for teardown race */
ready = sk->sk_data_ready;
if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM)
queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
ready(sk, bytes);
}
struct rds_connection *conn;
struct rds_tcp_connection *tc;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
conn = sk->sk_user_data;
if (conn == NULL) {
write_space = sk->sk_write_space;
queue_delayed_work(rds_wq, &conn->c_send_w, 0);
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
/*
* write_space is only called when data leaves tcp's send queue if
if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1)
return -EINVAL;
- if (addr->srose_ndigis > ROSE_MAX_DIGIS)
+ if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
return -EINVAL;
if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) {
if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1)
return -EINVAL;
- if (addr->srose_ndigis > ROSE_MAX_DIGIS)
+ if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
return -EINVAL;
/* Source + Destination digis should not exceed ROSE_MAX_DIGIS */
u32 _xid;
__be32 *xp;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
dprintk("RPC: xs_udp_data_ready...\n");
if (!(xprt = xprt_from_sock(sk)))
goto out;
dropit:
skb_free_datagram(sk, skb);
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
}
static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
dprintk("RPC: xs_tcp_data_ready...\n");
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
if (!(xprt = xprt_from_sock(sk)))
goto out;
if (xprt->shutdown)
read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
} while (read > 0);
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
}
/*
{
struct rpc_xprt *xprt;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
if (!(xprt = xprt_from_sock(sk)))
goto out;
dprintk("RPC: xs_tcp_state_change client %p...\n", xprt);
switch (sk->sk_state) {
case TCP_ESTABLISHED:
- spin_lock_bh(&xprt->transport_lock);
+ spin_lock(&xprt->transport_lock);
if (!xprt_test_and_set_connected(xprt)) {
struct sock_xprt *transport = container_of(xprt,
struct sock_xprt, xprt);
xprt_wake_pending_tasks(xprt, -EAGAIN);
}
- spin_unlock_bh(&xprt->transport_lock);
+ spin_unlock(&xprt->transport_lock);
break;
case TCP_FIN_WAIT1:
/* The client initiated a shutdown of the socket */
xs_sock_mark_closed(xprt);
}
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
}
/**
{
struct rpc_xprt *xprt;
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
if (!(xprt = xprt_from_sock(sk)))
goto out;
dprintk("RPC: %s client %p...\n"
__func__, xprt, sk->sk_err);
xprt_wake_pending_tasks(xprt, -EAGAIN);
out:
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
}
static void xs_write_space(struct sock *sk)
*/
static void xs_udp_write_space(struct sock *sk)
{
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
/* from net/core/sock.c:sock_def_write_space */
if (sock_writeable(sk))
xs_write_space(sk);
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
}
/**
*/
static void xs_tcp_write_space(struct sock *sk)
{
- read_lock(&sk->sk_callback_lock);
+ read_lock_bh(&sk->sk_callback_lock);
/* from net/core/stream.c:sk_stream_write_space */
if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
xs_write_space(sk);
- read_unlock(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock);
}
static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
} else if (!iwp->pointer)
return -EFAULT;
- extra = kmalloc(extra_size, GFP_KERNEL);
+ extra = kzalloc(extra_size, GFP_KERNEL);
if (!extra)
return -ENOMEM;
tmpl->mode == XFRM_MODE_BEET) {
remote = &tmpl->id.daddr;
local = &tmpl->saddr;
- family = tmpl->encap_family;
- if (xfrm_addr_any(local, family)) {
- error = xfrm_get_saddr(net, &tmp, remote, family);
+ if (xfrm_addr_any(local, tmpl->encap_family)) {
+ error = xfrm_get_saddr(net, &tmp, remote, tmpl->encap_family);
if (error)
goto fail;
local = &tmp;
EXPORT_SYMBOL(xfrm_sad_getinfo);
static int
-xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
- xfrm_address_t *daddr, xfrm_address_t *saddr,
- unsigned short family)
+xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl,
+ struct xfrm_tmpl *tmpl,
+ xfrm_address_t *daddr, xfrm_address_t *saddr,
+ unsigned short family)
{
struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
if (!afinfo)
return -1;
- afinfo->init_tempsel(x, fl, tmpl, daddr, saddr);
+ afinfo->init_tempsel(&x->sel, fl);
+
+ if (family != tmpl->encap_family) {
+ xfrm_state_put_afinfo(afinfo);
+ afinfo = xfrm_state_get_afinfo(tmpl->encap_family);
+ if (!afinfo)
+ return -1;
+ }
+ afinfo->init_temprop(x, tmpl, daddr, saddr);
xfrm_state_put_afinfo(afinfo);
return 0;
}
int error = 0;
struct xfrm_state *best = NULL;
u32 mark = pol->mark.v & pol->mark.m;
+ unsigned short encap_family = tmpl->encap_family;
to_put = NULL;
spin_lock_bh(&xfrm_state_lock);
- h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family);
+ h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
- if (x->props.family == family &&
+ if (x->props.family == encap_family &&
x->props.reqid == tmpl->reqid &&
(mark & x->mark.m) == x->mark.v &&
!(x->props.flags & XFRM_STATE_WILDRECV) &&
- xfrm_state_addr_check(x, daddr, saddr, family) &&
+ xfrm_state_addr_check(x, daddr, saddr, encap_family) &&
tmpl->mode == x->props.mode &&
tmpl->id.proto == x->id.proto &&
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
- xfrm_state_look_at(pol, x, fl, family, daddr, saddr,
+ xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr,
&best, &acquire_in_progress, &error);
}
if (best)
goto found;
- h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family);
+ h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family);
hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) {
- if (x->props.family == family &&
+ if (x->props.family == encap_family &&
x->props.reqid == tmpl->reqid &&
(mark & x->mark.m) == x->mark.v &&
!(x->props.flags & XFRM_STATE_WILDRECV) &&
- xfrm_state_addr_check(x, daddr, saddr, family) &&
+ xfrm_state_addr_check(x, daddr, saddr, encap_family) &&
tmpl->mode == x->props.mode &&
tmpl->id.proto == x->id.proto &&
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
- xfrm_state_look_at(pol, x, fl, family, daddr, saddr,
+ xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr,
&best, &acquire_in_progress, &error);
}
if (!x && !error && !acquire_in_progress) {
if (tmpl->id.spi &&
(x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
- tmpl->id.proto, family)) != NULL) {
+ tmpl->id.proto, encap_family)) != NULL) {
to_put = x0;
error = -EEXIST;
goto out;
error = -ENOMEM;
goto out;
}
- /* Initialize temporary selector matching only
+ /* Initialize temporary state matching only
* to current session. */
- xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
+ xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family);
memcpy(&x->mark, &pol->mark, sizeof(x->mark));
error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
x->km.state = XFRM_STATE_ACQ;
list_add(&x->km.all, &net->xfrm.state_all);
hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
- h = xfrm_src_hash(net, daddr, saddr, family);
+ h = xfrm_src_hash(net, daddr, saddr, encap_family);
hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
if (x->id.spi) {
- h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family);
+ h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family);
hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
}
x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
{
int i;
unsigned int ret;
+ unsigned int nents;
struct scatterlist sg[10];
printk(KERN_INFO "DMA fifo test start\n");
* byte at the beginning, after the kfifo_skip().
*/
sg_init_table(sg, ARRAY_SIZE(sg));
- ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
- printk(KERN_INFO "DMA sgl entries: %d\n", ret);
- if (!ret) {
+ nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
+ printk(KERN_INFO "DMA sgl entries: %d\n", nents);
+ if (!nents) {
/* fifo is full and no sgl was created */
printk(KERN_WARNING "error kfifo_dma_in_prepare\n");
return -EIO;
/* receive data */
printk(KERN_INFO "scatterlist for receive:\n");
- for (i = 0; i < ARRAY_SIZE(sg); i++) {
+ for (i = 0; i < nents; i++) {
printk(KERN_INFO
"sg[%d] -> "
"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
kfifo_dma_in_finish(&fifo, ret);
/* Prepare to transmit data, example: 8 bytes */
- ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
- printk(KERN_INFO "DMA sgl entries: %d\n", ret);
- if (!ret) {
+ nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
+ printk(KERN_INFO "DMA sgl entries: %d\n", nents);
+ if (!nents) {
/* no data was available and no sgl was created */
printk(KERN_WARNING "error kfifo_dma_out_prepare\n");
return -EIO;
}
printk(KERN_INFO "scatterlist for transmit:\n");
- for (i = 0; i < ARRAY_SIZE(sg); i++) {
+ for (i = 0; i < nents; i++) {
printk(KERN_INFO
"sg[%d] -> "
"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
const pid_t gpid = task_pid_nr(current);
static const int tomoyo_buffer_len = 4096;
char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
+ pid_t ppid;
if (!buffer)
return NULL;
do_gettimeofday(&tv);
+ rcu_read_lock();
+ ppid = task_tgid_vnr(current->real_parent);
+ rcu_read_unlock();
snprintf(buffer, tomoyo_buffer_len - 1,
"#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
" task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
" egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid,
- (pid_t) sys_getpid(), (pid_t) sys_getppid(),
+ task_tgid_vnr(current), ppid,
current_uid(), current_gid(), current_euid(),
current_egid(), current_suid(), current_sgid(),
current_fsuid(), current_fsgid());
/********** Function prototypes. **********/
-extern asmlinkage long sys_getpid(void);
-extern asmlinkage long sys_getppid(void);
-
/* Check whether the given string starts with the given keyword. */
bool tomoyo_str_starts(char **src, const char *find);
/* Get tomoyo_realpath() of current process. */
/* max number of user-defined controls */
#define MAX_USER_CONTROLS 32
+#define MAX_CONTROL_COUNT 1028
struct snd_kctl_ioctl {
struct list_head list; /* list of all ioctls */
if (snd_BUG_ON(!control || !control->count))
return NULL;
+
+ if (control->count > MAX_CONTROL_COUNT)
+ return NULL;
+
kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
if (kctl == NULL) {
snd_printk(KERN_ERR "Cannot allocate control instance\n");
return 0;
}
#else /* !CONFIG_PROC_FS */
-static int proc_init(struct snd_akm4xxx *ak) {}
+static int proc_init(struct snd_akm4xxx *ak) { return 0; }
#endif
int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
/* Lenovo Thinkpad T61/X61 */
SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
+ SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
{}
};
}
if (spec->autocfg.dig_in_pin) {
- hda_nid_t dig_nid;
- err = snd_hda_get_connections(codec,
- spec->autocfg.dig_in_pin,
- &dig_nid, 1);
- if (err > 0)
- spec->dig_in_nid = dig_nid;
+ dig_nid = codec->start_nid;
+ for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
+ unsigned int wcaps = get_wcaps(codec, dig_nid);
+ if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
+ continue;
+ if (!(wcaps & AC_WCAP_DIGITAL))
+ continue;
+ if (!(wcaps & AC_WCAP_CONN_LIST))
+ continue;
+ err = get_connection_index(codec, dig_nid,
+ spec->autocfg.dig_in_pin);
+ if (err >= 0) {
+ spec->dig_in_nid = dig_nid;
+ break;
+ }
+ }
}
}
chip->model.suspend = claro_suspend;
chip->model.resume = claro_resume;
chip->model.set_adc_params = set_ak5385_params;
+ chip->model.device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2 |
+ CAPTURE_1_FROM_SPDIF;
break;
}
if (id->driver_data == MODEL_MERIDIAN ||
if (err < 0)
return err;
+ memset(&info, 0, sizeof(info));
spin_lock_irqsave(&hdsp->lock, flags);
info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO:
+ memset(&info, 0, sizeof(info));
spin_lock_irq(&hdspm->lock);
info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
#include <linux/firmware.h>
#include <linux/module.h>
+#include <asm/clkdev.h>
#include <asm/clock.h>
#include <cpu/sh7722.h>
};
static struct clk siumckb_clk = {
- .name = "siumckb_clk",
- .id = -1,
.ops = &siumckb_clk_ops,
.rate = 0, /* initialised at run-time */
};
+static struct clk_lookup *siumckb_lookup;
+
static int migor_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
if (ret < 0)
return ret;
+ siumckb_lookup = clkdev_alloc(&siumckb_clk, "siumckb_clk", NULL);
+ if (!siumckb_lookup) {
+ ret = -ENOMEM;
+ goto eclkdevalloc;
+ }
+ clkdev_add(siumckb_lookup);
+
/* Port number used on this machine: port B */
migor_snd_device = platform_device_alloc("soc-audio", 1);
if (!migor_snd_device) {
epdevadd:
platform_device_put(migor_snd_device);
epdevalloc:
+ clkdev_drop(siumckb_lookup);
+eclkdevalloc:
clk_unregister(&siumckb_clk);
return ret;
}
static void __exit migor_exit(void)
{
+ clkdev_drop(siumckb_lookup);
clk_unregister(&siumckb_clk);
platform_device_unregister(migor_snd_device);
}
data[1] = (value >> 8) & 0xff;
data[2] = value & 0xff;
- if (!snd_soc_codec_volatile_register(codec, reg))
- reg_cache[reg] = value;
+ if (!snd_soc_codec_volatile_register(codec, reg)
+ && reg < codec->reg_cache_size)
+ reg_cache[reg] = value;
if (codec->cache_only) {
codec->cache_sync = 1;
# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
# we depend the various files onto their directories.
DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
-$(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS)))
+$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
# In the second step, we make a rule to actually create these directories
$(sort $(dir $(DIRECTORY_DEPS))):
$(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
register_python_scripting(&python_scripting_unsupported_ops);
}
#else
-struct scripting_ops python_scripting_ops;
+extern struct scripting_ops python_scripting_ops;
void setup_python_scripting(void)
{
register_perl_scripting(&perl_scripting_unsupported_ops);
}
#else
-struct scripting_ops perl_scripting_ops;
+extern struct scripting_ops perl_scripting_ops;
void setup_perl_scripting(void)
{
switch (key) {
case 'a':
- if (browser->selection->map == NULL &&
+ if (browser->selection->map == NULL ||
browser->selection->map->dso->annotate_warned)
continue;
goto do_annotate;
events = file->f_op->poll(file, &irqfd->pt);
list_add_tail(&irqfd->list, &kvm->irqfds.items);
- spin_unlock_irq(&kvm->irqfds.lock);
/*
* Check if there was an event already pending on the eventfd
if (events & POLLIN)
schedule_work(&irqfd->inject);
+ spin_unlock_irq(&kvm->irqfds.lock);
+
/*
* do not drop the file until the irqfd is fully initialized, otherwise
* we might race against the POLLHUP
asmlinkage void kvm_handle_fault_on_reboot(void)
{
- if (kvm_rebooting)
+ if (kvm_rebooting) {
/* spin while reset goes on */
+ local_irq_enable();
while (true)
;
+ }
/* Fault while not rebooting. We want the trace. */
BUG();
}