# o print "Entering directory ...";
MAKEFLAGS += -rR --no-print-directory
+# Add custom flags here to avoid conflict with updates
+EXTRAVERSION := $(EXTRAVERSION)-omap1
+
# We are using a recursive build, so we need to do a little thinking
# to get the ordering right.
#
KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
$(if $(KBUILD_OUTPUT),, \
$(error output directory "$(saved-output)" does not exist))
+ # Check that OUTPUT directory is not the same as where we have kernel src
+ $(if $(filter-out $(KBUILD_OUTPUT),$(shell /bin/pwd)),, \
+ $(error Output directory (O=...) specifies kernel src dir))
- PHONY += $(MAKECMDGOALS)
+ PHONY += $(MAKECMDGOALS) sub-make
- $(filter-out _all,$(MAKECMDGOALS)) _all:
+ $(filter-out _all sub-make,$(MAKECMDGOALS)) _all: sub-make
+ $(Q)@:
+
+ sub-make: FORCE
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
KBUILD_SRC=$(CURDIR) \
- KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
+ KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \
+ $(filter-out _all sub-make,$(MAKECMDGOALS))
# Leave processing to above invocation of make
skip-makefile := 1
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
+SUBARCH := arm
+
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
#
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
ARCH ?= $(SUBARCH)
-CROSS_COMPILE ?=
+CROSS_COMPILE ?= arm-linux-
# Architecture as present in compile.h
- UTS_MACHINE := $(ARCH)
+ UTS_MACHINE := $(ARCH)
+ SRCARCH := $(ARCH)
KCONFIG_CONFIG ?= .config
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-include include/linux/autoconf.h
- CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
+ KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
- CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration
- AFLAGS := -D__ASSEMBLY__
+ KBUILD_AFLAGS := -D__ASSEMBLY__
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
- export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
+ export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
- export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
- export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
- export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+ export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+ export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+ export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
- CFLAGS += -Os
+ KBUILD_CFLAGS += -Os
else
- CFLAGS += -O2
+ KBUILD_CFLAGS += -O2
endif
include $(srctree)/arch/$(ARCH)/Makefile
ifdef CONFIG_FRAME_POINTER
- CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
+ KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
else
- CFLAGS += -fomit-frame-pointer
+ KBUILD_CFLAGS += -fomit-frame-pointer
endif
ifdef CONFIG_DEBUG_INFO
- CFLAGS += -g
+ KBUILD_CFLAGS += -g
+ KBUILD_AFLAGS += -gdwarf-2
endif
# Force gcc to behave correct even for buggy distributions
- CFLAGS += $(call cc-option, -fno-stack-protector)
+ KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
# warn about C99 declaration after statement
- CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
+ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
- CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+
+ # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
+ KBUILD_CPPFLAGS += $(CPPFLAGS)
+ KBUILD_AFLAGS += $(AFLAGS)
+ KBUILD_CFLAGS += $(CFLAGS)
# Use --build-id when available.
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
- vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
+ vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds
export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
# Rule to link vmlinux - also used during CONFIG_KALLSYMS
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o FORCE
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
+ endif
+ ifdef CONFIG_SAMPLES
+ $(Q)$(MAKE) $(build)=samples
endif
$(call vmlinux-modpost)
$(call if_changed_rule,vmlinux__)
/bin/false; \
fi;
$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
- $(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
+ $(Q)ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm
endif
# prepare2 creates a makefile if using a separate output directory
prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
include/asm include/config/auto.conf
- ifneq ($(KBUILD_MODULES),)
- $(Q)mkdir -p $(MODVERDIR)
- $(Q)rm -f $(MODVERDIR)/*
- endif
+ $(cmd_crmodverdir)
archprepare: prepare1 scripts_basic
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
- # FIXME: The asm symlink changes when $(ARCH) changes. That's
- # hard to detect, but I suppose "make mrproper" is a good idea
- # before switching between archs anyway.
-
- include/asm:
- @echo ' SYMLINK $@ -> include/asm-$(ARCH)'
- $(Q)if [ ! -d include ]; then mkdir -p include; fi;
- @ln -fsn asm-$(ARCH) $@
+ # The asm symlink changes when $(ARCH) changes.
+ # Detect this and ask user to run make mrproper
+
+ include/asm: FORCE
+ $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \
+ if [ -L include/asm ]; then \
+ if [ "$$asmlink" != "$(SRCARCH)" ]; then \
+ echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \
+ echo " set ARCH or save .config and run 'make mrproper' to fix it"; \
+ exit 1; \
+ fi; \
+ else \
+ echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \
+ if [ ! -d include ]; then \
+ mkdir -p include; \
+ fi; \
+ ln -fsn asm-$(SRCARCH) $@; \
+ fi
# Generate some files
# ---------------------------------------------------------------------------
INSTALL_HDR_PATH=$(objtree)/usr
export INSTALL_HDR_PATH
- HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
+ HDRFILTER=generic i386 x86_64
+ HDRARCHES=$(filter-out $(HDRFILTER),$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
PHONY += headers_install_all
headers_install_all: include/linux/version.h scripts_basic FORCE
PHONY += headers_install
headers_install: include/linux/version.h scripts_basic FORCE
- @if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
- echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
+ @if [ ! -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
+ echo '*** Error: Headers not exportable for this architecture ($(SRCARCH))'; \
exit 1 ; fi
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include
PHONY += headers_check_all
headers_check_all: headers_install_all
PHONY += headers_check
headers_check: headers_install
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include HDRCHECK=1
# ---------------------------------------------------------------------------
# Modules
fi
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
- # If System.map exists, run depmod. This deliberately does not have a
- # dependency on System.map since that would run the dependency tree on
- # vmlinux. This depmod is only for convenience to give the initial
+ # This depmod is only for convenience to give the initial
# boot a modules.dep even before / is mounted read-write. However the
# boot script depmod is the master version.
- ifeq "$(strip $(INSTALL_MOD_PATH))" ""
- depmod_opts :=
- else
- depmod_opts := -b $(INSTALL_MOD_PATH) -r
- endif
PHONY += _modinst_post
_modinst_post: _modinst_
- if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
+ $(call cmd,depmod)
else # CONFIG_MODULES
@echo ' cscope - Generate cscope index'
@echo ' kernelrelease - Output the release version string'
@echo ' kernelversion - Output the version stored in Makefile'
- @if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+ @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
echo ' (default: $(INSTALL_HDR_PATH))'; \
fi
@echo 'Static analysers'
@echo ' checkstack - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel'
- @if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+ @echo ' export_report - List the usages of all exported symbols'
+ @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
echo ' headers_check - Sanity check on exported headers'; \
fi
@echo ''
KBUILD_MODULES := 1
PHONY += crmodverdir
crmodverdir:
- $(Q)mkdir -p $(MODVERDIR)
- $(Q)rm -f $(MODVERDIR)/*
+ $(cmd_crmodverdir)
PHONY += $(objtree)/Module.symvers
$(objtree)/Module.symvers:
$(Q)mkdir -p $(MODLIB)/$(install-dir)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
- # Run depmod only is we have System.map and depmod is executable
- quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
- cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
- $(DEPMOD) -ae -F System.map \
- $(if $(strip $(INSTALL_MOD_PATH)), \
- -b $(INSTALL_MOD_PATH) -r) \
- $(KERNELRELEASE); \
- fi
-
PHONY += _emodinst_post
_emodinst_post: _emodinst_
$(call cmd,depmod)
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
clean: rm-dirs := $(MODVERDIR)
+ clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers
clean: $(clean-dirs)
$(call cmd,rmdirs)
+ $(call cmd,rmfiles)
@find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
ifeq ($(ARCH),um)
ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
else
- ALLINCLUDE_ARCHS := $(ARCH)
+ ALLINCLUDE_ARCHS := $(SRCARCH)
endif
else
#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour.
ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
endif
+ # Take care of arch/x86
+ ifeq ($(ARCH), $(SRCARCH))
ALLSOURCE_ARCHS := $(ARCH)
+ else
+ ALLSOURCE_ARCHS := $(ARCH) $(SRCARCH)
+ endif
define find-sources
- ( for ARCH in $(ALLSOURCE_ARCHS) ; do \
- find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
+ ( for arch in $(ALLSOURCE_ARCHS) ; do \
+ find $(__srctree)arch/$${arch} $(RCS_FIND_IGNORE) \
-name $1 -print; \
done ; \
find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
find $(__srctree)include $(RCS_FIND_IGNORE) \
\( -name config -o -name 'asm-*' \) -prune \
-o -name $1 -print; \
- for ARCH in $(ALLINCLUDE_ARCHS) ; do \
- find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
+ for arch in $(ALLINCLUDE_ARCHS) ; do \
+ find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \
-name $1 -print; \
done ; \
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
-name $1 -print; \
find $(__srctree) $(RCS_FIND_IGNORE) \
- \( -name include -o -name arch \) -prune -o \
+ \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
-name $1 -print; \
)
endef
namespacecheck:
$(PERL) $(srctree)/scripts/namespace.pl
+ export_report:
+ $(PERL) $(srctree)/scripts/export_report.pl
+
endif #ifeq ($(config-targets),1)
endif #ifeq ($(mixed-targets),1)
# Modules
/ %/: prepare scripts FORCE
+ $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir)
%.ko: prepare scripts FORCE
+ $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)))
cmd_rmfiles = rm -f $(rm-files)
+ # Run depmod only is we have System.map and depmod is executable
+ # and we build for the host arch
+ quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
+ cmd_depmod = \
+ if [ -r System.map -a -x $(DEPMOD) ]; then \
+ $(DEPMOD) -ae -F System.map \
+ $(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) -r) \
+ $(KERNELRELEASE); \
+ fi
+
+ # Create temporary dir for module support files
+ # clean it up only when building all modules
+ cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
+ $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
- a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \
- $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+ a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
+ $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
quiet_cmd_as_o_S = AS $@
config ARCH_NS9XXX
bool "NetSilicon NS9xxx"
+ select GENERIC_GPIO
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
help
Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
System.
This enables support for Philips PNX4008 mobile platform.
config ARCH_PXA
- bool "PXA2xx-based"
+ bool "PXA2xx/PXA3xx-based"
depends on MMU
select ARCH_MTD_XIP
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
- Support for Intel's PXA2XX processor line.
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
config ARCH_RPC
bool "RiscPC"
bool "TI OMAP"
select GENERIC_GPIO
select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
help
- Support for TI's OMAP platform (OMAP1 and OMAP2).
+ Support for TI's OMAP platform (OMAP1, OMAP2 and OMAP3).
endchoice
config IWMMXT
bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3
- default y if PXA27x
+ default y if PXA27x || PXA3xx
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
- but it is indepedent of the system firmware. And like a reboot
+ but it is independent of the system firmware. And like a reboot
you can start any kernel with it, not just Linux.
It is an ongoing process to be certain the hardware in a machine
config VFP
bool "VFP-format floating point maths"
- depends on CPU_V6 || CPU_ARM926T
+ depends on CPU_V6 || CPU_ARM926T || CPU_V7
help
Say Y to include VFP support code in the kernel. This is needed
if your hardware includes a VFP unit.
Say N if your target does not have VFP hardware.
+config VFPv3
+ bool
+ depends on VFP
+ default y if CPU_V7
+
+config NEON
+ bool "NEON Advanced SIMD Extension support"
+ depends on VFPv3 && CPU_V7
+ help
+ Say Y to include support code for NEON, the ARMv7 Advanced SIMD
+ Extensions.
+
endmenu
menu "Userspace binary formats"
source "drivers/block/Kconfig"
+ # misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
+
+ source "drivers/misc/Kconfig"
+
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
source "drivers/w1/Kconfig"
+ source "drivers/power/Kconfig"
+
source "drivers/hwmon/Kconfig"
- #source "drivers/l3/Kconfig"
+ source "drivers/ssb/Kconfig"
- source "drivers/misc/Kconfig"
+ #source "drivers/l3/Kconfig"
source "drivers/mfd/Kconfig"
- source "drivers/leds/Kconfig"
-
source "drivers/media/Kconfig"
source "drivers/video/Kconfig"
source "drivers/mmc/Kconfig"
+ source "drivers/leds/Kconfig"
+
source "drivers/rtc/Kconfig"
source "drivers/dma/Kconfig"
+if ARCH_OMAP
+source "drivers/cbus/Kconfig"
+endif
+
endmenu
source "fs/Kconfig"
- source "arch/arm/oprofile/Kconfig"
+ source "kernel/Kconfig.instrumentation"
source "arch/arm/Kconfig.debug"
LDFLAGS_vmlinux :=-p --no-undefined -X
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
- OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
+ OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9
- #CFLAGS +=-pipe
+ #KBUILD_CFLAGS +=-pipe
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
- CFLAGS +=$(call cc-option,-marm,)
+ KBUILD_CFLAGS +=$(call cc-option,-marm,)
# Do not use arch/arm/defconfig - it's always outdated.
# Select a platform tht is kept up-to-date
endif
ifeq ($(CONFIG_FRAME_POINTER),y)
- CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
+ KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
endif
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
- CPPFLAGS += -mbig-endian
+ KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
LD += -EB
else
- CPPFLAGS += -mlittle-endian
+ KBUILD_CPPFLAGS += -mlittle-endian
AS += -EL
LD += -EL
endif
endif
# Need -Uarm for gcc < 3.x
- CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
- AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
+ KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+ KBUILD_AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
CHECKFLAGS += -D__arm__
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
machine-$(CONFIG_ARCH_OMAP1) := omap1
machine-$(CONFIG_ARCH_OMAP2) := omap2
+ machine-$(CONFIG_ARCH_OMAP3) := omap2
incdir-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
OBJS += head-at91rm9200.o
endif
+ifeq ($(CONFIG_MACH_OMAP_PERSEUS2),y)
+OBJS += head-omap.o
+endif
+
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
ifeq ($(CONFIG_CPU_CP15),y)
OBJS += big-endian.o
LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
endif
LDFLAGS_vmlinux += -p --no-undefined -X \
- $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -T
+ $(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T
# Don't allow any static data in misc.o, which
# would otherwise mess up our GOT table
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+ #include <linux/i2c.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <asm/hardware.h>
+ #include <asm/gpio.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
- #include <asm/arch/gpio.h>
#include <asm/arch/usb.h>
+ #include <asm/arch/tps65010.h>
#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
#include <asm/arch/common.h>
&osk5912_mcbsp1_device,
};
+ static struct i2c_board_info __initdata osk_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("tps65010", 0x48),
+ .type = "tps65010",
+ .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)),
+ },
+ /* TODO when driver support is ready:
+ * - aic23 audio chip at 0x1a
+ * - on Mistral, 24c04 eeprom at 0x50
+ * - optionally on Mistral, ov9640 camera sensor at 0x30
+ */
+ };
+
static void __init osk_init_smc91x(void)
{
if ((omap_request_gpio(0)) < 0) {
};
#endif
-static struct omap_board_config_kernel osk_config[] = {
+static struct omap_board_config_kernel osk_config[] __initdata = {
{ OMAP_TAG_USB, &osk_usb_config },
{ OMAP_TAG_UART, &osk_uart_config },
#ifdef CONFIG_OMAP_OSK_MISTRAL
omap_board_config_size = ARRAY_SIZE(osk_config);
USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+ /* irq for tps65010 chip */
+ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */
+ if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0)
+ gpio_direction_input(OMAP_MPUIO(1));
+
+ i2c_register_board_info(1, osk_i2c_board_info,
+ ARRAY_SIZE(osk_i2c_board_info));
+
omap_serial_init();
osk_mistral_init();
}
omap1_map_common_io();
}
+ #ifdef CONFIG_TPS65010
+ static int __init osk_tps_init(void)
+ {
+ if (!machine_is_omap_osk())
+ return 0;
+
+ /* Let LED1 (D9) blink */
+ tps65010_set_led(LED1, BLINK);
+
+ /* Disable LED 2 (D2) */
+ tps65010_set_led(LED2, OFF);
+
+ /* Set GPIO 1 HIGH to disable VBUS power supply;
+ * OHCI driver powers it up/down as needed.
+ */
+ tps65010_set_gpio_out_value(GPIO1, HIGH);
+
+ /* Set GPIO 2 low to turn on LED D3 */
+ tps65010_set_gpio_out_value(GPIO2, HIGH);
+
+ /* Set GPIO 3 low to take ethernet out of reset */
+ tps65010_set_gpio_out_value(GPIO3, LOW);
+
+ /* gpio4 for VDD_DSP */
+ /* FIXME send power to DSP iff it's configured */
+
+ /* Enable LOW_PWR */
+ tps65010_set_low_pwr(ON);
+
+ /* Switch VLDO2 to 3.0V for AIC23 */
+ tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V
+ | TPS_LDO1_ENABLE);
+
+ return 0;
+ }
+ fs_initcall(osk_tps_init);
+ #endif
+
MACHINE_START(OMAP_OSK, "TI-OSK")
/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
.phys_io = 0xfff00000,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
- #include <linux/pm.h>
+ #include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
- #include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
.store = omap_pm_sleep_while_idle_store,
};
-extern struct kset power_subsys;
static void (*omap_sram_idle)(void) = NULL;
static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
/*
* omap_pm_prepare - Do preliminary suspend work.
- * @state: suspend state we're entering.
*
*/
- static int omap_pm_prepare(suspend_state_t state)
+ static int omap_pm_prepare(void)
{
- int error = 0;
-
/* We cannot sleep in idle until we have resumed */
saved_idle = pm_idle;
pm_idle = NULL;
- switch (state)
- {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- break;
- default:
- return -EINVAL;
- }
-
- return error;
+ return 0;
}
/**
* omap_pm_finish - Finish up suspend sequence.
- * @state: State we're coming out of.
*
* This is called after we wake back up (or if entering the sleep state
* failed).
*/
- static int omap_pm_finish(suspend_state_t state)
+ static void omap_pm_finish(void)
{
pm_idle = saved_idle;
- return 0;
}
- static struct pm_ops omap_pm_ops ={
+ static struct platform_suspend_ops omap_pm_ops ={
.prepare = omap_pm_prepare,
.enter = omap_pm_enter,
.finish = omap_pm_finish,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
static int __init omap_pm_init(void)
else if (cpu_is_omap16xx())
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
- pm_set_ops(&omap_pm_ops);
+ suspend_set_ops(&omap_pm_ops);
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
omap_pm_init_proc();
*
* OMAP2 Power Management Routines
*
+ * Copyright (C) 2005 Texas Instruments, Inc.
* Copyright (C) 2006 Nokia Corporation
- * Tony Lindgren <tony@atomide.com>
*
- * Copyright (C) 2005 Texas Instruments, Inc.
+ * Written by:
* Richard Woodruff <r-woodruff2@ti.com>
+ * Tony Lindgren
+ * Juha Yrjola
+ * Amit Kucheria <amit.kucheria@nokia.com>
+ * Igor Stoppa <igor.stoppa@nokia.com>
*
* Based on pm.c for omap1
*
* published by the Free Software Foundation.
*/
- #include <linux/pm.h>
+ #include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/irqs.h>
#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
+#include <asm/arch/gpio.h>
#include <asm/arch/pm.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
-#include "prcm-regs.h"
+#include "prm.h"
+#include "prm_regbits_24xx.h"
+#include "cm.h"
+#include "cm_regbits_24xx.h"
+#include "sdrc.h"
-static struct clk *vclk;
static void (*omap2_sram_idle)(void);
-static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
+static void (*omap2_sram_suspend)(void __iomem *dllctrl);
static void (*saved_idle)(void);
-extern void __init pmdomain_init(void);
-extern void pmdomain_set_autoidle(void);
+static u32 omap2_read_32k_sync_counter(void)
+{
+ return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010);
+}
+
+#ifdef CONFIG_PM_DEBUG
+int omap2_pm_debug = 0;
-static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
+static int serial_console_clock_disabled;
+static int serial_console_uart;
+static unsigned int serial_console_next_disable;
-void omap2_pm_idle(void)
+static struct clk *console_iclk, *console_fclk;
+
+static void serial_console_kick(void)
{
- local_irq_disable();
- local_fiq_disable();
- if (need_resched()) {
- local_fiq_enable();
- local_irq_enable();
+ serial_console_next_disable = omap2_read_32k_sync_counter();
+ /* Keep the clocks on for 4 secs */
+ serial_console_next_disable += 4 * 32768;
+}
+
+static void serial_wait_tx(void)
+{
+ static const unsigned long uart_bases[3] = {
+ 0x4806a000, 0x4806c000, 0x4806e000
+ };
+ unsigned long lsr_reg;
+ int looped = 0;
+
+ /* Wait for TX FIFO and THR to get empty */
+ lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 << 2));
+ while ((__raw_readb(lsr_reg) & 0x60) != 0x60)
+ looped = 1;
+ if (looped)
+ serial_console_kick();
+}
+
+static void serial_console_fclk_mask(u32 *f1, u32 *f2)
+{
+ switch (serial_console_uart) {
+ case 1:
+ *f1 &= ~(1 << 21);
+ break;
+ case 2:
+ *f1 &= ~(1 << 22);
+ break;
+ case 3:
+ *f2 &= ~(1 << 2);
+ break;
+ }
+}
+
+static void serial_console_sleep(int enable)
+{
+ if (console_iclk == NULL || console_fclk == NULL)
return;
+
+ if (enable) {
+ BUG_ON(serial_console_clock_disabled);
+ if (clk_get_usecount(console_fclk) == 0)
+ return;
+ if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0)
+ return;
+ serial_wait_tx();
+ clk_disable(console_iclk);
+ clk_disable(console_fclk);
+ serial_console_clock_disabled = 1;
+ } else {
+ int serial_wakeup = 0;
+ u32 l;
+
+ switch (serial_console_uart) {
+ case 1:
+ l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
+ if (l & OMAP24XX_ST_UART1)
+ serial_wakeup = 1;
+ break;
+ case 2:
+ l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
+ if (l & OMAP24XX_ST_UART2)
+ serial_wakeup = 1;
+ break;
+ case 3:
+ l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2);
+ if (l & OMAP24XX_ST_UART3)
+ serial_wakeup = 1;
+ break;
+ }
+ if (serial_wakeup)
+ serial_console_kick();
+ if (!serial_console_clock_disabled)
+ return;
+ clk_enable(console_iclk);
+ clk_enable(console_fclk);
+ serial_console_clock_disabled = 0;
}
+}
- /*
- * Since an interrupt may set up a timer, we don't want to
- * reprogram the hardware timer with interrupts enabled.
- * Re-enable interrupts only after returning from idle.
- */
- timer_dyn_reprogram();
+static void pm_init_serial_console(void)
+{
+ const struct omap_serial_console_config *conf;
+ char name[16];
+ u32 l;
- omap2_sram_idle();
- local_fiq_enable();
- local_irq_enable();
+ conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
+ struct omap_serial_console_config);
+ if (conf == NULL)
+ return;
+ if (conf->console_uart > 3 || conf->console_uart < 1)
+ return;
+ serial_console_uart = conf->console_uart;
+ sprintf(name, "uart%d_fck", conf->console_uart);
+ console_fclk = clk_get(NULL, name);
+ if (IS_ERR(console_fclk))
+ console_fclk = NULL;
+ name[6] = 'i';
+ console_iclk = clk_get(NULL, name);
+ if (IS_ERR(console_fclk))
+ console_iclk = NULL;
+ if (console_fclk == NULL || console_iclk == NULL) {
+ serial_console_uart = 0;
+ return;
+ }
+ switch (serial_console_uart) {
+ case 1:
+ l = prm_read_mod_reg(CORE_MOD, PM_WKEN1);
+ l |= OMAP24XX_ST_UART1;
+ prm_write_mod_reg(l, CORE_MOD, PM_WKEN1);
+ break;
+ case 2:
+ l = prm_read_mod_reg(CORE_MOD, PM_WKEN1);
+ l |= OMAP24XX_ST_UART2;
+ prm_write_mod_reg(l, CORE_MOD, PM_WKEN1);
+ break;
+ case 3:
+ l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKEN2);
+ l |= OMAP24XX_ST_UART3;
+ prm_write_mod_reg(l, CORE_MOD, OMAP24XX_PM_WKEN2);
+ break;
+ }
}
-static int omap2_pm_prepare(void)
+#define DUMP_PRM_MOD_REG(mod, reg) \
+ regs[reg_count].name = #mod "." #reg; \
+ regs[reg_count++].val = prm_read_mod_reg(mod, reg)
+#define DUMP_CM_MOD_REG(mod, reg) \
+ regs[reg_count].name = #mod "." #reg; \
+ regs[reg_count++].val = cm_read_mod_reg(mod, reg)
+#define DUMP_PRM_REG(reg) \
+ regs[reg_count].name = #reg; \
+ regs[reg_count++].val = prm_read_reg(reg)
+#define DUMP_CM_REG(reg) \
+ regs[reg_count].name = #reg; \
+ regs[reg_count++].val = cm_read_reg(reg)
+#define DUMP_INTC_REG(reg, off) \
+ regs[reg_count].name = #reg; \
+ regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off)))
+
+static void omap2_pm_dump(int mode, int resume, unsigned int us)
{
- /* We cannot sleep in idle until we have resumed */
- saved_idle = pm_idle;
- pm_idle = NULL;
- return 0;
+ struct reg {
+ const char *name;
+ u32 val;
+ } regs[32];
+ int reg_count = 0, i;
+ const char *s1 = NULL, *s2 = NULL;
+
+ if (!resume) {
+#if 0
+ /* MPU */
+ DUMP_PRM_REG(OMAP24XX_PRCM_IRQENABLE_MPU);
+ DUMP_CM_MOD_REG(MPU_MOD, CM_CLKSTCTRL);
+ DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTCTRL);
+ DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTST);
+ DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
+#endif
+#if 0
+ /* INTC */
+ DUMP_INTC_REG(INTC_MIR0, 0x0084);
+ DUMP_INTC_REG(INTC_MIR1, 0x00a4);
+ DUMP_INTC_REG(INTC_MIR2, 0x00c4);
+#endif
+#if 0
+ DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
+ DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN2);
+ DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
+ DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
+ DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
+ DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
+ DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN_PLL);
+ DUMP_PRM_REG(OMAP24XX_PRCM_CLKEMUL_CTRL);
+ DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
+ DUMP_PRM_MOD_REG(CORE_REG, PM_PWSTST);
+ DUMP_PRM_REG(OMAP24XX_PRCM_CLKSRC_CTRL);
+#endif
+#if 0
+ /* DSP */
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTCTRL);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTST);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTCTRL);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTST);
+#endif
+ } else {
+ DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
+ DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
+ DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
+ DUMP_PRM_REG(OMAP24XX_PRCM_IRQSTATUS_MPU);
+#if 1
+ DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
+ DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
+ DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
+#endif
+ }
+
+ switch (mode) {
+ case 0:
+ s1 = "full";
+ s2 = "retention";
+ break;
+ case 1:
+ s1 = "MPU";
+ s2 = "retention";
+ break;
+ case 2:
+ s1 = "MPU";
+ s2 = "idle";
+ break;
+ }
+
+ if (!resume)
+#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ)
+ printk("--- Going to %s %s (next timer after %u ms)\n", s1, s2,
+ jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
+ jiffies));
+#else
+ printk("--- Going to %s %s\n", s1, s2);
+#endif
+ else
+ printk("--- Woke up (slept for %u.%03u ms)\n", us / 1000, us % 1000);
+ for (i = 0; i < reg_count; i++)
+ printk("%-20s: 0x%08x\n", regs[i].name, regs[i].val);
}
-#define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \
- OMAP_IRQ_BIT(INT_24XX_GPIO_BANK2) | \
- OMAP_IRQ_BIT(INT_24XX_GPIO_BANK3))
+#else
+static inline void serial_console_sleep(int enable) {}
+static inline void pm_init_serial_console(void) {}
+static inline void omap2_pm_dump(int mode, int resume, unsigned int us) {}
+static inline void serial_console_fclk_mask(u32 *f1, u32 *f2) {}
-#define INT1_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK4))
+#define omap2_pm_debug 0
-#define INT2_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_UART1_IRQ) | \
- OMAP_IRQ_BIT(INT_24XX_UART2_IRQ) | \
- OMAP_IRQ_BIT(INT_24XX_UART3_IRQ))
+#endif
-#define preg(reg) printk("%s\t(0x%p):\t0x%08x\n", #reg, ®, reg);
+static unsigned short enable_dyn_sleep = 0; /* disabled till drivers are fixed */
-static void omap2_pm_debug(char * desc)
+static ssize_t omap_pm_sleep_while_idle_show(struct kset * subsys, char *buf)
{
- printk("%s:\n", desc);
-
- preg(CM_CLKSTCTRL_MPU);
- preg(CM_CLKSTCTRL_CORE);
- preg(CM_CLKSTCTRL_GFX);
- preg(CM_CLKSTCTRL_DSP);
- preg(CM_CLKSTCTRL_MDM);
-
- preg(PM_PWSTCTRL_MPU);
- preg(PM_PWSTCTRL_CORE);
- preg(PM_PWSTCTRL_GFX);
- preg(PM_PWSTCTRL_DSP);
- preg(PM_PWSTCTRL_MDM);
-
- preg(PM_PWSTST_MPU);
- preg(PM_PWSTST_CORE);
- preg(PM_PWSTST_GFX);
- preg(PM_PWSTST_DSP);
- preg(PM_PWSTST_MDM);
-
- preg(CM_AUTOIDLE1_CORE);
- preg(CM_AUTOIDLE2_CORE);
- preg(CM_AUTOIDLE3_CORE);
- preg(CM_AUTOIDLE4_CORE);
- preg(CM_AUTOIDLE_WKUP);
- preg(CM_AUTOIDLE_PLL);
- preg(CM_AUTOIDLE_DSP);
- preg(CM_AUTOIDLE_MDM);
-
- preg(CM_ICLKEN1_CORE);
- preg(CM_ICLKEN2_CORE);
- preg(CM_ICLKEN3_CORE);
- preg(CM_ICLKEN4_CORE);
- preg(CM_ICLKEN_GFX);
- preg(CM_ICLKEN_WKUP);
- preg(CM_ICLKEN_DSP);
- preg(CM_ICLKEN_MDM);
-
- preg(CM_IDLEST1_CORE);
- preg(CM_IDLEST2_CORE);
- preg(CM_IDLEST3_CORE);
- preg(CM_IDLEST4_CORE);
- preg(CM_IDLEST_GFX);
- preg(CM_IDLEST_WKUP);
- preg(CM_IDLEST_CKGEN);
- preg(CM_IDLEST_DSP);
- preg(CM_IDLEST_MDM);
-
- preg(RM_RSTST_MPU);
- preg(RM_RSTST_GFX);
- preg(RM_RSTST_WKUP);
- preg(RM_RSTST_DSP);
- preg(RM_RSTST_MDM);
-
- preg(PM_WKDEP_MPU);
- preg(PM_WKDEP_CORE);
- preg(PM_WKDEP_GFX);
- preg(PM_WKDEP_DSP);
- preg(PM_WKDEP_MDM);
-
- preg(CM_FCLKEN_WKUP);
- preg(CM_ICLKEN_WKUP);
- preg(CM_IDLEST_WKUP);
- preg(CM_AUTOIDLE_WKUP);
- preg(CM_CLKSEL_WKUP);
-
- preg(PM_WKEN_WKUP);
- preg(PM_WKST_WKUP);
+ return sprintf(buf, "%hu\n", enable_dyn_sleep);
}
-static inline void omap2_pm_save_registers(void)
+static ssize_t omap_pm_sleep_while_idle_store(struct kset * subsys,
+ const char * buf,
+ size_t n)
{
- /* Save interrupt registers */
- OMAP24XX_SAVE(INTC_MIR0);
- OMAP24XX_SAVE(INTC_MIR1);
- OMAP24XX_SAVE(INTC_MIR2);
-
- /* Save power control registers */
- OMAP24XX_SAVE(CM_CLKSTCTRL_MPU);
- OMAP24XX_SAVE(CM_CLKSTCTRL_CORE);
- OMAP24XX_SAVE(CM_CLKSTCTRL_GFX);
- OMAP24XX_SAVE(CM_CLKSTCTRL_DSP);
- OMAP24XX_SAVE(CM_CLKSTCTRL_MDM);
-
- /* Save power state registers */
- OMAP24XX_SAVE(PM_PWSTCTRL_MPU);
- OMAP24XX_SAVE(PM_PWSTCTRL_CORE);
- OMAP24XX_SAVE(PM_PWSTCTRL_GFX);
- OMAP24XX_SAVE(PM_PWSTCTRL_DSP);
- OMAP24XX_SAVE(PM_PWSTCTRL_MDM);
-
- /* Save autoidle registers */
- OMAP24XX_SAVE(CM_AUTOIDLE1_CORE);
- OMAP24XX_SAVE(CM_AUTOIDLE2_CORE);
- OMAP24XX_SAVE(CM_AUTOIDLE3_CORE);
- OMAP24XX_SAVE(CM_AUTOIDLE4_CORE);
- OMAP24XX_SAVE(CM_AUTOIDLE_WKUP);
- OMAP24XX_SAVE(CM_AUTOIDLE_PLL);
- OMAP24XX_SAVE(CM_AUTOIDLE_DSP);
- OMAP24XX_SAVE(CM_AUTOIDLE_MDM);
-
- /* Save idle state registers */
- OMAP24XX_SAVE(CM_IDLEST1_CORE);
- OMAP24XX_SAVE(CM_IDLEST2_CORE);
- OMAP24XX_SAVE(CM_IDLEST3_CORE);
- OMAP24XX_SAVE(CM_IDLEST4_CORE);
- OMAP24XX_SAVE(CM_IDLEST_GFX);
- OMAP24XX_SAVE(CM_IDLEST_WKUP);
- OMAP24XX_SAVE(CM_IDLEST_CKGEN);
- OMAP24XX_SAVE(CM_IDLEST_DSP);
- OMAP24XX_SAVE(CM_IDLEST_MDM);
-
- /* Save clock registers */
- OMAP24XX_SAVE(CM_FCLKEN1_CORE);
- OMAP24XX_SAVE(CM_FCLKEN2_CORE);
- OMAP24XX_SAVE(CM_ICLKEN1_CORE);
- OMAP24XX_SAVE(CM_ICLKEN2_CORE);
- OMAP24XX_SAVE(CM_ICLKEN3_CORE);
- OMAP24XX_SAVE(CM_ICLKEN4_CORE);
+ unsigned short value;
+ if (sscanf(buf, "%hu", &value) != 1 ||
+ (value != 0 && value != 1)) {
+ printk(KERN_ERR "idle_sleep_store: Invalid value\n");
+ return -EINVAL;
+ }
+ enable_dyn_sleep = value;
+ return n;
}
-static inline void omap2_pm_restore_registers(void)
+static struct subsys_attribute sleep_while_idle_attr = {
+ .attr = {
+ .name = __stringify(sleep_while_idle),
+ .mode = 0644,
+ },
+ .show = omap_pm_sleep_while_idle_show,
+ .store = omap_pm_sleep_while_idle_store,
+};
+
+static struct clk *osc_ck, *emul_ck;
+
+#define CONTROL_DEVCONF __REG32(OMAP2_CTRL_BASE + 0x274)
+
+static int omap2_fclks_active(void)
{
- /* Restore clock state registers */
- OMAP24XX_RESTORE(CM_CLKSTCTRL_MPU);
- OMAP24XX_RESTORE(CM_CLKSTCTRL_CORE);
- OMAP24XX_RESTORE(CM_CLKSTCTRL_GFX);
- OMAP24XX_RESTORE(CM_CLKSTCTRL_DSP);
- OMAP24XX_RESTORE(CM_CLKSTCTRL_MDM);
-
- /* Restore power state registers */
- OMAP24XX_RESTORE(PM_PWSTCTRL_MPU);
- OMAP24XX_RESTORE(PM_PWSTCTRL_CORE);
- OMAP24XX_RESTORE(PM_PWSTCTRL_GFX);
- OMAP24XX_RESTORE(PM_PWSTCTRL_DSP);
- OMAP24XX_RESTORE(PM_PWSTCTRL_MDM);
-
- /* Restore idle state registers */
- OMAP24XX_RESTORE(CM_IDLEST1_CORE);
- OMAP24XX_RESTORE(CM_IDLEST2_CORE);
- OMAP24XX_RESTORE(CM_IDLEST3_CORE);
- OMAP24XX_RESTORE(CM_IDLEST4_CORE);
- OMAP24XX_RESTORE(CM_IDLEST_GFX);
- OMAP24XX_RESTORE(CM_IDLEST_WKUP);
- OMAP24XX_RESTORE(CM_IDLEST_CKGEN);
- OMAP24XX_RESTORE(CM_IDLEST_DSP);
- OMAP24XX_RESTORE(CM_IDLEST_MDM);
-
- /* Restore autoidle registers */
- OMAP24XX_RESTORE(CM_AUTOIDLE1_CORE);
- OMAP24XX_RESTORE(CM_AUTOIDLE2_CORE);
- OMAP24XX_RESTORE(CM_AUTOIDLE3_CORE);
- OMAP24XX_RESTORE(CM_AUTOIDLE4_CORE);
- OMAP24XX_RESTORE(CM_AUTOIDLE_WKUP);
- OMAP24XX_RESTORE(CM_AUTOIDLE_PLL);
- OMAP24XX_RESTORE(CM_AUTOIDLE_DSP);
- OMAP24XX_RESTORE(CM_AUTOIDLE_MDM);
-
- /* Restore clock registers */
- OMAP24XX_RESTORE(CM_FCLKEN1_CORE);
- OMAP24XX_RESTORE(CM_FCLKEN2_CORE);
- OMAP24XX_RESTORE(CM_ICLKEN1_CORE);
- OMAP24XX_RESTORE(CM_ICLKEN2_CORE);
- OMAP24XX_RESTORE(CM_ICLKEN3_CORE);
- OMAP24XX_RESTORE(CM_ICLKEN4_CORE);
-
- /* REVISIT: Clear interrupts here */
-
- /* Restore interrupt registers */
- OMAP24XX_RESTORE(INTC_MIR0);
- OMAP24XX_RESTORE(INTC_MIR1);
- OMAP24XX_RESTORE(INTC_MIR2);
+ u32 f1, f2;
+
+ f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+ serial_console_fclk_mask(&f1, &f2);
+ if (f1 | f2)
+ return 1;
+ return 0;
}
-static int omap2_pm_suspend(void)
+static int omap2_irq_pending(void)
{
- int processor_type = 0;
+ u32 pending_reg = IO_ADDRESS(0x480fe098);
+ int i;
- /* REVISIT: 0x21 or 0x26? */
- if (cpu_is_omap2420())
- processor_type = 0x21;
+ for (i = 0; i < 4; i++) {
+ if (__raw_readl(pending_reg))
+ return 1;
+ pending_reg += 0x20;
+ }
+ return 0;
+}
- if (!processor_type)
- return -ENOTSUPP;
+static atomic_t sleep_block = ATOMIC_INIT(0);
- local_irq_disable();
- local_fiq_disable();
+void omap2_block_sleep(void)
+{
+ atomic_inc(&sleep_block);
+}
- omap2_pm_save_registers();
+void omap2_allow_sleep(void)
+{
+ int i;
- /* Disable interrupts except for the wake events */
- INTC_MIR_SET0 = 0xffffffff & ~INT0_WAKE_MASK;
- INTC_MIR_SET1 = 0xffffffff & ~INT1_WAKE_MASK;
- INTC_MIR_SET2 = 0xffffffff & ~INT2_WAKE_MASK;
+ i = atomic_dec_return(&sleep_block);
+ BUG_ON(i < 0);
+}
- pmdomain_set_autoidle();
+static void omap2_enter_full_retention(void)
+{
+ u32 sleep_time = 0;
+
+ /* There is 1 reference hold for all children of the oscillator
+ * clock, the following will remove it. If no one else uses the
+ * oscillator itself it will be disabled if/when we enter retention
+ * mode.
+ */
+ clk_disable(osc_ck);
/* Clear old wake-up events */
- PM_WKST1_CORE = 0;
- PM_WKST2_CORE = 0;
- PM_WKST_WKUP = 0;
+ /* REVISIT: These write to reserved bits? */
+ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
- /* Enable wake-up events */
- PM_WKEN1_CORE = (1 << 22) | (1 << 21); /* UART1 & 2 */
- PM_WKEN2_CORE = (1 << 2); /* UART3 */
- PM_WKEN_WKUP = (1 << 2) | (1 << 0); /* GPIO & GPT1 */
+ /* Try to enter retention */
+ prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | OMAP_LOGICRETSTATE,
+ MPU_MOD, PM_PWSTCTRL);
+
+ /* Workaround to kill USB */
+ CONTROL_DEVCONF |= 0x00008000;
- /* Disable clocks except for CM_ICLKEN2_CORE. It gets disabled
- * in the SRAM suspend code */
- CM_FCLKEN1_CORE = 0;
- CM_FCLKEN2_CORE = 0;
- CM_ICLKEN1_CORE = 0;
- CM_ICLKEN3_CORE = 0;
- CM_ICLKEN4_CORE = 0;
+ omap2_gpio_prepare_for_retention();
- omap2_pm_debug("Status before suspend");
+ if (omap2_pm_debug) {
+ omap2_pm_dump(0, 0, 0);
+ sleep_time = omap2_read_32k_sync_counter();
+ }
+
+ /* One last check for pending IRQs to avoid extra latency due
+ * to sleeping unnecessarily. */
+ if (omap2_irq_pending())
+ goto no_sleep;
+
+ serial_console_sleep(1);
+ /* Jump to SRAM suspend code */
+ omap2_sram_suspend(OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL));
+no_sleep:
+ serial_console_sleep(0);
+
+ if (omap2_pm_debug) {
+ unsigned long long tmp;
+ u32 resume_time;
+
+ resume_time = omap2_read_32k_sync_counter();
+ tmp = resume_time - sleep_time;
+ tmp *= 1000000;
+ omap2_pm_dump(0, 1, tmp / 32768);
+ }
+ omap2_gpio_resume_after_retention();
+
+ clk_enable(osc_ck);
+
+}
+
+static int omap2_i2c_active(void)
+{
+ u32 l;
+
+ l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ return l & (OMAP2420_EN_I2C2 | OMAP2420_EN_I2C1);
+}
+
+static int sti_console_enabled;
+
+static int omap2_allow_mpu_retention(void)
+{
+ u32 l;
+
+ if (atomic_read(&sleep_block))
+ return 0;
+
+ /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
+ l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ if (l & (OMAP2420_EN_MMC | OMAP24XX_EN_UART2 |
+ OMAP24XX_EN_UART1 | OMAP24XX_EN_MCSPI2 |
+ OMAP24XX_EN_MCSPI1 | OMAP24XX_EN_DSS1))
+ return 0;
+ /* Check for UART3. */
+ l = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+ if (l & OMAP24XX_EN_UART3)
+ return 0;
+ if (sti_console_enabled)
+ return 0;
+
+ return 1;
+}
+
+static void omap2_enter_mpu_retention(void)
+{
+ u32 sleep_time = 0;
+ int only_idle = 0;
+
+ /* Putting MPU into the WFI state while a transfer is active
+ * seems to cause the I2C block to timeout. Why? Good question. */
+ if (omap2_i2c_active())
+ return;
+
+ /* The peripherals seem not to be able to wake up the MPU when
+ * it is in retention mode. */
+ if (omap2_allow_mpu_retention()) {
+ /* REVISIT: These write to reserved bits? */
+ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
+
+ /* Try to enter MPU retention */
+ prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
+ OMAP_LOGICRETSTATE,
+ MPU_MOD, PM_PWSTCTRL);
+ } else {
+ /* Block MPU retention */
+
+ prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD, PM_PWSTCTRL);
+ only_idle = 1;
+ }
+
+ if (omap2_pm_debug) {
+ omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
+ sleep_time = omap2_read_32k_sync_counter();
+ }
+
+ omap2_sram_idle();
- /* Must wait for serial buffers to clear */
- mdelay(200);
+ if (omap2_pm_debug) {
+ unsigned long long tmp;
+ u32 resume_time;
- /* Jump to SRAM suspend code
- * REVISIT: When is this SDRC_DLLB_CTRL?
+ resume_time = omap2_read_32k_sync_counter();
+ tmp = resume_time - sleep_time;
+ tmp *= 1000000;
+ omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768);
+ }
+}
+
+static int omap2_can_sleep(void)
+{
+ if (!enable_dyn_sleep)
+ return 0;
+ if (omap2_fclks_active())
+ return 0;
+ if (atomic_read(&sleep_block) > 0)
+ return 0;
+ if (clk_get_usecount(osc_ck) > 1)
+ return 0;
+ if (omap_dma_running())
+ return 0;
+
+ return 1;
+}
+
+static void omap2_pm_idle(void)
+{
+ local_irq_disable();
+ local_fiq_disable();
+
+ if (!omap2_can_sleep()) {
+ /* timer_dyn_reprogram() takes about 100-200 us to complete.
+ * In some contexts (e.g. when waiting for a GPMC-SDRAM DMA
+ * transfer to complete), the increased latency is too much.
+ *
+ * omap2_block_sleep() and omap2_allow_sleep() can be used
+ * to indicate this.
+ */
+ if (atomic_read(&sleep_block) == 0) {
+ timer_dyn_reprogram();
+ if (omap2_irq_pending())
+ goto out;
+ }
+ omap2_enter_mpu_retention();
+ goto out;
+ }
+
+ /*
+ * Since an interrupt may set up a timer, we don't want to
+ * reprogram the hardware timer with interrupts enabled.
+ * Re-enable interrupts only after returning from idle.
*/
- omap2_sram_suspend(SDRC_DLLA_CTRL, processor_type);
+ timer_dyn_reprogram();
- /* Back from sleep */
- omap2_pm_restore_registers();
+ if (omap2_irq_pending())
+ goto out;
+ omap2_enter_full_retention();
+
+out:
local_fiq_enable();
local_irq_enable();
- static int omap2_pm_prepare(suspend_state_t state)
+}
+
- int error = 0;
-
++static int omap2_pm_prepare(void)
+{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- break;
- default:
- return -EINVAL;
- }
-
- return error;
+ /* We cannot sleep in idle until we have resumed */
+ saved_idle = pm_idle;
+ pm_idle = NULL;
+
++ return 0;
+}
+
+static int omap2_pm_suspend(void)
+{
+ u32 wken_wkup, mir1;
+
+ wken_wkup = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+ prm_write_mod_reg(wken_wkup & ~OMAP24XX_EN_GPT1, WKUP_MOD, PM_WKEN);
+
+ /* Mask GPT1 */
+ mir1 = omap_readl(0x480fe0a4);
+ omap_writel(1 << 5, 0x480fe0ac);
+
+ omap2_enter_full_retention();
+
+ omap_writel(mir1, 0x480fe0a4);
+ prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
return 0;
}
{
int ret = 0;
- switch (state)
- {
+ switch (state) {
case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM:
ret = omap2_pm_suspend();
return ret;
}
- static int omap2_pm_finish(suspend_state_t state)
+ static void omap2_pm_finish(void)
{
pm_idle = saved_idle;
- return 0;
}
- static struct pm_ops omap_pm_ops = {
+ static struct platform_suspend_ops omap_pm_ops = {
.prepare = omap2_pm_prepare,
.enter = omap2_pm_enter,
.finish = omap2_pm_finish,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
+static void __init prcm_setup_regs(void)
+{
+ u32 l;
+
+ /* Enable autoidle */
+ prm_write_reg(OMAP24XX_AUTOIDLE, OMAP24XX_PRCM_SYSCONFIG);
+
+ /* Set all domain wakeup dependencies */
+ prm_write_mod_reg(OMAP_EN_WKUP, MPU_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, OMAP24XX_DSP_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
+
+ l = prm_read_mod_reg(CORE_MOD, PM_PWSTCTRL);
+ /* Enable retention for all memory blocks */
+ l |= OMAP24XX_MEM3RETSTATE | OMAP24XX_MEM2RETSTATE |
+ OMAP24XX_MEM1RETSTATE;
+
+ /* Set power state to RETENTION */
+ l &= ~OMAP_POWERSTATE_MASK;
+ l |= 0x01 << OMAP_POWERSTATE_SHIFT;
+ prm_write_mod_reg(l, CORE_MOD, PM_PWSTCTRL);
+
+ prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
+ OMAP_LOGICRETSTATE,
+ MPU_MOD, PM_PWSTCTRL);
+
+ /* Power down DSP and GFX */
+ prm_write_mod_reg(OMAP24XX_FORCESTATE | (0x3 << OMAP_POWERSTATE_SHIFT),
+ OMAP24XX_DSP_MOD, PM_PWSTCTRL);
+ prm_write_mod_reg(OMAP24XX_FORCESTATE | (0x3 << OMAP_POWERSTATE_SHIFT),
+ GFX_MOD, PM_PWSTCTRL);
+
+ /* Enable clock auto control for all domains */
+ cm_write_mod_reg(OMAP24XX_AUTOSTATE_MPU, MPU_MOD, CM_CLKSTCTRL);
+ cm_write_mod_reg(OMAP24XX_AUTOSTATE_DSS | OMAP24XX_AUTOSTATE_L4 |
+ OMAP24XX_AUTOSTATE_L3,
+ CORE_MOD, CM_CLKSTCTRL);
+ cm_write_mod_reg(OMAP24XX_AUTOSTATE_GFX, GFX_MOD, CM_CLKSTCTRL);
+ cm_write_mod_reg(OMAP2420_AUTOSTATE_IVA | OMAP24XX_AUTOSTATE_DSP,
+ OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
+
+ /* Enable clock autoidle for all domains */
+ cm_write_mod_reg(OMAP24XX_AUTO_CAM |
+ OMAP24XX_AUTO_MAILBOXES |
+ OMAP24XX_AUTO_WDT4 |
+ OMAP2420_AUTO_WDT3 |
+ OMAP24XX_AUTO_MSPRO |
+ OMAP2420_AUTO_MMC |
+ OMAP24XX_AUTO_FAC |
+ OMAP2420_AUTO_EAC |
+ OMAP24XX_AUTO_HDQ |
+ OMAP24XX_AUTO_UART2 |
+ OMAP24XX_AUTO_UART1 |
+ OMAP24XX_AUTO_I2C2 |
+ OMAP24XX_AUTO_I2C1 |
+ OMAP24XX_AUTO_MCSPI2 |
+ OMAP24XX_AUTO_MCSPI1 |
+ OMAP24XX_AUTO_MCBSP2 |
+ OMAP24XX_AUTO_MCBSP1 |
+ OMAP24XX_AUTO_GPT12 |
+ OMAP24XX_AUTO_GPT11 |
+ OMAP24XX_AUTO_GPT10 |
+ OMAP24XX_AUTO_GPT9 |
+ OMAP24XX_AUTO_GPT8 |
+ OMAP24XX_AUTO_GPT7 |
+ OMAP24XX_AUTO_GPT6 |
+ OMAP24XX_AUTO_GPT5 |
+ OMAP24XX_AUTO_GPT4 |
+ OMAP24XX_AUTO_GPT3 |
+ OMAP24XX_AUTO_GPT2 |
+ OMAP2420_AUTO_VLYNQ |
+ OMAP24XX_AUTO_DSS,
+ CORE_MOD, CM_AUTOIDLE1);
+ cm_write_mod_reg(OMAP24XX_AUTO_UART3 |
+ OMAP24XX_AUTO_SSI |
+ OMAP24XX_AUTO_USB,
+ CORE_MOD, CM_AUTOIDLE2);
+ cm_write_mod_reg(OMAP24XX_AUTO_SDRC |
+ OMAP24XX_AUTO_GPMC |
+ OMAP24XX_AUTO_SDMA,
+ CORE_MOD, OMAP24XX_CM_AUTOIDLE3);
+ cm_write_mod_reg(OMAP24XX_AUTO_PKA |
+ OMAP24XX_AUTO_AES |
+ OMAP24XX_AUTO_RNG |
+ OMAP24XX_AUTO_SHA |
+ OMAP24XX_AUTO_DES,
+ CORE_MOD, OMAP24XX_CM_AUTOIDLE4);
+
+ cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI, OMAP24XX_DSP_MOD, CM_AUTOIDLE);
+
+ /* Put DPLL and both APLLs into autoidle mode */
+ cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
+ (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
+ (0x03 << OMAP24XX_AUTO_54M_SHIFT),
+ PLL_MOD, CM_AUTOIDLE);
+
+ cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL |
+ OMAP24XX_AUTO_WDT1 |
+ OMAP24XX_AUTO_MPU_WDT |
+ OMAP24XX_AUTO_GPIOS |
+ OMAP24XX_AUTO_32KSYNC |
+ OMAP24XX_AUTO_GPT1,
+ WKUP_MOD, CM_AUTOIDLE);
+
+ /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
+ * stabilisation */
+ prm_write_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_PRCM_CLKSSETUP);
+
+ /* Configure automatic voltage transition */
+ prm_write_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_PRCM_VOLTSETUP);
+ prm_write_reg(OMAP24XX_AUTO_EXTVOLT |
+ (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
+ OMAP24XX_MEMRETCTRL |
+ (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
+ (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
+ OMAP24XX_PRCM_VOLTCTRL);
+
+ /* Enable wake-up events */
+ prm_write_mod_reg(OMAP24XX_EN_GPIOS | OMAP24XX_EN_GPT1,
+ WKUP_MOD, PM_WKEN);
+}
+
int __init omap2_pm_init(void)
{
- printk("Power Management for TI OMAP.\n");
+ u32 l;
+
+ printk(KERN_INFO "Power Management for OMAP2 initializing\n");
+ l = prm_read_reg(OMAP24XX_PRCM_REVISION);
+ printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
- vclk = clk_get(NULL, "virt_prcm_set");
- if (IS_ERR(vclk)) {
- printk(KERN_ERR "Could not get PM vclk\n");
+ osc_ck = clk_get(NULL, "osc_ck");
+ if (IS_ERR(osc_ck)) {
+ printk(KERN_ERR "could not get osc_ck\n");
return -ENODEV;
}
+ if (cpu_is_omap242x()) {
+ emul_ck = clk_get(NULL, "emul_ck");
+ if (IS_ERR(emul_ck)) {
+ printk(KERN_ERR "could not get emul_ck\n");
+ clk_put(osc_ck);
+ return -ENODEV;
+ }
+ }
+
+ prcm_setup_regs();
+
+ pm_init_serial_console();
+
+ /* Hack to prevent MPU retention when STI console is enabled. */
+ {
+ const struct omap_sti_console_config *sti;
+
+ sti = omap_get_config(OMAP_TAG_STI_CONSOLE,
+ struct omap_sti_console_config);
+ if (sti != NULL && sti->enable)
+ sti_console_enabled = 1;
+ }
+
/*
* We copy the assembler sleep/wakeup routines to SRAM.
* These routines need to be in SRAM as that's the only
*/
omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
omap24xx_idle_loop_suspend_sz);
-
omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
omap24xx_cpu_suspend_sz);
- pm_set_ops(&omap_pm_ops);
+ suspend_set_ops(&omap_pm_ops);
pm_idle = omap2_pm_idle;
- pmdomain_init();
+ l = subsys_create_file(&power_subsys, &sleep_while_idle_attr);
+ if (l)
+ printk(KERN_ERR "subsys_create_file failed: %d\n", l);
return 0;
}
-__initcall(omap2_pm_init);
+late_initcall(omap2_pm_init);
*
* OMAP2 GP timer support.
*
+ * Update to use new clocksource/clockevent layers
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * Original driver:
* Copyright (C) 2005 Nokia Corporation
* Author: Paul Mundt <paul.mundt@nokia.com>
- * Juha Yrjölä <juha.yrjola@nokia.com>
+ * Juha Yrjölä <juha.yrjola@nokia.com>
* OMAP Dual-mode timer framework support by Timo Teras
*
* Some parts based off of TI's 24xx code:
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/mach/time.h>
#include <asm/arch/dmtimer.h>
static struct omap_dm_timer *gptimer;
-
-static inline void omap2_gp_timer_start(unsigned long load_val)
-{
- omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val);
- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
- omap_dm_timer_start(gptimer);
-}
+static struct clock_event_device clockevent_gpt;
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
{
- write_seqlock(&xtime_lock);
+ struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
+ struct clock_event_device *evt = &clockevent_gpt;
- omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
- timer_tick();
-
- write_sequnlock(&xtime_lock);
+ omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW);
+ evt->event_handler(evt);
return IRQ_HANDLED;
}
.handler = omap2_gp_timer_interrupt,
};
-static void __init omap2_gp_timer_init(void)
+static int omap2_gp_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
{
- u32 tick_period;
+ omap_dm_timer_set_load(gptimer, 0, 0xffffffff - cycles);
+ omap_dm_timer_start(gptimer);
+
+ return 0;
+}
+
+static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 period;
+
+ omap_dm_timer_stop(gptimer);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
+ period -= 1;
+
+ omap_dm_timer_set_load(gptimer, 1, 0xffffffff - period);
+ omap_dm_timer_start(gptimer);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_gpt = {
+ .name = "gp timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = omap2_gp_timer_set_next_event,
+ .set_mode = omap2_gp_timer_set_mode,
+};
+
+static void __init omap2_gp_clockevent_init(void)
+{
+ u32 tick_rate;
- omap_dm_timer_init();
gptimer = omap_dm_timer_request_specific(1);
BUG_ON(gptimer == NULL);
omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
- tick_period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
- tick_period -= 1;
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
+ omap2_gp_timer_irq.dev_id = (void *)gptimer;
setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
- omap2_gp_timer_start(tick_period);
+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
+
+ clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
+ clockevent_gpt.shift);
+ clockevent_gpt.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &clockevent_gpt);
+ clockevent_gpt.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_gpt);
+
+ clockevent_gpt.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&clockevent_gpt);
+}
+
+/*
+ * clocksource
+ */
+static struct omap_dm_timer *gpt_clocksource;
+static cycle_t clocksource_read_cycles(void)
+{
+ return (cycle_t)omap_dm_timer_read_counter(gpt_clocksource);
+}
+
+static struct clocksource clocksource_gpt = {
+ .name = "gp timer",
+ .rating = 300,
+ .read = clocksource_read_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 24,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/* Setup free-running counter for clocksource */
+static void __init omap2_gp_clocksource_init(void)
+{
+ static struct omap_dm_timer *gpt;
+ u32 tick_rate, tick_period;
+ static char err1[] __initdata = KERN_ERR
+ "%s: failed to request dm-timer\n";
+ static char err2[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ gpt = omap_dm_timer_request();
+ if (!gpt)
+ printk(err1, clocksource_gpt.name);
+ gpt_clocksource = gpt;
+
+ omap_dm_timer_set_source(gpt, OMAP_TIMER_SRC_SYS_CLK);
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt));
+ tick_period = (tick_rate / HZ) - 1;
+
+ omap_dm_timer_set_load(gpt, 1, 0);
+ omap_dm_timer_start(gpt);
+
+ clocksource_gpt.mult =
+ clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift);
+ if (clocksource_register(&clocksource_gpt))
+ printk(err2, clocksource_gpt.name);
+}
+
+static void __init omap2_gp_timer_init(void)
+{
+ omap_dm_timer_init();
+
+ omap2_gp_clockevent_init();
+ omap2_gp_clocksource_init();
}
struct sys_timer omap_timer = {
select CPU_CP15_MMU
select CPU_COPY_V3 if MMU
select CPU_TLB_V3 if MMU
+ select CPU_PABRT_NOIFAR
help
The ARM610 is the successor to the ARM3 processor
and was produced by VLSI Technology Inc.
select CPU_CP15_MMU
select CPU_COPY_V3 if MMU
select CPU_TLB_V3 if MMU
+ select CPU_PABRT_NOIFAR
help
A 32-bit RISC microprocessor based on the ARM7 processor core
designed by Advanced RISC Machines Ltd. The ARM710 is the
default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
select CPU_32v4T
select CPU_ABRT_LV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4
select CPU_CACHE_VIVT
select CPU_CP15_MMU
default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
select CPU_32v4T
select CPU_ABRT_EV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
default y if ARCH_LH7A40X || ARCH_KS8695
select CPU_32v4T
select CPU_ABRT_EV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
default y if ARCH_OMAP15XX
select CPU_32v4T
select CPU_ABRT_EV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
select CPU_32v5
select CPU_ABRT_EV5TJ
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
depends on ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
depends on ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
depends on ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
depends on ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
select CPU_32v3 if ARCH_RPC
select CPU_32v4 if !ARCH_RPC
select CPU_ABRT_EV4
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
default y
select CPU_32v4
select CPU_ABRT_EV4
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
# XScale
config CPU_XSCALE
bool
- depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000
+ depends on ARCH_IOP32X || ARCH_IOP33X || PXA25x || PXA27x || ARCH_IXP4XX || ARCH_IXP2000
default y
select CPU_32v5
select CPU_ABRT_EV5T
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
# XScale Core Version 3
config CPU_XSC3
bool
- depends on ARCH_IXP23XX || ARCH_IOP13XX
+ depends on ARCH_IXP23XX || ARCH_IOP13XX || PXA3xx
default y
select CPU_32v5
select CPU_ABRT_EV5T
default y if ARCH_MX3
select CPU_32v6
select CPU_ABRT_EV6
+ select CPU_PABRT_NOIFAR
select CPU_CACHE_V6
select CPU_CACHE_VIPT
select CPU_CP15_MMU
# ARMv7
config CPU_V7
bool "Support ARM V7 processor"
- depends on ARCH_INTEGRATOR
+ depends on ARCH_INTEGRATOR || ARCH_OMAP3
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
+ select CPU_PABRT_IFAR
select CPU_CACHE_V7
select CPU_CACHE_VIPT
select CPU_CP15_MMU
config CPU_ABRT_EV7
bool
+config CPU_PABRT_IFAR
+ bool
+
+config CPU_PABRT_NOIFAR
+ bool
+
# The cache model
config CPU_CACHE_V3
bool
If you don't know what this all is, saying Y is a safe choice.
+config ARM_XENON
+ bool "Enable Xenon extension"
+ depends on CPU_V7
+ help
+ Say Y here if you have a CPU with Xenon extension and code to make
+ use of it. Say N for code that can run on CPUs without Xenon.
+
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
depends on ARCH_SUPPORTS_BIG_ENDIAN
#define MPU_CLK "virt_prcm_set"
#endif
+static struct clk *mpu_clk;
+
/* TODO: Add support for SDRAM timing changes */
int omap_verify_speed(struct cpufreq_policy *policy)
{
- struct clk * mpu_clk;
-
if (policy->cpu)
return -EINVAL;
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
- mpu_clk = clk_get(NULL, MPU_CLK);
- if (IS_ERR(mpu_clk))
- return PTR_ERR(mpu_clk);
+
policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
- clk_put(mpu_clk);
-
return 0;
}
unsigned int omap_getspeed(unsigned int cpu)
{
- struct clk * mpu_clk;
unsigned long rate;
if (cpu)
return 0;
- mpu_clk = clk_get(NULL, MPU_CLK);
- if (IS_ERR(mpu_clk))
- return 0;
rate = clk_get_rate(mpu_clk) / 1000;
- clk_put(mpu_clk);
-
return rate;
}
unsigned int target_freq,
unsigned int relation)
{
- struct clk * mpu_clk;
struct cpufreq_freqs freqs;
int ret = 0;
- mpu_clk = clk_get(NULL, MPU_CLK);
- if (IS_ERR(mpu_clk))
- return PTR_ERR(mpu_clk);
-
freqs.old = omap_getspeed(0);
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
freqs.cpu = 0;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
ret = clk_set_rate(mpu_clk, target_freq * 1000);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- clk_put(mpu_clk);
return ret;
}
static int __init omap_cpu_init(struct cpufreq_policy *policy)
{
- struct clk * mpu_clk;
-
mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
if (policy->cpu != 0)
return -EINVAL;
policy->cur = policy->min = policy->max = omap_getspeed(0);
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
- clk_put(mpu_clk);
return 0;
}
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ clk_put(mpu_clk);
+ return 0;
+}
+
static struct cpufreq_driver omap_driver = {
.flags = CPUFREQ_STICKY,
.verify = omap_verify_speed,
.target = omap_target,
.get = omap_getspeed,
.init = omap_cpu_init,
+ .exit = omap_cpu_exit,
.name = "omap",
};
* linux/arch/arm/plat-omap/dma.c
*
* Copyright (C) 2003 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
if (cpu_is_omap24xx()) {
int i;
- u32 lch_base = OMAP24XX_DMA_BASE + lch * 0x60 + 0x80;
+ u32 lch_base = OMAP_DMA4_BASE + lch * 0x60 + 0x80;
for (i = 0; i < 0x44; i += 4)
omap_writel(0, lch_base + i);
}
(OMAP1_DMA_CDSA_U_REG(lch) << 16));
if (cpu_is_omap24xx())
- offset = OMAP2_DMA_CDSA_REG(lch);
+ offset = OMAP_DMA_CDAC_REG(lch);
return offset;
}
* Support functions for OMAP GPIO
*
* Copyright (C) 2003-2005 Nokia Corporation
- * Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <linux/err.h>
#include <linux/clk.h>
#define OMAP24XX_GPIO_LEVELDETECT1 0x0044
#define OMAP24XX_GPIO_RISINGDETECT 0x0048
#define OMAP24XX_GPIO_FALLINGDETECT 0x004c
+#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050
+#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054
#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060
#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064
#define OMAP24XX_GPIO_CLEARWKUENA 0x0080
#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
#define OMAP24XX_GPIO_SETDATAOUT 0x0094
+/*
+ * omap34xx specific GPIO registers
+ */
+
+#define OMAP34XX_GPIO1_BASE (void __iomem *)0x48310000
+#define OMAP34XX_GPIO2_BASE (void __iomem *)0x49050000
+#define OMAP34XX_GPIO3_BASE (void __iomem *)0x49052000
+#define OMAP34XX_GPIO4_BASE (void __iomem *)0x49054000
+#define OMAP34XX_GPIO5_BASE (void __iomem *)0x49056000
+#define OMAP34XX_GPIO6_BASE (void __iomem *)0x49058000
+
+
struct gpio_bank {
void __iomem *base;
u16 irq;
u16 virtual_irq_start;
int method;
u32 reserved_map;
-#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
+#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
u32 suspend_wakeup;
u32 saved_wakeup;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
u32 non_wakeup_gpios;
u32 enabled_non_wakeup_gpios;
#endif
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct gpio_bank gpio_bank_34xx[6] = {
+ { OMAP34XX_GPIO1_BASE, INT_34XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX },
+ { OMAP34XX_GPIO2_BASE, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX },
+ { OMAP34XX_GPIO3_BASE, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX },
+ { OMAP34XX_GPIO4_BASE, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX },
+ { OMAP34XX_GPIO5_BASE, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX },
+ { OMAP34XX_GPIO6_BASE, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_24XX },
+};
+
+#endif
+
static struct gpio_bank *gpio_bank;
static int gpio_bank_count;
if (cpu_is_omap24xx())
return &gpio_bank[gpio >> 5];
#endif
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx())
+ return &gpio_bank[gpio >> 5];
+#endif
}
static inline int get_gpio_index(int gpio)
#ifdef CONFIG_ARCH_OMAP24XX
if (cpu_is_omap24xx())
return gpio & 0x1f;
+#endif
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx())
+ return gpio & 0x1f;
#endif
return gpio & 0x0f;
}
#ifdef CONFIG_ARCH_OMAP24XX
if (cpu_is_omap24xx() && gpio < 128)
return 0;
+#endif
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx() && gpio < 160)
+ return 0;
#endif
return -1;
}
reg += OMAP730_GPIO_DIR_CONTROL;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_OE;
break;
l &= ~(1 << gpio);
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
if (enable)
reg += OMAP24XX_GPIO_SETDATAOUT;
reg += OMAP730_GPIO_DATA_INPUT;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_DATAIN;
break;
__raw_writel(l, base + reg); \
} while(0)
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
{
void __iomem *base = bank->base;
/* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level
* triggering requested. */
}
+
+void
+omap_set_gpio_debounce(int gpio, int enable)
+{
+ struct gpio_bank *bank;
+ void __iomem *reg;
+ u32 val, l = 1 << get_gpio_index(gpio);
+
+ bank = get_gpio_bank(gpio);
+ reg = bank->base;
+
+ reg += OMAP24XX_GPIO_DEBOUNCE_EN;
+ val = __raw_readl(reg);
+
+ if (enable)
+ val |= l;
+ else
+ val &= ~l;
+
+ __raw_writel(val, reg);
+}
+EXPORT_SYMBOL(omap_set_gpio_debounce);
+
+void
+omap_set_gpio_debounce_time(int gpio, int enc_time)
+{
+ struct gpio_bank *bank;
+ void __iomem *reg;
+
+ bank = get_gpio_bank(gpio);
+ reg = bank->base;
+
+ enc_time &= 0xff;
+ reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
+ __raw_writel(enc_time, reg);
+}
+EXPORT_SYMBOL(omap_set_gpio_debounce_time);
#endif
static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
goto bad;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
set_24xx_gpio_triggering(bank, gpio, trigger);
break;
unsigned gpio;
int retval;
- if (!cpu_is_omap24xx() && irq > IH_MPUIO_BASE)
+ if (!(cpu_class_is_omap2()) && irq > IH_MPUIO_BASE)
gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
else
gpio = irq - IH_GPIO_BASE;
return -EINVAL;
/* OMAP1 allows only only edge triggering */
- if (!cpu_is_omap24xx()
+ if (!(cpu_class_is_omap2())
&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
return -EINVAL;
reg += OMAP730_GPIO_INT_STATUS;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQSTATUS1;
break;
__raw_writel(gpio_mask, reg);
/* Workaround for clearing DSP GPIO interrupts to allow retention */
- if (cpu_is_omap2420())
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
__raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2);
+#endif
}
static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
inv = 1;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQENABLE1;
mask = 0xffffffff;
l |= gpio_mask;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
if (enable)
reg += OMAP24XX_GPIO_SETIRQENABLE1;
spin_unlock(&bank->lock);
return 0;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
if (bank->non_wakeup_gpios & (1 << gpio)) {
printk(KERN_ERR "Unable to modify wakeup on "
__raw_writel(1 << get_gpio_index(gpio), reg);
}
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
if (bank->method == METHOD_GPIO_24XX) {
/* Disable wake-up during idle for dynamic tick */
void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
if (bank->method == METHOD_GPIO_730)
isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
if (bank->method == METHOD_GPIO_24XX)
isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
#endif
if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
isr &= 0x0000ffff;
- if (cpu_is_omap24xx()) {
+ if (cpu_class_is_omap2()) {
level_mask =
__raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT0) |
}
}
- if (cpu_is_omap24xx()) {
+ if (cpu_class_is_omap2()) {
/* clear level sensitive interrupts after handler(s) */
_enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
_clear_gpio_irqbank(bank, isr_saved & level_mask);
/*---------------------------------------------------------------------*/
static int initialized;
+#if !defined(CONFIG_ARCH_OMAP3)
static struct clk * gpio_ick;
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2)
static struct clk * gpio_fck;
+#endif
-#ifdef CONFIG_ARCH_OMAP2430
+#if defined(CONFIG_ARCH_OMAP2430)
static struct clk * gpio5_ick;
static struct clk * gpio5_fck;
#endif
+#if defined(CONFIG_ARCH_OMAP3)
+static struct clk *gpio_fclks[OMAP34XX_NR_GPIOS];
+static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
+#endif
+
static int __init _omap_gpio_init(void)
{
int i;
struct gpio_bank *bank;
+#if defined(CONFIG_ARCH_OMAP3)
+ char clk_name[11];
+#endif
initialized = 1;
+#if defined(CONFIG_ARCH_OMAP1)
if (cpu_is_omap15xx()) {
gpio_ick = clk_get(NULL, "arm_gpio_ck");
if (IS_ERR(gpio_ick))
else
clk_enable(gpio_ick);
}
- if (cpu_is_omap24xx()) {
+#endif
+#if defined(CONFIG_ARCH_OMAP2)
+ if (cpu_class_is_omap2()) {
gpio_ick = clk_get(NULL, "gpios_ick");
if (IS_ERR(gpio_ick))
printk("Could not get gpios_ick\n");
clk_enable(gpio_fck);
/*
- * On 2430 GPIO 5 uses CORE L4 ICLK
+ * On 2430 & 3430 GPIO 5 uses CORE L4 ICLK
*/
-#ifdef CONFIG_ARCH_OMAP2430
+#if defined(CONFIG_ARCH_OMAP2430)
if (cpu_is_omap2430()) {
gpio5_ick = clk_get(NULL, "gpio5_ick");
if (IS_ERR(gpio5_ick))
clk_enable(gpio5_fck);
}
#endif
-}
+ }
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+ if (cpu_is_omap34xx()) {
+ for (i = 0; i < OMAP34XX_NR_GPIOS; i++) {
+ sprintf(clk_name, "gpio%d_ick", i + 1);
+ gpio_iclks[i] = clk_get(NULL, clk_name);
+ if (IS_ERR(gpio_iclks[i]))
+ printk(KERN_ERR "Could not get %s\n", clk_name);
+ else
+ clk_enable(gpio_iclks[i]);
+ sprintf(clk_name, "gpio%d_fck", i + 1);
+ gpio_fclks[i] = clk_get(NULL, clk_name);
+ if (IS_ERR(gpio_fclks[i]))
+ printk(KERN_ERR "Could not get %s\n", clk_name);
+ else
+ clk_enable(gpio_fclks[i]);
+ }
+ }
+#endif
+
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap15xx()) {
printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
}
+#endif
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx()) {
+ int rev;
+
+ gpio_bank_count = OMAP34XX_NR_GPIOS;
+ gpio_bank = gpio_bank_34xx;
+ rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ printk(KERN_INFO "OMAP34xx GPIO hardware version %d.%d\n",
+ (rev >> 4) & 0x0f, rev & 0x0f);
+ }
#endif
for (i = 0; i < gpio_bank_count; i++) {
int j, gpio_count = 16;
gpio_count = 32; /* 730 has 32-bit GPIOs */
}
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
if (bank->method == METHOD_GPIO_24XX) {
static const u32 non_wakeup_gpios[] = {
0xe203ffc0, 0x08700040
if (cpu_is_omap16xx())
omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX)
/* Enable autoidle for the OCP interface */
if (cpu_is_omap24xx())
omap_writel(1 << 0, 0x48019010);
+#elif defined(CONFIG_ARCH_OMAP34XX)
+ if (cpu_is_omap34xx())
+ omap_writel(1 << 0, 0x48306814);
#endif
-
return 0;
}
-#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
+#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX) || defined (CONFIG_ARCH_OMAP34XX)
static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
{
int i;
- if (!cpu_is_omap24xx() && !cpu_is_omap16xx())
+ if ((!cpu_class_is_omap2()) && (!cpu_is_omap16xx()))
return 0;
for (i = 0; i < gpio_bank_count; i++) {
wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
break;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
#endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
static int workaround_enabled;
if (!(bank->enabled_non_wakeup_gpios))
continue;
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+#endif
bank->saved_fallingdetect = l1;
bank->saved_risingdetect = l2;
l1 &= ~bank->enabled_non_wakeup_gpios;
l2 &= ~bank->enabled_non_wakeup_gpios;
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
__raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
__raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
+#endif
c++;
}
if (!c) {
if (!(bank->enabled_non_wakeup_gpios))
continue;
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
__raw_writel(bank->saved_fallingdetect,
bank->base + OMAP24XX_GPIO_FALLINGDETECT);
__raw_writel(bank->saved_risingdetect,
bank->base + OMAP24XX_GPIO_RISINGDETECT);
+#endif
/* Check if any of the non-wakeup interrupt GPIOs have changed
* state. If so, generate an IRQ by software. This is
* horribly racy, but it's the best we can do to work around
* this silicon bug. */
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+#endif
l ^= bank->saved_datain;
l &= bank->non_wakeup_gpios;
if (l) {
u32 old0, old1;
-
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
__raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
__raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
__raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
__raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+#endif
}
}
mpuio_init();
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
- if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+ if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
if (ret == 0) {
ret = sysdev_class_register(&omap_gpio_sysclass);
if (ret == 0)
if (bank_is_mpuio(bank))
gpio = OMAP_MPUIO(0);
- else if (cpu_is_omap24xx() || cpu_is_omap730())
+ else if (cpu_class_is_omap2() || cpu_is_omap730())
bankwidth = 32;
for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
obj-$(CONFIG_FB_I810) += video/i810/
obj-$(CONFIG_FB_INTEL) += video/intelfb/
+# we also need input/serio early so serio bus is initialized by the time
+# serial drivers start registering their serio ports
+obj-$(CONFIG_SERIO) += input/serio/
obj-y += serial/
obj-$(CONFIG_PARPORT) += parport/
-obj-y += base/ block/ misc/ mfd/ net/ media/
+obj-y += base/ block/ misc/ mfd/ net/ media/ cbus/
+obj-$(CONFIG_I2C) += i2c/
+obj-y += cbus/
obj-$(CONFIG_NUBUS) += nubus/
obj-$(CONFIG_ATM) += atm/
obj-y += macintosh/
obj-$(CONFIG_PARIDE) += block/paride/
obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_USB) += usb/
+obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/
obj-$(CONFIG_PCI) += usb/
obj-$(CONFIG_USB_GADGET) += usb/gadget/
-obj-$(CONFIG_SERIO) += input/serio/
obj-$(CONFIG_GAMEPORT) += input/gameport/
obj-$(CONFIG_INPUT) += input/
obj-$(CONFIG_I2O) += message/
obj-$(CONFIG_RTC_LIB) += rtc/
-obj-y += i2c/
obj-$(CONFIG_W1) += w1/
obj-$(CONFIG_POWER_SUPPLY) += power/
obj-$(CONFIG_HWMON) += hwmon/
- obj-$(CONFIG_WATCHDOG) += char/watchdog/
+ obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
obj-$(CONFIG_BT) += bluetooth/
obj-$(CONFIG_EISA) += eisa/
obj-$(CONFIG_LGUEST_GUEST) += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
+ obj-$(CONFIG_CPU_IDLE) += cpuidle/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_NEW_LEDS) += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
obj-$(CONFIG_SUPERH) += sh/
obj-$(CONFIG_GENERIC_TIME) += clocksource/
obj-$(CONFIG_DMA_ENGINE) += dma/
+ obj-$(CONFIG_DCA) += dca/
obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/
+ obj-$(CONFIG_SSB) += ssb/
+ obj-$(CONFIG_VIRTIO) += virtio/
Say Y here to compile support for SCO over HCI USB.
+ config BT_HCIBTUSB
+ tristate "HCI USB driver (alternate version)"
+ depends on USB && EXPERIMENTAL && BT_HCIUSB=n
+ help
+ Bluetooth HCI USB driver.
+ This driver is required if you want to use Bluetooth devices with
+ USB interface.
+
+ This driver is still experimental and has no SCO support.
+
+ Say Y here to compile support for Bluetooth USB devices into the
+ kernel or say M to compile it as module (btusb).
+
+ config BT_HCIBTSDIO
+ tristate "HCI SDIO driver"
+ depends on MMC
+ help
+ Bluetooth HCI SDIO driver.
+ This driver is required if you want to use Bluetooth device with
+ SDIO interface.
+
+ Say Y here to compile support for Bluetooth SDIO devices into the
+ kernel or say M to compile it as module (btsdio).
+
config BT_HCIUART
tristate "HCI UART driver"
help
Say Y here to compile support for HCI BCSP protocol.
+ config BT_HCIUART_LL
+ bool "HCILL protocol support"
+ depends on BT_HCIUART
+ help
+ HCILL (HCI Low Level) is a serial protocol for communication
+ between Bluetooth device and host. This protocol is required for
+ serial Bluetooth devices that are based on Texas Instruments'
+ BRF chips.
+
+ Say Y here to compile support for HCILL protocol.
+
config BT_HCIBCM203X
tristate "HCI BCM203x USB driver"
depends on USB
Say Y here to compile support for HCI UART devices into the
kernel or say M to compile it as module (btuart_cs).
+config BT_HCIBRF6150
+ tristate "HCI TI BRF6150 driver with H4 extensions"
+ depends on BT && ARCH_OMAP
+ help
+ Bluetooth HCI driver for TI BRF6150 with H4 extensions.
+ This driver provides support for BRF6150 Bluetooth chip
+ with vendor-specific H4 extensions.
+
+ Say Y here to compile support for TI BRF6150 devices into the
+ kernel or say M to compile it as module (brf6150).
+
+config BT_HCIH4P
+ tristate "HCI driver with H4 Nokia extensions"
+ depends on BT && ARCH_OMAP
+ help
+ Bluetooth HCI driver with H4 extensions. This driver provides
+ support for H4+ Bluetooth chip with vendor-specific H4 extensions.
+
+ Say Y here to compile support for h4 extended devices into the kernel
+ or say M to compile it as module (hci_h4p).
+
config BT_HCIVHCI
tristate "HCI VHCI (Virtual HCI device) driver"
help
obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
+obj-$(CONFIG_BT_HCIBRF6150) += brf6150.o
+obj-$(CONFIG_BT_HCIH4P) += hci_h4p/
+ obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
+ obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
+
hci_uart-y := hci_ldisc.o
hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o
hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o
+ hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o
hci_uart-objs := $(hci_uart-y)
* Mostly based on original driver:
*
* Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrj��<juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
.name = "omap_rng",
.owner = THIS_MODULE,
},
- .probe = omap_rng_probe,
.remove = __exit_p(omap_rng_remove),
.suspend = omap_rng_suspend,
.resume = omap_rng_resume
if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
return -ENODEV;
- return platform_driver_register(&omap_rng_driver);
+ return platform_driver_probe(&omap_rng_driver, omap_rng_probe);
}
static void __exit omap_rng_exit(void)
config SENSORS_ABITUGURU
tristate "Abit uGuru (rev 1 & 2)"
- depends on EXPERIMENTAL
+ depends on X86 && EXPERIMENTAL
help
If you say yes here you get support for the sensor part of the first
and second revision of the Abit uGuru chip. The voltage and frequency
config SENSORS_ABITUGURU3
tristate "Abit uGuru (rev 3)"
- depends on HWMON && EXPERIMENTAL
+ depends on X86 && EXPERIMENTAL
help
If you say yes here you get support for the sensor part of the
third revision of the Abit uGuru chip. Only reading the sensors
This driver can also be built as a module. If so, the module
will be called adm9240.
+ config SENSORS_ADT7470
+ tristate "Analog Devices ADT7470"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the Analog Devices
+ ADT7470 temperature monitoring chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called adt7470.
+
config SENSORS_K8TEMP
tristate "AMD Athlon64/FX or Opteron temperature sensor"
depends on X86 && PCI && EXPERIMENTAL
config SENSORS_AMS
tristate "Apple Motion Sensor driver"
depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
+ select INPUT_POLLDEV
help
Support for the motion sensor included in PowerBooks. Includes
implementations for PMU and I2C.
config SENSORS_ASB100
tristate "Asus ASB100 Bach"
- depends on I2C && EXPERIMENTAL
+ depends on X86 && I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the ASB100 Bach sensor
will be called ds1621.
config SENSORS_F71805F
- tristate "Fintek F71805F/FG and F71872F/FG"
+ tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG"
depends on EXPERIMENTAL
help
If you say yes here you get support for hardware monitoring
- features of the Fintek F71805F/FG and F71872F/FG Super-I/O
- chips.
+ features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG
+ Super-I/O chips.
This driver can also be built as a module. If so, the module
will be called f71805f.
+ config SENSORS_F71882FG
+ tristate "Fintek F71882FG and F71883FG"
+ depends on EXPERIMENTAL
+ help
+ If you say yes here you get support for hardware monitoring
+ features of the Fintek F71882FG and F71883FG Super-I/O chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called f71882fg.
+
+ config SENSORS_F75375S
+ tristate "Fintek F75375S/SP and F75373";
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for hardware monitoring
+ features of the Fintek F75375S/SP and F75373
+
+ This driver can also be built as a module. If so, the module
+ will be called f75375s.
+
config SENSORS_FSCHER
tristate "FSC Hermes"
- depends on I2C
+ depends on X86 && I2C
help
If you say yes here you get support for Fujitsu Siemens
Computers Hermes sensor chips.
config SENSORS_FSCPOS
tristate "FSC Poseidon"
- depends on I2C
+ depends on X86 && I2C
help
If you say yes here you get support for Fujitsu Siemens
Computers Poseidon sensor chips.
This driver can also be built as a module. If so, the module
will be called fscpos.
+ config SENSORS_FSCHMD
+ tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
+ depends on X86 && I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for various Fujitsu Siemens
+ Computers sensor chips.
+
+ This is a new merged driver for FSC sensor chips which is intended
+ as a replacment for the fscpos, fscscy and fscher drivers and adds
+ support for several other FCS sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called fschmd.
+
config SENSORS_GL518SM
tristate "Genesys Logic GL518SM"
depends on I2C
sensor inside your CPU. Supported all are all known variants
of Intel Core family.
+ config SENSORS_IBMPEX
+ tristate "IBM PowerExecutive temperature/power sensors"
+ select IPMI_SI
+ depends on IPMI_HANDLER
+ help
+ If you say yes here you get support for the temperature and
+ power sensors in various IBM System X servers that support
+ PowerExecutive. So far this includes the x3550, x3650, x3655,
+ x3755, and certain HS20 blades.
+
+ This driver can also be built as a module. If so, the module
+ will be called ibmpex.
+
config SENSORS_IT87
tristate "ITE IT87xx and compatibles"
select HWMON_VID
config SENSORS_LM93
tristate "National Semiconductor LM93 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
select HWMON_VID
help
If you say yes here you get support for National Semiconductor LM93
will be called sis5595.
config SENSORS_DME1737
- tristate "SMSC DME1737 and compatibles"
+ tristate "SMSC DME1737, SCH311x and compatibles"
depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the hardware monitoring
and fan control features of the SMSC DME1737 (and compatibles
- like the Asus A8000) Super-I/O chip.
+ like the Asus A8000) and SCH311x Super-I/O chips.
This driver can also be built as a module. If so, the module
will be called dme1737.
config SENSORS_HDAPS
tristate "IBM Hard Drive Active Protection System (hdaps)"
depends on INPUT && X86
+ select INPUT_POLLDEV
default n
help
This driver provides support for the IBM Hard Drive Active Protection
depends on INPUT && X86
select NEW_LEDS
select LEDS_CLASS
+ select INPUT_POLLDEV
default n
help
This driver provides support for the Apple System Management
Say Y here if you have an applicable laptop and want to experience
the awesome power of applesmc.
+config SENSORS_TSC210X
+ tristate "TI TSC210x battery & temperature sensors"
+ depends on HWMON && SPI_MASTER
+ select SPI_TSC210X
+ help
+ Say Y if your board has a TSC210x chip and you want to
+ have its battery state, auxiliary input and/or temperature
+ sensors exported through hwmon.
+
+ This driver can also be built as a module. In this case
+ the module will be called tsc210x_sensors.
+
config HWMON_DEBUG_CHIP
bool "Hardware Monitoring Chip debugging messages"
default n
obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
+ obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_AMS) += ams/
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
+ obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o
+ obj-$(CONFIG_SENSORS_F75375S) += f75375s.o
obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
+ obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o
obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
+ obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
obj-$(CONFIG_SENSORS_LM63) += lm63.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
+obj-$(CONFIG_SENSORS_TSC210X) += tsc210x_sensors.o
ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
EXTRA_CFLAGS += -DDEBUG
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
+ obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
+obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
EXTRA_CFLAGS += -DDEBUG
This driver implements support for HIL-keyboards attached
to your machine, so normally you should say Y here.
+ config KEYBOARD_HP6XX
+ tristate "HP Jornada 6XX Keyboard support"
+ depends on SH_HP6XX
+ select INPUT_POLLDEV
+ help
+ This adds support for the onboard keyboard found on
+ HP Jornada 620/660/680/690.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jornada680_kbd.
+
+ config KEYBOARD_HP7XX
+ tristate "HP Jornada 7XX Keyboard Driver"
+ depends on SA1100_JORNADA720_SSP && SA1100_SSP
+ help
+ Say Y here to add support for the HP Jornada 7xx (710/720/728)
+ onboard keyboard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jornada720_kbd.
+
config KEYBOARD_OMAP
tristate "TI OMAP keypad support"
depends on (ARCH_OMAP1 || ARCH_OMAP2)
To compile this driver as a module, choose M here: the
module will be called omap-keypad.
+config KEYBOARD_TWL4030
+ tristate "TI TWL4030 keypad support"
+ depends on TWL4030_CORE && MACH_OMAP_2430SDP
+ help
+ Say Y here if you want to use the OMAP TWL4030 keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called omap-twl4030keypad. This driver depends on
+ TWL4030 Core and TWL4030 GPIO I2C client driver
+
+config OMAP_PS2
+ tristate "TI OMAP Innovator 1510 PS/2 keyboard & mouse support"
+ depends on ARCH_OMAP15XX && MACH_OMAP_INNOVATOR
+ help
+ Say Y here if you want to use the OMAP Innovator 1510 PS/2
+ keyboard and mouse.
+
+ To compile this driver as a module, choose M here: the
+ module will be called innovator_ps2.
+
++config KEYBOARD_TSC2301
++ tristate "TSC2301 keypad support"
++ depends on SPI_TSC2301
++ help
++ Say Y here for if you are using the keypad features of TSC2301.
++
config KEYBOARD_PXA27x
tristate "PXA27x keyboard support"
depends on PXA27x
To compile this driver as a module, choose M here: the
module will be called gpio-keys.
- config KEYBOARD_TSC2301
- tristate "TSC2301 keypad support"
- depends on SPI_TSC2301
+ config KEYBOARD_MAPLE
+ tristate "Maple bus keyboard"
+ depends on SH_DREAMCAST && MAPLE
help
- Say Y here for if you are using the keypad features of TSC2301.
+ Say Y here if you have a Dreamcast console running Linux and have
+ a keyboard attached to its Maple bus.
+
+ To compile this driver as a module, choose M here: the
+ module will be called maple_keyb.
+
+ config KEYBOARD_BFIN
+ tristate "Blackfin BF54x keypad support"
+ depends on BF54x
+ help
+ Say Y here if you want to use the BF54x keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bf54x-keys.
endif
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
- obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
+ obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
+obj-$(CONFIG_OMAP_PS2) += innovator_ps2.o
++obj-$(CONFIG_KEYBOARD_TSC2301) += tsc2301_kp.o
++obj-$(CONFIG_KEYBOARD_TWL4030) += omap-twl4030keypad.o
obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o
- obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
+ obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
- obj-$(CONFIG_KEYBOARD_TSC2301) += tsc2301_kp.o
- obj-$(CONFIG_KEYBOARD_TWL4030) += omap-twl4030keypad.o
+ obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
+ obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
+ obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
+ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
* OMAP Keypad Driver
*
* Copyright (C) 2003 Nokia Corporation
- * Written by Timo Teräs <ext-timo.teras@nokia.com>
+ * Written by Timo Teräs <ext-timo.teras@nokia.com>
*
* Added support for H2 & H3 Keypad
* Copyright (C) 2004 Texas Instruments
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/errno.h>
#include <asm/arch/gpio.h>
#include <asm/arch/keypad.h>
unsigned int cols;
unsigned long delay;
unsigned int debounce;
+ int suspended;
+ spinlock_t suspend_lock;
};
DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
{
struct omap_kp *omap_kp = dev_id;
+ unsigned long flags;
+
+ spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+ if (omap_kp->suspended) {
+ spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
/* disable keyboard interrupt and schedule for handling */
if (cpu_is_omap24xx()) {
omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
kp_cur_group = -1;
}
- }
+ }
}
static ssize_t omap_kp_enable_show(struct device *dev,
#ifdef CONFIG_PM
static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
{
- /* Nothing yet */
+ struct omap_kp *omap_kp = platform_get_drvdata(dev);
+ unsigned long flags;
+ spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+
+ /*
+ * Re-enable the interrupt in case it has been masked by the
+ * handler and a key is still pressed. We need the interrupt
+ * to wake us up from suspended.
+ */
+ if (cpu_class_is_omap1())
+ omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+ omap_kp->suspended = 1;
+ spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
return 0;
}
static int omap_kp_resume(struct platform_device *dev)
{
- /* Nothing yet */
+ struct omap_kp *omap_kp = platform_get_drvdata(dev);
+ omap_kp->suspended = 0;
return 0;
}
#else
struct omap_kp *omap_kp;
struct input_dev *input_dev;
struct omap_kp_platform_data *pdata = pdev->dev.platform_data;
- int i, col_idx, row_idx, irq_idx, ret;
+ int i, col_idx = 0, row_idx = 0, irq_idx, ret;
if (!pdata->rows || !pdata->cols || !pdata->keymap) {
printk(KERN_ERR "No rows, cols or keymap from pdata\n");
platform_set_drvdata(pdev, omap_kp);
+ spin_lock_init(&omap_kp->suspend_lock);
omap_kp->input = input_dev;
+ omap_kp->suspended = 0;
/* Disable the interrupt for the MPUIO keyboard */
if (!cpu_is_omap24xx())
keymap = pdata->keymap;
if (pdata->rep)
- set_bit(EV_REP, input_dev->evbit);
+ __set_bit(EV_REP, input_dev->evbit);
if (pdata->delay)
omap_kp->delay = pdata->delay;
goto err2;
/* setup input device */
- set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
for (i = 0; keymap[i] != 0; i++)
- set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
+ __set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
input_dev->name = "omap-keypad";
input_dev->phys = "omap-keypad/input0";
input_dev->dev.parent = &pdev->dev;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
- input_dev->keycode = keymap;
- input_dev->keycodesize = sizeof(unsigned int);
- input_dev->keycodemax = pdata->keymapsize;
-
ret = input_register_device(omap_kp->input);
if (ret < 0) {
printk(KERN_ERR "Unable to register omap-keypad input device\n");
} else {
for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
if (request_irq(OMAP_GPIO_IRQ(row_gpios[irq_idx]),
- omap_kp_interrupt,
+ omap_kp_interrupt,
IRQF_TRIGGER_FALLING,
- "omap-keypad", omap_kp) < 0)
+ "omap-keypad", omap_kp) < 0)
goto err5;
}
}
return 0;
err5:
- for (i = irq_idx-1; i >=0; i--)
+ for (i = irq_idx - 1; i >=0; i--)
free_irq(row_gpios[i], 0);
err4:
input_unregister_device(omap_kp->input);
if (cpu_is_omap24xx()) {
int i;
for (i = 0; i < omap_kp->cols; i++)
- omap_free_gpio(col_gpios[i]);
+ omap_free_gpio(col_gpios[i]);
for (i = 0; i < omap_kp->rows; i++) {
- omap_free_gpio(row_gpios[i]);
+ omap_free_gpio(row_gpios[i]);
free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
}
} else {
module_init(omap_kp_init);
module_exit(omap_kp_exit);
- MODULE_AUTHOR("Timo Teräs");
+ MODULE_AUTHOR("Timo Teräs");
MODULE_DESCRIPTION("OMAP Keypad Driver");
MODULE_LICENSE("GPL");
To compile this driver as a module, choose M here: the
module will be called hp680_ts_input.
+ config TOUCHSCREEN_HP7XX
+ tristate "HP Jornada 710/720/728 touchscreen"
+ depends on SA1100_JORNADA720_SSP
+ help
+ Say Y here if you have a HP Jornada 710/720/728 and want
+ to support the built-in touchscreen.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jornada720_ts.
+
config TOUCHSCREEN_PENMOUNT
tristate "Penmount serial touchscreen"
select SERIO
To compile this driver as a module, choose M here: the
module will be called ucb1400_ts.
+config TOUCHSCREEN_TSC2102
+ tristate "TSC 2102 based touchscreens"
+ depends on SPI_MASTER
+ select SPI_TSC2102
+ help
+ Say Y here if you have a touchscreen interface using the
+ TI TSC 2102 controller, and your board-specific initialization
+ code includes that in its table of SPI devices. Also make
+ sure the proper SPI controller is selected.
+
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called tsc2102_ts.
+
+config TOUCHSCREEN_TSC210X
+ tristate "TI TSC210x based touchscreens"
+ depends on SPI_MASTER
+ select SPI_TSC210X
+ help
+ Say Y here if you have a touchscreen interface using a
+ TI TSC210x controller, and your board-specific initialisation
+ code includes that in its table of SPI devices.
+
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called tsc210x_ts.
+
+config TOUCHSCREEN_TSC2301
+ tristate "TSC2301 touchscreen support"
+ depends on SPI_TSC2301
+ help
+ Say Y here for if you are using the touchscreen features of TSC2301.
+
config TOUCHSCREEN_USB_COMPOSITE
tristate "USB Touchscreen Driver"
depends on USB_ARCH_HAS_HCD
- Gunze AHL61
- DMC TSC-10/25
- IRTOUCHSYSTEMS/UNITOP
+ - IdealTEK URTC1000
+ - GoTop Super_Q2/GogoPen/PenPower tablets
Have a look at <http://linux.chapter7.ch/touchkit/> for
a usage description and the required user-space stuff.
bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
depends on TOUCHSCREEN_USB_COMPOSITE
+ config TOUCHSCREEN_USB_IDEALTEK
+ default y
+ bool "IdealTEK URTC1000 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+ config TOUCHSCREEN_USB_GENERAL_TOUCH
+ default y
+ bool "GeneralTouch Touchscreen device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+ config TOUCHSCREEN_USB_GOTOP
+ default y
+ bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
endif
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+ obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
+obj-$(CONFIG_TOUCHSCREEN_TSC2102) += tsc2102_ts.o
+obj-$(CONFIG_TOUCHSCREEN_OMAP) += omap/
+obj-$(CONFIG_TOUCHSCREEN_TSC210X) += tsc210x_ts.o
+obj-$(CONFIG_TOUCHSCREEN_TSC2301) += tsc2301_ts.o
help
This option enables support for the PCEngines WRAP programmable LEDs.
+config LEDS_OMAP_DEBUG
+ boolean "LED Support for OMAP debug board LEDs"
+ depends on LEDS_CLASS=y && ARCH_OMAP
+ help
+ Enables support for the LEDs on the debug board used with OMAP
+ reference boards like H2/H3/H4 and Perseus2. Up to six of these
+ may be claimed by the original ARM debug LED API.
+
+config LEDS_OMAP
+ tristate "LED Support for OMAP GPIO LEDs"
+ depends on LEDS_CLASS && ARCH_OMAP
+ help
+ This option enables support for the LEDs on OMAP processors.
+
+config LEDS_OMAP_PWM
+ tristate "LED Support for OMAP PWM-controlled LEDs"
+ depends on LEDS_CLASS && ARCH_OMAP && OMAP_DM_TIMER
+ help
+ This options enables support for LEDs connected to GPIO lines
+ controlled by a PWM timer on OMAP CPUs.
+
config LEDS_H1940
tristate "LED Support for iPAQ H1940 device"
- depends LEDS_CLASS && ARCH_H1940
+ depends on LEDS_CLASS && ARCH_H1940
help
This option enables support for the LEDs on the h1940.
- config LEDS_COBALT
- tristate "LED Support for Cobalt Server front LED"
+ config LEDS_COBALT_QUBE
+ tristate "LED Support for the Cobalt Qube series front LED"
depends on LEDS_CLASS && MIPS_COBALT
help
- This option enables support for the front LED on Cobalt Server
+ This option enables support for the front LED on Cobalt Qube series
+
+ config LEDS_COBALT_RAQ
+ bool "LED Support for the Cobalt Raq series"
+ depends on LEDS_CLASS && MIPS_COBALT
+ select LEDS_TRIGGERS
+ help
+ This option enables support for the Cobalt Raq series LEDs.
config LEDS_GPIO
tristate "LED Support for GPIO connected LEDs"
outputs. To be useful the particular board must have LEDs
and they must be connected to the GPIO lines.
+ config LEDS_CM_X270
+ tristate "LED Support for the CM-X270 LEDs"
+ depends on LEDS_CLASS && MACH_ARMCORE
+ help
+ This option enables support for the CM-X270 LEDs.
+
comment "LED Triggers"
config LEDS_TRIGGERS
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
+obj-$(CONFIG_LEDS_OMAP) += leds-omap.o
+obj-$(CONFIG_LEDS_OMAP_PWM) += leds-omap-pwm.o
obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
- obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o
+ obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
+ obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
+ obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
jumper sets the card to 0x358.
config RADIO_GEMTEK
- tristate "GemTek Radio Card support"
+ tristate "GemTek Radio card (or compatible) support"
depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have this FM radio card, and then fill in the
- port address below.
+ I/O port address and settings below. The following cards either have
+ GemTek Radio tuner or are rebranded GemTek Radio cards:
+
+ - Sound Vision 16 Gold with FM Radio
+ - Typhoon Radio card (some models)
+ - Hama Radio card
In order to control your radio card, you will need to use programs
that are compatible with the Video For Linux API. Information on
module will be called radio-gemtek.
config RADIO_GEMTEK_PORT
- hex "GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)"
+ hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0c24c or 0x28c)"
depends on RADIO_GEMTEK=y
default "34c"
help
Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
0x34c, if you haven't changed the jumper setting on the card. On
Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
- port is 0x28c.
+ port is 0x20c, 0x248 or 0x28c.
+ If automatic I/O port probing is enabled this port will be used only
+ in case of automatic probing failure, ie. as a fallback.
+
+ config RADIO_GEMTEK_PROBE
+ bool "Automatic I/O port probing"
+ depends on RADIO_GEMTEK=y
+ default y
+ help
+ Say Y here to enable automatic probing for GemTek Radio card. The
+ following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and
+ 0x28c.
config RADIO_GEMTEK_PCI
tristate "GemTek PCI Radio Card support"
help
Enter the I/O port of your Zoltrix radio card.
+config RADIO_TEA5761
+ tristate "Philips Semiconductors TEA5761 I2C FM Radio"
+ select I2C
+ select VIDEO_V4L2
+ help
+ Choose Y here if you have one of these AM/FM radio cards.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video For Linux 2 API. Information on
+ this API and pointers to "v4l" programs may be found at
+ <file:Documentation/video4linux/API.html>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-tea5761.
+
config USB_DSBR
tristate "D-Link/GemTek USB FM radio support"
depends on USB && VIDEO_V4L2
To compile this driver as a module, choose M here: the
module will be called wm8739.
+ config VIDEO_VP27SMPX
+ tristate "Panasonic VP27s internal MPX"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the internal MPX of the Panasonic VP27s tuner.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vp27smpx.
+
comment "Video decoders"
config VIDEO_BT819
This is a driver for the Toshiba TCM825x VGA camera sensor.
It is used for example in Nokia N800.
+config VIDEO_OV9640
+ tristate "OmniVision OV9640 sensor support"
+ depends on I2C && VIDEO_V4L2
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV9640 camera. It is currently working with the TI OMAP2
+ camera controller.
+
config VIDEO_SAA7110
tristate "Philips SAA7110 video decoder"
depends on VIDEO_V4L1 && I2C
config VIDEO_VIVI
tristate "Virtual Video Driver"
depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
- select VIDEO_BUF
+ select VIDEOBUF_VMALLOC
default n
---help---
Enables a virtual video driver. This device shows a color bar
Say Y here to include support for Philips SAB3036 compatible tuners.
If in doubt, say N.
- config TUNER_TEA5761
- bool "TEA 5761 radio tuner (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- depends on I2C
- select VIDEO_TUNER
- help
- Say Y here to include support for Philips TEA5761 radio tuner.
- If in doubt, say N.
-
config VIDEO_VINO
tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
source "drivers/media/video/cx88/Kconfig"
+ source "drivers/media/video/cx23885/Kconfig"
+
source "drivers/media/video/ivtv/Kconfig"
+source drivers/media/video/omap/Kconfig
+
config VIDEO_M32R_AR
tristate "AR devices"
depends on M32R && VIDEO_V4L1
CMOS camera controller. This is the controller found on first-
generation OLPC systems.
+config VIDEO_OMAP2
+ tristate "OMAP 2 Camera support (EXPERIMENTAL)"
+ select VIDEO_BUF
+ depends on VIDEO_V4L2 && ARCH_OMAP24XX
+ ---help---
+ Driver for an OMAP 2 camera controller.
+
+
#
# USB Multimedia device configuration
#
zr36067-objs := zoran_procfs.o zoran_device.o \
zoran_driver.o zoran_card.o
- tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \
- mt20xx.o tda8290.o tea5767.o tda9887.o
-
- tuner-$(CONFIG_TUNER_TEA5761) += tea5761.o
+ tuner-objs := tuner-core.o tuner-types.o tda9887.o
msp3400-objs := msp3400-driver.o msp3400-kthreads.o
obj-$(CONFIG_VIDEO_MEYE) += meye.o
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
- obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_MXB) += mxb.o
obj-$(CONFIG_TUNER_3036) += tuner-3036.o
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
- obj-$(CONFIG_VIDEO_BUF) += video-buf.o
- obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
+
+ obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o
+ obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o
+ obj-$(CONFIG_TUNER_TDA8290) += tda8290.o
+ obj-$(CONFIG_TUNER_TEA5767) += tea5767.o
+ obj-$(CONFIG_TUNER_TEA5761) += tea5761.o
+
+ obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
+ obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
+ obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
+ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
+obj-$(CONFIG_VIDEO_OMAP_CAMERA) += omap/
obj-$(CONFIG_VIDEO_CX25840) += cx25840/
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_OMAP2) += omap24xxcam.o omap24xxcam-dma.o
obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
obj-$(CONFIG_USB_DABUSB) += dabusb.o
obj-$(CONFIG_USB_OV511) += ov511.o
obj-$(CONFIG_USB_VICAM) += usbvideo/
obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
+ obj-$(CONFIG_VIDEO_IVTV) += ivtv/
+
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
If unsure, say N.
+ config MMC_RICOH_MMC
+ tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)"
+ depends on PCI && EXPERIMENTAL && MMC_SDHCI
+ help
+ This selects the disabler for the Ricoh MMC Controller. This
+ proprietary controller is unnecessary because the SDHCI driver
+ supports MMC cards on the SD controller, but if it is not
+ disabled, it will steal the MMC cards away - rendering them
+ useless. It is safe to select this driver even if you don't
+ have a Ricoh based card reader.
+
+
+ To compile this driver as a module, choose M here:
+ the module will be called ricoh_mmc.
+
+ If unsure, say Y.
+
config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
select TPS65010 if MACH_OMAP_H2
+ select OMAP_GPIO_SWITCH if MACH_NOKIA_N800
help
This selects the TI OMAP Multimedia card Interface.
If you have an OMAP board with a Multimedia Card slot,
To compile this driver as a module, choose M here: the
module will be called tifm_sd.
+ config MMC_SPI
+ tristate "MMC/SD over SPI (EXPERIMENTAL)"
+ depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL
+ select CRC7
+ select CRC_ITU_T
+ help
+ Some systems accss MMC/SD cards using a SPI controller instead of
+ using a "native" MMC/SD controller. This has a disadvantage of
+ being relatively high overhead, but a compensating advantage of
+ working on many systems without dedicated MMC/SD controllers.
+
+ If unsure, or if your system has no SPI master driver, say N.
+
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
+#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/clk.h>
+ #include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/irq.h>
- #include <asm/scatterlist.h>
#include <asm/mach-types.h>
#include <asm/arch/board.h>
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
#include <asm/arch/tps65010.h>
+#include <asm/arch/board-sx1.h>
#define OMAP_MMC_REG_CMD 0x00
#define OMAP_MMC_REG_ARGL 0x04
enum dma_data_direction dma_data_dir;
BUG_ON(host->dma_ch < 0);
- if (data->error != MMC_ERR_NONE)
+ if (data->error)
omap_stop_dma(host->dma_ch);
/* Release DMA channel lazily */
mod_timer(&host->dma_timer, jiffies + HZ);
}
}
- if (host->data == NULL || cmd->error != MMC_ERR_NONE) {
+ if (host->data == NULL || cmd->error) {
host->mrq = NULL;
clk_disable(host->fclk);
mmc_request_done(host->mmc, cmd->mrq);
sg = host->data->sg + host->sg_idx;
host->buffer_bytes_left = sg->length;
- host->buffer = page_address(sg->page) + sg->offset;
+ host->buffer = sg_virt(sg);
if (host->buffer_bytes_left > host->total_bytes_left)
host->buffer_bytes_left = host->total_bytes_left;
}
if (status & OMAP_MMC_STAT_DATA_TOUT) {
dev_dbg(mmc_dev(host->mmc), "data timeout\n");
if (host->data) {
- host->data->error |= MMC_ERR_TIMEOUT;
+ host->data->error = -ETIMEDOUT;
transfer_error = 1;
}
}
if (status & OMAP_MMC_STAT_DATA_CRC) {
if (host->data) {
- host->data->error |= MMC_ERR_BADCRC;
+ host->data->error = -EILSEQ;
dev_dbg(mmc_dev(host->mmc),
"data CRC error, bytes left %d\n",
host->total_bytes_left);
dev_err(mmc_dev(host->mmc),
"command timeout, CMD %d\n",
host->cmd->opcode);
- host->cmd->error = MMC_ERR_TIMEOUT;
+ host->cmd->error = -ETIMEDOUT;
end_command = 1;
}
}
dev_err(mmc_dev(host->mmc),
"command CRC error (CMD%d, arg 0x%08x)\n",
host->cmd->opcode, host->cmd->arg);
- host->cmd->error = MMC_ERR_BADCRC;
+ host->cmd->error = -EILSEQ;
end_command = 1;
} else
dev_err(mmc_dev(host->mmc),
static void mmc_omap_switch_handler(struct work_struct *work)
{
struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, switch_work);
- struct mmc_card *card;
static int complained = 0;
- int cards = 0, cover_open;
+ int cover_open;
if (host->switch_pin == -1)
return;
host->switch_last_state = cover_open;
}
mmc_detect_change(host->mmc, 0);
- list_for_each_entry(card, &host->mmc->cards, node) {
- if (mmc_card_present(card))
- cards++;
- }
if (mmc_omap_cover_is_open(host)) {
if (!complained) {
dev_info(mmc_dev(host->mmc), "cover is open\n");
*/
static void mmc_omap_power(struct mmc_omap_host *host, int on)
{
- if (on) {
+ if (machine_is_sx1())
+ sx1_setmmcpower(on);
+ else if (on) {
if (machine_is_omap_innovator())
innovator_fpga_socket_power(1);
else if (machine_is_omap_h2())
if (dsor > 250)
dsor = 250;
- dsor++;
if (ios->bus_width == MMC_BUS_WIDTH_4)
dsor |= 1 << 15;
help
Support for NAND flash on Amstrad E3 (Delta).
+config MTD_NAND_OMAP
+ tristate "NAND Flash device on OMAP H3/H2/P2 boards"
+ depends on ARM && ARCH_OMAP1 && MTD_NAND && (MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_PERSEUS2)
+ help
+ Support for NAND flash on Texas Instruments H3/H2/P2 platforms.
+
+config MTD_NAND_OMAP_HW
+ bool "OMAP HW NAND Flash controller support"
+ depends on ARM && ARCH_OMAP16XX && MTD_NAND
+
+ help
+ Driver for TI OMAP16xx hardware NAND flash controller.
+
config MTD_NAND_TOTO
tristate "NAND Flash device on TOTO board"
depends on ARCH_OMAP && BROKEN
This enables the driver for the NAND flash controller on the
AMD/Alchemy 1550 SOC.
+ config MTD_NAND_BF5XX
+ tristate "Blackfin on-chip NAND Flash Controller driver"
+ depends on BF54x && MTD_NAND
+ help
+ This enables the Blackfin on-chip NAND flash controller
+
+ No board specific support is done by this driver, each board
+ must advertise a platform_device for the driver to attach.
+
+ This driver can also be built as a module. If so, the module
+ will be called bf5xx-nand.
+
+ config MTD_NAND_BF5XX_HWECC
+ bool "BF5XX NAND Hardware ECC"
+ depends on MTD_NAND_BF5XX
+ help
+ Enable the use of the BF5XX's internal ECC generator when
+ using NAND.
+
config MTD_NAND_RTC_FROM4
tristate "Renesas Flash ROM 4-slot interface board (FROM_BOARD4)"
depends on SH_SOLUTION_ENGINE
config MTD_NAND_NDFC
tristate "NDFC NanD Flash Controller"
- depends on 44x
+ depends on 4xx && !PPC_MERGE
select MTD_NAND_ECC_SMC
help
- NDFC Nand Flash Controllers are integrated in EP44x SoCs
+ NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
config MTD_NAND_S3C2410_CLKSTOP
bool "S3C2410 NAND IDLE clock stop"
select REED_SOLOMON
select REED_SOLOMON_DEC16
help
- Use NAND flash attached to the CAFÉ chip designed for the $100
+ Use NAND flash attached to the CAFÉ chip designed for the OLPC
laptop.
config MTD_NAND_CS553X
devices. You will need to provide platform-specific functions
via platform_data.
+ config MTD_ALAUDA
+ tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
+ depends on MTD_NAND && USB
+ help
+ These two (and possibly other) Alauda-based cardreaders for
+ SmartMedia and xD allow raw flash access.
endif # MTD_NAND
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
+ obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
+obj-$(CONFIG_MTD_NAND_OMAP) += omap-nand-flash.o
+obj-$(CONFIG_MTD_NAND_OMAP_HW) += omap-hw.o
obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
+ obj-$(CONFIG_MTD_ALAUDA) += alauda.o
nand-objs := nand_base.o nand_bbt.o
help
Support for OneNAND flash via platform device driver.
+config MTD_ONENAND_OMAP2
+ tristate "OneNAND on OMAP2 support"
+ depends on MTD_ONENAND && ARCH_OMAP2
+ help
+ Support for a OneNAND flash device connected to an OMAP2 CPU
+ via the GPMC memory controller.
+
config MTD_ONENAND_OTP
bool "OneNAND OTP Support"
help
OTP block is fully-guaranteed to be a valid block.
+ config MTD_ONENAND_2X_PROGRAM
+ bool "OneNAND 2X program support"
+ help
+ The 2X Program is an extension of Program Operation.
+ Since the device is equipped with two DataRAMs, and two-plane NAND
+ Flash memory array, these two component enables simultaneous program
+ of 4KiB. Plane1 has only even blocks such as block0, block2, block4
+ while Plane2 has only odd blocks such as block1, block3, block5.
+ So MTD regards it as 4KiB page size and 256KiB block size
+
+ Now the following chips support it. (KFXXX16Q2M)
+ Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
+ Mux: KFM2G16Q2M, KFN4G16Q2M,
+
+ And more recent chips
+
+ config MTD_ONENAND_SIM
+ tristate "OneNAND simulator support"
+ depends on MTD_PARTITIONS
+ help
+ The simulator may simulate various OneNAND flash chips for the
+ OneNAND MTD layer.
+
endif # MTD_ONENAND
# Board specific.
obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
+obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o
+ # Simulator
+ obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
+
onenand-objs = onenand_base.o onenand_bbt.o
default:
block = (int) (addr >> this->erase_shift);
page = (int) (addr >> this->page_shift);
+
+ if (ONENAND_IS_2PLANE(this)) {
+ /* Make the even block number */
+ block &= ~1;
+ /* Is it the odd plane? */
+ if (addr & this->writesize)
+ block++;
+ page >>= 1;
+ }
page &= this->page_mask;
break;
}
value = onenand_bufferram_address(this, block);
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
- /* Switch to the next data buffer */
- ONENAND_SET_NEXT_BUFFERRAM(this);
+ if (ONENAND_IS_2PLANE(this))
+ /* It is always BufferRAM0 */
+ ONENAND_SET_BUFFERRAM0(this);
+ else
+ /* Switch to the next data buffer */
+ ONENAND_SET_NEXT_BUFFERRAM(this);
return 0;
}
break;
default:
+ if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
+ cmd = ONENAND_CMD_2X_PROG;
dataram = ONENAND_CURRENT_BUFFERRAM(this);
break;
}
printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl);
if (ctrl & ONENAND_CTRL_LOCK)
printk(KERN_ERR "onenand_wait: it's locked error.\n");
- return ctrl;
+ return -EIO;
}
if (interrupt & ONENAND_INT_READ) {
int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
if (ecc) {
- printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
if (ecc & ONENAND_ECC_2BIT_ALL) {
+ printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
mtd->ecc_stats.failed++;
- return ecc;
- } else if (ecc & ONENAND_ECC_1BIT_ALL)
+ return -EBADMSG;
+ } else if (ecc & ONENAND_ECC_1BIT_ALL) {
+ printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
mtd->ecc_stats.corrected++;
+ }
}
} else if (state == FL_READING) {
printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
*/
static irqreturn_t onenand_interrupt(int irq, void *data)
{
-- struct onenand_chip *this = (struct onenand_chip *) data;
++ struct onenand_chip *this = data;
/* To handle shared interrupt */
if (!this->complete.done)
struct onenand_chip *this = mtd->priv;
if (ONENAND_CURRENT_BUFFERRAM(this)) {
+ /* Note: the 'this->writesize' is a real page size */
if (area == ONENAND_DATARAM)
- return mtd->writesize;
+ return this->writesize;
if (area == ONENAND_SPARERAM)
return mtd->oobsize;
}
return 0;
}
+ /**
+ * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
+ * @param mtd MTD data structure
+ * @param addr address to check
+ * @return blockpage address
+ *
+ * Get blockpage address at 2x program mode
+ */
+ static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
+ {
+ struct onenand_chip *this = mtd->priv;
+ int blockpage, block, page;
+
+ /* Calculate the even block number */
+ block = (int) (addr >> this->erase_shift) & ~1;
+ /* Is it the odd plane? */
+ if (addr & this->writesize)
+ block++;
+ page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
+ blockpage = (block << 7) | page;
+
+ return blockpage;
+ }
+
/**
* onenand_check_bufferram - [GENERIC] Check BufferRAM information
* @param mtd MTD data structure
int blockpage, found = 0;
unsigned int i;
- blockpage = (int) (addr >> this->page_shift);
+ if (ONENAND_IS_2PLANE(this))
+ blockpage = onenand_get_2x_blockpage(mtd, addr);
+ else
+ blockpage = (int) (addr >> this->page_shift);
/* Is there valid data? */
i = ONENAND_CURRENT_BUFFERRAM(this);
int blockpage;
unsigned int i;
- blockpage = (int) (addr >> this->page_shift);
+ if (ONENAND_IS_2PLANE(this))
+ blockpage = onenand_get_2x_blockpage(mtd, addr);
+ else
+ blockpage = (int) (addr >> this->page_shift);
/* Invalidate another BufferRAM */
i = ONENAND_NEXT_BUFFERRAM(this);
}
/**
- * onenand_read - [MTD Interface] Read data from flash
+ * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
+ * @param mtd MTD device structure
+ * @param buf destination address
+ * @param column oob offset to read from
+ * @param thislen oob length to read
+ */
+ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
+ int thislen)
+ {
+ struct onenand_chip *this = mtd->priv;
+ struct nand_oobfree *free;
+ int readcol = column;
+ int readend = column + thislen;
+ int lastgap = 0;
+ unsigned int i;
+ uint8_t *oob_buf = this->oob_buf;
+
+ free = this->ecclayout->oobfree;
+ for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+ if (readcol >= lastgap)
+ readcol += free->offset - lastgap;
+ if (readend >= lastgap)
+ readend += free->offset - lastgap;
+ lastgap = free->offset + free->length;
+ }
+ this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
+ free = this->ecclayout->oobfree;
+ for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+ int free_end = free->offset + free->length;
+ if (free->offset < readend && free_end > readcol) {
+ int st = max_t(int,free->offset,readcol);
+ int ed = min_t(int,free_end,readend);
+ int n = ed - st;
+ memcpy(buf, oob_buf + st, n);
+ buf += n;
+ } else if (column == 0)
+ break;
+ }
+ return 0;
+ }
+
+ /**
+ * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
* @param mtd MTD device structure
* @param from offset to read from
- * @param len number of bytes to read
- * @param retlen pointer to variable to store the number of read bytes
- * @param buf the databuffer to put data
+ * @param ops: oob operation description structure
*
- * Read with ecc
- */
- static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char *buf)
+ * OneNAND read main and/or out-of-band data
+ */
+ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
+ struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
struct mtd_ecc_stats stats;
- int read = 0, column;
- int thislen;
+ size_t len = ops->len;
+ size_t ooblen = ops->ooblen;
+ u_char *buf = ops->datbuf;
+ u_char *oobbuf = ops->oobbuf;
+ int read = 0, column, thislen;
+ int oobread = 0, oobcolumn, thisooblen, oobsize;
int ret = 0, boundary = 0;
+ int writesize = this->writesize;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+ if (ops->mode == MTD_OOB_AUTO)
+ oobsize = this->ecclayout->oobavail;
+ else
+ oobsize = mtd->oobsize;
+
+ oobcolumn = from & (mtd->oobsize - 1);
/* Do not allow reads past end of device */
if ((from + len) > mtd->size) {
- printk(KERN_ERR "onenand_read: Attempt read beyond end of device\n");
- *retlen = 0;
+ printk(KERN_ERR "onenand_read_ops_nolock: Attempt read beyond end of device\n");
+ ops->retlen = 0;
+ ops->oobretlen = 0;
return -EINVAL;
}
- /* Grab the lock and see if the device is available */
- onenand_get_device(mtd, FL_READING);
-
stats = mtd->ecc_stats;
/* Read-while-load method */
/* Do first load to bufferRAM */
if (read < len) {
if (!onenand_check_bufferram(mtd, from)) {
- this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
+ this->command(mtd, ONENAND_CMD_READ, from, writesize);
ret = this->wait(mtd, FL_READING);
onenand_update_bufferram(mtd, from, !ret);
}
}
- thislen = min_t(int, mtd->writesize, len - read);
- column = from & (mtd->writesize - 1);
- if (column + thislen > mtd->writesize)
- thislen = mtd->writesize - column;
+ thislen = min_t(int, writesize, len - read);
+ column = from & (writesize - 1);
+ if (column + thislen > writesize)
+ thislen = writesize - column;
while (!ret) {
/* If there is more to load then start next load */
from += thislen;
if (read + thislen < len) {
- this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
+ this->command(mtd, ONENAND_CMD_READ, from, writesize);
/*
* Chip boundary handling in DDP
* Now we issued chip 1 read and pointed chip 1
}
/* While load is going, read from last bufferRAM */
this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
+
+ /* Read oob area if needed */
+ if (oobbuf) {
+ thisooblen = oobsize - oobcolumn;
+ thisooblen = min_t(int, thisooblen, ooblen - oobread);
+
+ if (ops->mode == MTD_OOB_AUTO)
+ onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
+ else
+ this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
+ oobread += thisooblen;
+ oobbuf += thisooblen;
+ oobcolumn = 0;
+ }
+
/* See if we are done */
read += thislen;
if (read == len)
this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
ONENAND_SET_NEXT_BUFFERRAM(this);
buf += thislen;
- thislen = min_t(int, mtd->writesize, len - read);
+ thislen = min_t(int, writesize, len - read);
column = 0;
cond_resched();
/* Now wait for load */
onenand_update_bufferram(mtd, from, !ret);
}
- /* Deselect and wake up anyone waiting on the device */
- onenand_release_device(mtd);
-
/*
* Return success, if no ECC failures, else -EBADMSG
* fs driver will take care of that, because
* retlen == desired len and result == -EBADMSG
*/
- *retlen = read;
+ ops->retlen = read;
+ ops->oobretlen = oobread;
if (mtd->ecc_stats.failed - stats.failed)
return -EBADMSG;
}
/**
- * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
- * @param mtd MTD device structure
- * @param buf destination address
- * @param column oob offset to read from
- * @param thislen oob length to read
- */
- static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
- int thislen)
- {
- struct onenand_chip *this = mtd->priv;
- struct nand_oobfree *free;
- int readcol = column;
- int readend = column + thislen;
- int lastgap = 0;
- unsigned int i;
- uint8_t *oob_buf = this->oob_buf;
-
- free = this->ecclayout->oobfree;
- for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
- if (readcol >= lastgap)
- readcol += free->offset - lastgap;
- if (readend >= lastgap)
- readend += free->offset - lastgap;
- lastgap = free->offset + free->length;
- }
- this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
- free = this->ecclayout->oobfree;
- for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
- int free_end = free->offset + free->length;
- if (free->offset < readend && free_end > readcol) {
- int st = max_t(int,free->offset,readcol);
- int ed = min_t(int,free_end,readend);
- int n = ed - st;
- memcpy(buf, oob_buf + st, n);
- buf += n;
- } else if (column == 0)
- break;
- }
- return 0;
- }
-
- /**
- * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band
+ * onenand_read_oob_nolock - [MTD Interface] OneNAND read out-of-band
* @param mtd MTD device structure
* @param from offset to read from
- * @param len number of bytes to read
- * @param retlen pointer to variable to store the number of read bytes
- * @param buf the databuffer to put data
- * @param mode operation mode
+ * @param ops: oob operation description structure
*
* OneNAND read out-of-band data from the spare area
*/
- static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
+ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
from += ops->ooboffs;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
/* Initialize return length value */
ops->oobretlen = 0;
column = from & (mtd->oobsize - 1);
if (unlikely(column >= oobsize)) {
- printk(KERN_ERR "onenand_read_oob: Attempted to start read outside oob\n");
+ printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n");
return -EINVAL;
}
if (unlikely(from >= mtd->size ||
column + len > ((mtd->size >> this->page_shift) -
(from >> this->page_shift)) * oobsize)) {
- printk(KERN_ERR "onenand_read_oob: Attempted to read beyond end of device\n");
+ printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n");
return -EINVAL;
}
- /* Grab the lock and see if the device is available */
- onenand_get_device(mtd, FL_READING);
-
while (read < len) {
cond_resched();
this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
if (ret) {
- printk(KERN_ERR "onenand_read_oob: read failed = 0x%x\n", ret);
+ printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
break;
}
}
}
- /* Deselect and wake up anyone waiting on the device */
+ ops->oobretlen = read;
+ return ret;
+ }
+
+ /**
+ * onenand_read - [MTD Interface] Read data from flash
+ * @param mtd MTD device structure
+ * @param from offset to read from
+ * @param len number of bytes to read
+ * @param retlen pointer to variable to store the number of read bytes
+ * @param buf the databuffer to put data
+ *
+ * Read with ecc
+ */
+ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+ {
+ struct mtd_oob_ops ops = {
+ .len = len,
+ .ooblen = 0,
+ .datbuf = buf,
+ .oobbuf = NULL,
+ };
+ int ret;
+
+ onenand_get_device(mtd, FL_READING);
+ ret = onenand_read_ops_nolock(mtd, from, &ops);
onenand_release_device(mtd);
- ops->oobretlen = read;
+ *retlen = ops.retlen;
return ret;
}
/**
- * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
+ * onenand_read_oob - [MTD Interface] Read main and/or out-of-band
* @param mtd: MTD device structure
* @param from: offset to read from
* @param ops: oob operation description structure
+
+ * Read main and/or out-of-band
*/
static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
+ int ret;
+
switch (ops->mode) {
case MTD_OOB_PLACE:
case MTD_OOB_AUTO:
default:
return -EINVAL;
}
- return onenand_do_read_oob(mtd, from, ops);
+
+ onenand_get_device(mtd, FL_READING);
+ if (ops->datbuf)
+ ret = onenand_read_ops_nolock(mtd, from, ops);
+ else
+ ret = onenand_read_oob_nolock(mtd, from, ops);
+ onenand_release_device(mtd);
+
+ return ret;
}
/**
/* Read more? */
if (read < len) {
/* Update Page size */
- from += mtd->writesize;
+ from += this->writesize;
column = 0;
}
}
* @param mtd MTD device structure
* @param buf the databuffer to verify
* @param to offset to read from
- *
*/
static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
{
* @param buf the databuffer to verify
* @param addr offset to read from
* @param len number of bytes to read and compare
- *
*/
static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
{
int thislen, column;
while (len != 0) {
- thislen = min_t(int, mtd->writesize, len);
- column = addr & (mtd->writesize - 1);
- if (column + thislen > mtd->writesize)
- thislen = mtd->writesize - column;
+ thislen = min_t(int, this->writesize, len);
+ column = addr & (this->writesize - 1);
+ if (column + thislen > this->writesize)
+ thislen = this->writesize - column;
- this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
+ this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
onenand_update_bufferram(mtd, addr, 0);
#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
/**
- * onenand_write - [MTD Interface] write buffer to FLASH
+ * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
+ * @param mtd MTD device structure
+ * @param oob_buf oob buffer
+ * @param buf source address
+ * @param column oob offset to write to
+ * @param thislen oob length to write
+ */
+ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
+ const u_char *buf, int column, int thislen)
+ {
+ struct onenand_chip *this = mtd->priv;
+ struct nand_oobfree *free;
+ int writecol = column;
+ int writeend = column + thislen;
+ int lastgap = 0;
+ unsigned int i;
+
+ free = this->ecclayout->oobfree;
+ for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+ if (writecol >= lastgap)
+ writecol += free->offset - lastgap;
+ if (writeend >= lastgap)
+ writeend += free->offset - lastgap;
+ lastgap = free->offset + free->length;
+ }
+ free = this->ecclayout->oobfree;
+ for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+ int free_end = free->offset + free->length;
+ if (free->offset < writeend && free_end > writecol) {
+ int st = max_t(int,free->offset,writecol);
+ int ed = min_t(int,free_end,writeend);
+ int n = ed - st;
+ memcpy(oob_buf + st, buf, n);
+ buf += n;
+ } else if (column == 0)
+ break;
+ }
+ return 0;
+ }
+
+ /**
+ * onenand_write_ops_nolock - [OneNAND Interface] write main and/or out-of-band
* @param mtd MTD device structure
* @param to offset to write to
- * @param len number of bytes to write
- * @param retlen pointer to variable to store the number of written bytes
- * @param buf the data to write
+ * @param ops oob operation description structure
*
- * Write with ECC
+ * Write main and/or oob with ECC
*/
- static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf)
+ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
+ struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
- int written = 0;
+ int written = 0, column, thislen, subpage;
+ int oobwritten = 0, oobcolumn, thisooblen, oobsize;
+ size_t len = ops->len;
+ size_t ooblen = ops->ooblen;
+ const u_char *buf = ops->datbuf;
+ const u_char *oob = ops->oobbuf;
+ u_char *oobbuf;
int ret = 0;
- int column, subpage;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
/* Initialize retlen, in case of early exit */
- *retlen = 0;
+ ops->retlen = 0;
+ ops->oobretlen = 0;
/* Do not allow writes past end of device */
if (unlikely((to + len) > mtd->size)) {
- printk(KERN_ERR "onenand_write: Attempt write to past end of device\n");
+ printk(KERN_ERR "onenand_write_ops_nolock: Attempt write to past end of device\n");
return -EINVAL;
}
/* Reject writes, which are not page aligned */
if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
- printk(KERN_ERR "onenand_write: Attempt to write not page aligned data\n");
+ printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n");
return -EINVAL;
}
- column = to & (mtd->writesize - 1);
+ if (ops->mode == MTD_OOB_AUTO)
+ oobsize = this->ecclayout->oobavail;
+ else
+ oobsize = mtd->oobsize;
- /* Grab the lock and see if the device is available */
- onenand_get_device(mtd, FL_WRITING);
+ oobcolumn = to & (mtd->oobsize - 1);
+
+ column = to & (mtd->writesize - 1);
/* Loop until all data write */
while (written < len) {
- int thislen = min_t(int, mtd->writesize - column, len - written);
u_char *wbuf = (u_char *) buf;
+ thislen = min_t(int, mtd->writesize - column, len - written);
+ thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
+
cond_resched();
this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
}
this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
- this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
+
+ if (oob) {
+ oobbuf = this->oob_buf;
+
+ /* We send data to spare ram with oobsize
+ * to prevent byte access */
+ memset(oobbuf, 0xff, mtd->oobsize);
+ if (ops->mode == MTD_OOB_AUTO)
+ onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
+ else
+ memcpy(oobbuf + oobcolumn, oob, thisooblen);
+
+ oobwritten += thisooblen;
+ oob += thisooblen;
+ oobcolumn = 0;
+ } else
+ oobbuf = (u_char *) ffchars;
+
+ this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
/* In partial page write we don't update bufferram */
onenand_update_bufferram(mtd, to, !ret && !subpage);
+ if (ONENAND_IS_2PLANE(this)) {
+ ONENAND_SET_BUFFERRAM1(this);
+ onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
+ }
if (ret) {
- printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
break;
}
/* Only check verify write turn on */
ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
if (ret) {
- printk(KERN_ERR "onenand_write: verify failed %d\n", ret);
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
break;
}
/* Deselect and wake up anyone waiting on the device */
onenand_release_device(mtd);
- *retlen = written;
+ ops->retlen = written;
return ret;
}
- /**
- * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
- * @param mtd MTD device structure
- * @param oob_buf oob buffer
- * @param buf source address
- * @param column oob offset to write to
- * @param thislen oob length to write
- */
- static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
- const u_char *buf, int column, int thislen)
- {
- struct onenand_chip *this = mtd->priv;
- struct nand_oobfree *free;
- int writecol = column;
- int writeend = column + thislen;
- int lastgap = 0;
- unsigned int i;
-
- free = this->ecclayout->oobfree;
- for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
- if (writecol >= lastgap)
- writecol += free->offset - lastgap;
- if (writeend >= lastgap)
- writeend += free->offset - lastgap;
- lastgap = free->offset + free->length;
- }
- free = this->ecclayout->oobfree;
- for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
- int free_end = free->offset + free->length;
- if (free->offset < writeend && free_end > writecol) {
- int st = max_t(int,free->offset,writecol);
- int ed = min_t(int,free_end,writeend);
- int n = ed - st;
- memcpy(oob_buf + st, buf, n);
- buf += n;
- } else if (column == 0)
- break;
- }
- return 0;
- }
/**
- * onenand_do_write_oob - [Internal] OneNAND write out-of-band
+ * onenand_write_oob_nolock - [Internal] OneNAND write out-of-band
* @param mtd MTD device structure
* @param to offset to write to
* @param len number of bytes to write
*
* OneNAND write out-of-band
*/
- static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
- struct mtd_oob_ops *ops)
+ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
+ struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
int column, ret = 0, oobsize;
to += ops->ooboffs;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
/* Initialize retlen, in case of early exit */
ops->oobretlen = 0;
column = to & (mtd->oobsize - 1);
if (unlikely(column >= oobsize)) {
- printk(KERN_ERR "onenand_write_oob: Attempted to start write outside oob\n");
+ printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n");
return -EINVAL;
}
/* For compatibility with NAND: Do not allow write past end of page */
if (unlikely(column + len > oobsize)) {
- printk(KERN_ERR "onenand_write_oob: "
+ printk(KERN_ERR "onenand_write_oob_nolock: "
"Attempt to write past end of page\n");
return -EINVAL;
}
if (unlikely(to >= mtd->size ||
column + len > ((mtd->size >> this->page_shift) -
(to >> this->page_shift)) * oobsize)) {
- printk(KERN_ERR "onenand_write_oob: Attempted to write past end of device\n");
+ printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n");
return -EINVAL;
}
- /* Grab the lock and see if the device is available */
- onenand_get_device(mtd, FL_WRITING);
-
oobbuf = this->oob_buf;
/* Loop until all data write */
this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
onenand_update_bufferram(mtd, to, 0);
+ if (ONENAND_IS_2PLANE(this)) {
+ ONENAND_SET_BUFFERRAM1(this);
+ onenand_update_bufferram(mtd, to + this->writesize, 0);
+ }
ret = this->wait(mtd, FL_WRITING);
if (ret) {
- printk(KERN_ERR "onenand_write_oob: write failed %d\n", ret);
+ printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret);
break;
}
ret = onenand_verify_oob(mtd, oobbuf, to);
if (ret) {
- printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
+ printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret);
break;
}
column = 0;
}
- /* Deselect and wake up anyone waiting on the device */
- onenand_release_device(mtd);
-
ops->oobretlen = written;
return ret;
}
+ /**
+ * onenand_write - [MTD Interface] write buffer to FLASH
+ * @param mtd MTD device structure
+ * @param to offset to write to
+ * @param len number of bytes to write
+ * @param retlen pointer to variable to store the number of written bytes
+ * @param buf the data to write
+ *
+ * Write with ECC
+ */
+ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+ {
+ struct mtd_oob_ops ops = {
+ .len = len,
+ .ooblen = 0,
+ .datbuf = (u_char *) buf,
+ .oobbuf = NULL,
+ };
+ int ret;
+
+ onenand_get_device(mtd, FL_WRITING);
+ ret = onenand_write_ops_nolock(mtd, to, &ops);
+ onenand_release_device(mtd);
+
+ *retlen = ops.retlen;
+ return ret;
+ }
+
/**
* onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
* @param mtd: MTD device structure
static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
+ int ret;
+
switch (ops->mode) {
case MTD_OOB_PLACE:
case MTD_OOB_AUTO:
default:
return -EINVAL;
}
- return onenand_do_write_oob(mtd, to, ops);
+
+ onenand_get_device(mtd, FL_WRITING);
+ if (ops->datbuf)
+ ret = onenand_write_ops_nolock(mtd, to, ops);
+ else
+ ret = onenand_write_oob_nolock(mtd, to, ops);
+ onenand_release_device(mtd);
+
+ return ret;
}
/**
- * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
+ * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
* @param mtd MTD device structure
* @param ofs offset from device start
- * @param getchip 0, if the chip is already selected
* @param allowbbt 1, if its allowed to access the bbt area
*
* Check, if the block is bad. Either by reading the bad block table or
* calling of the scan function.
*/
- static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
+ static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
{
struct onenand_chip *this = mtd->priv;
struct bbm_info *bbm = this->bbm;
cond_resched();
/* Check if we have a bad block, we do not erase bad blocks */
- if (onenand_block_checkbad(mtd, addr, 0, 0)) {
+ if (onenand_block_isbad_nolock(mtd, addr, 0)) {
printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
instr->state = MTD_ERASE_FAILED;
goto erase_exit;
erase_exit:
ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
- /* Do call back function */
- if (!ret)
- mtd_erase_callback(instr);
/* Deselect and wake up anyone waiting on the device */
onenand_release_device(mtd);
+ /* Do call back function */
+ if (!ret)
+ mtd_erase_callback(instr);
+
return ret;
}
*/
static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
{
+ int ret;
+
/* Check for invalid offset */
if (ofs > mtd->size)
return -EINVAL;
- return onenand_block_checkbad(mtd, ofs, 1, 0);
+ onenand_get_device(mtd, FL_READING);
+ ret = onenand_block_isbad_nolock(mtd, ofs, 0);
+ onenand_release_device(mtd);
+ return ret;
}
/**
/* We write two bytes, so we dont have to mess with 16 bit access */
ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
- return onenand_do_write_oob(mtd, ofs, &ops);
+ return onenand_write_oob_nolock(mtd, ofs, &ops);
}
/**
return ret;
}
- return this->block_markbad(mtd, ofs);
+ onenand_get_device(mtd, FL_WRITING);
+ ret = this->block_markbad(mtd, ofs);
+ onenand_release_device(mtd);
+ return ret;
}
/**
*/
static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
- return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
+ int ret;
+
+ onenand_get_device(mtd, FL_LOCKING);
+ ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
+ onenand_release_device(mtd);
+ return ret;
}
/**
*/
static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
- return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
+ int ret;
+
+ onenand_get_device(mtd, FL_LOCKING);
+ ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
+ onenand_release_device(mtd);
+ return ret;
}
/**
loff_t ofs = this->chipsize >> 1;
size_t len = mtd->erasesize;
- onenand_unlock(mtd, ofs, len);
+ onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
}
onenand_check_lock_status(this);
return 0;
}
- onenand_unlock(mtd, 0x0, this->chipsize);
+ onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK);
return 0;
}
size_t *retlen, u_char *buf)
{
struct onenand_chip *this = mtd->priv;
+ struct mtd_oob_ops ops = {
+ .len = len,
+ .ooblen = 0,
+ .datbuf = buf,
+ .oobbuf = NULL,
+ };
int ret;
/* Enter OTP access mode */
this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
this->wait(mtd, FL_OTPING);
- ret = mtd->read(mtd, from, len, retlen, buf);
+ ret = onenand_read_ops_nolock(mtd, from, &ops);
/* Exit OTP access mode */
this->command(mtd, ONENAND_CMD_RESET, 0, 0);
/**
* do_otp_write - [DEFAULT] Write OTP block area
* @param mtd MTD device structure
- * @param from The offset to write
+ * @param to The offset to write
* @param len number of bytes to write
* @param retlen pointer to variable to store the number of write bytes
* @param buf the databuffer to put/get data
*
* Write OTP block area.
*/
- static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len,
+ static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, u_char *buf)
{
struct onenand_chip *this = mtd->priv;
unsigned char *pbuf = buf;
int ret;
+ struct mtd_oob_ops ops;
/* Force buffer page aligned */
if (len < mtd->writesize) {
this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
this->wait(mtd, FL_OTPING);
- ret = mtd->write(mtd, from, len, retlen, pbuf);
+ ops.len = len;
+ ops.ooblen = 0;
+ ops.datbuf = pbuf;
+ ops.oobbuf = NULL;
+ ret = onenand_write_ops_nolock(mtd, to, &ops);
+ *retlen = ops.retlen;
/* Exit OTP access mode */
this->command(mtd, ONENAND_CMD_RESET, 0, 0);
this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
this->wait(mtd, FL_OTPING);
- ret = onenand_do_write_oob(mtd, from, &ops);
+ ret = onenand_write_oob_nolock(mtd, from, &ops);
*retlen = ops.oobretlen;
if (((mtd->writesize * otp_pages) - (from + len)) < 0)
return 0;
+ onenand_get_device(mtd, FL_OTPING);
while (len > 0 && otp_pages > 0) {
if (!action) { /* OTP Info functions */
struct otp_info *otpinfo;
len -= sizeof(struct otp_info);
- if (len <= 0)
- return -ENOSPC;
+ if (len <= 0) {
+ ret = -ENOSPC;
+ break;
+ }
otpinfo = (struct otp_info *) buf;
otpinfo->start = from;
len -= size;
*retlen += size;
- if (ret < 0)
- return ret;
+ if (ret)
+ break;
}
otp_pages--;
}
+ onenand_release_device(mtd);
- return 0;
+ return ret;
}
/**
*
* Check and set OneNAND features
* - lock scheme
+ * - two plane
*/
static void onenand_check_features(struct mtd_info *mtd)
{
process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
/* Lock scheme */
- if (density >= ONENAND_DEVICE_DENSITY_1Gb) {
+ switch (density) {
+ case ONENAND_DEVICE_DENSITY_4Gb:
+ this->options |= ONENAND_HAS_2PLANE;
+
+ case ONENAND_DEVICE_DENSITY_2Gb:
+ /* 2Gb DDP don't have 2 plane */
+ if (!ONENAND_IS_DDP(this))
+ this->options |= ONENAND_HAS_2PLANE;
+ this->options |= ONENAND_HAS_UNLOCK_ALL;
+
+ case ONENAND_DEVICE_DENSITY_1Gb:
/* A-Die has all block unlock */
- if (process) {
- printk(KERN_DEBUG "Chip support all block unlock\n");
+ if (process)
this->options |= ONENAND_HAS_UNLOCK_ALL;
- }
- } else {
- /* Some OneNAND has continues lock scheme */
- if (!process) {
- printk(KERN_DEBUG "Lock scheme is Continues Lock\n");
+ break;
+
+ default:
+ /* Some OneNAND has continuous lock scheme */
+ if (!process)
this->options |= ONENAND_HAS_CONT_LOCK;
- }
+ break;
}
+
+ if (this->options & ONENAND_HAS_CONT_LOCK)
+ printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
+ if (this->options & ONENAND_HAS_UNLOCK_ALL)
+ printk(KERN_DEBUG "Chip support all block unlock\n");
+ if (this->options & ONENAND_HAS_2PLANE)
+ printk(KERN_DEBUG "Chip has 2 plane\n");
}
/**
(16 << density),
vcc ? "2.65/3.3" : "1.8",
device);
- printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version);
+ printk(KERN_INFO "OneNAND version = 0x%04x\n", version);
}
static const struct onenand_manufacturers onenand_manuf_ids[] = {
this->erase_shift = ffs(mtd->erasesize) - 1;
this->page_shift = ffs(mtd->writesize) - 1;
this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
+ /* It's real page size */
+ this->writesize = mtd->writesize;
/* REVIST: Multichip handling */
/* Check OneNAND features */
onenand_check_features(mtd);
+ /*
+ * We emulate the 4KiB page and 256KiB erase block size
+ * But oobsize is still 64 bytes.
+ * It is only valid if you turn on 2X program support,
+ * Otherwise it will be ignored by compiler.
+ */
+ if (ONENAND_IS_2PLANE(this)) {
+ mtd->writesize <<= 1;
+ mtd->erasesize <<= 1;
+ }
+
return 0;
}
Say Y here if you want to build support for the Cirrus logic
EP7211 chipset's infrared module.
+ config KSDAZZLE_DONGLE
+ tristate "KingSun Dazzle IrDA-USB dongle (EXPERIMENTAL)"
+ depends on IRDA && USB && EXPERIMENTAL
+ help
+ Say Y or M here if you want to build support for the KingSun Dazzle
+ IrDA-USB bridge device driver.
+
+ This USB bridge does not conform to the IrDA-USB device class
+ specification, and therefore needs its own specific driver. This
+ dongle supports SIR speeds only (9600 through 115200 bps).
+
+ To compile it as a module, choose M here: the module will be called
+ ksdazzle-sir.
+ config KS959_DONGLE
+ tristate "KingSun KS-959 IrDA-USB dongle (EXPERIMENTAL)"
+ depends on IRDA && USB && EXPERIMENTAL
+ help
+ Say Y or M here if you want to build support for the KingSun KS-959
+ IrDA-USB bridge device driver.
+
+ This USB bridge does not conform to the IrDA-USB device class
+ specification, and therefore needs its own specific driver. This
+ dongle supports SIR speeds only (9600 through 57600 bps).
+
+ To compile it as a module, choose M here: the module will be called
+ ks959-sir.
comment "Old SIR device drivers"
To compile it as a module, choose M here: the module will be called
mcs7780.
+config OMAP_IR
+ tristate "OMAP IrDA(SIR/MIR/FIR)"
+ depends on IRDA && ARCH_OMAP
+ select GPIOEXPANDER_OMAP if (MACH_OMAP_H3 || MACH_OMAP_H4)
+ help
+ Say Y here if you want to build support for the Texas Instruments
+ OMAP IrDA device driver, which supports SIR/MIR/FIR. This driver
+ relies on platform specific helper routines so available capabilities
+ may vary from one OMAP target to another.
+
endmenu
obj-$(CONFIG_VIA_FIR) += via-ircc.o
obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o
obj-$(CONFIG_MCS_FIR) += mcs7780.o
+obj-$(CONFIG_OMAP_IR) += omap-ir.o
# Old dongle drivers for old SIR drivers
obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o
obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o
obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o
obj-$(CONFIG_EP7211_DONGLE) += ep7211-sir.o
obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o
+ obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o
+ obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o
# The SIR helper module
sir-dev-objs := sir_dev.o sir_dongle.o
*/
#define MII_DELAY 1
- /* store this information for the driver.. */
- struct smc_local {
- /*
- * If I have to wait until memory is available to send a
- * packet, I will store the skbuff here, until I get the
- * desired memory. Then, I'll send it out and free it.
- */
- struct sk_buff *pending_tx_skb;
- struct tasklet_struct tx_task;
-
- /*
- * these are things that the kernel wants me to keep, so users
- * can find out semi-useless statistics of how well the card is
- * performing
- */
- struct net_device_stats stats;
-
- /* version/revision of the SMC91x chip */
- int version;
-
- /* Contains the current active transmission mode */
- int tcr_cur_mode;
-
- /* Contains the current active receive mode */
- int rcr_cur_mode;
-
- /* Contains the current active receive/phy mode */
- int rpc_cur_mode;
- int ctl_rfduplx;
- int ctl_rspeed;
-
- u32 msg_enable;
- u32 phy_type;
- struct mii_if_info mii;
-
- /* work queue */
- struct work_struct phy_configure;
- struct net_device *dev;
- int work_pending;
-
- spinlock_t lock;
-
- #ifdef SMC_USE_PXA_DMA
- /* DMA needs the physical address of the chip */
- u_long physaddr;
- #endif
- void __iomem *base;
- void __iomem *datacs;
- };
-
#if SMC_DEBUG > 0
#define DBG(n, args...) \
do { \
/* free any pending tx skb */
if (pending_skb) {
dev_kfree_skb(pending_skb);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
}
/*
dev->name, packet_number, status,
packet_len, packet_len);
+ if (unlikely(packet_len == 0 && !(status & RS_ERRORS))) {
+ printk(KERN_ERR "%s: bad memory timings: rxlen %u status %x\n",
+ dev->name, packet_len, status);
+ status |= RS_TOOSHORT;
+ }
back:
if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) {
}
SMC_WAIT_MMU_BUSY();
SMC_SET_MMU_CMD(MC_RELEASE);
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (status & RS_ALGNERR)
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & (RS_TOOSHORT | RS_TOOLONG))
- lp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (status & RS_BADCRC)
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
} else {
struct sk_buff *skb;
unsigned char *data;
/* set multicast stats */
if (status & RS_MULTICAST)
- lp->stats.multicast++;
+ dev->stats.multicast++;
/*
* Actual payload is packet_len - 6 (or 5 if odd byte).
dev->name);
SMC_WAIT_MMU_BUSY();
SMC_SET_MMU_CMD(MC_RELEASE);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
dev->last_rx = jiffies;
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += data_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += data_len;
}
}
packet_no = SMC_GET_AR();
if (unlikely(packet_no & AR_FAILED)) {
printk("%s: Memory allocation failed.\n", dev->name);
- lp->stats.tx_errors++;
- lp->stats.tx_fifo_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_fifo_errors++;
smc_special_unlock(&lp->lock);
goto done;
}
smc_special_unlock(&lp->lock);
dev->trans_start = jiffies;
- lp->stats.tx_packets++;
- lp->stats.tx_bytes += len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += len;
SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT);
numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
if (unlikely(numPages > 7)) {
printk("%s: Far too big packet error.\n", dev->name);
- lp->stats.tx_errors++;
- lp->stats.tx_dropped++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return 0;
}
dev->name, tx_status, packet_no);
if (!(tx_status & ES_TX_SUC))
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (tx_status & ES_LOSTCARR)
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (tx_status & (ES_LATCOL | ES_16COL)) {
PRINTK("%s: %s occurred on last xmit\n", dev->name,
(tx_status & ES_LATCOL) ?
"late collision" : "too many collisions");
- lp->stats.tx_window_errors++;
- if (!(lp->stats.tx_window_errors & 63) && net_ratelimit()) {
+ dev->stats.tx_window_errors++;
+ if (!(dev->stats.tx_window_errors & 63) && net_ratelimit()) {
printk(KERN_INFO "%s: unexpectedly large number of "
"bad collisions. Please check duplex "
"setting.\n", dev->name);
SMC_SELECT_BANK(2);
/* single collisions */
- lp->stats.collisions += card_stats & 0xF;
+ dev->stats.collisions += card_stats & 0xF;
card_stats >>= 4;
/* multiple collisions */
- lp->stats.collisions += card_stats & 0xF;
+ dev->stats.collisions += card_stats & 0xF;
} else if (status & IM_RX_OVRN_INT) {
DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
({ int eph_st; SMC_SELECT_BANK(0);
eph_st = SMC_GET_EPH_STATUS();
SMC_SELECT_BANK(2); eph_st; }) );
SMC_ACK_INT(IM_RX_OVRN_INT);
- lp->stats.rx_errors++;
- lp->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_fifo_errors++;
} else if (status & IM_EPH_INT) {
smc_eph_interrupt(dev);
} else if (status & IM_MDINT) {
return 0;
}
- /*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
- static struct net_device_stats *smc_query_statistics(struct net_device *dev)
- {
- struct smc_local *lp = netdev_priv(dev);
-
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
-
- return &lp->stats;
- }
-
/*
* Ethtool support
*/
{
struct smc_local *lp = netdev_priv(dev);
static int version_printed = 0;
- int i, retval;
+ int retval;
unsigned int val, revision_register;
const char *version_string;
+ DECLARE_MAC_BUF(mac);
DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
dev->hard_start_xmit = smc_hard_start_xmit;
dev->tx_timeout = smc_timeout;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
- dev->get_stats = smc_query_statistics;
dev->set_multicast_list = smc_set_multicast_list;
dev->ethtool_ops = &smc_ethtool_ops;
#ifdef CONFIG_NET_POLL_CONTROLLER
"set using ifconfig\n", dev->name);
} else {
/* Print the Ethernet address */
- printk("%s: Ethernet addr: ", dev->name);
- for (i = 0; i < 5; i++)
- printk("%2.2x:", dev->dev_addr[i]);
- printk("%2.2x\n", dev->dev_addr[5]);
+ printk("%s: Ethernet addr: %s\n",
+ dev->name, print_mac(mac, dev->dev_addr));
}
if (lp->phy_type == 0) {
ret = -ENOMEM;
goto out_release_io;
}
- SET_MODULE_OWNER(ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->dma = (unsigned char)-1;
goto out_release_attrib;
}
- platform_set_drvdata(pdev, ndev);
- ret = smc_probe(ndev, addr);
- if (ret != 0)
- goto out_iounmap;
#ifdef SMC_USE_PXA_DMA
- else {
+ {
struct smc_local *lp = netdev_priv(ndev);
+ lp->device = &pdev->dev;
lp->physaddr = res->start;
}
#endif
+ platform_set_drvdata(pdev, ndev);
+ ret = smc_probe(ndev, addr);
+ if (ret != 0)
+ goto out_iounmap;
+
smc_request_datacs(pdev, ndev);
return 0;
#include <asm/mach-types.h>
#include <asm/arch/cpu.h>
-#define SMC_IRQ_FLAGS (( \
- machine_is_omap_h2() \
- || machine_is_omap_h3() \
- || machine_is_omap_h4() \
- || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
- ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
-
+#ifdef CONFIG_ARCH_OMAP1
+#define SMC_IRQ_FLAGS ((machine_is_omap_innovator() || \
+ machine_is_omap_osk()) \
+ ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING)
+#else
+#define SMC_IRQ_FLAGS (machine_is_omap_apollon() \
+ ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_LOW)
+#endif
#elif defined(CONFIG_SH_SH4202_MICRODEV)
#elif defined(CONFIG_SUPERH)
#ifdef CONFIG_SOLUTION_ENGINE
+ #define SMC_IRQ_FLAGS (0)
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#endif
+
+ /* store this information for the driver.. */
+ struct smc_local {
+ /*
+ * If I have to wait until memory is available to send a
+ * packet, I will store the skbuff here, until I get the
+ * desired memory. Then, I'll send it out and free it.
+ */
+ struct sk_buff *pending_tx_skb;
+ struct tasklet_struct tx_task;
+
+ /* version/revision of the SMC91x chip */
+ int version;
+
+ /* Contains the current active transmission mode */
+ int tcr_cur_mode;
+
+ /* Contains the current active receive mode */
+ int rcr_cur_mode;
+
+ /* Contains the current active receive/phy mode */
+ int rpc_cur_mode;
+ int ctl_rfduplx;
+ int ctl_rspeed;
+
+ u32 msg_enable;
+ u32 phy_type;
+ struct mii_if_info mii;
+
+ /* work queue */
+ struct work_struct phy_configure;
+ struct net_device *dev;
+ int work_pending;
+
+ spinlock_t lock;
+
+ #ifdef SMC_USE_PXA_DMA
+ /* DMA needs the physical address of the chip */
+ u_long physaddr;
+ struct device *device;
+ #endif
+ void __iomem *base;
+ void __iomem *datacs;
+ };
+
+
#ifdef SMC_USE_PXA_DMA
/*
* Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
#ifdef SMC_insl
#undef SMC_insl
#define SMC_insl(a, r, p, l) \
- smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
+ smc_pxa_dma_insl(a, lp, r, dev->dma, p, l)
static inline void
- smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
+ smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
u_char *buf, int len)
{
+ u_long physaddr = lp->physaddr;
dma_addr_t dmabuf;
/* fallback if no DMA available */
}
len *= 4;
- dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
+ dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg;
while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax();
DCSR(dma) = 0;
- dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
+ dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
}
#endif
#ifdef SMC_insw
#undef SMC_insw
#define SMC_insw(a, r, p, l) \
- smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
+ smc_pxa_dma_insw(a, lp, r, dev->dma, p, l)
static inline void
- smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
+ smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
u_char *buf, int len)
{
+ u_long physaddr = lp->physaddr;
dma_addr_t dmabuf;
/* fallback if no DMA available */
}
len *= 2;
- dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
+ dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg;
while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax();
DCSR(dma) = 0;
- dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
+ dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
}
#endif
This driver can also be built as a module. If so, the module
will be called rtc-ds1307.
+ config RTC_DRV_DS1374
+ tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for Dallas Semiconductor
+ DS1374 real-time clock chips. If an interrupt is associated
+ with the device, the alarm functionality is supported.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1374.
+
config RTC_DRV_DS1672
tristate "Dallas/Maxim DS1672"
help
depends on MENELAUS
help
If you say yes here you get support for the RTC on the
- TWL92330 "Menelaus" power mangement chip, used with OMAP2
+ TWL92330 "Menelaus" power management chip, used with OMAP2
platforms. The support is integrated with the rest of
the Menelaus driver; it's not separate module.
+config RTC_DRV_TWL4030
+ tristate "OMAP TWL4030 Real Time Clock"
+ depends on RTC_CLASS && TWL4030_CORE
+ help
+ If you say yes here you get support for internal Real-Time
+ Clock of TWL4030 chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-twl4030.
+
endif # I2C
comment "SPI RTC drivers"
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
+ obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
+obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
Controller in master SPI mode.
config SPI_MPC83xx
- tristate "Freescale MPC83xx SPI controller"
- depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
+ tristate "Freescale MPC83xx/QUICC Engine SPI controller"
+ depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
select SPI_BITBANG
help
- This enables using the Freescale MPC83xx SPI controller in master
- mode.
+ This enables using the Freescale MPC83xx and QUICC Engine SPI
+ controllers in master mode.
Note, this driver uniquely supports the SPI controller on the MPC83xx
- family of PowerPC processors. The MPC83xx uses a simple set of shift
- registers for data (opposed to the CPM based descriptor model).
+ family of PowerPC processors, plus processors with QUICC Engine
+ technology. This driver uses a simple set of shift registers for data
+ (opposed to the CPM based descriptor model).
config SPI_OMAP_UWIRE
tristate "OMAP1 MicroWire"
This driver can also be built as a module. If so, the module
will be called at25.
+config SPI_TSC2101
+ depends on SPI_MASTER
+ tristate "TSC2101 chip support"
+ ---help---
+ Say Y here if you want support for the TSC2101 chip.
+ At the moment it provides basic register read / write interface
+ as well as a way to enable the MCLK clock.
+
+config SPI_TSC2102
+ depends on SPI_MASTER
+ tristate "TSC2102 codec support"
+ ---help---
+ Say Y here if you want support for the TSC2102 chip. It
+ will be needed for the touchscreen driver on some boards.
+
+config SPI_TSC210X
+ depends on SPI_MASTER && EXPERIMENTAL
+ tristate "TI TSC210x (TSC2101/TSC2102) support"
+ help
+ Say Y here if you want support for the TSC210x chips. Some
+ boards use these for touchscreen and audio support.
+
+ These are members of a family of highly integrated PDA analog
+ interface circuit. They include a 12-bit ADC used for battery,
+ temperature, touchscreen, and other sensors. They also have
+ an audio DAC and amplifier, and in some models an audio ADC.
+ The audio support is highly chip-specific, but most of the
+ sensor support works the same.
+
+ Note that the device has to be present in the board's SPI
+ devices table for this driver to load. This driver doesn't
+ automatically enable touchscreen, sensors or audio
+ functionality - enable these in their respective menus.
+
+config SPI_TSC2301
+ tristate "TSC2301 driver"
+ depends on SPI_MASTER
+ help
+ Say Y here if you have a TSC2301 chip connected to an SPI
+ bus on your board.
+
+ The TSC2301 is a highly integrated PDA analog interface circuit.
+ It contains a complete 12-bit A/D resistive touch screen
+ converter (ADC) including drivers, touch pressure measurement
+ capability, keypad controller, and 8-bit D/A converter (DAC) output
+ for LCD contrast control.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tsc2301.
+
+config SPI_TSC2301_AUDIO
+ boolean "TSC2301 audio support"
+ depends on SPI_TSC2301 && SND
+ help
+ Say Y here for if you are using the audio features of TSC2301.
+
config SPI_SPIDEV
tristate "User mode SPI device driver support"
depends on SPI_MASTER && EXPERIMENTAL
driver on a new board. Enable these files by choosing "Y"
here. If in doubt, or to conserve kernel memory, say "N".
+ config USB_GADGET_DEBUG_FS
+ boolean "Debugging information files in debugfs"
+ depends on USB_GADGET && DEBUG_FS
+ help
+ Some of the drivers in the "gadget" framework can expose
+ debugging information in files under /sys/kernel/debug/.
+ The information in these files may help when you're
+ troubleshooting or bringing up a driver on a new board.
+ Enable these files by choosing "Y" here. If in doubt, or
+ to conserve kernel memory, say "N".
+
config USB_GADGET_SELECTED
boolean
default USB_GADGET
select USB_GADGET_SELECTED
+ config USB_GADGET_ATMEL_USBA
+ boolean "Atmel USBA"
+ select USB_GADGET_DUALSPEED
+ depends on AVR32
+ help
+ USBA is the integrated high-speed USB Device controller on
+ the AT32AP700x processors from Atmel.
+
+ config USB_ATMEL_USBA
+ tristate
+ depends on USB_GADGET_ATMEL_USBA
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
config USB_GADGET_FSL_USB2
boolean "Freescale Highspeed USB DR Peripheral Controller"
depends on MPC834x || PPC_MPC831x
default USB_GADGET
select USB_GADGET_SELECTED
-
+# built in ../musb along with host support
+config USB_GADGET_MUSB_HDRC
+ boolean "Inventra HDRC USB Peripheral (TI, ...)"
+ depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
+ select USB_GADGET_DUALSPEED
+ select USB_GADGET_SELECTED
+ help
+ This OTG-capable silicon IP is used in dual designs including
+ the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
+
config USB_GADGET_OMAP
boolean "OMAP USB Device Controller"
depends on ARCH_OMAP
- select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+ select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
help
Many Texas Instruments OMAP processors have flexible full
speed USB device controllers, with support for up to 30
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/usb/ch9.h>
- #include <linux/usb_gadget.h>
+ #include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
udc->gadget.dev.parent->power.power_state = PMSG_ON;
udc->gadget.dev.power.power_state = PMSG_ON;
UDC_SYSCON1_REG |= UDC_PULLUP_EN;
- #ifndef CONFIG_USB_OTG
- if (!cpu_is_omap15xx())
+ if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx())
OTG_CTRL_REG |= OTG_BSESSVLD;
- #endif
UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
}
static void pullup_disable(struct omap_udc *udc)
{
- #ifndef CONFIG_USB_OTG
- if (!cpu_is_omap15xx())
+ if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx())
OTG_CTRL_REG &= ~OTG_BSESSVLD;
- #endif
UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
UDC_SYSCON1_REG &= ~UDC_PULLUP_EN;
}
{
u16 devstat;
- if (!udc->gadget.is_otg)
+ if (!gadget_is_otg(udc->gadget))
return;
if (OTG_CTRL_REG & OTG_ID)
* and ignored for PIO-IN on newer chips
* (for more reliable behavior)
*/
- if (!use_dma || cpu_is_omap15xx() || cpu_is_omap24xx())
+ if ((!use_dma && (addr & USB_DIR_IN))
+ || machine_is_omap_apollon()
+ || cpu_is_omap15xx())
dbuf = 0;
switch (maxp) {
To have support for your specific LCD panel you will have to
select the proper drivers which depend on this option.
+ config LCD_LTV350QV
+ tristate "Samsung LTV350QV LCD Panel"
+ depends on LCD_CLASS_DEVICE && SPI_MASTER
+ default n
+ help
+ If you have a Samsung LTV350QV LCD panel, say y to include a
+ power control driver for it. The panel starts up in power
+ off state, so you need this driver in order to see any
+ output.
+
+ The LTV350QV panel is present on all ATSTK1000 boards.
+
#
# Backlight
#
select the proper drivers which depend on this option.
config BACKLIGHT_CORGI
- tristate "Sharp Corgi Backlight Driver (SL Series)"
- depends on BACKLIGHT_CLASS_DEVICE && PXA_SHARPSL
- default y
+ tristate "Generic (aka Sharp Corgi) Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE
+ default n
help
- If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
- backlight driver.
+ Say y to enable the generic platform backlight driver previously
+ known as the Corgi backlight driver. If you have a Sharp Zaurus
+ SL-C7xx, SL-Cxx00 or SL-6000x say y. Most users can say n.
config BACKLIGHT_LOCOMO
tristate "Sharp LOCOMO LCD/Backlight Driver"
If you have a HP Jornada 680, say y to enable the
backlight driver.
+config BACKLIGHT_OMAP
+ tristate "OMAP LCD Backlight"
+ depends on BACKLIGHT_CLASS_DEVICE && (ARCH_OMAP1 || ARCH_OMAP2)
+ default y
+ help
+ This driver controls the LCD backlight level and power
+ for the PWL module of OMAP processors. Say Y if you plan
+ to use power saving.
+
config BACKLIGHT_PROGEAR
tristate "Frontpath ProGear Backlight Driver"
depends on BACKLIGHT_CLASS_DEVICE && PCI && X86
# Backlight & LCD drivers
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
+ obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
+
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_OMAP) += omap_bl.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
config FB_OMAP
tristate "OMAP frame buffer support (EXPERIMENTAL)"
- depends on FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
+ depends on FB
+ help
Frame buffer driver for OMAP based boards.
+config FB_OMAP_LCDC_EXTERNAL
+ bool "External LCD controller support"
+ depends on FB_OMAP
+ help
+ Say Y here, if you want to have support for boards with an
+ external LCD controller connected to the SoSSI/RFBI interface.
+
+config FB_OMAP_LCDC_HWA742
+ bool "Epson HWA742 LCD controller support"
+ depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
+ help
+ Say Y here if you want to have support for the external
+ Epson HWA742 LCD controller.
+
+config FB_OMAP_LCDC_BLIZZARD
+ bool "Epson Blizzard LCD controller support"
+ depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
+ help
+ Say Y here if you want to have support for the external
+ Epson Blizzard LCD controller.
+
+config FB_OMAP_MANUAL_UPDATE
+ bool "Default to manual update mode"
+ depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
+ help
+ Say Y here, if your user-space applications are capable of
+ notifying the frame buffer driver when a change has occured in
+ the frame buffer content and thus a reload of the image data to
+ the external frame buffer is required. If unsure, say N.
+
+config FB_OMAP_LCD_MIPID
+ bool "MIPI DBI-C/DCS compatible LCD support"
+ depends on FB_OMAP && SPI_MASTER && CBUS_TAHVO
+ help
+ Say Y here if you want to have support for LCDs compatible with
+ the Mobile Industry Processor Interface DBI-C/DCS
+ specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3)
+
config FB_OMAP_BOOTLOADER_INIT
- bool "Check bootloader initializaion"
+ bool "Check bootloader initialization"
depends on FB_OMAP
help
Say Y here if you want to enable checking if the bootloader has
answer yes. Answer no if you have a dedicated video
memory, or don't use any of the accelerated features.
-config FB_OMAP_LCDC_EXTERNAL
- bool "External LCD controller support"
- depends on FB_OMAP
- help
- Say Y here, if you want to have support for boards with an
- external LCD controller connected to the SoSSI/RFBI interface.
-config FB_OMAP_LCDC_HWA742
- bool "Epson HWA742 LCD controller support"
- depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
- help
- Say Y here if you want to have support for the external
- Epson HWA742 LCD controller.
-
-config FB_OMAP_LCDC_BLIZZARD
- bool "Epson Blizzard LCD controller support"
- depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
- help
- Say Y here if you want to have support for the external
- Epson Blizzard LCD controller.
* OMAP2 Remote Frame Buffer Interface support
*
* Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * Author: Juha Yrj�l� <juha.yrjola@nokia.com>
* Imre Deak <imre.deak@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
static int rfbi_get_clocks(void)
{
if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) {
- dev_err(rfbi.fbdev->dev, "can't get dss_ick");
+ dev_err(rfbi.fbdev->dev, "can't get dss_ick\n");
return PTR_ERR(rfbi.dss_ick);
}
if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) {
- dev_err(rfbi.fbdev->dev, "can't get dss1_fck");
+ dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
clk_put(rfbi.dss_ick);
return PTR_ERR(rfbi.dss1_fck);
}
#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */
#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */
#define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */
+ #define I2C_DRIVERID_VP27SMPX 93 /* Panasonic VP27s tuner internal MPX */
+ #define I2C_DRIVERID_CS4270 94 /* Cirrus Logic 4270 audio codec */
+#define I2C_DRIVERID_MISC 99 /* Whatever until sorted out */
+
#define I2C_DRIVERID_I2CDEV 900
#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */
#define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */
#define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */
#define I2C_HW_B_INTELFB 0x010021 /* intel framebuffer driver */
+ #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */
/* --- PCF 8584 based algorithms */
#define I2C_HW_P_LP 0x020000 /* Parallel port interface */
#include <linux/tty_driver.h>
#include <linux/console.h>
#include <linux/init.h>
+ #include <linux/jiffies.h>
+ #include <linux/nmi.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h> /* For in_interrupt() */
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+#ifdef CONFIG_DEBUG_LL
+extern void printascii(char *);
+#endif
+
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
__setup("log_buf_len=", log_buf_len_setup);
+ #ifdef CONFIG_BOOT_PRINTK_DELAY
+
+ static unsigned int boot_delay; /* msecs delay after each printk during bootup */
+ static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */
+
+ static int __init boot_delay_setup(char *str)
+ {
+ unsigned long lpj;
+ unsigned long long loops_per_msec;
+
+ lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */
+ loops_per_msec = (unsigned long long)lpj / 1000 * HZ;
+
+ get_option(&str, &boot_delay);
+ if (boot_delay > 10 * 1000)
+ boot_delay = 0;
+
+ printk_delay_msec = loops_per_msec;
+ printk(KERN_DEBUG "boot_delay: %u, preset_lpj: %ld, lpj: %lu, "
+ "HZ: %d, printk_delay_msec: %llu\n",
+ boot_delay, preset_lpj, lpj, HZ, printk_delay_msec);
+ return 1;
+ }
+ __setup("boot_delay=", boot_delay_setup);
+
+ static void boot_delay_msec(void)
+ {
+ unsigned long long k;
+ unsigned long timeout;
+
+ if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
+ return;
+
+ k = (unsigned long long)printk_delay_msec * boot_delay;
+
+ timeout = jiffies + msecs_to_jiffies(boot_delay);
+ while (k) {
+ k--;
+ cpu_relax();
+ /*
+ * use (volatile) jiffies to prevent
+ * compiler reduction; loop termination via jiffies
+ * is secondary and may or may not happen.
+ */
+ if (time_after(jiffies, timeout))
+ break;
+ touch_nmi_watchdog();
+ }
+ }
+ #else
+ static inline void boot_delay_msec(void)
+ {
+ }
+ #endif
+
+ /*
+ * Return the number of unread characters in the log buffer.
+ */
+ int log_buf_get_len(void)
+ {
+ return logged_chars;
+ }
+
+ /*
+ * Copy a range of characters from the log buffer.
+ */
+ int log_buf_copy(char *dest, int idx, int len)
+ {
+ int ret, max;
+ bool took_lock = false;
+
+ if (!oops_in_progress) {
+ spin_lock_irq(&logbuf_lock);
+ took_lock = true;
+ }
+
+ max = log_buf_get_len();
+ if (idx < 0 || idx >= max) {
+ ret = -1;
+ } else {
+ if (len > max)
+ len = max;
+ ret = len;
+ idx += (log_end - max);
+ while (len-- > 0)
+ dest[len] = LOG_BUF(idx + len);
+ }
+
+ if (took_lock)
+ spin_unlock_irq(&logbuf_lock);
+
+ return ret;
+ }
+
+ /*
+ * Extract a single character from the log buffer.
+ */
+ int log_buf_read(int idx)
+ {
+ char ret;
+
+ if (log_buf_copy(&ret, idx, 1) == 1)
+ return ret;
+ else
+ return -1;
+ }
+
/*
* Commands to do_syslog:
*
init_MUTEX(&console_sem);
}
-#if defined(CONFIG_PRINTK_TIME)
-static int printk_time = 1;
-#else
static int printk_time = 0;
-#endif
-module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
+
+#ifdef CONFIG_PRINTK_TIME
+
+/*
+ * Initialize printk time. Note that on some systems sched_clock()
+ * does not work until timer is initialized.
+ */
+static int __init printk_time_init(void)
+{
+ printk_time = 1;
+
+ return 0;
+}
+subsys_initcall(printk_time_init);
+
+#else
static int __init printk_time_setup(char *str)
{
__setup("time", printk_time_setup);
+#endif
+module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
+
__attribute__((weak)) unsigned long long printk_clock(void)
{
return sched_clock();
static char printk_buf[1024];
static int log_level_unknown = 1;
+ boot_delay_msec();
+
preempt_disable();
if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
/* If a crash is occurring during printk() on this CPU,
/* Emit the output into the temporary buffer */
printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+#ifdef CONFIG_DEBUG_LL
+ printascii(printk_buf);
+#endif
+
/*
* Copy the output into log_buf. If the caller didn't provide
* appropriate log level tags, we insert them here
return -1;
}
- #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+ int console_suspend_enabled = 1;
+ EXPORT_SYMBOL(console_suspend_enabled);
+
+ static int __init console_suspend_disable(char *str)
+ {
+ console_suspend_enabled = 0;
+ return 1;
+ }
+ __setup("no_console_suspend", console_suspend_disable);
+
/**
* suspend_console - suspend the console subsystem
*
*/
void suspend_console(void)
{
+ if (!console_suspend_enabled)
+ return;
printk("Suspending console(s)\n");
acquire_console_sem();
console_suspended = 1;
void resume_console(void)
{
+ if (!console_suspend_enabled)
+ return;
console_suspended = 0;
release_console_sem();
}
- #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
/**
* acquire_console_sem - lock the console system for exclusive use.
If you are unsure how to answer this question, answer N.
config SECURITY_CAPABILITIES
- tristate "Default Linux Capabilities"
+ bool "Default Linux Capabilities"
depends on SECURITY
help
This enables the "default" Linux capabilities functionality.
If you are unsure how to answer this question, answer Y.
+ config SECURITY_FILE_CAPABILITIES
+ bool "File POSIX Capabilities (EXPERIMENTAL)"
+ depends on (SECURITY=n || SECURITY_CAPABILITIES!=n) && EXPERIMENTAL
+ default n
+ help
+ This enables filesystem capabilities, allowing you to give
+ binaries a subset of root's powers without using setuid 0.
+
+ If in doubt, answer N.
+
config SECURITY_ROOTPLUG
- tristate "Root Plug Support"
- depends on USB && SECURITY
+ bool "Root Plug Support"
+ depends on USB=y && SECURITY
help
This is a sample LSM module that should only be used as such.
It prevents any programs running with egid == 0 if a specific
If you are unsure how to answer this question, answer N.
+config SECURITY_LOWMEM
+ tristate "Low memory watermark support"
+ depends on SECURITY
+ help
+ Implements low memory watermark support.
+
+ If you are unsure how to answer this question, answer N.
+
source security/selinux/Kconfig
endmenu
obj-$(CONFIG_SOUND_OSS) += sound.o
obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o
+obj-$(CONFIG_SOUND_OMAP) += omap-audio-dma-intfc.o omap-audio.o
+obj-$(CONFIG_SOUND_OMAP_TSC2101)+= omap-audio-tsc2101.o
+obj-$(CONFIG_SOUND_OMAP_AIC23) += omap-audio-aic23.o
+
# Please leave it as is, cause the link order is significant !
obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o
- obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o
obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o
obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o
obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o