--- /dev/null
+What: /sys/class/scsi_host/hostX/isci_id
+Date: June 2011
+Contact: Dave Jiang <dave.jiang@intel.com>
+Description:
+ This file contains the enumerated host ID for the Intel
+ SCU controller. The Intel(R) C600 Series Chipset SATA/SAS
+ Storage Control Unit embeds up to two 4-port controllers in
+ a single PCI device. The controllers are enumerated in order
+ which usually means the lowest number scsi_host corresponds
+ with the first controller, but this association is not
+ guaranteed. The 'isci_id' attribute unambiguously identifies
+ the controller index: '0' for the first controller,
+ '1' for the second.
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-h264-vui-sar-idc">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC</constant> </entry>
<entry>enum v4l2_mpeg_video_h264_vui_sar_idc</entry>
</row>
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-h264-level">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_LEVEL</constant> </entry>
<entry>enum v4l2_mpeg_video_h264_level</entry>
</row>
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-mpeg4-level">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL</constant> </entry>
<entry>enum v4l2_mpeg_video_mpeg4_level</entry>
</row>
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-h264-profile">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_PROFILE</constant> </entry>
- <entry>enum v4l2_mpeg_h264_profile</entry>
+ <entry>enum v4l2_mpeg_video_h264_profile</entry>
</row>
<row><entry spanname="descr">The profile information for H264.
Applicable to the H264 encoder.
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-mpeg4-profile">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE</constant> </entry>
- <entry>enum v4l2_mpeg_mpeg4_profile</entry>
+ <entry>enum v4l2_mpeg_video_mpeg4_profile</entry>
</row>
<row><entry spanname="descr">The profile information for MPEG4.
Applicable to the MPEG4 encoder.
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-multi-slice-mode">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE</constant> </entry>
- <entry>enum v4l2_mpeg_multi_slice_mode</entry>
+ <entry>enum v4l2_mpeg_video_multi_slice_mode</entry>
</row>
<row><entry spanname="descr">Determines how the encoder should handle division of frame into slices.
Applicable to the encoder.
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-h264-loop-filter-mode">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE</constant> </entry>
- <entry>enum v4l2_mpeg_h264_loop_filter_mode</entry>
+ <entry>enum v4l2_mpeg_video_h264_loop_filter_mode</entry>
</row>
<row><entry spanname="descr">Loop filter mode for H264 encoder.
Possible values are:</entry>
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-h264-entropy-mode">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE</constant> </entry>
- <entry>enum v4l2_mpeg_h264_symbol_mode</entry>
+ <entry>enum v4l2_mpeg_video_h264_entropy_mode</entry>
</row>
<row><entry spanname="descr">Entropy coding mode for H264 - CABAC/CAVALC.
Applicable to the H264 encoder.
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-video-header-mode">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_HEADER_MODE</constant> </entry>
- <entry>enum v4l2_mpeg_header_mode</entry>
+ <entry>enum v4l2_mpeg_video_header_mode</entry>
</row>
<row><entry spanname="descr">Determines whether the header is returned as the first buffer or is
it returned together with the first frame. Applicable to encoders.
Applicable to the H264 encoder.</entry>
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-mfc51-video-frame-skip-mode">
<entry spanname="id"><constant>V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE</constant> </entry>
- <entry>enum v4l2_mpeg_mfc51_frame_skip_mode</entry>
+ <entry>enum v4l2_mpeg_mfc51_video_frame_skip_mode</entry>
</row>
<row><entry spanname="descr">
Indicates in what conditions the encoder should skip frames. If encoding a frame would cause the encoded stream to be larger then
</entry>
</row>
<row><entry></entry></row>
- <row>
+ <row id="v4l2-mpeg-mfc51-video-force-frame-type">
<entry spanname="id"><constant>V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE</constant> </entry>
- <entry>enum v4l2_mpeg_mfc51_force_frame_type</entry>
+ <entry>enum v4l2_mpeg_mfc51_video_force_frame_type</entry>
</row>
<row><entry spanname="descr">Force a frame type for the next queued buffer. Applicable to encoders.
Possible values are:</entry>
5.2 stat file
-5.2.1 memory.stat file includes following statistics
+memory.stat file includes following statistics
# per-memory cgroup local status
cache - # of bytes of page cache memory.
file_mapped is accounted only when the memory cgroup is owner of page
cache.)
-5.2.2 memory.vmscan_stat
-
-memory.vmscan_stat includes statistics information for memory scanning and
-freeing, reclaiming. The statistics shows memory scanning information since
-memory cgroup creation and can be reset to 0 by writing 0 as
-
- #echo 0 > ../memory.vmscan_stat
-
-This file contains following statistics.
-
-[param]_[file_or_anon]_pages_by_[reason]_[under_heararchy]
-[param]_elapsed_ns_by_[reason]_[under_hierarchy]
-
-For example,
-
- scanned_file_pages_by_limit indicates the number of scanned
- file pages at vmscan.
-
-Now, 3 parameters are supported
-
- scanned - the number of pages scanned by vmscan
- rotated - the number of pages activated at vmscan
- freed - the number of pages freed by vmscan
-
-If "rotated" is high against scanned/freed, the memcg seems busy.
-
-Now, 2 reason are supported
-
- limit - the memory cgroup's limit
- system - global memory pressure + softlimit
- (global memory pressure not under softlimit is not handled now)
-
-When under_hierarchy is added in the tail, the number indicates the
-total memcg scan of its children and itself.
-
-elapsed_ns is a elapsed time in nanosecond. This may include sleep time
-and not indicates CPU usage. So, please take this as just showing
-latency.
-
-Here is an example.
-
-# cat /cgroup/memory/A/memory.vmscan_stat
-scanned_pages_by_limit 9471864
-scanned_anon_pages_by_limit 6640629
-scanned_file_pages_by_limit 2831235
-rotated_pages_by_limit 4243974
-rotated_anon_pages_by_limit 3971968
-rotated_file_pages_by_limit 272006
-freed_pages_by_limit 2318492
-freed_anon_pages_by_limit 962052
-freed_file_pages_by_limit 1356440
-elapsed_ns_by_limit 351386416101
-scanned_pages_by_system 0
-scanned_anon_pages_by_system 0
-scanned_file_pages_by_system 0
-rotated_pages_by_system 0
-rotated_anon_pages_by_system 0
-rotated_file_pages_by_system 0
-freed_pages_by_system 0
-freed_anon_pages_by_system 0
-freed_file_pages_by_system 0
-elapsed_ns_by_system 0
-scanned_pages_by_limit_under_hierarchy 9471864
-scanned_anon_pages_by_limit_under_hierarchy 6640629
-scanned_file_pages_by_limit_under_hierarchy 2831235
-rotated_pages_by_limit_under_hierarchy 4243974
-rotated_anon_pages_by_limit_under_hierarchy 3971968
-rotated_file_pages_by_limit_under_hierarchy 272006
-freed_pages_by_limit_under_hierarchy 2318492
-freed_anon_pages_by_limit_under_hierarchy 962052
-freed_file_pages_by_limit_under_hierarchy 1356440
-elapsed_ns_by_limit_under_hierarchy 351386416101
-scanned_pages_by_system_under_hierarchy 0
-scanned_anon_pages_by_system_under_hierarchy 0
-scanned_file_pages_by_system_under_hierarchy 0
-rotated_pages_by_system_under_hierarchy 0
-rotated_anon_pages_by_system_under_hierarchy 0
-rotated_file_pages_by_system_under_hierarchy 0
-freed_pages_by_system_under_hierarchy 0
-freed_anon_pages_by_system_under_hierarchy 0
-freed_file_pages_by_system_under_hierarchy 0
-elapsed_ns_by_system_under_hierarchy 0
-
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
--- /dev/null
+* ARM L2 Cache Controller
+
+ARM cores often have a separate level 2 cache controller. There are various
+implementations of the L2 cache controller with compatible programming models.
+The ARM L2 cache representation in the device tree should be done as follows:
+
+Required properties:
+
+- compatible : should be one of:
+ "arm,pl310-cache"
+ "arm,l220-cache"
+ "arm,l210-cache"
+- cache-unified : Specifies the cache is a unified cache.
+- cache-level : Should be set to 2 for a level 2 cache.
+- reg : Physical base address and size of cache controller's memory mapped
+ registers.
+
+Optional properties:
+
+- arm,data-latency : Cycles of latency for Data RAM accesses. Specifies 3 cells of
+ read, write and setup latencies. Minimum valid values are 1. Controllers
+ without setup latency control should use a value of 0.
+- arm,tag-latency : Cycles of latency for Tag RAM accesses. Specifies 3 cells of
+ read, write and setup latencies. Controllers without setup latency control
+ should use 0. Controllers without separate read and write Tag RAM latency
+ values should only use the first cell.
+- arm,dirty-latency : Cycles of latency for Dirty RAMs. This is a single cell.
+- arm,filter-ranges : <start length> Starting address and length of window to
+ filter. Addresses in the filter window are directed to the M1 port. Other
+ addresses will go to the M0 port.
+- interrupts : 1 combined interrupt.
+
+Example:
+
+L2: cache-controller {
+ compatible = "arm,pl310-cache";
+ reg = <0xfff12000 0x1000>;
+ arm,data-latency = <1 1 1>;
+ arm,tag-latency = <2 2 2>;
+ arm,filter-latency = <0x80000000 0x8000000>;
+ cache-unified;
+ cache-level = <2>;
+ interrupts = <45>;
+};
interface that was used by acer-wmi driver. It will replaced by
information log when acer-wmi initial.
Who: Lee, Chun-Yi <jlee@novell.com>
+
+----------------------------
+What: The XFS nodelaylog mount option
+When: 3.3
+Why: The delaylog mode that has been the default since 2.6.39 has proven
+ stable, and the old code is in the way of additional improvements in
+ the log code.
+Who: Christoph Hellwig <hch@lst.de>
the devices explicitly. Please see Documentation/i2c/instantiating-devices for
details.
+WARNING: Do not access chip registers using the i2cdump command, and do not use
+any of the i2ctools commands on a command register (0xa5 to 0xac). The chips
+supported by this driver interpret any access to a command register (including
+read commands) as request to execute the command in question. This may result in
+power loss, board resets, and/or Flash corruption. Worst case, your board may
+turn into a brick.
+
Sysfs entries
-------------
<mailto:thomas@winischhofer.net>
0xF4 00-1F video/mbxfb.h mbxfb
<mailto:raph@8d.com>
+0xF6 all LTTng Linux Trace Toolkit Next Generation
+ <mailto:mathieu.desnoyers@efficios.com>
0xFD all linux/dm-ioctl.h
Override pmtimer IOPort with a hex value.
e.g. pmtmr=0x508
- pnp.debug [PNP]
- Enable PNP debug messages. This depends on the
- CONFIG_PNP_DEBUG_MESSAGES option.
+ pnp.debug=1 [PNP]
+ Enable PNP debug messages (depends on the
+ CONFIG_PNP_DEBUG_MESSAGES option). Change at run-time
+ via /sys/module/pnp/parameters/debug. We always show
+ current resource usage; turning this on also shows
+ possible settings and some assignment information.
pnpacpi= [ACPI]
{ off }
F: drivers/net/wan/sdla.c
FRAMEBUFFER LAYER
-M: Paul Mundt <lethal@linux-sh.org>
+M: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
L: linux-fbdev@vger.kernel.org
W: http://linux-fbdev.sourceforge.net/
Q: http://patchwork.kernel.org/project/linux-fbdev/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git
+T: git git://github.com/schandinat/linux-2.6.git fbdev-next
S: Maintained
F: Documentation/fb/
F: Documentation/devicetree/bindings/fb/
F: drivers/input/input-mt.c
K: \b(ABS|SYN)_MT_
+INTEL C600 SERIES SAS CONTROLLER DRIVER
+M: Intel SCU Linux support <intel-linux-scu@intel.com>
+M: Dan Williams <dan.j.williams@intel.com>
+M: Dave Jiang <dave.jiang@intel.com>
+M: Ed Nadolski <edmund.nadolski@intel.com>
+L: linux-scsi@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
+S: Maintained
+F: drivers/scsi/isci/
+F: firmware/isci/
+
INTEL IDLE DRIVER
M: Len Brown <lenb@kernel.org>
L: linux-pm@lists.linux-foundation.org
L: netdev@vger.kernel.org
W: http://www.linuxfoundation.org/en/Net
W: http://patchwork.ozlabs.org/project/netdev/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
S: Maintained
F: net/
F: include/net/
OSD LIBRARY and FILESYSTEM
M: Boaz Harrosh <bharrosh@panasas.com>
-M: Benny Halevy <bhalevy@panasas.com>
+M: Benny Halevy <bhalevy@tonian.com>
L: osd-dev@open-osd.org
W: http://open-osd.org
T: git git://git.open-osd.org/open-osd.git
VERSION = 3
PATCHLEVEL = 1
SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc6
NAME = "Divemaster Edition"
# *DOCUMENTATION*
def_bool y
config GENERIC_GPIO
- def_bool y
+ bool
config ZONE_DMA
bool
The base address of exception vectors.
config ARM_PATCH_PHYS_VIRT
- bool "Patch physical to virtual translations at runtime"
+ bool "Patch physical to virtual translations at runtime" if EMBEDDED
+ default y
depends on !XIP_KERNEL && MMU
depends on !ARCH_REALVIEW || !SPARSEMEM
help
kernel in system memory.
This can only be used with non-XIP MMU kernels where the base
- of physical memory is at a 16MB boundary, or theoretically 64K
- for the MSM machine class.
+ of physical memory is at a 16MB boundary.
+
+ Only disable this option if you know that you do not require
+ this feature (eg, building a kernel for a single machine) and
+ you need to shrink the kernel to the minimal size.
-config ARM_PATCH_PHYS_VIRT_16BIT
+
+config GENERIC_BUG
def_bool y
- depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
- help
- This option extends the physical to virtual translation patching
- to allow physical memory down to a theoretical minimum of 64K
- boundaries.
+ depends on BUG
source "init/Kconfig"
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select CLKDEV_LOOKUP
- select ARM_PATCH_PHYS_VIRT if MMU
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
select CLKDEV_LOOKUP
select HAVE_MACH_CLKDEV
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
help
Support for ST-Ericsson U300 series mobile platforms.
This workaround defines cpu_relax() as smp_mb(), preventing correctly
written polling loops from denying visibility of updates to memory.
+config ARM_ERRATA_364296
+ bool "ARM errata: Possible cache data corruption with hit-under-miss enabled"
+ depends on CPU_V6 && !SMP
+ help
+ This options enables the workaround for the 364296 ARM1136
+ r0p2 erratum (possible cache data corruption with
+ hit-under-miss enabled). It sets the undocumented bit 31 in
+ the auxiliary control register and the FI bit in the control
+ register, thus disabling hit-under-miss without putting the
+ processor into full low interrupt latency mode. ARM11MPCore
+ is not affected.
+
endmenu
source "arch/arm/common/Kconfig"
If you don't know what to do here, say Y.
+config ARM_CPU_TOPOLOGY
+ bool "Support cpu topology definition"
+ depends on SMP && CPU_V7
+ default y
+ help
+ Support ARM cpu topology definition. The MPIDR register defines
+ affinity between processors which is then used to describe the cpu
+ topology of an ARM System.
+
+config SCHED_MC
+ bool "Multi-core scheduler support"
+ depends on ARM_CPU_TOPOLOGY
+ help
+ Multi-core scheduler support improves the CPU scheduler's decision
+ making when dealing with multi-core CPU chips at a cost of slightly
+ increased overhead in some places. If unsure say N here.
+
+config SCHED_SMT
+ bool "SMT scheduler support"
+ depends on ARM_CPU_TOPOLOGY
+ help
+ Improves the CPU scheduler's decision making when dealing with
+ MultiThreading at a cost of slightly increased overhead in some
+ places. If unsure say N here.
+
config HAVE_ARM_SCU
bool
help
# These options are only for real kernel hackers who want to get their hands dirty.
config DEBUG_LL
- bool "Kernel low-level debugging functions"
+ bool "Kernel low-level debugging functions (read help!)"
depends on DEBUG_KERNEL
help
Say Y here to include definitions of printascii, printch, printhex
in the kernel. This is helpful if you are debugging code that
executes before the console is initialized.
+ Note that selecting this option will limit the kernel to a single
+ UART definition, as specified below. Attempting to boot the kernel
+ image on a different platform *will not work*, so this option should
+ not be enabled for kernels that are intended to be portable.
+
+choice
+ prompt "Kernel low-level debugging port"
+ depends on DEBUG_LL
+
+ config DEBUG_DC21285_PORT
+ bool "Kernel low-level debugging messages via footbridge serial port"
+ depends on FOOTBRIDGE
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port in the DC21285 (Footbridge).
+ Saying N will cause the debug messages to appear on the first
+ 16550 serial port.
+
+ config DEBUG_CLPS711X_UART2
+ bool "Kernel low-level debugging messages via UART2"
+ depends on ARCH_CLPS711X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the second serial port on these devices.
+ Saying N will cause the debug messages to appear on the first
+ serial port.
+
+endchoice
+
config EARLY_PRINTK
bool "Early printk"
depends on DEBUG_LL
buffer driver that will allow you to collect traces of the
kernel code.
-config DEBUG_DC21285_PORT
- bool "Kernel low-level debugging messages via footbridge serial port"
- depends on DEBUG_LL && FOOTBRIDGE
- help
- Say Y here if you want the debug print routines to direct their
- output to the serial port in the DC21285 (Footbridge). Saying N
- will cause the debug messages to appear on the first 16550
- serial port.
-
-config DEBUG_CLPS711X_UART2
- bool "Kernel low-level debugging messages via UART2"
- depends on DEBUG_LL && ARCH_CLPS711X
- help
- Say Y here if you want the debug print routines to direct their
- output to the second serial port on these devices. Saying N will
- cause the debug messages to appear on the first serial port.
-
config DEBUG_S3C_UART
depends on PLAT_SAMSUNG
int "S3C UART to use for low-level debug"
ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000
endif
+textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
+textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
+textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
$(obj)/uImage: STARTADDR=$(LOADADDR)
+check_for_multiple_loadaddr = \
+if [ $(words $(LOADADDR)) -gt 1 ]; then \
+ echo 'multiple load addresses: $(LOADADDR)'; \
+ echo 'This is incompatible with uImages'; \
+ echo 'Specify LOADADDR on the commandline to build an uImage'; \
+ false; \
+fi
+
$(obj)/uImage: $(obj)/zImage FORCE
+ @$(check_for_multiple_loadaddr)
$(call if_changed,uimage)
@echo ' Image $@ is ready'
( echo "following symbols must have non local/private scope:" >&2; \
echo "$$bad_syms" >&2; rm -f $@; false )
+check_for_multiple_zreladdr = \
+if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" == "" ]; then \
+ echo 'multiple zreladdrs: $(ZRELADDR)'; \
+ echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
+ false; \
+fi
+
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
+ @$(check_for_multiple_zreladdr)
$(call if_changed,ld)
@$(check_for_bad_syms)
/* Disable clock to MMC hardware block */
- __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+ __raw_writel(__raw_readl(SMSTPCR3) | (1 << 12), SMSTPCR3);
mmc_update_progress(MMC_PROGRESS_DONE);
}
goto err;
/* Disable clock to SDHI1 hardware block */
- __raw_writel(__raw_readl(SMSTPCR3) & (1 << 13), SMSTPCR3);
+ __raw_writel(__raw_readl(SMSTPCR3) | (1 << 13), SMSTPCR3);
mmc_update_progress(MMC_PROGRESS_DONE);
return -EINVAL;
mask = 0xff << shift;
- bit = 1 << (cpu + shift);
+ bit = 1 << (cpu_logical_map(cpu) + shift);
spin_lock(&irq_controller_lock);
val = readl_relaxed(reg) & ~mask;
unsigned int irq_start)
{
unsigned int gic_irqs, irq_limit, i;
+ u32 cpumask;
void __iomem *base = gic->dist_base;
- u32 cpumask = 1 << smp_processor_id();
+ u32 cpu = 0;
+#ifdef CONFIG_SMP
+ cpu = cpu_logical_map(smp_processor_id());
+#endif
+
+ cpumask = 1 << cpu;
cpumask |= cpumask << 8;
cpumask |= cpumask << 16;
#ifdef CONFIG_SMP
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
- unsigned long map = *cpus_addr(*mask);
+ int cpu;
+ unsigned long map = 0;
+
+ /* Convert our logical CPU mask into a physical one. */
+ for_each_cpu(cpu, mask)
+ map |= 1 << cpu_logical_map(cpu);
/*
* Ensure that stores to Normal memory are visible to the
*/
#include <linux/device.h>
+#include <linux/gpio.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <asm/gpio.h>
#include <asm/hardware/scoop.h>
/* PCMCIA to Scoop linkage
include include/asm-generic/Kbuild.asm
header-y += hwcap.h
+
+generic-y += auxvec.h
+generic-y += bitsperlong.h
+generic-y += cputime.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += ioctl.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += local.h
+generic-y += local64.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += resource.h
+generic-y += sections.h
+generic-y += siginfo.h
+generic-y += sizes.h
+++ /dev/null
-#ifndef __ASMARM_AUXVEC_H
-#define __ASMARM_AUXVEC_H
-
-#endif
+++ /dev/null
-#include <asm-generic/bitsperlong.h>
#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void __bug(const char *file, int line) __attribute__((noreturn));
-
-/* give file/line information */
-#define BUG() __bug(__FILE__, __LINE__)
+/*
+ * Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
+ * We need to be careful not to conflict with those used by other modules and
+ * the register_undef_hook() system.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+#define BUG_INSTR_VALUE 0xde02
+#define BUG_INSTR_TYPE ".hword "
#else
+#define BUG_INSTR_VALUE 0xe7f001f2
+#define BUG_INSTR_TYPE ".word "
+#endif
-/* this just causes an oops */
-#define BUG() do { *(int *)0 = 0; } while (1)
-#endif
+#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
+#define _BUG(file, line, value) __BUG(file, line, value)
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
+/*
+ * The extra indirection is to ensure that the __FILE__ string comes through
+ * OK. Many version of gcc do not support the asm %c parameter which would be
+ * preferable to this unpleasantness. We use mergeable string sections to
+ * avoid multiple copies of the string appearing in the kernel image.
+ */
+
+#define __BUG(__file, __line, __value) \
+do { \
+ BUILD_BUG_ON(sizeof(struct bug_entry) != 12); \
+ asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \
+ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
+ "2:\t.asciz " #__file "\n" \
+ ".popsection\n" \
+ ".pushsection __bug_table,\"a\"\n" \
+ "3:\t.word 1b, 2b\n" \
+ "\t.hword " #__line ", 0\n" \
+ ".popsection"); \
+ unreachable(); \
+} while (0)
+
+#else /* not CONFIG_DEBUG_BUGVERBOSE */
+
+#define __BUG(__file, __line, __value) \
+do { \
+ asm volatile(BUG_INSTR_TYPE #__value); \
+ unreachable(); \
+} while (0)
+#endif /* CONFIG_DEBUG_BUGVERBOSE */
#define HAVE_ARCH_BUG
-#endif
+#endif /* CONFIG_BUG */
#include <asm-generic/bug.h>
+++ /dev/null
-#ifndef __ARM_CPUTIME_H
-#define __ARM_CPUTIME_H
-
-#include <asm-generic/cputime.h>
-
-#endif /* __ARM_CPUTIME_H */
#define CPUID_CACHETYPE 1
#define CPUID_TCM 2
#define CPUID_TLBTYPE 3
+#define CPUID_MPIDR 5
#define CPUID_EXT_PFR0 "c1, 0"
#define CPUID_EXT_PFR1 "c1, 1"
return read_cpuid(CPUID_TCM);
}
+static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
+{
+ return read_cpuid(CPUID_MPIDR);
+}
+
/*
* Intel's XScale3 core supports some v6 features (supersections, L2)
* but advertises itself as v5 as it does not support the v6 ISA. For
#endif
};
+struct omap_device;
+
struct pdev_archdata {
+#ifdef CONFIG_ARCH_OMAP
+ struct omap_device *od;
+#endif
};
#endif
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
{
- return (void *)__bus_to_virt(addr);
+ return (void *)__bus_to_virt((unsigned long)addr);
}
static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
/* Private internal data */
const char *card_desc; /* Card description */
- CONST unsigned int podaddr; /* Base Linux address for card */
CONST loader_t loader; /* loader program */
u64 dma_mask;
};
+++ /dev/null
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-#include <asm-generic/emergency-restart.h>
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
+++ /dev/null
-#ifndef _ARM_ERRNO_H
-#define _ARM_ERRNO_H
-
-#include <asm-generic/errno.h>
-
-#endif
/* not all ARM platforms necessarily support this API ... */
#include <mach/gpio.h>
+#ifndef __ARM_GPIOLIB_COMPLEX
+/* Note: this may rely upon the value of ARCH_NR_GPIOS set in mach/gpio.h */
+#include <asm-generic/gpio.h>
+
+/* The trivial gpiolib dispatchers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#endif
+
+/*
+ * Provide a default gpio_to_irq() which should satisfy every case.
+ * However, some platforms want to do this differently, so allow them
+ * to override it.
+ */
+#ifndef gpio_to_irq
+#define gpio_to_irq __gpio_to_irq
+#endif
+
#endif /* _ARCH_ARM_GPIO_H */
#define L2X0_CLEAN_INV_LINE_PA 0x7F0
#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
#define L2X0_CLEAN_INV_WAY 0x7FC
-#define L2X0_LOCKDOWN_WAY_D 0x900
-#define L2X0_LOCKDOWN_WAY_I 0x904
+/*
+ * The lockdown registers repeat 8 times for L310, the L210 has only one
+ * D and one I lockdown register at 0x0900 and 0x0904.
+ */
+#define L2X0_LOCKDOWN_WAY_D_BASE 0x900
+#define L2X0_LOCKDOWN_WAY_I_BASE 0x904
+#define L2X0_LOCKDOWN_STRIDE 0x08
+#define L2X0_ADDR_FILTER_START 0xC00
+#define L2X0_ADDR_FILTER_END 0xC04
#define L2X0_TEST_OPERATION 0xF00
#define L2X0_LINE_DATA 0xF10
#define L2X0_LINE_TAG 0xF30
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
#define L2X0_AUX_CTRL_MASK 0xc0000fff
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (0x7 << 3)
+#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
+#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (0x7 << 6)
+#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
+#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (0x7 << 9)
#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
-#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17)
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
+#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0
+#define L2X0_LATENCY_CTRL_RD_SHIFT 4
+#define L2X0_LATENCY_CTRL_WR_SHIFT 8
+
+#define L2X0_ADDR_FILTER_EN 1
+
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask);
#endif
#endif
#include <mach/hardware.h>
#include <asm-generic/gpio.h>
+#define __ARM_GPIOLIB_COMPLEX
+
#define IOP3XX_N_GPIOS 8
static inline int gpio_get_value(unsigned gpio)
*/
#include <mach/io.h>
+/*
+ * This is the limit of PC card/PCI/ISA IO space, which is by default
+ * 64K if we have PC card, PCI or ISA support. Otherwise, default to
+ * zero to prevent ISA/PCI drivers claiming IO space (and potentially
+ * oopsing.)
+ *
+ * Only set this larger if you really need inb() et.al. to operate over
+ * a larger address space. Note that SOC_COMMON ioremaps each sockets
+ * IO space area, and so inb() et.al. must be defined to operate as per
+ * readb() et.al. on such platforms.
+ */
+#ifndef IO_SPACE_LIMIT
+#if defined(CONFIG_PCMCIA_SOC_COMMON) || defined(CONFIG_PCMCIA_SOC_COMMON_MODULE)
+#define IO_SPACE_LIMIT ((resource_size_t)0xffffffff)
+#elif defined(CONFIG_PCI) || defined(CONFIG_ISA) || defined(CONFIG_PCCARD)
+#define IO_SPACE_LIMIT ((resource_size_t)0xffff)
+#else
+#define IO_SPACE_LIMIT ((resource_size_t)0)
+#endif
+#endif
+
/*
* IO port access primitives
* -------------------------
+++ /dev/null
-#include <asm-generic/ioctl.h>
+++ /dev/null
-#include <asm-generic/irq_regs.h>
+++ /dev/null
-#include <asm-generic/kdebug.h>
+++ /dev/null
-#include <asm-generic/local.h>
+++ /dev/null
-#include <asm-generic/local64.h>
* so that all we need to do is modify the 8-bit constant field.
*/
#define __PV_BITS_31_24 0x81000000
-#define __PV_BITS_23_16 0x00810000
extern unsigned long __pv_phys_offset;
#define PHYS_OFFSET __pv_phys_offset
{
unsigned long t;
__pv_stub(x, t, "add", __PV_BITS_31_24);
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
- __pv_stub(t, t, "add", __PV_BITS_23_16);
-#endif
return t;
}
{
unsigned long t;
__pv_stub(x, t, "sub", __PV_BITS_31_24);
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
- __pv_stub(t, t, "sub", __PV_BITS_23_16);
-#endif
return t;
}
#else
/* Add __virt_to_phys patching state as well */
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
-#else
#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
-#endif
#else
#define MODULE_ARCH_VERMAGIC_P2V ""
#endif
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern void copy_page(void *to, const void *from);
-typedef unsigned long pteval_t;
-
-#undef STRICT_MM_TYPECHECKS
-
-#ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { pteval_t pte; } pte_t;
-typedef struct { unsigned long pmd; } pmd_t;
-typedef struct { unsigned long pgd[2]; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-
-#define pte_val(x) ((x).pte)
-#define pmd_val(x) ((x).pmd)
-#define pgd_val(x) ((x).pgd[0])
-#define pgprot_val(x) ((x).pgprot)
-
-#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
-#define __pgprot(x) ((pgprot_t) { (x) } )
-
-#else
-/*
- * .. while these make it easier on the compiler
- */
-typedef pteval_t pte_t;
-typedef unsigned long pmd_t;
-typedef unsigned long pgd_t[2];
-typedef unsigned long pgprot_t;
-
-#define pte_val(x) (x)
-#define pmd_val(x) (x)
-#define pgd_val(x) ((x)[0])
-#define pgprot_val(x) (x)
-
-#define __pte(x) (x)
-#define __pmd(x) (x)
-#define __pgprot(x) (x)
-
-#endif /* STRICT_MM_TYPECHECKS */
+#include <asm/pgtable-2level-types.h>
#endif /* CONFIG_MMU */
+++ /dev/null
-#ifndef __ARM_PERCPU
-#define __ARM_PERCPU
-
-#include <asm-generic/percpu.h>
-
-#endif
*/
#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free(mm, pmd) do { } while (0)
-#define pgd_populate(mm,pmd,pte) BUG()
+#define pud_populate(mm,pmd,pte) BUG()
extern pgd_t *pgd_alloc(struct mm_struct *mm);
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
}
static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
- unsigned long prot)
+ pmdval_t prot)
{
- unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
+ pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot;
pmdp[0] = __pmd(pmdval);
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
flush_pmd_entry(pmdp);
--- /dev/null
+/*
+ * arch/arm/include/asm/pgtable-2level-hwdef.h
+ *
+ * Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASM_PGTABLE_2LEVEL_HWDEF_H
+#define _ASM_PGTABLE_2LEVEL_HWDEF_H
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ * - common
+ */
+#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
+#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0)
+#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0)
+#define PMD_BIT4 (_AT(pmdval_t, 1) << 4)
+#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5)
+#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */
+/*
+ * - section
+ */
+#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
+#define PMD_SECT_AP_WRITE (_AT(pmdval_t, 1) << 10)
+#define PMD_SECT_AP_READ (_AT(pmdval_t, 1) << 11)
+#define PMD_SECT_TEX(x) (_AT(pmdval_t, (x)) << 12) /* v5 */
+#define PMD_SECT_APX (_AT(pmdval_t, 1) << 15) /* v6 */
+#define PMD_SECT_S (_AT(pmdval_t, 1) << 16) /* v6 */
+#define PMD_SECT_nG (_AT(pmdval_t, 1) << 17) /* v6 */
+#define PMD_SECT_SUPER (_AT(pmdval_t, 1) << 18) /* v6 */
+#define PMD_SECT_AF (_AT(pmdval_t, 0))
+
+#define PMD_SECT_UNCACHED (_AT(pmdval_t, 0))
+#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
+#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
+#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
+#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
+
+/*
+ * - coarse table (not used)
+ */
+
+/*
+ * + Level 2 descriptor (PTE)
+ * - common
+ */
+#define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0)
+#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0)
+#define PTE_TYPE_LARGE (_AT(pteval_t, 1) << 0)
+#define PTE_TYPE_SMALL (_AT(pteval_t, 2) << 0)
+#define PTE_TYPE_EXT (_AT(pteval_t, 3) << 0) /* v5 */
+#define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2)
+#define PTE_CACHEABLE (_AT(pteval_t, 1) << 3)
+
+/*
+ * - extended small page/tiny page
+ */
+#define PTE_EXT_XN (_AT(pteval_t, 1) << 0) /* v6 */
+#define PTE_EXT_AP_MASK (_AT(pteval_t, 3) << 4)
+#define PTE_EXT_AP0 (_AT(pteval_t, 1) << 4)
+#define PTE_EXT_AP1 (_AT(pteval_t, 2) << 4)
+#define PTE_EXT_AP_UNO_SRO (_AT(pteval_t, 0) << 4)
+#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
+#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
+#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
+#define PTE_EXT_TEX(x) (_AT(pteval_t, (x)) << 6) /* v5 */
+#define PTE_EXT_APX (_AT(pteval_t, 1) << 9) /* v6 */
+#define PTE_EXT_COHERENT (_AT(pteval_t, 1) << 9) /* XScale3 */
+#define PTE_EXT_SHARED (_AT(pteval_t, 1) << 10) /* v6 */
+#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* v6 */
+
+/*
+ * - small page
+ */
+#define PTE_SMALL_AP_MASK (_AT(pteval_t, 0xff) << 4)
+#define PTE_SMALL_AP_UNO_SRO (_AT(pteval_t, 0x00) << 4)
+#define PTE_SMALL_AP_UNO_SRW (_AT(pteval_t, 0x55) << 4)
+#define PTE_SMALL_AP_URO_SRW (_AT(pteval_t, 0xaa) << 4)
+#define PTE_SMALL_AP_URW_SRW (_AT(pteval_t, 0xff) << 4)
+
+#define PHYS_MASK (~0UL)
+
+#endif
--- /dev/null
+/*
+ * arch/arm/include/asm/pgtable-2level-types.h
+ *
+ * Copyright (C) 1995-2003 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _ASM_PGTABLE_2LEVEL_TYPES_H
+#define _ASM_PGTABLE_2LEVEL_TYPES_H
+
+#include <asm/types.h>
+
+typedef u32 pteval_t;
+typedef u32 pmdval_t;
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { pteval_t pte; } pte_t;
+typedef struct { pmdval_t pmd; } pmd_t;
+typedef struct { pmdval_t pgd[2]; } pgd_t;
+typedef struct { pteval_t pgprot; } pgprot_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((x).pmd)
+#define pgd_val(x) ((x).pgd[0])
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef pteval_t pte_t;
+typedef pmdval_t pmd_t;
+typedef pmdval_t pgd_t[2];
+typedef pteval_t pgprot_t;
+
+#define pte_val(x) (x)
+#define pmd_val(x) (x)
+#define pgd_val(x) ((x)[0])
+#define pgprot_val(x) (x)
+
+#define __pte(x) (x)
+#define __pmd(x) (x)
+#define __pgprot(x) (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* _ASM_PGTABLE_2LEVEL_TYPES_H */
--- /dev/null
+/*
+ * arch/arm/include/asm/pgtable-2level.h
+ *
+ * Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASM_PGTABLE_2LEVEL_H
+#define _ASM_PGTABLE_2LEVEL_H
+
+/*
+ * Hardware-wise, we have a two level page table structure, where the first
+ * level has 4096 entries, and the second level has 256 entries. Each entry
+ * is one 32-bit word. Most of the bits in the second level entry are used
+ * by hardware, and there aren't any "accessed" and "dirty" bits.
+ *
+ * Linux on the other hand has a three level page table structure, which can
+ * be wrapped to fit a two level page table structure easily - using the PGD
+ * and PTE only. However, Linux also expects one "PTE" table per page, and
+ * at least a "dirty" bit.
+ *
+ * Therefore, we tweak the implementation slightly - we tell Linux that we
+ * have 2048 entries in the first level, each of which is 8 bytes (iow, two
+ * hardware pointers to the second level.) The second level contains two
+ * hardware PTE tables arranged contiguously, preceded by Linux versions
+ * which contain the state information Linux needs. We, therefore, end up
+ * with 512 entries in the "PTE" level.
+ *
+ * This leads to the page tables having the following layout:
+ *
+ * pgd pte
+ * | |
+ * +--------+
+ * | | +------------+ +0
+ * +- - - - + | Linux pt 0 |
+ * | | +------------+ +1024
+ * +--------+ +0 | Linux pt 1 |
+ * | |-----> +------------+ +2048
+ * +- - - - + +4 | h/w pt 0 |
+ * | |-----> +------------+ +3072
+ * +--------+ +8 | h/w pt 1 |
+ * | | +------------+ +4096
+ *
+ * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
+ * PTE_xxx for definitions of bits appearing in the "h/w pt".
+ *
+ * PMD_xxx definitions refer to bits in the first level page table.
+ *
+ * The "dirty" bit is emulated by only granting hardware write permission
+ * iff the page is marked "writable" and "dirty" in the Linux PTE. This
+ * means that a write to a clean page will cause a permission fault, and
+ * the Linux MM layer will mark the page dirty via handle_pte_fault().
+ * For the hardware to notice the permission change, the TLB entry must
+ * be flushed, and ptep_set_access_flags() does that for us.
+ *
+ * The "accessed" or "young" bit is emulated by a similar method; we only
+ * allow accesses to the page if the "young" bit is set. Accesses to the
+ * page will cause a fault, and handle_pte_fault() will set the young bit
+ * for us as long as the page is marked present in the corresponding Linux
+ * PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is
+ * up to date.
+ *
+ * However, when the "young" bit is cleared, we deny access to the page
+ * by clearing the hardware PTE. Currently Linux does not flush the TLB
+ * for us in this case, which means the TLB will retain the transation
+ * until either the TLB entry is evicted under pressure, or a context
+ * switch which changes the user space mapping occurs.
+ */
+#define PTRS_PER_PTE 512
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD 2048
+
+#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
+#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
+#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
+
+/*
+ * PMD_SHIFT determines the size of the area a second-level page table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PMD_SHIFT 21
+#define PGDIR_SHIFT 21
+
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT 20
+#define SECTION_SIZE (1UL << SECTION_SHIFT)
+#define SECTION_MASK (~(SECTION_SIZE-1))
+
+/*
+ * ARMv6 supersection address mask and size definitions.
+ */
+#define SUPERSECTION_SHIFT 24
+#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT)
+#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1))
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+
+/*
+ * "Linux" PTE definitions.
+ *
+ * We keep two sets of PTEs - the hardware and the linux version.
+ * This allows greater flexibility in the way we map the Linux bits
+ * onto the hardware tables, and allows us to have YOUNG and DIRTY
+ * bits.
+ *
+ * The PTE table pointer refers to the hardware entries; the "Linux"
+ * entries are stored 1024 bytes below.
+ */
+#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
+#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
+#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
+#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
+#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
+#define L_PTE_USER (_AT(pteval_t, 1) << 8)
+#define L_PTE_XN (_AT(pteval_t, 1) << 9)
+#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
+
+/*
+ * These are the memory types, defined to be compatible with
+ * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
+ */
+#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
+#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
+#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
+#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
+#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
+#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
+#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
+#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
+#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
+#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
+#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
+
+#endif /* _ASM_PGTABLE_2LEVEL_H */
#ifndef _ASMARM_PGTABLE_HWDEF_H
#define _ASMARM_PGTABLE_HWDEF_H
-/*
- * Hardware page table definitions.
- *
- * + Level 1 descriptor (PMD)
- * - common
- */
-#define PMD_TYPE_MASK (3 << 0)
-#define PMD_TYPE_FAULT (0 << 0)
-#define PMD_TYPE_TABLE (1 << 0)
-#define PMD_TYPE_SECT (2 << 0)
-#define PMD_BIT4 (1 << 4)
-#define PMD_DOMAIN(x) ((x) << 5)
-#define PMD_PROTECTION (1 << 9) /* v5 */
-/*
- * - section
- */
-#define PMD_SECT_BUFFERABLE (1 << 2)
-#define PMD_SECT_CACHEABLE (1 << 3)
-#define PMD_SECT_XN (1 << 4) /* v6 */
-#define PMD_SECT_AP_WRITE (1 << 10)
-#define PMD_SECT_AP_READ (1 << 11)
-#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */
-#define PMD_SECT_APX (1 << 15) /* v6 */
-#define PMD_SECT_S (1 << 16) /* v6 */
-#define PMD_SECT_nG (1 << 17) /* v6 */
-#define PMD_SECT_SUPER (1 << 18) /* v6 */
-
-#define PMD_SECT_UNCACHED (0)
-#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
-#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
-#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
-#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
-#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
-#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
-
-/*
- * - coarse table (not used)
- */
-
-/*
- * + Level 2 descriptor (PTE)
- * - common
- */
-#define PTE_TYPE_MASK (3 << 0)
-#define PTE_TYPE_FAULT (0 << 0)
-#define PTE_TYPE_LARGE (1 << 0)
-#define PTE_TYPE_SMALL (2 << 0)
-#define PTE_TYPE_EXT (3 << 0) /* v5 */
-#define PTE_BUFFERABLE (1 << 2)
-#define PTE_CACHEABLE (1 << 3)
-
-/*
- * - extended small page/tiny page
- */
-#define PTE_EXT_XN (1 << 0) /* v6 */
-#define PTE_EXT_AP_MASK (3 << 4)
-#define PTE_EXT_AP0 (1 << 4)
-#define PTE_EXT_AP1 (2 << 4)
-#define PTE_EXT_AP_UNO_SRO (0 << 4)
-#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
-#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
-#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
-#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
-#define PTE_EXT_APX (1 << 9) /* v6 */
-#define PTE_EXT_COHERENT (1 << 9) /* XScale3 */
-#define PTE_EXT_SHARED (1 << 10) /* v6 */
-#define PTE_EXT_NG (1 << 11) /* v6 */
-
-/*
- * - small page
- */
-#define PTE_SMALL_AP_MASK (0xff << 4)
-#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
-#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
-#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
-#define PTE_SMALL_AP_URW_SRW (0xff << 4)
+#include <asm/pgtable-2level-hwdef.h>
#endif
#define _ASMARM_PGTABLE_H
#include <linux/const.h>
-#include <asm-generic/4level-fixup.h>
#include <asm/proc-fns.h>
#ifndef CONFIG_MMU
+#include <asm-generic/4level-fixup.h>
#include "pgtable-nommu.h"
#else
+#include <asm-generic/pgtable-nopud.h>
#include <asm/memory.h>
#include <mach/vmalloc.h>
#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable-2level.h>
+
/*
* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 8MB value just means that there will be a 8MB "hole" after the
#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
#endif
-/*
- * Hardware-wise, we have a two level page table structure, where the first
- * level has 4096 entries, and the second level has 256 entries. Each entry
- * is one 32-bit word. Most of the bits in the second level entry are used
- * by hardware, and there aren't any "accessed" and "dirty" bits.
- *
- * Linux on the other hand has a three level page table structure, which can
- * be wrapped to fit a two level page table structure easily - using the PGD
- * and PTE only. However, Linux also expects one "PTE" table per page, and
- * at least a "dirty" bit.
- *
- * Therefore, we tweak the implementation slightly - we tell Linux that we
- * have 2048 entries in the first level, each of which is 8 bytes (iow, two
- * hardware pointers to the second level.) The second level contains two
- * hardware PTE tables arranged contiguously, preceded by Linux versions
- * which contain the state information Linux needs. We, therefore, end up
- * with 512 entries in the "PTE" level.
- *
- * This leads to the page tables having the following layout:
- *
- * pgd pte
- * | |
- * +--------+
- * | | +------------+ +0
- * +- - - - + | Linux pt 0 |
- * | | +------------+ +1024
- * +--------+ +0 | Linux pt 1 |
- * | |-----> +------------+ +2048
- * +- - - - + +4 | h/w pt 0 |
- * | |-----> +------------+ +3072
- * +--------+ +8 | h/w pt 1 |
- * | | +------------+ +4096
- *
- * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
- * PTE_xxx for definitions of bits appearing in the "h/w pt".
- *
- * PMD_xxx definitions refer to bits in the first level page table.
- *
- * The "dirty" bit is emulated by only granting hardware write permission
- * iff the page is marked "writable" and "dirty" in the Linux PTE. This
- * means that a write to a clean page will cause a permission fault, and
- * the Linux MM layer will mark the page dirty via handle_pte_fault().
- * For the hardware to notice the permission change, the TLB entry must
- * be flushed, and ptep_set_access_flags() does that for us.
- *
- * The "accessed" or "young" bit is emulated by a similar method; we only
- * allow accesses to the page if the "young" bit is set. Accesses to the
- * page will cause a fault, and handle_pte_fault() will set the young bit
- * for us as long as the page is marked present in the corresponding Linux
- * PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is
- * up to date.
- *
- * However, when the "young" bit is cleared, we deny access to the page
- * by clearing the hardware PTE. Currently Linux does not flush the TLB
- * for us in this case, which means the TLB will retain the transation
- * until either the TLB entry is evicted under pressure, or a context
- * switch which changes the user space mapping occurs.
- */
-#define PTRS_PER_PTE 512
-#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD 2048
-
-#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
-#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
-#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
-
-/*
- * PMD_SHIFT determines the size of the area a second-level page table can map
- * PGDIR_SHIFT determines what a third-level page table entry can map
- */
-#define PMD_SHIFT 21
-#define PGDIR_SHIFT 21
-
#define LIBRARY_TEXT_START 0x0c000000
#ifndef __ASSEMBLY__
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
-#endif /* !__ASSEMBLY__ */
-
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
* This is the lowest virtual address we can permit any user space
*/
#define FIRST_USER_ADDRESS PAGE_SIZE
-#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
-
-/*
- * section address mask and size definitions.
- */
-#define SECTION_SHIFT 20
-#define SECTION_SIZE (1UL << SECTION_SHIFT)
-#define SECTION_MASK (~(SECTION_SIZE-1))
-
-/*
- * ARMv6 supersection address mask and size definitions.
- */
-#define SUPERSECTION_SHIFT 24
-#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT)
-#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1))
-
-/*
- * "Linux" PTE definitions.
- *
- * We keep two sets of PTEs - the hardware and the linux version.
- * This allows greater flexibility in the way we map the Linux bits
- * onto the hardware tables, and allows us to have YOUNG and DIRTY
- * bits.
- *
- * The PTE table pointer refers to the hardware entries; the "Linux"
- * entries are stored 1024 bytes below.
- */
-#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
-#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
-#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
-#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
-#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
-#define L_PTE_USER (_AT(pteval_t, 1) << 8)
-#define L_PTE_XN (_AT(pteval_t, 1) << 9)
-#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
-
-/*
- * These are the memory types, defined to be compatible with
- * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
- */
-#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
-#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
-#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
-#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
-#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
-#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
-#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
-#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
-#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
-#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
-#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
-
-#ifndef __ASSEMBLY__
-
/*
* The pgprot_* and protection_map entries will be fixed up in runtime
* to include the cachable and bufferable bits based on memory policy,
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
+ * The "pud_xxx()" functions here are trivial when the pmd is folded into
+ * the pud: the pud entry is never bad, always exists, and can't be set or
+ * cleared.
*/
-#define pgd_none(pgd) (0)
-#define pgd_bad(pgd) (0)
-#define pgd_present(pgd) (1)
-#define pgd_clear(pgdp) do { } while (0)
-#define set_pgd(pgd,pgdp) do { } while (0)
+#define pud_none(pud) (0)
+#define pud_bad(pud) (0)
+#define pud_present(pud) (1)
+#define pud_clear(pudp) do { } while (0)
#define set_pud(pud,pudp) do { } while (0)
/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, addr) ((pmd_t *)(dir))
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+{
+ return (pmd_t *)pud;
+}
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd))
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
{
- return __va(pmd_val(pmd) & PAGE_MASK);
+ return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
}
-#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
/* we don't need complex calculations here as the pmd is folded into the pgd */
#define pmd_addr_end(addr,end) (end)
#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
#define pte_unmap(pte) __pte_unmap(pte)
-#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
+#define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
* encoded error on failure.
*/
extern struct platform_device *
-reserve_pmu(enum arm_pmu_type device);
+reserve_pmu(enum arm_pmu_type type);
/**
* release_pmu() - Relinquish control of the performance counters
* the actual hardware initialisation.
*/
extern int
-init_pmu(enum arm_pmu_type device);
+init_pmu(enum arm_pmu_type type);
#else /* CONFIG_CPU_HAS_PMU */
#include <linux/err.h>
static inline struct platform_device *
-reserve_pmu(enum arm_pmu_type device)
+reserve_pmu(enum arm_pmu_type type)
{
return ERR_PTR(-ENODEV);
}
static inline int
-release_pmu(struct platform_device *pdev)
+release_pmu(enum arm_pmu_type type)
{
return -ENODEV;
}
static inline int
-init_pmu(enum arm_pmu_type device)
+init_pmu(enum arm_pmu_type type)
{
return -ENODEV;
}
+++ /dev/null
-#include <asm-generic/poll.h>
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+
+/* These three are private to arch/arm/kernel/suspend.c */
+extern void cpu_do_suspend(void *);
+extern void cpu_do_resume(void *);
#else
#define cpu_proc_init processor._proc_init
#define cpu_proc_fin processor._proc_fin
#define cpu_dcache_clean_area processor.dcache_clean_area
#define cpu_set_pte_ext processor.set_pte_ext
#define cpu_do_switch_mm processor.switch_mm
+
+/* These three are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend processor.do_suspend
+#define cpu_do_resume processor.do_resume
#endif
extern void cpu_resume(void);
+++ /dev/null
-#ifndef _ARM_RESOURCE_H
-#define _ARM_RESOURCE_H
-
-#include <asm-generic/resource.h>
-
-#endif
+++ /dev/null
-#include <asm-generic/sections.h>
+++ /dev/null
-#ifndef _ASMARM_SIGINFO_H
-#define _ASMARM_SIGINFO_H
-
-#include <asm-generic/siginfo.h>
-
-#endif
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/* Size definitions
- * Copyright (C) ARM Limited 1998. All rights reserved.
- */
-#include <asm-generic/sizes.h>
-
-#define SZ_48M (SZ_32M + SZ_16M)
*/
extern void platform_smp_prepare_cpus(unsigned int);
+/*
+ * Logical CPU mapping.
+ */
+extern int __cpu_logical_map[NR_CPUS];
+#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+
/*
* Initial data for bringing up a secondary CPU.
*/
#ifndef __ASM_ARM_SUSPEND_H
#define __ASM_ARM_SUSPEND_H
-#include <asm/memory.h>
-#include <asm/tlbflush.h>
-
extern void cpu_resume(void);
-
-/*
- * Hide the first two arguments to __cpu_suspend - these are an implementation
- * detail which platform code shouldn't have to know about.
- */
-static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
-{
- extern int __cpu_suspend(int, long, unsigned long,
- int (*)(unsigned long));
- int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn);
- flush_tlb_all();
- return ret;
-}
+extern int cpu_suspend(unsigned long, int (*)(unsigned long));
#endif
#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
#include <linux/linkage.h>
#include <linux/irqflags.h>
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-extern asmlinkage void __backtrace(void);
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
struct mm_struct;
extern void show_pte(struct mm_struct *mm, unsigned long addr);
extern void __show_regs(struct pt_regs *);
-extern int cpu_architecture(void);
+extern int __pure cpu_architecture(void);
extern void cpu_init(void);
void arm_machine_restart(char mode, const char *cmd);
#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
#define tlb_migrate_finish(mm) do { } while (0)
* these operations. This is typically used when we are removing
* PMD entries.
*/
-static inline void flush_pmd_entry(pmd_t *pmd)
+static inline void flush_pmd_entry(void *pmd)
{
const unsigned int __tlb_flag = __cpu_tlb_flags;
dsb();
}
-static inline void clean_pmd_entry(pmd_t *pmd)
+static inline void clean_pmd_entry(void *pmd)
{
const unsigned int __tlb_flag = __cpu_tlb_flags;
#ifndef _ASM_ARM_TOPOLOGY_H
#define _ASM_ARM_TOPOLOGY_H
+#ifdef CONFIG_ARM_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cputopo_arm {
+ int thread_id;
+ int core_id;
+ int socket_id;
+ cpumask_t thread_sibling;
+ cpumask_t core_sibling;
+};
+
+extern struct cputopo_arm cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
+#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
+#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
+
+#define mc_capable() (cpu_topology[0].socket_id != -1)
+#define smt_capable() (cpu_topology[0].thread_id != -1)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
#include <asm-generic/topology.h>
#endif /* _ASM_ARM_TOPOLOGY_H */
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
-obj-$(CONFIG_PM_SLEEP) += sleep.o
+obj-$(CONFIG_PM_SLEEP) += sleep.o suspend.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
+obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
extern void fpundefinstr(void);
-
-EXPORT_SYMBOL(__backtrace);
-
/* platform dependent support */
EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__const_udelay);
memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
- src_pgd = pgd_offset(mm, EASI_BASE);
+ src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE);
dst_pgd = pgd_offset(mm, EASI_START);
memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
#define ecard_probeirqhw() (0)
#endif
-#ifndef IO_EC_MEMC8_BASE
-#define IO_EC_MEMC8_BASE 0
-#endif
-
-static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
{
- unsigned long address = 0;
+ void __iomem *address = NULL;
int slot = ec->slot_no;
if (ec->slot_no == 8)
- return IO_EC_MEMC8_BASE;
+ return ECARD_MEMC8_BASE;
ectcr &= ~(1 << slot);
switch (type) {
case ECARD_MEMC:
if (slot < 4)
- address = IO_EC_MEMC_BASE + (slot << 12);
+ address = ECARD_MEMC_BASE + (slot << 14);
break;
case ECARD_IOC:
if (slot < 4)
- address = IO_EC_IOC_BASE + (slot << 12);
-#ifdef IO_EC_IOC4_BASE
+ address = ECARD_IOC_BASE + (slot << 14);
else
- address = IO_EC_IOC4_BASE + ((slot - 4) << 12);
-#endif
+ address = ECARD_IOC4_BASE + ((slot - 4) << 14);
if (address)
- address += speed << 17;
+ address += speed << 19;
break;
-#ifdef IO_EC_EASI_BASE
case ECARD_EASI:
- address = IO_EC_EASI_BASE + (slot << 22);
+ address = ECARD_EASI_BASE + (slot << 24);
if (speed == ECARD_FAST)
ectcr |= 1 << slot;
break;
-#endif
+
default:
break;
}
ecard_t **ecp;
ecard_t *ec;
struct ex_ecid cid;
+ void __iomem *addr;
int i, rc;
ec = ecard_alloc_card(type, slot);
}
rc = -ENODEV;
- if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0)
+ if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
goto nodev;
cid.r_zero = 1;
ec->cid.fiqmask = cid.r_fiqmask;
ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
ec->fiqaddr =
- ec->irqaddr = (void __iomem *)ioaddr(ec->podaddr);
+ ec->irqaddr = addr;
if (ec->cid.is) {
ec->irqmask = ec->cid.irqmask;
set_irq_flags(ec->irq, IRQF_VALID);
}
-#ifdef IO_EC_MEMC8_BASE
if (slot == 8)
ec->irq = 11;
-#endif
#ifdef CONFIG_ARCH_RPC
/* On RiscPC, only first two slots have DMA capability */
if (slot < 2)
ecard_probe(slot, ECARD_IOC);
}
-#ifdef IO_EC_MEMC8_BASE
ecard_probe(8, ECARD_IOC);
-#endif
irqhw = ecard_probeirqhw();
#include <asm/unwind.h>
#include <asm/unistd.h>
#include <asm/tls.h>
+#include <asm/system.h>
#include "entry-header.S"
#include <asm/entry-macro-multi.S>
ldr r0, [r4, #-4]
#else
ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2
- and r9, r0, #0xf800
- cmp r9, #0xe800 @ 32-bit instruction if xx >= 0
+ cmp r0, #0xe800 @ 32-bit instruction if xx >= 0
ldrhhs r9, [r4] @ bottom 16 bits
orrhs r0, r9, r0, lsl #16
#endif
#endif
beq call_fpe
@ Thumb instruction
-#if __LINUX_ARM_ARCH__ >= 7
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
+/*
+ * Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms
+ * can never be supported in a single kernel, this code is not applicable at
+ * all when __LINUX_ARM_ARCH__ < 6. This allows simplifying assumptions to be
+ * made about .arch directives.
+ */
+#if __LINUX_ARM_ARCH__ < 7
+/* If the target CPU may not be Thumb-2-capable, a run-time check is needed: */
+#define NEED_CPU_ARCHITECTURE
+ ldr r5, .LCcpu_architecture
+ ldr r5, [r5]
+ cmp r5, #CPU_ARCH_ARMv7
+ blo __und_usr_unknown
+/*
+ * The following code won't get run unless the running CPU really is v7, so
+ * coding round the lack of ldrht on older arches is pointless. Temporarily
+ * override the assembler target arch with the minimum required instead:
+ */
+ .arch armv6t2
+#endif
2:
ARM( ldrht r5, [r4], #2 )
THUMB( ldrht r5, [r4] )
THUMB( add r4, r4, #2 )
- and r0, r5, #0xf800 @ mask bits 111x x... .... ....
- cmp r0, #0xe800 @ 32bit instruction if xx != 0
+ cmp r5, #0xe800 @ 32bit instruction if xx != 0
blo __und_usr_unknown
3: ldrht r0, [r4]
add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
orr r0, r0, r5, lsl #16
+
+#if __LINUX_ARM_ARCH__ < 7
+/* If the target arch was overridden, change it back: */
+#ifdef CONFIG_CPU_32v6K
+ .arch armv6k
#else
+ .arch armv6
+#endif
+#endif /* __LINUX_ARM_ARCH__ < 7 */
+#else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */
b __und_usr_unknown
#endif
UNWIND(.fnend )
movw_pc lr @ CP#14 (Debug)
movw_pc lr @ CP#15 (Control)
+#ifdef NEED_CPU_ARCHITECTURE
+ .align 2
+.LCcpu_architecture:
+ .word __cpu_architecture
+#endif
+
#ifdef CONFIG_NEON
.align 6
#include <asm/memory.h>
#include <asm/thread_info.h>
#include <asm/system.h>
+#include <asm/pgtable.h>
#ifdef CONFIG_DEBUG_LL
#include <mach/debug-macro.S>
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
#endif
+#define PG_DIR_SIZE 0x4000
+#define PMD_ORDER 2
+
.globl swapper_pg_dir
- .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
+ .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
.macro pgtbl, rd, phys
- add \rd, \phys, #TEXT_OFFSET - 0x4000
+ add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
.endm
#ifdef CONFIG_XIP_KERNEL
pgtbl r4, r8 @ page table address
/*
- * Clear the 16K level 1 swapper page table
+ * Clear the swapper page table
*/
mov r0, r4
mov r3, #0
- add r6, r0, #0x4000
+ add r6, r0, #PG_DIR_SIZE
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
sub r0, r0, r3 @ virt->phys offset
add r5, r5, r0 @ phys __enable_mmu
add r6, r6, r0 @ phys __enable_mmu_end
- mov r5, r5, lsr #20
- mov r6, r6, lsr #20
+ mov r5, r5, lsr #SECTION_SHIFT
+ mov r6, r6, lsr #SECTION_SHIFT
-1: orr r3, r7, r5, lsl #20 @ flags + kernel base
- str r3, [r4, r5, lsl #2] @ identity mapping
- teq r5, r6
- addne r5, r5, #1 @ next section
- bne 1b
+1: orr r3, r7, r5, lsl #SECTION_SHIFT @ flags + kernel base
+ str r3, [r4, r5, lsl #PMD_ORDER] @ identity mapping
+ cmp r5, r6
+ addlo r5, r5, #1 @ next section
+ blo 1b
/*
* Now setup the pagetables for our kernel direct
* mapped region.
*/
mov r3, pc
- mov r3, r3, lsr #20
- orr r3, r7, r3, lsl #20
- add r0, r4, #(KERNEL_START & 0xff000000) >> 18
- str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
+ mov r3, r3, lsr #SECTION_SHIFT
+ orr r3, r7, r3, lsl #SECTION_SHIFT
+ add r0, r4, #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
+ str r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]!
ldr r6, =(KERNEL_END - 1)
- add r0, r0, #4
- add r6, r4, r6, lsr #18
+ add r0, r0, #1 << PMD_ORDER
+ add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
1: cmp r0, r6
- add r3, r3, #1 << 20
- strls r3, [r0], #4
+ add r3, r3, #1 << SECTION_SHIFT
+ strls r3, [r0], #1 << PMD_ORDER
bls 1b
#ifdef CONFIG_XIP_KERNEL
*/
add r3, r8, #TEXT_OFFSET
orr r3, r3, r7
- add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
- str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
+ add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
+ str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]!
ldr r6, =(_end - 1)
add r0, r0, #4
- add r6, r4, r6, lsr #18
+ add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
1: cmp r0, r6
add r3, r3, #1 << 20
strls r3, [r0], #4
* Then map boot params address in r2 or
* the first 1MB of ram if boot params address is not specified.
*/
- mov r0, r2, lsr #20
- movs r0, r0, lsl #20
+ mov r0, r2, lsr #SECTION_SHIFT
+ movs r0, r0, lsl #SECTION_SHIFT
moveq r0, r8
sub r3, r0, r8
add r3, r3, #PAGE_OFFSET
- add r3, r4, r3, lsr #18
+ add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
orr r6, r7, r0
str r6, [r3]
*/
addruart r7, r3
- mov r3, r3, lsr #20
- mov r3, r3, lsl #2
+ mov r3, r3, lsr #SECTION_SHIFT
+ mov r3, r3, lsl #PMD_ORDER
add r0, r4, r3
rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
cmp r3, #0x0800 @ limit to 512MB
movhi r3, #0x0800
add r6, r0, r3
- mov r3, r7, lsr #20
+ mov r3, r7, lsr #SECTION_SHIFT
ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
- orr r3, r7, r3, lsl #20
+ orr r3, r7, r3, lsl #SECTION_SHIFT
1: str r3, [r0], #4
- add r3, r3, #1 << 20
- teq r0, r6
- bne 1b
+ add r3, r3, #1 << SECTION_SHIFT
+ cmp r0, r6
+ blo 1b
#else /* CONFIG_DEBUG_ICEDCC */
/* we don't need any serial debugging mappings for ICEDCC */
* If we're using the NetWinder or CATS, we also need to map
* in the 16550-type serial port for the debug messages
*/
- add r0, r4, #0xff000000 >> 18
+ add r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER)
orr r3, r7, #0x7c000000
str r3, [r0]
#endif
* Similar reasons here - for debug. This is
* only for Acorn RiscPC architectures.
*/
- add r0, r4, #0x02000000 >> 18
+ add r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER)
orr r3, r7, #0x02000000
str r3, [r0]
- add r0, r4, #0xd8000000 >> 18
+ add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
str r3, [r0]
#endif
#endif
add r5, r5, r3 @ adjust table end address
add r7, r7, r3 @ adjust __pv_phys_offset address
str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
-#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
mov r6, r3, lsr #24 @ constant for add/sub instructions
teq r3, r6, lsl #24 @ must be 16MiB aligned
-#else
- mov r6, r3, lsr #16 @ constant for add/sub instructions
- teq r3, r6, lsl #16 @ must be 64kiB aligned
-#endif
THUMB( it ne @ cross section branch )
bne __error
str r6, [r7, #4] @ save to __pv_offset
.text
__fixup_a_pv_table:
#ifdef CONFIG_THUMB2_KERNEL
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
- lsls r0, r6, #24
- lsr r6, #8
- beq 1f
- clz r7, r0
- lsr r0, #24
- lsl r0, r7
- bic r0, 0x0080
- lsrs r7, #1
- orrcs r0, #0x0080
- orr r0, r0, r7, lsl #12
-#endif
-1: lsls r6, #24
- beq 4f
+ lsls r6, #24
+ beq 2f
clz r7, r6
lsr r6, #24
lsl r6, r7
orrcs r6, #0x0080
orr r6, r6, r7, lsl #12
orr r6, #0x4000
- b 4f
-2: @ at this point the C flag is always clear
- add r7, r3
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
- ldrh ip, [r7]
- tst ip, 0x0400 @ the i bit tells us LS or MS byte
- beq 3f
- cmp r0, #0 @ set C flag, and ...
- biceq ip, 0x0400 @ immediate zero value has a special encoding
- streqh ip, [r7] @ that requires the i bit cleared
-#endif
-3: ldrh ip, [r7, #2]
+ b 2f
+1: add r7, r3
+ ldrh ip, [r7, #2]
and ip, 0x8f00
- orrcc ip, r6 @ mask in offset bits 31-24
- orrcs ip, r0 @ mask in offset bits 23-16
+ orr ip, r6 @ mask in offset bits 31-24
strh ip, [r7, #2]
-4: cmp r4, r5
+2: cmp r4, r5
ldrcc r7, [r4], #4 @ use branch for delay slot
- bcc 2b
+ bcc 1b
bx lr
#else
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
- and r0, r6, #255 @ offset bits 23-16
- mov r6, r6, lsr #8 @ offset bits 31-24
-#else
- mov r0, #0 @ just in case...
-#endif
- b 3f
-2: ldr ip, [r7, r3]
+ b 2f
+1: ldr ip, [r7, r3]
bic ip, ip, #0x000000ff
- tst ip, #0x400 @ rotate shift tells us LS or MS byte
- orrne ip, ip, r6 @ mask in offset bits 31-24
- orreq ip, ip, r0 @ mask in offset bits 23-16
+ orr ip, ip, r6 @ mask in offset bits 31-24
str ip, [r7, r3]
-3: cmp r4, r5
+2: cmp r4, r5
ldrcc r7, [r4], #4 @ use branch for delay slot
- bcc 2b
+ bcc 1b
mov pc, lr
#endif
ENDPROC(__fixup_a_pv_table)
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
*/
#undef MODULES_VADDR
-#define MODULES_VADDR (((unsigned long)_etext + ~PGDIR_MASK) & PGDIR_MASK)
+#define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
#endif
#ifdef CONFIG_MMU
{
if (type < 0 || type >= ARM_NUM_PMU_DEVICES) {
pr_warning("received registration request for unknown "
- "device %d\n", type);
+ "PMU device type %d\n", type);
return -EINVAL;
}
device_initcall(register_pmu_driver);
struct platform_device *
-reserve_pmu(enum arm_pmu_type device)
+reserve_pmu(enum arm_pmu_type type)
{
struct platform_device *pdev;
- if (test_and_set_bit_lock(device, &pmu_lock)) {
+ if (test_and_set_bit_lock(type, &pmu_lock)) {
pdev = ERR_PTR(-EBUSY);
- } else if (pmu_devices[device] == NULL) {
- clear_bit_unlock(device, &pmu_lock);
+ } else if (pmu_devices[type] == NULL) {
+ clear_bit_unlock(type, &pmu_lock);
pdev = ERR_PTR(-ENODEV);
} else {
- pdev = pmu_devices[device];
+ pdev = pmu_devices[type];
}
return pdev;
EXPORT_SYMBOL_GPL(reserve_pmu);
int
-release_pmu(enum arm_pmu_type device)
+release_pmu(enum arm_pmu_type type)
{
- if (WARN_ON(!pmu_devices[device]))
+ if (WARN_ON(!pmu_devices[type]))
return -EINVAL;
- clear_bit_unlock(device, &pmu_lock);
+ clear_bit_unlock(type, &pmu_lock);
return 0;
}
EXPORT_SYMBOL_GPL(release_pmu);
}
int
-init_pmu(enum arm_pmu_type device)
+init_pmu(enum arm_pmu_type type)
{
int err = 0;
- switch (device) {
+ switch (type) {
case ARM_PMU_DEVICE_CPU:
err = init_cpu_pmu();
break;
default:
- pr_warning("attempt to initialise unknown device %d\n",
- device);
+ pr_warning("attempt to initialise PMU of unknown "
+ "type %d\n", type);
err = -EINVAL;
}
printk("\n");
printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
__show_regs(regs);
- __backtrace();
+ dump_stack();
}
ATOMIC_NOTIFIER_HEAD(thread_notify_head);
mov r0,#0
ldr r1,kexec_mach_type
ldr r2,kexec_boot_atags
- mov pc,lr
+ ARM( mov pc, lr )
+ THUMB( bx lr )
.align
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/memblock.h>
+#include <linux/bug.h>
+#include <linux/compiler.h>
#include <asm/unified.h>
#include <asm/cpu.h>
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
#include <asm/tlbflush.h>
+#include <asm/system.h>
#include <asm/prom.h>
#include <asm/mach/arch.h>
EXPORT_SYMBOL(outer_cache);
#endif
+/*
+ * Cached cpu_architecture() result for use by assembler code.
+ * C code should use the cpu_architecture() function instead of accessing this
+ * variable directly.
+ */
+int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
+
struct stack {
u32 irq[3];
u32 abt[3];
"?(17)",
};
-int cpu_architecture(void)
+static int __get_cpu_architecture(void)
{
int cpu_arch;
return cpu_arch;
}
+int __pure cpu_architecture(void)
+{
+ BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
+
+ return __cpu_architecture;
+}
+
static int cpu_has_aliasing_icache(unsigned int arch)
{
int aliasing_icache;
if (arch >= CPU_ARCH_ARMv6) {
if ((cachetype & (7 << 29)) == 4 << 29) {
/* ARMv7 register format */
+ arch = CPU_ARCH_ARMv7;
cacheid = CACHEID_VIPT_NONALIASING;
if ((cachetype & (3 << 14)) == 1 << 14)
cacheid |= CACHEID_ASID_TAGGED;
- else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
- cacheid |= CACHEID_VIPT_I_ALIASING;
- } else if (cachetype & (1 << 23)) {
- cacheid = CACHEID_VIPT_ALIASING;
} else {
- cacheid = CACHEID_VIPT_NONALIASING;
- if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
- cacheid |= CACHEID_VIPT_I_ALIASING;
+ arch = CPU_ARCH_ARMv6;
+ if (cachetype & (1 << 23))
+ cacheid = CACHEID_VIPT_ALIASING;
+ else
+ cacheid = CACHEID_VIPT_NONALIASING;
}
+ if (cpu_has_aliasing_icache(arch))
+ cacheid |= CACHEID_VIPT_I_ALIASING;
} else {
cacheid = CACHEID_VIVT;
}
}
cpu_name = list->cpu_name;
+ __cpu_architecture = __get_cpu_architecture();
#ifdef MULTI_CPU
processor = *list->proc;
.text
/*
- * Save CPU state for a suspend
- * r1 = v:p offset
- * r2 = suspend function arg0
- * r3 = suspend function
+ * Save CPU state for a suspend. This saves the CPU general purpose
+ * registers, and allocates space on the kernel stack to save the CPU
+ * specific registers and some other data for resume.
+ * r0 = suspend function arg0
+ * r1 = suspend function
*/
ENTRY(__cpu_suspend)
stmfd sp!, {r4 - r11, lr}
#ifdef MULTI_CPU
ldr r10, =processor
- ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
- ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+ ldr r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
#else
- ldr r5, =cpu_suspend_size
- ldr ip, =cpu_do_resume
+ ldr r4, =cpu_suspend_size
#endif
- mov r6, sp @ current virtual SP
- sub sp, sp, r5 @ allocate CPU state on stack
- mov r0, sp @ save pointer to CPU save block
- add ip, ip, r1 @ convert resume fn to phys
- stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn
- ldr r5, =sleep_save_sp
- add r6, sp, r1 @ convert SP to phys
- stmfd sp!, {r2, r3} @ save suspend func arg and pointer
+ mov r5, sp @ current virtual SP
+ add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
+ sub sp, sp, r4 @ allocate CPU state on stack
+ stmfd sp!, {r0, r1} @ save suspend func arg and pointer
+ add r0, sp, #8 @ save pointer to save block
+ mov r1, r4 @ size of save block
+ mov r2, r5 @ virtual SP
+ ldr r3, =sleep_save_sp
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
ALT_UP(mov lr, #0)
and lr, lr, #15
- str r6, [r5, lr, lsl #2] @ save phys SP
-#else
- str r6, [r5] @ save phys SP
-#endif
-#ifdef MULTI_CPU
- mov lr, pc
- ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
-#else
- bl cpu_do_suspend
-#endif
-
- @ flush data cache
-#ifdef MULTI_CACHE
- ldr r10, =cpu_cache
- mov lr, pc
- ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
-#else
- bl __cpuc_flush_kern_all
+ add r3, r3, lr, lsl #2
#endif
+ bl __cpu_suspend_save
adr lr, BSYM(cpu_suspend_abort)
ldmfd sp!, {r0, pc} @ call suspend fn
ENDPROC(__cpu_suspend)
.ltorg
cpu_suspend_abort:
- ldmia sp!, {r1 - r3} @ pop v:p, virt SP, phys resume fn
+ ldmia sp!, {r1 - r3} @ pop phys pgd, virt SP, phys resume fn
+ teq r0, #0
+ moveq r0, #1 @ force non-zero value
mov sp, r2
ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_suspend_abort)
/*
* r0 = control register value
- * r1 = v:p offset (preserved by cpu_do_resume)
- * r2 = phys page table base
- * r3 = L1 section flags
*/
+ .align 5
ENTRY(cpu_resume_mmu)
- adr r4, cpu_resume_turn_mmu_on
- mov r4, r4, lsr #20
- orr r3, r3, r4, lsl #20
- ldr r5, [r2, r4, lsl #2] @ save old mapping
- str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
- sub r2, r2, r1
ldr r3, =cpu_resume_after_mmu
- bic r1, r0, #CR_C @ ensure D-cache is disabled
- b cpu_resume_turn_mmu_on
-ENDPROC(cpu_resume_mmu)
- .ltorg
- .align 5
-cpu_resume_turn_mmu_on:
- mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc
- mrc p15, 0, r1, c0, c0, 0 @ read id reg
- mov r1, r1
- mov r1, r1
+ mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc
+ mrc p15, 0, r0, c0, c0, 0 @ read id reg
+ mov r0, r0
+ mov r0, r0
mov pc, r3 @ jump to virtual address
-ENDPROC(cpu_resume_turn_mmu_on)
+ENDPROC(cpu_resume_mmu)
cpu_resume_after_mmu:
- str r5, [r2, r4, lsl #2] @ restore old mapping
- mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache
bl cpu_init @ restore the und/abt/irq banked regs
mov r0, #0 @ return zero on success
ldmfd sp!, {r4 - r11, pc}
ldr r0, sleep_save_sp @ stack phys addr
#endif
setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
- @ load v:p, stack, resume fn
+ @ load phys pgd, stack, resume fn
ARM( ldmia r0!, {r1, sp, pc} )
THUMB( ldmia r0!, {r1, r2, r3} )
THUMB( mov sp, r2 )
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
+#include <asm/topology.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/localtimer.h>
+#include <asm/smp_plat.h>
/*
* as from 2.5, kernels no longer have an init_tasks structure
}
#endif /* CONFIG_HOTPLUG_CPU */
+int __cpu_logical_map[NR_CPUS];
+
+void __init smp_setup_processor_id(void)
+{
+ int i;
+ u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
+
+ cpu_logical_map(0) = cpu;
+ for (i = 1; i < NR_CPUS; ++i)
+ cpu_logical_map(i) = i == cpu ? 0 : i;
+
+ printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
+}
+
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
cpu_info->loops_per_jiffy = loops_per_jiffy;
+
+ store_cpu_topology(cpuid);
}
/*
{
unsigned int ncores = num_possible_cpus();
+ init_cpu_topology();
+
smp_store_cpu_info(smp_processor_id());
/*
clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
+ clockevents_register_device(clk);
+
/* Make sure our local interrupt controller has this enabled */
gic_enable_ppi(clk->irq);
-
- clockevents_register_device(clk);
}
--- /dev/null
+#include <linux/init.h>
+
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/memory.h>
+#include <asm/suspend.h>
+#include <asm/tlbflush.h>
+
+static pgd_t *suspend_pgd;
+
+extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
+extern void cpu_resume_mmu(void);
+
+/*
+ * This is called by __cpu_suspend() to save the state, and do whatever
+ * flushing is required to ensure that when the CPU goes to sleep we have
+ * the necessary data available when the caches are not searched.
+ */
+void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
+{
+ *save_ptr = virt_to_phys(ptr);
+
+ /* This must correspond to the LDM in cpu_resume() assembly */
+ *ptr++ = virt_to_phys(suspend_pgd);
+ *ptr++ = sp;
+ *ptr++ = virt_to_phys(cpu_do_resume);
+
+ cpu_do_suspend(ptr);
+
+ flush_cache_all();
+ outer_clean_range(*save_ptr, *save_ptr + ptrsz);
+ outer_clean_range(virt_to_phys(save_ptr),
+ virt_to_phys(save_ptr) + sizeof(*save_ptr));
+}
+
+/*
+ * Hide the first two arguments to __cpu_suspend - these are an implementation
+ * detail which platform code shouldn't have to know about.
+ */
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+ struct mm_struct *mm = current->active_mm;
+ int ret;
+
+ if (!suspend_pgd)
+ return -EINVAL;
+
+ /*
+ * Provide a temporary page table with an identity mapping for
+ * the MMU-enable code, required for resuming. On successful
+ * resume (indicated by a zero return code), we need to switch
+ * back to the correct page tables.
+ */
+ ret = __cpu_suspend(arg, fn);
+ if (ret == 0)
+ cpu_switch_mm(mm->pgd, mm);
+
+ return ret;
+}
+
+static int __init cpu_suspend_init(void)
+{
+ suspend_pgd = pgd_alloc(&init_mm);
+ if (suspend_pgd) {
+ unsigned long addr = virt_to_phys(cpu_resume_mmu);
+ identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
+ }
+ return suspend_pgd ? 0 : -ENOMEM;
+}
+core_initcall(cpu_suspend_init);
--- /dev/null
+/*
+ * arch/arm/kernel/topology.c
+ *
+ * Copyright (C) 2011 Linaro Limited.
+ * Written by: Vincent Guittot
+ *
+ * based on arch/sh/kernel/topology.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+
+#include <asm/cputype.h>
+#include <asm/topology.h>
+
+#define MPIDR_SMP_BITMASK (0x3 << 30)
+#define MPIDR_SMP_VALUE (0x2 << 30)
+
+#define MPIDR_MT_BITMASK (0x1 << 24)
+
+/*
+ * These masks reflect the current use of the affinity levels.
+ * The affinity level can be up to 16 bits according to ARM ARM
+ */
+
+#define MPIDR_LEVEL0_MASK 0x3
+#define MPIDR_LEVEL0_SHIFT 0
+
+#define MPIDR_LEVEL1_MASK 0xF
+#define MPIDR_LEVEL1_SHIFT 8
+
+#define MPIDR_LEVEL2_MASK 0xFF
+#define MPIDR_LEVEL2_SHIFT 16
+
+struct cputopo_arm cpu_topology[NR_CPUS];
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+{
+ return &cpu_topology[cpu].core_sibling;
+}
+
+/*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+ * which prevents simultaneous write access to cpu_topology array
+ */
+void store_cpu_topology(unsigned int cpuid)
+{
+ struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
+ unsigned int mpidr;
+ unsigned int cpu;
+
+ /* If the cpu topology has been already set, just return */
+ if (cpuid_topo->core_id != -1)
+ return;
+
+ mpidr = read_cpuid_mpidr();
+
+ /* create cpu topology mapping */
+ if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
+ /*
+ * This is a multiprocessor system
+ * multiprocessor format & multiprocessor mode field are set
+ */
+
+ if (mpidr & MPIDR_MT_BITMASK) {
+ /* core performance interdependency */
+ cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
+ & MPIDR_LEVEL0_MASK;
+ cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
+ & MPIDR_LEVEL1_MASK;
+ cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT)
+ & MPIDR_LEVEL2_MASK;
+ } else {
+ /* largely independent cores */
+ cpuid_topo->thread_id = -1;
+ cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
+ & MPIDR_LEVEL0_MASK;
+ cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
+ & MPIDR_LEVEL1_MASK;
+ }
+ } else {
+ /*
+ * This is an uniprocessor system
+ * we are in multiprocessor format but uniprocessor system
+ * or in the old uniprocessor format
+ */
+ cpuid_topo->thread_id = -1;
+ cpuid_topo->core_id = 0;
+ cpuid_topo->socket_id = -1;
+ }
+
+ /* update core and thread sibling masks */
+ for_each_possible_cpu(cpu) {
+ struct cputopo_arm *cpu_topo = &cpu_topology[cpu];
+
+ if (cpuid_topo->socket_id == cpu_topo->socket_id) {
+ cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+ if (cpu != cpuid)
+ cpumask_set_cpu(cpu,
+ &cpuid_topo->core_sibling);
+
+ if (cpuid_topo->core_id == cpu_topo->core_id) {
+ cpumask_set_cpu(cpuid,
+ &cpu_topo->thread_sibling);
+ if (cpu != cpuid)
+ cpumask_set_cpu(cpu,
+ &cpuid_topo->thread_sibling);
+ }
+ }
+ }
+ smp_wmb();
+
+ printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
+ cpuid, cpu_topology[cpuid].thread_id,
+ cpu_topology[cpuid].core_id,
+ cpu_topology[cpuid].socket_id, mpidr);
+}
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void init_cpu_topology(void)
+{
+ unsigned int cpu;
+
+ /* init core mask */
+ for_each_possible_cpu(cpu) {
+ struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
+
+ cpu_topo->thread_id = -1;
+ cpu_topo->core_id = -1;
+ cpu_topo->socket_id = -1;
+ cpumask_clear(&cpu_topo->core_sibling);
+ cpumask_clear(&cpu_topo->thread_sibling);
+ }
+ smp_wmb();
+}
#include <linux/kdebug.h>
#include <linux/module.h>
#include <linux/kexec.h>
+#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/sched.h>
spin_lock_irq(&die_lock);
console_verbose();
bust_spinlocks(1);
+ if (!user_mode(regs))
+ report_bug(regs->ARM_pc, regs);
ret = __die(str, err, thread, regs);
if (regs && kexec_should_crash(thread->task))
}
}
+#ifdef CONFIG_GENERIC_BUG
+
+int is_valid_bugaddr(unsigned long pc)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ unsigned short bkpt;
+#else
+ unsigned long bkpt;
+#endif
+
+ if (probe_kernel_address((unsigned *)pc, bkpt))
+ return 0;
+
+ return bkpt == BUG_INSTR_VALUE;
+}
+
+#endif
+
static LIST_HEAD(undef_hook);
static DEFINE_SPINLOCK(undef_lock);
arm_notify_die("unknown data abort code", regs, &info, instr, 0);
}
-void __attribute__((noreturn)) __bug(const char *file, int line)
-{
- printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
- *(int *)0 = 0;
-
- /* Avoid "noreturn function does return" */
- for (;;);
-}
-EXPORT_SYMBOL(__bug);
-
void __readwrite_bug(const char *fn)
{
printk("%s called, but not implemented\n", fn);
#define ARM_CPU_KEEP(x)
#endif
-#if defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)
+#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
+ defined(CONFIG_GENERIC_BUG)
#define ARM_EXIT_KEEP(x) x
#else
#define ARM_EXIT_KEEP(x)
#define mask r7
#define offset r8
-ENTRY(__backtrace)
- mov r1, #0x10
- mov r0, fp
-
ENTRY(c_backtrace)
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
mov pc, lr
-ENDPROC(__backtrace)
ENDPROC(c_backtrace)
#else
stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
mov r1, frame
bl printk
no_frame: ldmfd sp!, {r4 - r8, pc}
-ENDPROC(__backtrace)
ENDPROC(c_backtrace)
.pushsection __ex_table,"a"
# INITRD_PHYS must be in RAM
ifeq ($(CONFIG_ARCH_AT91CAP9),y)
- zreladdr-y := 0x70008000
+ zreladdr-y += 0x70008000
params_phys-y := 0x70000100
initrd_phys-y := 0x70410000
else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
- zreladdr-y := 0x70008000
+ zreladdr-y += 0x70008000
params_phys-y := 0x70000100
initrd_phys-y := 0x70410000
else
- zreladdr-y := 0x20008000
+ zreladdr-y += 0x20008000
params_phys-y := 0x20000100
initrd_phys-y := 0x20410000
endif
#include <asm/mach/irq.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <mach/board.h>
#include <mach/cpu.h>
-#include <mach/gpio.h>
#include <mach/at91cap9.h>
#include <mach/at91cap9_matrix.h>
#include <mach/at91sam9_smc.h>
#include <asm/mach/map.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91rm9200.h>
#include <mach/at91rm9200_mc.h>
#include <asm/mach/map.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/cpu.h>
#include <mach/at91sam9260.h>
#include <mach/at91sam9260_matrix.h>
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
- CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
#include <asm/mach/map.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <video/atmel_lcdc.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9261.h>
#include <mach/at91sam9261_matrix.h>
#include <mach/at91sam9_smc.h>
#include <asm/mach/map.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <video/atmel_lcdc.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9263.h>
#include <mach/at91sam9263_matrix.h>
#include <mach/at91sam9_smc.h>
#include <asm/mach/map.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <linux/atmel-mci.h>
#include <video/atmel_lcdc.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9g45.h>
#include <mach/at91sam9g45_matrix.h>
#include <mach/at91sam9_smc.h>
#include <asm/mach/map.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <video/atmel_lcdc.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9rl.h>
#include <mach/at91sam9rl_matrix.h>
#include <mach/at91sam9_smc.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/cpu.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include "sam9_smc.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/map.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91cap9_matrix.h>
#include <mach/at91sam9_smc.h>
#include <mach/system_rev.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91sam9260_matrix.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91rm9200_mc.h>
#include <mach/cpu.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include "generic.h"
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/gpio.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/cpu.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/cpu.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/cpu.h>
#include <mach/at91rm9200_mc.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include "sam9_smc.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91rm9200_mc.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91rm9200_mc.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91rm9200_mc.h>
#include "generic.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include "sam9_smc.h"
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
#include <mach/system_rev.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
#include <mach/system_rev.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
#include <mach/system_rev.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/system_rev.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/mach/irq.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
#include <mach/system_rev.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_shdwc.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/board.h>
-#include <mach/gpio.h>
#include <mach/at91rm9200_mc.h>
#include <mach/cpu.h>
#include <linux/clk.h>
#include <linux/errno.h>
+#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/debugfs.h>
#include <mach/hardware.h>
#include <mach/at91_pio.h>
-#include <mach/gpio.h>
-
-#include <asm/gpio.h>
#include "generic.h"
*/
#include <asm/errno.h>
-#include <asm-generic/gpio.h> /* cansleep wrappers */
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
#define gpio_to_irq(gpio) (gpio)
#define irq_to_gpio(irq) (irq)
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <mach/board.h>
-#include <mach/gpio.h>
/* ------------------------------------------------------------------------- */
* (at your option) any later version.
*/
+#include <linux/gpio.h>
#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <asm/mach/irq.h>
#include <mach/at91_pmc.h>
-#include <mach/gpio.h>
#include <mach/cpu.h>
#include "generic.h"
# Address where decompressor will be written and eventually executed.
#
# default to SDRAM
-zreladdr-y := $(CONFIG_BCM_ZRELADDR)
+zreladdr-y += $(CONFIG_BCM_ZRELADDR)
params_phys-y := 0x00000800
# The standard locations for stuff on CLPS711x type processors
- zreladdr-y := 0xc0028000
+ zreladdr-y += 0xc0028000
params_phys-y := 0xc0000100
# Should probably have some agreement on these...
initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00C00000
* published by the Free Software Foundation.
*/
-#include <mach/hardware.h>
#include <asm/hardware/entry-macro-gic.S>
.macro disable_fiq
#include <linux/io.h>
#include <asm/proc-fns.h>
-#include <mach/hardware.h>
static inline void arch_idle(void)
{
*/
#include <asm/mach-types.h>
-#include <mach/hardware.h>
#include <mach/cns3xxx.h>
#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
return &cns3xxx_pcie[root->domain];
}
-static struct cns3xxx_pcie *pdev_to_cnspci(struct pci_dev *dev)
+static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev)
{
return sysdata_to_cnspci(dev->sysdata);
}
# Common objects
obj-y := time.o clock.o serial.o io.o psc.o \
- gpio.o dma.o usb.o common.o sram.o aemif.o
+ dma.o usb.o common.o sram.o aemif.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
-obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
obj-$(CONFIG_AINTC) += irq.o
obj-$(CONFIG_CP_INTC) += cp_intc.o
ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
$(error Cannot enable DaVinci and DA8XX platforms concurrently)
else
- zreladdr-y := 0xc0008000
+ zreladdr-y += 0xc0008000
params_phys-y := 0xc0000100
initrd_phys-y := 0xc0800000
endif
else
- zreladdr-y := 0x80008000
+ zreladdr-y += 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
endif
},
};
+#ifdef CONFIG_MTD
+static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
+{
+ char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
+ size_t retlen;
+
+ if (!strcmp(mtd->name, "MAC-Address")) {
+ mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
+ if (retlen == ETH_ALEN)
+ pr_info("Read MAC addr from SPI Flash: %pM\n",
+ mac_addr);
+ }
+}
+
+static struct mtd_notifier da850evm_spi_notifier = {
+ .add = da850_evm_m25p80_notify_add,
+};
+
+static void da850_evm_setup_mac_addr(void)
+{
+ register_mtd_user(&da850evm_spi_notifier);
+}
+#else
+static void da850_evm_setup_mac_addr(void) { }
+#endif
+
static struct mtd_partition da850_evm_norflash_partition[] = {
{
.name = "bootloaders + env",
if (ret)
pr_warning("da850_evm_init: sata registration failed: %d\n",
ret);
+
+ da850_evm_setup_mac_addr();
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
-#include <mach/gpio.h>
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <mach/da8xx.h>
#include <mach/cpufreq.h>
#include <mach/pm.h>
-#include <mach/gpio.h>
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <mach/common.h>
#include <mach/asp.h>
#include <mach/spi.h>
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <asm/mach/map.h>
#include <mach/asp.h>
#include <mach/keyscan.h>
#include <mach/spi.h>
-
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <mach/serial.h>
#include <mach/common.h>
#include <mach/asp.h>
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <mach/serial.h>
#include <mach/common.h>
#include <mach/asp.h>
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
--- /dev/null
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DAVINCI_DAVINCI_GPIO_H
+#define __DAVINCI_DAVINCI_GPIO_H
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm-generic/gpio.h>
+
+#include <mach/irqs.h>
+#include <mach/common.h>
+
+#define DAVINCI_GPIO_BASE 0x01C67000
+
+enum davinci_gpio_type {
+ GPIO_TYPE_DAVINCI = 0,
+ GPIO_TYPE_TNETV107X,
+};
+
+/*
+ * basic gpio routines
+ *
+ * board-specific init should be done by arch/.../.../board-XXX.c (maybe
+ * initializing banks together) rather than boot loaders; kexec() won't
+ * go through boot loaders.
+ *
+ * the gpio clock will be turned on when gpios are used, and you may also
+ * need to pay attention to PINMUX registers to be sure those pins are
+ * used as gpios, not with other peripherals.
+ *
+ * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
+ * and maybe for later updates, code may write GPIO(N). These may be
+ * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
+ * may not support all the GPIOs in that range.
+ *
+ * GPIOs can also be on external chips, numbered after the ones built-in
+ * to the DaVinci chip. For now, they won't be usable as IRQ sources.
+ */
+#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
+
+/* Convert GPIO signal to GPIO pin number */
+#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
+
+struct davinci_gpio_controller {
+ struct gpio_chip chip;
+ int irq_base;
+ spinlock_t lock;
+ void __iomem *regs;
+ void __iomem *set_data;
+ void __iomem *clr_data;
+ void __iomem *in_data;
+};
+
+/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
+ * with constant parameters; or in outlined code they execute at runtime.
+ *
+ * You'd access the controller directly when reading or writing more than
+ * one gpio value at a time, and to support wired logic where the value
+ * being driven by the cpu need not match the value read back.
+ *
+ * These are NOT part of the cross-platform GPIO interface
+ */
+static inline struct davinci_gpio_controller *
+__gpio_to_controller(unsigned gpio)
+{
+ struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
+ int index = gpio / 32;
+
+ if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
+ return NULL;
+
+ return ctlrs + index;
+}
+
+static inline u32 __gpio_mask(unsigned gpio)
+{
+ return 1 << (gpio % 32);
+}
+
+#endif /* __DAVINCI_DAVINCI_GPIO_H */
#ifndef __DAVINCI_GPIO_H
#define __DAVINCI_GPIO_H
-#include <linux/io.h>
-#include <linux/spinlock.h>
-
#include <asm-generic/gpio.h>
-#include <mach/irqs.h>
-#include <mach/common.h>
-
-#define DAVINCI_GPIO_BASE 0x01C67000
-
-enum davinci_gpio_type {
- GPIO_TYPE_DAVINCI = 0,
- GPIO_TYPE_TNETV107X,
-};
-
-/*
- * basic gpio routines
- *
- * board-specific init should be done by arch/.../.../board-XXX.c (maybe
- * initializing banks together) rather than boot loaders; kexec() won't
- * go through boot loaders.
- *
- * the gpio clock will be turned on when gpios are used, and you may also
- * need to pay attention to PINMUX registers to be sure those pins are
- * used as gpios, not with other peripherals.
- *
- * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
- * and maybe for later updates, code may write GPIO(N). These may be
- * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
- * may not support all the GPIOs in that range.
- *
- * GPIOs can also be on external chips, numbered after the ones built-in
- * to the DaVinci chip. For now, they won't be usable as IRQ sources.
- */
-#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
-
-/* Convert GPIO signal to GPIO pin number */
-#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
-
-struct davinci_gpio_controller {
- struct gpio_chip chip;
- int irq_base;
- spinlock_t lock;
- void __iomem *regs;
- void __iomem *set_data;
- void __iomem *clr_data;
- void __iomem *in_data;
-};
-
-/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
- * with constant parameters; or in outlined code they execute at runtime.
- *
- * You'd access the controller directly when reading or writing more than
- * one gpio value at a time, and to support wired logic where the value
- * being driven by the cpu need not match the value read back.
- *
- * These are NOT part of the cross-platform GPIO interface
- */
-static inline struct davinci_gpio_controller *
-__gpio_to_controller(unsigned gpio)
-{
- struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
- int index = gpio / 32;
-
- if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
- return NULL;
-
- return ctlrs + index;
-}
-
-static inline u32 __gpio_mask(unsigned gpio)
-{
- return 1 << (gpio % 32);
-}
+/* The inline versions use the static inlines in the driver header */
+#include "gpio-davinci.h"
/*
* The get/set/clear functions will inline when called with constant
return __gpio_cansleep(gpio);
}
-static inline int gpio_to_irq(unsigned gpio)
-{
- return __gpio_to_irq(gpio);
-}
-
static inline int irq_to_gpio(unsigned irq)
{
/* don't support the reverse mapping */
#define PSC_STATE_DISABLE 2
#define PSC_STATE_ENABLE 3
-#define MDSTAT_STATE_MASK 0x1f
+#define MDSTAT_STATE_MASK 0x3f
#define MDCTL_FORCE BIT(31)
#ifndef __ASSEMBLER__
ENDPROC(davinci_ddr_psc_config)
CACHE_FLUSH:
- .word arm926_flush_kern_cache_all
+#ifdef CONFIG_CPU_V6
+ .word v6_flush_kern_cache_all
+#else
+ .word arm926_flush_kern_cache_all
+#endif
ENTRY(davinci_cpu_suspend_sz)
.word . - davinci_cpu_suspend
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <mach/psc.h>
#include <mach/cp_intc.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
#include <mach/hardware.h>
#include <mach/tnetv107x.h>
+#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000400
initrd_phys-y := 0x00800000
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define IO_SPACE_LIMIT 0xffff
-
u8 __inb8(unsigned int port);
void __outb8(u8 val, unsigned int port);
- zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00008000
+ zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) += 0x00008000
params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100
- zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0008000
+ zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) += 0xc0008000
params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100
- zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0008000
+ zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) += 0xd0008000
params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0000100
- zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0008000
+ zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) += 0xe0008000
params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0000100
- zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0008000
+ zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) += 0xf0008000
params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0000100
/* maximum value for irq capable line identifiers */
#define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7)
-/* new generic GPIO API - see Documentation/gpio.txt */
-
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-
-/*
- * Map GPIO A0..A7 (0..7) to irq 64..71,
- * B0..B7 (7..15) to irq 72..79, and
- * F0..F7 (16..24) to irq 80..87.
- */
-#define gpio_to_irq(gpio) \
- (((gpio) <= EP93XX_GPIO_LINE_MAX_IRQ) ? (64 + (gpio)) : -EINVAL)
-
+#define gpio_to_irq __gpio_to_irq
#define irq_to_gpio(irq) ((irq) - gpio_to_irq(0))
#endif
* TS72xx memory map:
*
* virt phys size
- * febff000 22000000 4K model number register
+ * febff000 22000000 4K model number register (bits 0-2)
* febfe000 22400000 4K options register
* febfd000 22800000 4K options register #2
* febf9000 10800000 4K TS-5620 RTC index register
#define TS72XX_MODEL_TS7200 0x00
#define TS72XX_MODEL_TS7250 0x01
#define TS72XX_MODEL_TS7260 0x02
+#define TS72XX_MODEL_TS7300 0x03
+#define TS72XX_MODEL_TS7400 0x04
+#define TS72XX_MODEL_MASK 0x07
#define TS72XX_OPTIONS_PHYS_BASE 0x22400000
#ifndef __ASSEMBLY__
+static inline int ts72xx_model(void)
+{
+ return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK;
+}
+
static inline int board_is_ts7200(void)
{
- return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200;
+ return ts72xx_model() == TS72XX_MODEL_TS7200;
}
static inline int board_is_ts7250(void)
{
- return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250;
+ return ts72xx_model() == TS72XX_MODEL_TS7250;
}
static inline int board_is_ts7260(void)
{
- return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260;
+ return ts72xx_model() == TS72XX_MODEL_TS7260;
+}
+
+static inline int board_is_ts7300(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7300;
+}
+
+static inline int board_is_ts7400(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7400;
}
static inline int is_max197_installed(void)
- zreladdr-y := 0x40008000
+ zreladdr-y += 0x40008000
params_phys-y := 0x40000100
.ctrlbit = (1 << 21),
}, {
.name = "ac97",
- .id = -1,
+ .devname = "samsung-ac97",
.enable = exynos4_clk_ip_peril_ctrl,
.ctrlbit = (1 << 27),
}, {
#include <plat/exynos4.h>
#include <plat/adc-core.h>
#include <plat/sdhci.h>
-#include <plat/devs.h>
#include <plat/fb-core.h>
#include <plat/fimc-core.h>
#include <plat/iic-core.h>
+#include <plat/reset.h>
#include <mach/regs-irq.h>
+#include <mach/regs-pmu.h>
extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
unsigned int irq_start);
local_irq_enable();
}
+static void exynos4_sw_reset(void)
+{
+ __raw_writel(0x1, S5P_SWRESET);
+}
+
/*
* exynos4_map_io
*
/* set idle function */
pm_idle = exynos4_idle;
+ /* set sw_reset function */
+ s5p_reset_hook = exynos4_sw_reset;
+
return sysdev_register(&exynos4_sysdev);
}
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H __FILE__
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
/* GPIO bank sizes */
#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + \
CONFIG_SAMSUNG_GPIO_EXTRA + 1)
-#include <asm-generic/gpio.h>
-
#endif /* __ASM_ARCH_GPIO_H */
#define IRQ_HSMMC3 IRQ_SPI(76)
#define IRQ_DWMCI IRQ_SPI(77)
-#define IRQ_MIPICSI0 IRQ_SPI(78)
-
-#define IRQ_MIPICSI1 IRQ_SPI(80)
+#define IRQ_MIPI_CSIS0 IRQ_SPI(78)
+#define IRQ_MIPI_CSIS1 IRQ_SPI(80)
#define IRQ_ONENAND_AUDI IRQ_SPI(82)
#define IRQ_ROTATOR IRQ_SPI(83)
#define S5P_USE_STANDBY_WFE1 (1 << 25)
#define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24))
+#define S5P_SWRESET S5P_PMUREG(0x0400)
+
#define S5P_WAKEUP_STAT S5P_PMUREG(0x0600)
#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
#include <mach/regs-gpio.h>
+#include <asm/mach/irq.h>
+
static DEFINE_SPINLOCK(eint_lock);
static unsigned int eint0_15_data[16];
static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
+ struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
exynos4_irq_demux_eint(IRQ_EINT(16));
exynos4_irq_demux_eint(IRQ_EINT(24));
+ chained_irq_exit(chip, desc);
}
static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
u32 *irq_data = irq_get_handler_data(irq);
struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
chip->irq_mask(&desc->irq_data);
if (chip->irq_ack)
generic_handle_irq(*irq_data);
chip->irq_unmask(&desc->irq_data);
+ chained_irq_exit(chip, desc);
}
int __init exynos4_init_irq_eint(void)
};
static struct regulator_consumer_supply max8952_consumer =
- REGULATOR_SUPPLY("vddarm", NULL);
+ REGULATOR_SUPPLY("vdd_arm", NULL);
static struct max8952_platform_data universal_max8952_pdata __initdata = {
.gpio_vid0 = EXYNOS4_GPX0(3),
};
static struct regulator_consumer_supply lp3974_buck1_consumer =
- REGULATOR_SUPPLY("vddint", NULL);
+ REGULATOR_SUPPLY("vdd_int", NULL);
static struct regulator_consumer_supply lp3974_buck2_consumer =
REGULATOR_SUPPLY("vddg3d", NULL);
rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
writel(rstcon, EXYNOS4_RSTCON);
- udelay(50);
+ udelay(80);
clk_disable(otg_clk);
clk_put(otg_clk);
config ARCH_CATS
bool "CATS"
- select CLKSRC_I8253
select CLKEVT_I8253
+ select CLKSRC_I8253
select FOOTBRIDGE_HOST
select ISA
select ISA_DMA
config ARCH_NETWINDER
bool "NetWinder"
+ select CLKEVT_I8253
select CLKSRC_I8253
select FOOTBRIDGE_HOST
select ISA
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <video/vga.h>
#include <asm/irq.h>
#include <asm/system.h>
#define PCIO_SIZE 0x00100000
#define PCIO_BASE MMU_IO(0xff000000, 0x7c000000)
-#define IO_SPACE_LIMIT 0xffff
-
/*
* Translation of various region addresses to virtual addresses
*/
ifeq ($(CONFIG_GEMINI_MEM_SWAP),y)
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
else
- zreladdr-y := 0x10008000
+ zreladdr-y += 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x10800000
endif
#define __MACH_GPIO_H__
#include <mach/irqs.h>
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
#define gpio_to_irq(x) ((x) + GPIO_IRQ_BASE)
#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE)
- zreladdr-$(CONFIG_ARCH_H720X) := 0x40008000
+ zreladdr-$(CONFIG_ARCH_H720X) += 0x40008000
-zreladdr-$(CONFIG_ARCH_MX1) := 0x08008000
+zreladdr-$(CONFIG_ARCH_MX1) += 0x08008000
params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
-zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
+zreladdr-$(CONFIG_MACH_MX21) += 0xC0008000
params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
-zreladdr-$(CONFIG_ARCH_MX25) := 0x80008000
+zreladdr-$(CONFIG_ARCH_MX25) += 0x80008000
params_phys-$(CONFIG_ARCH_MX25) := 0x80000100
initrd_phys-$(CONFIG_ARCH_MX25) := 0x80800000
-zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
+zreladdr-$(CONFIG_MACH_MX27) += 0xA0008000
params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
-zreladdr-$(CONFIG_ARCH_MX3) := 0x80008000
+zreladdr-$(CONFIG_ARCH_MX3) += 0x80008000
params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <mach/hardware.h>
-#include <mach/gpio.h>
#include <mach/iomux-mx3.h>
/*
.init = eukrea_cpuimx27_timer_init,
};
-MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
+MACHINE_START(EUKREA_CPUIMX27, "EUKREA CPUIMX27")
.atag_offset = 0x100,
.map_io = mx27_map_io,
.init_early = imx27_init_early,
.init = eukrea_cpuimx35_timer_init,
};
-MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35")
+MACHINE_START(EUKREA_CPUIMX35SD, "Eukrea CPUIMX35")
/* Maintainer: Eukrea Electromatique */
.atag_offset = 0x100,
.map_io = mx35_map_io,
.init = eukrea_cpuimx25_timer_init,
};
-MACHINE_START(EUKREA_CPUIMX25, "Eukrea CPUIMX25")
+MACHINE_START(EUKREA_CPUIMX25SD, "Eukrea CPUIMX25")
/* Maintainer: Eukrea Electromatique */
.atag_offset = 0x100,
.map_io = mx25_map_io,
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <mach/iomux-mx27.h>
#include "devices-imx27.h"
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
{ /* Bus clock */
.con_id = "apb_pclk",
.clk = &dummy_apb_pclk,
+ }, {
+ /* Integrator/AP timer frequency */
+ .dev_id = "ap_timer",
+ .clk = &clk24mhz,
}, { /* UART0 */
.dev_id = "mb:16",
.clk = &uartclk,
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define IO_SPACE_LIMIT 0xffff
-
/*
* WARNING: this has to mirror definitions in platform.h
*/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
/**************************************************************************
* * Copyright © ARM Limited 1998. All rights reserved.
* ***********************************************************************/
#define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100)
#define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200)
-#define TICKS_PER_uSEC 24
-
-/*
- * These are useconds NOT ticks.
- *
- */
-#define mSEC_1 1000
-#define mSEC_10 (mSEC_1 * 10)
-
#define INTEGRATOR_CSR_BASE 0x10000000
#define INTEGRATOR_CSR_SIZE 0x10000000
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mtd/physmap.h>
+#include <linux/clk.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE)
#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE)
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
static unsigned long timer_reload;
-static void integrator_clocksource_init(u32 khz)
+static void integrator_clocksource_init(unsigned long inrate)
{
void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
- u32 ctrl = TIMER_CTRL_ENABLE;
+ u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
+ unsigned long rate = inrate;
- if (khz >= 1500) {
- khz /= 16;
- ctrl = TIMER_CTRL_DIV16;
+ if (rate >= 1500000) {
+ rate /= 16;
+ ctrl |= TIMER_CTRL_DIV16;
}
- writel(ctrl, base + TIMER_CTRL);
writel(0xffff, base + TIMER_LOAD);
+ writel(ctrl, base + TIMER_CTRL);
clocksource_mmio_init(base + TIMER_VALUE, "timer2",
- khz * 1000, 200, 16, clocksource_mmio_readl_down);
+ rate, 200, 16, clocksource_mmio_readl_down);
}
static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
{
u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
- BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT);
+ /* Disable timer */
+ writel(ctrl, clkevt_base + TIMER_CTRL);
- if (mode == CLOCK_EVT_MODE_PERIODIC) {
- writel(ctrl, clkevt_base + TIMER_CTRL);
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* Enable the timer and start the periodic tick */
writel(timer_reload, clkevt_base + TIMER_LOAD);
ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Leave the timer disabled, .set_next_event will enable it */
+ ctrl &= ~TIMER_CTRL_PERIODIC;
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ default:
+ /* Just leave in disabled state */
+ break;
}
- writel(ctrl, clkevt_base + TIMER_CTRL);
}
static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
static struct clock_event_device integrator_clockevent = {
.name = "timer1",
- .shift = 34,
- .features = CLOCK_EVT_FEAT_PERIODIC,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = clkevt_set_mode,
.set_next_event = clkevt_set_next_event,
.rating = 300,
- .cpumask = cpu_all_mask,
};
static struct irqaction integrator_timer_irq = {
.dev_id = &integrator_clockevent,
};
-static void integrator_clockevent_init(u32 khz)
+static void integrator_clockevent_init(unsigned long inrate)
{
- struct clock_event_device *evt = &integrator_clockevent;
+ unsigned long rate = inrate;
unsigned int ctrl = 0;
- if (khz * 1000 > 0x100000 * HZ) {
- khz /= 256;
+ /* Calculate and program a divisor */
+ if (rate > 0x100000 * HZ) {
+ rate /= 256;
ctrl |= TIMER_CTRL_DIV256;
- } else if (khz * 1000 > 0x10000 * HZ) {
- khz /= 16;
+ } else if (rate > 0x10000 * HZ) {
+ rate /= 16;
ctrl |= TIMER_CTRL_DIV16;
}
-
- timer_reload = khz * 1000 / HZ;
+ timer_reload = rate / HZ;
writel(ctrl, clkevt_base + TIMER_CTRL);
- evt->irq = IRQ_TIMERINT1;
- evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift);
- evt->max_delta_ns = clockevent_delta2ns(0xffff, evt);
- evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
-
setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
- clockevents_register_device(evt);
+ clockevents_config_and_register(&integrator_clockevent,
+ rate,
+ 1,
+ 0xffffU);
}
/*
*/
static void __init ap_init_timer(void)
{
- u32 khz = TICKS_PER_uSEC * 1000;
+ struct clk *clk;
+ unsigned long rate;
+
+ clk = clk_get_sys("ap_timer", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+ rate = clk_get_rate(clk);
writel(0, TIMER0_VA_BASE + TIMER_CTRL);
writel(0, TIMER1_VA_BASE + TIMER_CTRL);
writel(0, TIMER2_VA_BASE + TIMER_CTRL);
- integrator_clocksource_init(khz);
- integrator_clockevent_init(khz);
+ integrator_clocksource_init(rate);
+ integrator_clockevent_init(rate);
}
static struct sys_timer ap_timer = {
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
- zreladdr-y := 0xa0008000
+ zreladdr-y += 0xa0008000
params_phys-y := 0xa0000100
initrd_phys-y := 0xa0800000
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ixp2000.h>
static DEFINE_SPINLOCK(ixp2000_slowport_lock);
static unsigned long ixp2000_slowport_irq_flags;
*
* Copyright (C) 2002 Intel Corporation.
*
- * This program is free software, you can redistribute it and/or modify
+ * This program is free software, you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/*
* IXP2000 GPIO in/out, edge/level detection for IRQs:
* IRQs are generated on Falling-edge, Rising-Edge, Level-low, Level-High
- * or both Falling-edge and Rising-edge.
+ * or both Falling-edge and Rising-edge.
* This must be called *before* the corresponding IRQ is registerd.
* Use this instead of directly setting the GPIO registers.
* GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <asm/mach/flash.h>
#include <asm/mach/arch.h>
-#include <mach/gpio.h>
-
+#include <mach/gpio-ixp2000.h>
/*************************************************************************
* IXDP2x00 IRQ Initialization
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
- local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + SZ_48M);
+ local_write_config(PCI_BASE_ADDRESS_3, 4,
+ PHYS_OFFSET + SZ_32M + SZ_16M);
/*
* Enable CSR window at 64 MiB to allow PCI masters
* Author: Rod Whitby <rod@whitby.id.au>
* Maintainers: http://www.nslu2-linux.org/
*/
-
+#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/time.h>
-#include <asm/gpio.h>
#define DSMG600_SDA_PIN 5
#define DSMG600_SCL_PIN 4
* Maintainers: http://www.nslu2-linux.org/
*
*/
-
+#include <linux/gpio.h>
#include <linux/if_ether.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
-#include <asm/gpio.h>
#define FSG_SDA_PIN 12
#define FSG_SCL_PIN 13
#include <linux/kernel.h>
#include <mach/hardware.h>
+#define __ARM_GPIOLIB_COMPLEX
+
static inline int gpio_request(unsigned gpio, const char *label)
{
return 0;
#include <asm-generic/gpio.h> /* cansleep wrappers */
extern int gpio_to_irq(int gpio);
+#define gpio_to_irq gpio_to_irq
extern int irq_to_gpio(unsigned int irq);
#endif
#include <mach/hardware.h>
-#define IO_SPACE_LIMIT 0x0000ffff
-
extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
* Maintainers: http://www.nslu2-linux.org/
*
*/
-
+#include <linux/gpio.h>
#include <linux/if_ether.h>
#include <linux/irq.h>
#include <linux/jiffies.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
-#include <asm/gpio.h>
#define NAS100D_SDA_PIN 5
#define NAS100D_SCL_PIN 6
* Maintainers: http://www.nslu2-linux.org/
*
*/
-
+#include <linux/gpio.h>
#include <linux/if_ether.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/time.h>
-#include <asm/gpio.h>
#define NSLU2_SDA_PIN 7
#define NSLU2_SCL_PIN 6
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
-#include <asm/gpio.h>
#include "common.h"
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
-#include <asm/gpio.h>
#include <mach/hardware.h>
#include <plat/mpp.h>
#include "common.h"
# Makefile for KS8695 architecture support
#
-obj-y := cpu.o irq.o time.o gpio.o devices.o
+obj-y := cpu.o irq.o time.o devices.o
obj-m :=
obj-n :=
obj- :=
# PARAMS_PHYS must be within 4MB of ZRELADDR
# INITRD_PHYS must be in RAM
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <asm/mach/irq.h>
#include <mach/devices.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
#include "generic.h"
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <asm/mach/irq.h>
#include <mach/devices.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
#include "generic.h"
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
#include <mach/devices.h>
#include "generic.h"
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
--- /dev/null
+/*
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_KS8659_GPIO_H
+#define __MACH_KS8659_GPIO_H
+
+#include <linux/kernel.h>
+
+#define KS8695_GPIO_0 0
+#define KS8695_GPIO_1 1
+#define KS8695_GPIO_2 2
+#define KS8695_GPIO_3 3
+#define KS8695_GPIO_4 4
+#define KS8695_GPIO_5 5
+#define KS8695_GPIO_6 6
+#define KS8695_GPIO_7 7
+#define KS8695_GPIO_8 8
+#define KS8695_GPIO_9 9
+#define KS8695_GPIO_10 10
+#define KS8695_GPIO_11 11
+#define KS8695_GPIO_12 12
+#define KS8695_GPIO_13 13
+#define KS8695_GPIO_14 14
+#define KS8695_GPIO_15 15
+
+/*
+ * Configure GPIO pin as external interrupt source.
+ */
+extern int ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
+
+/* Register the GPIOs */
+extern void ks8695_register_gpios(void);
+
+#endif /* __MACH_KS8659_GPIO_H */
#ifndef __ASM_ARCH_GPIO_H_
#define __ASM_ARCH_GPIO_H_
-#include <linux/kernel.h>
-
-#define KS8695_GPIO_0 0
-#define KS8695_GPIO_1 1
-#define KS8695_GPIO_2 2
-#define KS8695_GPIO_3 3
-#define KS8695_GPIO_4 4
-#define KS8695_GPIO_5 5
-#define KS8695_GPIO_6 6
-#define KS8695_GPIO_7 7
-#define KS8695_GPIO_8 8
-#define KS8695_GPIO_9 9
-#define KS8695_GPIO_10 10
-#define KS8695_GPIO_11 11
-#define KS8695_GPIO_12 12
-#define KS8695_GPIO_13 13
-#define KS8695_GPIO_14 14
-#define KS8695_GPIO_15 15
-
-/*
- * Configure GPIO pin as external interrupt source.
- */
-extern int ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
-
/*
* Map IRQ number to GPIO line.
*/
extern int irq_to_gpio(unsigned int irq);
-#include <asm-generic/gpio.h>
-
-/* If it turns out that we need to optimise GPIO access for the
- * Micrel's GPIOs, then these can be changed to check their argument
- * directly as static inlines. However for now it's probably not
- * worthwhile.
- */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_to_irq __gpio_to_irq
-
-/* Register the GPIOs */
-extern void ks8695_register_gpios(void);
-
#endif
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/gpio.h>
#include <asm/leds.h>
#include <mach/devices.h>
-#include <mach/gpio.h>
static inline void ks8695_led_on(unsigned int led)
#
obj-y := timer.o irq.o common.o serial.o clock.o
-obj-y += gpiolib.o pm.o suspend.o
+obj-y += pm.o suspend.o
obj-y += phy3250.o
- zreladdr-y := 0x80008000
+ zreladdr-y += 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x82000000
--- /dev/null
+/*
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_GPIO_LPC32XX_H
+#define __MACH_GPIO_LPC32XX_H
+
+/*
+ * Note!
+ * Muxed GP pins need to be setup to the GP state in the board level
+ * code prior to using this driver.
+ * GPI pins : 28xP3 group
+ * GPO pins : 24xP3 group
+ * GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group
+ */
+
+#define LPC32XX_GPIO_P0_MAX 8
+#define LPC32XX_GPIO_P1_MAX 24
+#define LPC32XX_GPIO_P2_MAX 13
+#define LPC32XX_GPIO_P3_MAX 6
+#define LPC32XX_GPI_P3_MAX 28
+#define LPC32XX_GPO_P3_MAX 24
+
+#define LPC32XX_GPIO_P0_GRP 0
+#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
+#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
+#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
+#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
+#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
+
+/*
+ * A specific GPIO can be selected with this macro
+ * ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
+ * See the LPC32x0 User's guide for GPIO group numbers
+ */
+#define LPC32XX_GPIO(x, y) ((x) + (y))
+
+#endif /* __MACH_GPIO_LPC32XX_H */
-/*
- * arch/arm/mach-lpc32xx/include/mach/gpio.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-/*
- * Note!
- * Muxed GP pins need to be setup to the GP state in the board level
- * code prior to using this driver.
- * GPI pins : 28xP3 group
- * GPO pins : 24xP3 group
- * GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group
- */
-
-#define LPC32XX_GPIO_P0_MAX 8
-#define LPC32XX_GPIO_P1_MAX 24
-#define LPC32XX_GPIO_P2_MAX 13
-#define LPC32XX_GPIO_P3_MAX 6
-#define LPC32XX_GPI_P3_MAX 28
-#define LPC32XX_GPO_P3_MAX 24
-
-#define LPC32XX_GPIO_P0_GRP 0
-#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
-#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
-#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
-#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
-#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
-
-/*
- * A specific GPIO can be selected with this macro
- * ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
- * See the LPC32x0 User's guide for GPIO group numbers
- */
-#define LPC32XX_GPIO(x, y) ((x) + (y))
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
- return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
- return __gpio_to_irq(gpio);
-}
-
-#endif
#include <mach/hardware.h>
#include <mach/platform.h>
+#include <mach/gpio-lpc32xx.h>
#include "common.h"
/*
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <mach/addr-map.h>
#include <mach/mfp-pxa168.h>
#include <mach/pxa168.h>
-#include <mach/gpio.h>
#include <video/pxa168fb.h>
#include <linux/input.h>
#include <plat/pxa27x_keypad.h>
}, {
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
- .size = SZ_48M,
+ .size = SZ_32M + SZ_16M,
.mask_flags = 0,
}
};
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <mach/irqs.h>
#include <mach/dma.h>
#include <mach/mfp.h>
-#include <mach/gpio.h>
#include <mach/devices.h>
#include <mach/mmp2.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <mach/regs-apbc.h>
#include <mach/regs-apmu.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
#include <mach/dma.h>
#include <mach/devices.h>
#include <mach/mfp.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <mach/regs-apmu.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
#include <mach/dma.h>
#include <mach/mfp.h>
#include <mach/devices.h>
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <mach/addr-map.h>
#include <mach/mfp-pxa910.h>
#include <mach/pxa910.h>
-#include <mach/gpio.h>
#include "common.h"
}, {
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
- .size = SZ_48M,
+ .size = SZ_32M + SZ_16M,
.mask_flags = 0,
}
};
- zreladdr-y := 0x10008000
+ zreladdr-y += 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x10800000
* GNU General Public License for more details.
*
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <mach/vreg.h>
#include <mach/mpp.h>
-#include <mach/gpio.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/smsc911x.h>
#include <linux/usb/msm_hsusb.h>
#include <linux/clkdev.h>
+#include <linux/memblock.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/memory.h>
#include <asm/setup.h>
-#include <mach/gpio.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
extern struct sys_timer msm_timer;
+static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag,
+ char **cmdline, struct meminfo *mi)
+{
+ for (; tag->hdr.size; tag = tag_next(tag))
+ if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) {
+ tag->u.mem.start = 0;
+ tag->u.mem.size += SZ_2M;
+ }
+}
+
+static void __init msm7x30_reserve(void)
+{
+ memblock_remove(0x0, SZ_2M);
+}
+
static int hsusb_phy_init_seq[] = {
0x30, 0x32, /* Enable and set Pre-Emphasis Depth to 20% */
0x02, 0x36, /* Disable CDR Auto Reset feature */
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
.atag_offset = 0x100,
+ .fixup = msm7x30_fixup,
+ .reserve = msm7x30_reserve,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
.atag_offset = 0x100,
+ .fixup = msm7x30_fixup,
+ .reserve = msm7x30_reserve,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
.atag_offset = 0x100,
+ .fixup = msm7x30_fixup,
+ .reserve = msm7x30_reserve,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/clkdev.h>
+#include <linux/memblock.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
+#include <asm/setup.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include "devices.h"
+static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag,
+ char **cmdline, struct meminfo *mi)
+{
+ for (; tag->hdr.size; tag = tag_next(tag))
+ if (tag->hdr.tag == ATAG_MEM &&
+ tag->u.mem.start == 0x40200000) {
+ tag->u.mem.start = 0x40000000;
+ tag->u.mem.size += SZ_2M;
+ }
+}
+
+static void __init msm8960_reserve(void)
+{
+ memblock_remove(0x40000000, SZ_2M);
+}
+
static void __init msm8960_map_io(void)
{
msm_map_msm8960_io();
}
MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
+ .fixup = msm8960_fixup,
+ .reserve = msm8960_reserve,
.map_io = msm8960_map_io,
.init_irq = msm8960_init_irq,
.timer = &msm_timer,
MACHINE_END
MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
+ .fixup = msm8960_fixup,
+ .reserve = msm8960_reserve,
.map_io = msm8960_map_io,
.init_irq = msm8960_init_irq,
.timer = &msm_timer,
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/memblock.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
+#include <asm/setup.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
+static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag,
+ char **cmdline, struct meminfo *mi)
+{
+ for (; tag->hdr.size; tag = tag_next(tag))
+ if (tag->hdr.tag == ATAG_MEM &&
+ tag->u.mem.start == 0x40200000) {
+ tag->u.mem.start = 0x40000000;
+ tag->u.mem.size += SZ_2M;
+ }
+}
+
+static void __init msm8x60_reserve(void)
+{
+ memblock_remove(0x40000000, SZ_2M);
+}
static void __init msm8x60_map_io(void)
{
}
MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
+ .fixup = msm8x60_fixup,
+ .reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
.init_irq = msm8x60_init_irq,
.init_machine = msm8x60_init,
MACHINE_END
MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
+ .fixup = msm8x60_fixup,
+ .reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
.init_irq = msm8x60_init_irq,
.init_machine = msm8x60_init,
MACHINE_END
MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
+ .fixup = msm8x60_fixup,
+ .reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
.init_irq = msm8x60_init_irq,
.init_machine = msm8x60_init,
MACHINE_END
MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
+ .fixup = msm8x60_fixup,
+ .reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
.init_irq = msm8x60_init_irq,
.init_machine = msm8x60_init,
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <mach/board.h>
#include <mach/irqs.h>
#include <mach/sirc.h>
-#include <mach/gpio.h>
#include <mach/vreg.h>
#include <mach/mmc.h>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <asm/gpio.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
/* linux/arch/arm/mach-msm/board-trout-mmc.c
** Author: Brian Swetland <swetland@google.com>
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/debugfs.h>
-#include <asm/gpio.h>
#include <asm/io.h>
#include <mach/vreg.h>
/* linux/arch/arm/mach-msm/board-trout-mddi.c
** Author: Brian Swetland <swetland@google.com>
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <asm/io.h>
-#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <mach/msm_fb.h>
-/*
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-#ifndef __ASM_ARCH_MSM_GPIO_H
-#define __ASM_ARCH_MSM_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
-#endif /* __ASM_ARCH_MSM_GPIO_H */
+/* empty */
#elif defined(CONFIG_ARCH_QSD8X50)
#define PLAT_PHYS_OFFSET UL(0x20000000)
#elif defined(CONFIG_ARCH_MSM7X30)
-#define PLAT_PHYS_OFFSET UL(0x00200000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#elif defined(CONFIG_ARCH_MSM8X60)
-#define PLAT_PHYS_OFFSET UL(0x40200000)
+#define PLAT_PHYS_OFFSET UL(0x40000000)
#elif defined(CONFIG_ARCH_MSM8960)
-#define PLAT_PHYS_OFFSET UL(0x40200000)
+#define PLAT_PHYS_OFFSET UL(0x40000000)
#else
#define PLAT_PHYS_OFFSET UL(0x10000000)
#endif
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/irq.h>
-#include <asm/gpio.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <plat/mpp.h>
-#include <asm/gpio.h>
#include <mach/hardware.h>
#include "common.h"
#include "mpp.h"
- zreladdr-$(CONFIG_ARCH_MX50) := 0x70008000
+ zreladdr-$(CONFIG_ARCH_MX50) += 0x70008000
params_phys-$(CONFIG_ARCH_MX50) := 0x70000100
initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000
- zreladdr-$(CONFIG_ARCH_MX51) := 0x90008000
+ zreladdr-$(CONFIG_ARCH_MX51) += 0x90008000
params_phys-$(CONFIG_ARCH_MX51) := 0x90000100
initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
- zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000
+ zreladdr-$(CONFIG_ARCH_MX53) += 0x70008000
params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
-zreladdr-y := 0x40008000
+zreladdr-y += 0x40008000
#ifndef __MACH_MXS_GPIO_H__
#define __MACH_MXS_GPIO_H__
-#include <asm-generic/gpio.h>
-
#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
-/* use gpiolib dispatchers */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
#endif /* __MACH_MXS_GPIO_H__ */
- zreladdr-y := 0x80008000
+ zreladdr-y += 0x80008000
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
+#include <plat/gpio-nomadik.h>
#include <plat/mtu.h>
#include <mach/setup.h>
#include <linux/device.h>
#include <linux/amba/bus.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/mach/map.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
-#include <linux/gpio.h>
#include <linux/platform_device.h>
+#include <plat/gpio-nomadik.h>
/*
* There are two busses in the 8815NHK.
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H
-#include <plat/gpio.h>
-
#endif /* __ASM_ARCH_GPIO_H */
-zreladdr-y := 0x00008000
+zreladdr-y += 0x00008000
params_phys-y := 0x00000100
- zreladdr-y := 0x10008000
+ zreladdr-y += 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x10800000
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/input.h>
#include <plat/io.h>
#include <plat/board-ams-delta.h>
-#include <mach/gpio.h>
#include <plat/keypad.h>
#include <plat/mux.h>
#include <plat/usb.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <plat/tc.h>
-#include <mach/gpio.h>
#include <plat/mux.h>
#include <plat/flash.h>
#include <plat/fpga.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/mux.h>
#include <plat/usb.h>
#include <plat/board.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c/tps65010.h>
#include <plat/mmc.h>
-#include <mach/gpio.h>
#include "board-h2.h"
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/smc91x.h>
#include <mach/hardware.h>
-#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c/tps65010.h>
#include <plat/mmc.h>
-#include <mach/gpio.h>
#include "board-h3.h"
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/major.h>
#include <asm/setup.h>
#include <asm/page.h>
#include <mach/hardware.h>
-#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
* 02110-1301, USA.
*
*/
-
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <plat/mux.h>
#include <plat/flash.h>
#include <plat/fpga.h>
-#include <mach/gpio.h>
#include <plat/tc.h>
#include <plat/usb.h>
#include <plat/keypad.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/mux.h>
#include <plat/usb.h>
#include <plat/board.h>
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c/tps65010.h>
#include <mach/hardware.h>
-#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/input.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/flash.h>
#include <plat/mux.h>
#include <plat/usb.h>
*/
#include <linux/delay.h>
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <plat/led.h>
-#include <mach/gpio.h>
#include <plat/flash.h>
#include <plat/mux.h>
#include <plat/usb.h>
*/
#include <linux/delay.h>
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/flash.h>
#include <plat/mux.h>
#include <plat/usb.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <plat/tc.h>
-#include <mach/gpio.h>
#include <plat/mux.h>
#include <plat/fpga.h>
#include <plat/flash.h>
* published by the Free Software Foundation.
*/
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <plat/mmc.h>
-#include <mach/gpio.h>
#include <plat/board-sx1.h>
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/input.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/flash.h>
#include <plat/mux.h>
#include <plat/dma.h>
*/
#include <linux/delay.h>
+#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <plat/board-voiceblue.h>
#include <plat/common.h>
-#include <mach/gpio.h>
#include <plat/flash.h>
#include <plat/mux.h>
#include <plat/tc.h>
*/
#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mux.h>
-#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/omap7xx.h>
#include <plat/mcbsp.h>
*/
#include <linux/types.h>
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <asm/mach/irq.h>
#include <plat/fpga.h>
-#include <mach/gpio.h>
static void fpga_mask_irq(struct irq_data *d)
{
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
-#include <mach/gpio.h>
#include <plat/cpu.h>
#define IRQ_BANK(irq) ((irq) >> 5)
* The "surfer" expansion board and H2 sample board also have two-color
* green+red LEDs (in parallel), used here for timer and idle indicators.
*/
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <asm/mach-types.h>
#include <plat/fpga.h>
-#include <mach/gpio.h>
#include "leds.h"
*
* LED driver for OSK with optional Mistral QVGA board
*/
+#include <linux/gpio.h>
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
-#include <mach/gpio.h>
-
#include "leds.h"
*
* OMAP LEDs dispatcher
*/
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
-#include <mach/gpio.h>
#include <plat/mux.h>
#include "leds.h"
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <plat/board.h>
#include <plat/mux.h>
-#include <mach/gpio.h>
#include <plat/fpga.h>
#include "pm.h"
- zreladdr-y := 0x80008000
+ zreladdr-y += 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/gpio.h>
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <plat/mcspi.h>
-#include <mach/gpio.h>
#include <plat/board.h>
#include <plat/common.h>
#include <plat/gpmc.h>
.name = "gpt12_fck",
.ops = &clkops_null,
.parent = &secure_32k_fck,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
.name = "wdt1_fck",
.ops = &clkops_null,
.parent = &secure_32k_fck,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
} else if (cpu_is_omap446x()) {
cpu_mask = RATE_IN_4460;
cpu_clkflg = CK_446X;
+ } else {
+ return 0;
}
clk_init(&omap2_clk_functions);
- omap2_clk_disable_clkdm_control();
+
+ /*
+ * Must stay commented until all OMAP SoC drivers are
+ * converted to runtime PM, or drivers may start crashing
+ *
+ * omap2_clk_disable_clkdm_control();
+ */
for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
c++)
spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
ret = arch_clkdm->clkdm_wakeup(clkdm);
+ ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);
spin_unlock_irqrestore(&clkdm->lock, flags);
return ret;
}
spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
arch_clkdm->clkdm_deny_idle(clkdm);
+ pwrdm_state_switch(clkdm->pwrdm.ptr);
spin_unlock_irqrestore(&clkdm->lock, flags);
}
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mcbsp.h>
-#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/dma.h>
#include <plat/omap_hwmod.h>
.pa_end = OMAP243X_HS_BASE + SZ_4K - 1,
.flags = ADDR_TYPE_RT
},
+ { }
};
/* l4_core ->usbhsotg interface */
} else {
hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- pwrdm_wait_transition(pwrdm);
sleep_switch = FORCEWAKEUP_SWITCH;
}
}
return ret;
}
- pwrdm_wait_transition(pwrdm);
pwrdm_state_switch(pwrdm);
err:
return ret;
/**
* pwrdm_init - set up the powerdomain layer
- * @pwrdm_list: array of struct powerdomain pointers to register
+ * @pwrdms: array of struct powerdomain pointers to register
* @custom_funcs: func pointers for arch specific implementations
*
- * Loop through the array of powerdomains @pwrdm_list, registering all
- * that are available on the current CPU. If pwrdm_list is supplied
- * and not null, all of the referenced powerdomains will be
- * registered. No return value. XXX pwrdm_list is not really a
- * "list"; it is an array. Rename appropriately.
+ * Loop through the array of powerdomains @pwrdms, registering all
+ * that are available on the current CPU. Also, program all
+ * powerdomain target state as ON; this is to prevent domains from
+ * hitting low power states (if bootloader has target states set to
+ * something other than ON) and potentially even losing context while
+ * PM is not fully initialized. The PM late init code can then program
+ * the desired target state for all the power domains. No return
+ * value.
*/
-void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
+void pwrdm_init(struct powerdomain **pwrdms, struct pwrdm_ops *custom_funcs)
{
struct powerdomain **p = NULL;
+ struct powerdomain *temp_p;
if (!custom_funcs)
WARN(1, "powerdomain: No custom pwrdm functions registered\n");
else
arch_pwrdm = custom_funcs;
- if (pwrdm_list) {
- for (p = pwrdm_list; *p; p++)
+ if (pwrdms) {
+ for (p = pwrdms; *p; p++)
_pwrdm_register(*p);
}
+
+ list_for_each_entry(temp_p, &pwrdm_list, node)
+ pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
}
/**
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
* License, or (at your option) any later version.
*
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/phy.h>
#include <linux/marvell_phy.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
/*
* Check for devices with hard-wired IRQs.
*/
- irq = orion5x_pci_map_irq(const dev, slot, pin);
+ irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/gpio.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_reg.h>
#include <linux/ata_platform.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/ata_platform.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <mach/orion5x.h>
#include "common.h"
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/mbus.h>
+#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/i2c.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/serial_reg.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_reg.h>
#include <linux/ata_platform.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/serial_reg.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
-#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
- zreladdr-y := 0x80008000
+ zreladdr-y += 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
-
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/platform.h>
-#include <mach/gpio.h>
+#include <mach/gpio-pnx4008.h>
/* register definitions */
#define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
/*
- * arch/arm/mach-pnx4008/include/mach/gpio.h
+ * arch/arm/mach-pnx4008/include/mach/gpio-pnx4008.h
*
* PNX4008 GPIO driver - header file
*
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
-#include <mach/gpio.h>
+#include <mach/gpio-pnx4008.h>
#include <mach/clock.h>
#define UART_3 0
-zreladdr-y := 0x00008000
+zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
static struct of_device_id clkc_ids[] = {
{ .compatible = "sirf,prima2-clkc" },
+ {},
};
void __init sirfsoc_of_clk_init(void)
static struct of_device_id intc_ids[] = {
{ .compatible = "sirf,prima2-intc" },
+ {},
};
void __init sirfsoc_of_irq_init(void)
static struct of_device_id rstc_ids[] = {
{ .compatible = "sirf,prima2-rstc" },
+ {},
};
static int __init sirfsoc_of_rstc_init(void)
static struct of_device_id timer_ids[] = {
{ .compatible = "sirf,prima2-tick" },
+ {},
};
static void __init sirfsoc_of_timer_map(void)
- zreladdr-y := 0xa0008000
+ zreladdr-y += 0xa0008000
* initialization stuff for PXA machines which can be overridden later if
* need be.
*/
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/mach-types.h>
#include <mach/reset.h>
-#include <mach/gpio.h>
#include <mach/smemc.h>
#include <mach/pxa3xx-regs.h>
#ifndef __ASM_ARCH_LITTLETON_H
#define __ASM_ARCH_LITTLETON_H
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#define LITTLETON_ETH_PHYS 0x30000000
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
#include "generic.h"
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <asm/mach/flash.h>
#include <mach/pxa27x.h>
-#include <mach/gpio.h>
#include <mach/lpd270.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/hardware/sa1111.h>
#include <mach/pxa25x.h>
-#include <mach/gpio.h>
#include <mach/audio.h>
#include <mach/lubbock.h>
#include <mach/udc.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <asm/mach/flash.h>
#include <mach/pxa27x.h>
-#include <mach/gpio.h>
#include <mach/mainstone.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscore_ops.h>
-#include <mach/gpio.h>
#include <mach/pxa2xx-regs.h>
#include <mach/mfp-pxa2xx.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <media/soc_camera.h>
-#include <asm/gpio.h>
#include <mach/camera.h>
#include <asm/mach/map.h>
#include <mach/pxa27x.h>
* initialization stuff for PXA machines which can be overridden later if
* need be.
*/
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/suspend.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
#include <mach/pxa25x.h>
#include <mach/reset.h>
#include <mach/pm.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/suspend.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
#include <mach/pxa27x.h>
#include <mach/reset.h>
#include <mach/ohci.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/mach/map.h>
#include <asm/suspend.h>
#include <mach/hardware.h>
-#include <mach/gpio.h>
#include <mach/pxa3xx-regs.h>
#include <mach/reset.h>
#include <mach/ohci.h>
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscore_ops.h>
#include <mach/hardware.h>
-#include <mach/gpio.h>
#include <mach/pxa3xx-regs.h>
#include <mach/pxa930.h>
#include <mach/reset.h>
}, {
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
- .size = SZ_48M,
+ .size = SZ_32M + SZ_16M,
.mask_flags = 0,
}
};
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <mach/hardware.h>
#include <mach/mfp.h>
#include <mach/mfp-pxa930.h>
-#include <mach/gpio.h>
#include "generic.h"
ifeq ($(CONFIG_REALVIEW_HIGH_PHYS_OFFSET),y)
- zreladdr-y := 0x70008000
+ zreladdr-y += 0x70008000
params_phys-y := 0x70000100
initrd_phys-y := 0x70800000
else
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
endif
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
+/* empty */
*/
if (realview_reset)
realview_reset(mode);
+ dsb();
}
#endif
- zreladdr-y := 0x10008000
+ zreladdr-y += 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x18000000
#define EASI_SIZE 0x08000000 /* EASI I/O */
#define EASI_START 0x08000000
-#define EASI_BASE 0xe5000000
+#define EASI_BASE IOMEM(0xe5000000)
#define IO_START 0x03000000 /* I/O */
#define IO_SIZE 0x01000000
/*
* IO Addresses
*/
-#define VIDC_BASE IOMEM(0xe0400000)
-#define EXPMASK_BASE 0xe0360000
-#define IOMD_BASE IOMEM(0xe0200000)
-#define IOC_BASE IOMEM(0xe0200000)
-#define PCIO_BASE IOMEM(0xe0010000)
-#define FLOPPYDMA_BASE IOMEM(0xe002a000)
+#define ECARD_EASI_BASE (EASI_BASE)
+#define VIDC_BASE (IO_BASE + 0x00400000)
+#define EXPMASK_BASE (IO_BASE + 0x00360000)
+#define ECARD_IOC4_BASE (IO_BASE + 0x00270000)
+#define ECARD_IOC_BASE (IO_BASE + 0x00240000)
+#define IOMD_BASE (IO_BASE + 0x00200000)
+#define IOC_BASE (IO_BASE + 0x00200000)
+#define ECARD_MEMC8_BASE (IO_BASE + 0x0002b000)
+#define FLOPPYDMA_BASE (IO_BASE + 0x0002a000)
+#define PCIO_BASE (IO_BASE + 0x00010000)
+#define ECARD_MEMC_BASE (IO_BASE + 0x00000000)
#define vidc_writel(val) __raw_writel(val, VIDC_BASE)
-#define IO_EC_EASI_BASE 0x81400000
-#define IO_EC_IOC4_BASE 0x8009c000
-#define IO_EC_IOC_BASE 0x80090000
-#define IO_EC_MEMC8_BASE 0x8000ac00
-#define IO_EC_MEMC_BASE 0x80000000
-
#define NETSLOT_BASE 0x0302b000
#define NETSLOT_SIZE 0x00001000
#include <mach/hardware.h>
-#define IO_SPACE_LIMIT 0xffffffff
+#define IO_SPACE_LIMIT 0xffff
/*
- * We use two different types of addressing - PC style addresses, and ARM
- * addresses. PC style accesses the PC hardware with the normal PC IO
- * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+
- * and are translated to the start of IO. Note that all addresses are
- * shifted left!
- */
-#define __PORT_PCIO(x) (!((x) & 0x80000000))
-
-/*
- * Dynamic IO functions.
- */
-static inline void __outb (unsigned int value, unsigned int port)
-{
- unsigned long temp;
- __asm__ __volatile__(
- "tst %2, #0x80000000\n\t"
- "mov %0, %4\n\t"
- "addeq %0, %0, %3\n\t"
- "strb %1, [%0, %2, lsl #2] @ outb"
- : "=&r" (temp)
- : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
- : "cc");
-}
-
-static inline void __outw (unsigned int value, unsigned int port)
-{
- unsigned long temp;
- __asm__ __volatile__(
- "tst %2, #0x80000000\n\t"
- "mov %0, %4\n\t"
- "addeq %0, %0, %3\n\t"
- "str %1, [%0, %2, lsl #2] @ outw"
- : "=&r" (temp)
- : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
- : "cc");
-}
-
-static inline void __outl (unsigned int value, unsigned int port)
-{
- unsigned long temp;
- __asm__ __volatile__(
- "tst %2, #0x80000000\n\t"
- "mov %0, %4\n\t"
- "addeq %0, %0, %3\n\t"
- "str %1, [%0, %2, lsl #2] @ outl"
- : "=&r" (temp)
- : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
- : "cc");
-}
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr) \
-static inline unsigned sz __in##fnsuffix (unsigned int port) \
-{ \
- unsigned long temp, value; \
- __asm__ __volatile__( \
- "tst %2, #0x80000000\n\t" \
- "mov %0, %4\n\t" \
- "addeq %0, %0, %3\n\t" \
- "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \
- : "=&r" (temp), "=r" (value) \
- : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \
- : "cc"); \
- return (unsigned sz)value; \
-}
-
-static inline void __iomem *__deprecated __ioaddr(unsigned int port)
-{
- void __iomem *ret;
- if (__PORT_PCIO(port))
- ret = PCIO_BASE;
- else
- ret = IO_BASE;
- return ret + (port << 2);
-}
-
-#define DECLARE_IO(sz,fnsuffix,instr) \
- DECLARE_DYN_IN(sz,fnsuffix,instr)
-
-DECLARE_IO(char,b,"b")
-DECLARE_IO(short,w,"")
-DECLARE_IO(int,l,"")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
+ * We need PC style IO addressing for:
+ * - floppy (at 0x3f2,0x3f4,0x3f5,0x3f7)
+ * - parport (at 0x278-0x27a, 0x27b-0x27f, 0x778-0x77a)
+ * - 8250 serial (only for compile)
*
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
+ * These peripherals are found in an area of MMIO which looks very much
+ * like an ISA bus, but with registers at the low byte of each word.
*/
-#define __outbc(value,port) \
-({ \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "strb %0, [%1, %2] @ outbc" \
- : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
- else \
- __asm__ __volatile__( \
- "strb %0, [%1, %2] @ outbc" \
- : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \
-})
-
-#define __inbc(port) \
-({ \
- unsigned char result; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "ldrb %0, [%1, %2] @ inbc" \
- : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
- else \
- __asm__ __volatile__( \
- "ldrb %0, [%1, %2] @ inbc" \
- : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
- result; \
-})
-
-#define __outwc(value,port) \
-({ \
- unsigned long __v = value; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "str %0, [%1, %2] @ outwc" \
- : : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
- else \
- __asm__ __volatile__( \
- "str %0, [%1, %2] @ outwc" \
- : : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2)); \
-})
-
-#define __inwc(port) \
-({ \
- unsigned short result; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "ldr %0, [%1, %2] @ inwc" \
- : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
- else \
- __asm__ __volatile__( \
- "ldr %0, [%1, %2] @ inwc" \
- : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
- result & 0xffff; \
-})
-
-#define __outlc(value,port) \
-({ \
- unsigned long __v = value; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "str %0, [%1, %2] @ outlc" \
- : : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
- else \
- __asm__ __volatile__( \
- "str %0, [%1, %2] @ outlc" \
- : : "r" (__v), "r" (IO_BASE), "r" ((port) << 2)); \
-})
-
-#define __inlc(port) \
-({ \
- unsigned long result; \
- if (__PORT_PCIO((port))) \
- __asm__ __volatile__( \
- "ldr %0, [%1, %2] @ inlc" \
- : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
- else \
- __asm__ __volatile__( \
- "ldr %0, [%1, %2] @ inlc" \
- : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
- result; \
-})
-
-#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
-#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
-#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))
-#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
-#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
-#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
-
-/* the following macro is deprecated */
-#define ioaddr(port) ((unsigned long)__ioaddr((port)))
-
-#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
-#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
-
-#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l)
-#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)
+#define __io(a) (PCIO_BASE + ((a) << 2))
/*
* 1:1 mapping for ioremapped regions.
.length = IO_SIZE ,
.type = MT_DEVICE
}, { /* EASI space */
- .virtual = EASI_BASE,
+ .virtual = (unsigned long)EASI_BASE,
.pfn = __phys_to_pfn(EASI_START),
.length = EASI_SIZE,
.type = MT_DEVICE
ifeq ($(CONFIG_PM_H1940),y)
- zreladdr-y := 0x30108000
+ zreladdr-y += 0x30108000
params_phys-y := 0x30100100
else
- zreladdr-y := 0x30008000
+ zreladdr-y += 0x30008000
params_phys-y := 0x30000100
endif
* published by the Free Software Foundation.
*/
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
/* some boards require extra gpio capacity to support external
* devices that need GPIO.
*/
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#endif
-#include <asm-generic/gpio.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio-fns.h>
#ifndef __ASM_ARCH_H1940_LATCH_H
#define __ASM_ARCH_H1940_LATCH_H
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#define H1940_LATCH_GPIO(x) (S3C_GPIO_END + (x))
#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p))
-/* the following macro is deprecated */
-#define ioaddr(port) __ioaddr((port))
#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
- zreladdr-y := 0x50008000
+ zreladdr-y += 0x50008000
params_phys-y := 0x50000100
* published by the Free Software Foundation.
*/
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
/* GPIO bank sizes */
#define S3C64XX_GPIO_A_NR (8)
#define S3C64XX_GPIO_B_NR (7)
#define BOARD_NR_GPIOS 16
#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS)
-
-#include <asm-generic/gpio.h>
#include <linux/suspend.h>
#include <linux/serial_core.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <mach/map.h>
#include <mach/irqs.h>
- zreladdr-y := 0x20008000
+ zreladdr-y += 0x20008000
params_phys-y := 0x20000100
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H __FILE__
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
/* GPIO bank sizes */
#define S5P6440_GPIO_A_NR (6)
#define ARCH_NR_GPIOS (S5P64X0_GPIO_END + CONFIG_SAMSUNG_GPIO_EXTRA)
-#include <asm-generic/gpio.h>
-
#endif /* __ASM_ARCH_GPIO_H */
}
ct = gc->chip_types;
- ct->chip.irq_ack = irq_gc_ack;
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
- zreladdr-y := 0x20008000
+ zreladdr-y += 0x20008000
params_phys-y := 0x20000100
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H __FILE__
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
/* GPIO bank sizes */
#define S5PC100_GPIO_A0_NR (8)
#define S5PC100_GPIO_A1_NR (5)
/* define the number of gpios we need to the one after the MP04() range */
#define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1)
-#include <asm-generic/gpio.h>
-
#endif /* __ASM_ARCH_GPIO_H */
- zreladdr-y := 0x20008000
+ zreladdr-y += 0x20008000
params_phys-y := 0x20000100
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H __FILE__
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
/* Practically, GPIO banks up to MP03 are the configurable gpio banks */
/* GPIO bank sizes */
#define ARCH_NR_GPIOS (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + \
CONFIG_SAMSUNG_GPIO_EXTRA + 1)
-#include <asm-generic/gpio.h>
-
#endif /* __ASM_ARCH_GPIO_H */
SAVE_ITEM(S3C2410_TCNTO(0)),
};
-void s5pv210_cpu_suspend(unsigned long arg)
+static int s5pv210_cpu_suspend(unsigned long arg)
{
unsigned long tmp;
#
# Common support
-obj-y := clock.o generic.o gpio.o irq.o dma.o time.o #nmi-oopser.o
+obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_SA1100_SHANNON) += shannon.o
obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
-led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
# LEDs support
obj-$(CONFIG_LEDS) += $(led-y)
- zreladdr-y := 0xc0008000
ifeq ($(CONFIG_ARCH_SA1100),y)
- zreladdr-$(CONFIG_SA1111) := 0xc0208000
+ zreladdr-$(CONFIG_SA1111) += 0xc0208000
+else
+ zreladdr-y += 0xc0008000
endif
params_phys-y := 0xc0000100
initrd_phys-y := 0xc0800000
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/irq.h>
-#include <asm/gpio.h>
#include "generic.h"
#include <asm/irq.h>
#include <asm-generic/gpio.h>
+#define __ARM_GPIOLIB_COMPLEX
+
static inline int gpio_get_value(unsigned gpio)
{
if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
#define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
(IRQ_GPIO11 - 11 + gpio))
-#define irq_to_gpio(irq) ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \
- (irq - IRQ_GPIO11 + 11))
#endif
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define IO_SPACE_LIMIT 0xffffffff
-
/*
- * We don't actually have real ISA nor PCI buses, but there is so many
- * drivers out there that might just work if we fake them...
+ * __io() is required to be an equivalent mapping to __mem_pci() for
+ * SOC_COMMON to work.
*/
#define __io(a) __typesafe_io(a)
#define __mem_pci(a) (a)
#define GPIO_SMART_CARD GPIO_GPIO10
#define IRQ_GPIO_SMARD_CARD IRQ_GPIO10
-// CS3 Latch is write only, a shadow is necessary
+/*--- ucb1x00 GPIO ---*/
+#define SIMPAD_UCB1X00_GPIO_BASE (GPIO_MAX + 1)
+#define SIMPAD_UCB1X00_GPIO_PROG1 (SIMPAD_UCB1X00_GPIO_BASE)
+#define SIMPAD_UCB1X00_GPIO_PROG2 (SIMPAD_UCB1X00_GPIO_BASE + 1)
+#define SIMPAD_UCB1X00_GPIO_UP (SIMPAD_UCB1X00_GPIO_BASE + 2)
+#define SIMPAD_UCB1X00_GPIO_DOWN (SIMPAD_UCB1X00_GPIO_BASE + 3)
+#define SIMPAD_UCB1X00_GPIO_LEFT (SIMPAD_UCB1X00_GPIO_BASE + 4)
+#define SIMPAD_UCB1X00_GPIO_RIGHT (SIMPAD_UCB1X00_GPIO_BASE + 5)
+#define SIMPAD_UCB1X00_GPIO_6 (SIMPAD_UCB1X00_GPIO_BASE + 6)
+#define SIMPAD_UCB1X00_GPIO_7 (SIMPAD_UCB1X00_GPIO_BASE + 7)
+#define SIMPAD_UCB1X00_GPIO_HEADSET (SIMPAD_UCB1X00_GPIO_BASE + 8)
+#define SIMPAD_UCB1X00_GPIO_SPEAKER (SIMPAD_UCB1X00_GPIO_BASE + 9)
+
+/*--- CS3 Latch ---*/
+#define SIMPAD_CS3_GPIO_BASE (GPIO_MAX + 11)
+#define SIMPAD_CS3_VCC_5V_EN (SIMPAD_CS3_GPIO_BASE)
+#define SIMPAD_CS3_VCC_3V_EN (SIMPAD_CS3_GPIO_BASE + 1)
+#define SIMPAD_CS3_EN1 (SIMPAD_CS3_GPIO_BASE + 2)
+#define SIMPAD_CS3_EN0 (SIMPAD_CS3_GPIO_BASE + 3)
+#define SIMPAD_CS3_DISPLAY_ON (SIMPAD_CS3_GPIO_BASE + 4)
+#define SIMPAD_CS3_PCMCIA_BUFF_DIS (SIMPAD_CS3_GPIO_BASE + 5)
+#define SIMPAD_CS3_MQ_RESET (SIMPAD_CS3_GPIO_BASE + 6)
+#define SIMPAD_CS3_PCMCIA_RESET (SIMPAD_CS3_GPIO_BASE + 7)
+#define SIMPAD_CS3_DECT_POWER_ON (SIMPAD_CS3_GPIO_BASE + 8)
+#define SIMPAD_CS3_IRDA_SD (SIMPAD_CS3_GPIO_BASE + 9)
+#define SIMPAD_CS3_RS232_ON (SIMPAD_CS3_GPIO_BASE + 10)
+#define SIMPAD_CS3_SD_MEDIAQ (SIMPAD_CS3_GPIO_BASE + 11)
+#define SIMPAD_CS3_LED2_ON (SIMPAD_CS3_GPIO_BASE + 12)
+#define SIMPAD_CS3_IRDA_MODE (SIMPAD_CS3_GPIO_BASE + 13)
+#define SIMPAD_CS3_ENABLE_5V (SIMPAD_CS3_GPIO_BASE + 14)
+#define SIMPAD_CS3_RESET_SIMCARD (SIMPAD_CS3_GPIO_BASE + 15)
+
+#define SIMPAD_CS3_PCMCIA_BVD1 (SIMPAD_CS3_GPIO_BASE + 16)
+#define SIMPAD_CS3_PCMCIA_BVD2 (SIMPAD_CS3_GPIO_BASE + 17)
+#define SIMPAD_CS3_PCMCIA_VS1 (SIMPAD_CS3_GPIO_BASE + 18)
+#define SIMPAD_CS3_PCMCIA_VS2 (SIMPAD_CS3_GPIO_BASE + 19)
+#define SIMPAD_CS3_LOCK_IND (SIMPAD_CS3_GPIO_BASE + 20)
+#define SIMPAD_CS3_CHARGING_STATE (SIMPAD_CS3_GPIO_BASE + 21)
+#define SIMPAD_CS3_PCMCIA_SHORT (SIMPAD_CS3_GPIO_BASE + 22)
+#define SIMPAD_CS3_GPIO_23 (SIMPAD_CS3_GPIO_BASE + 23)
-#define CS3BUSTYPE unsigned volatile long
#define CS3_BASE 0xf1000000
-#define VCC_5V_EN 0x0001 // For 5V PCMCIA
-#define VCC_3V_EN 0x0002 // FOR 3.3V PCMCIA
-#define EN1 0x0004 // This is only for EPROM's
-#define EN0 0x0008 // Both should be enable for 3.3V or 5V
-#define DISPLAY_ON 0x0010
-#define PCMCIA_BUFF_DIS 0x0020
-#define MQ_RESET 0x0040
-#define PCMCIA_RESET 0x0080
-#define DECT_POWER_ON 0x0100
-#define IRDA_SD 0x0200 // Shutdown for powersave
-#define RS232_ON 0x0400
-#define SD_MEDIAQ 0x0800 // Shutdown for powersave
-#define LED2_ON 0x1000
-#define IRDA_MODE 0x2000 // Fast/Slow IrDA mode
-#define ENABLE_5V 0x4000 // Enable 5V circuit
-#define RESET_SIMCARD 0x8000
-
-#define RS232_ENABLE 0x0440
-#define PCMCIAMASK 0x402f
-
-
+long simpad_get_cs3_ro(void);
+long simpad_get_cs3_shadow(void);
+void simpad_set_cs3_bit(int value);
+void simpad_clear_cs3_bit(int value);
+
+#define VCC_5V_EN 0x0001 /* For 5V PCMCIA */
+#define VCC_3V_EN 0x0002 /* FOR 3.3V PCMCIA */
+#define EN1 0x0004 /* This is only for EPROM's */
+#define EN0 0x0008 /* Both should be enable for 3.3V or 5V */
+#define DISPLAY_ON 0x0010
+#define PCMCIA_BUFF_DIS 0x0020
+#define MQ_RESET 0x0040
+#define PCMCIA_RESET 0x0080
+#define DECT_POWER_ON 0x0100
+#define IRDA_SD 0x0200 /* Shutdown for powersave */
+#define RS232_ON 0x0400
+#define SD_MEDIAQ 0x0800 /* Shutdown for powersave */
+#define LED2_ON 0x1000
+#define IRDA_MODE 0x2000 /* Fast/Slow IrDA mode */
+#define ENABLE_5V 0x4000 /* Enable 5V circuit */
+#define RESET_SIMCARD 0x8000
+
+#define PCMCIA_BVD1 0x01
+#define PCMCIA_BVD2 0x02
+#define PCMCIA_VS1 0x04
+#define PCMCIA_VS2 0x08
+#define LOCK_IND 0x10
+#define CHARGING_STATE 0x20
+#define PCMCIA_SHORT 0x40
+
+/*--- Battery ---*/
struct simpad_battery {
unsigned char ac_status; /* line connected yes/no */
unsigned char status; /* battery loading yes/no */
+++ /dev/null
-/*
- * linux/arch/arm/mach-sa1100/leds-simpad.c
- *
- * Author: Juergen Messerer <juergen.messerer@siemens.ch>
- */
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <asm/system.h>
-#include <mach/simpad.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED 1
-#define LED_STATE_CLAIMED 2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-#define LED_GREEN (1)
-#define LED_MASK (1)
-
-extern void set_cs3_bit(int value);
-extern void clear_cs3_bit(int value);
-
-void simpad_leds_event(led_event_t evt)
-{
- switch (evt)
- {
- case led_start:
- hw_led_state = LED_GREEN;
- led_state = LED_STATE_ENABLED;
- break;
-
- case led_stop:
- led_state &= ~LED_STATE_ENABLED;
- break;
-
- case led_claim:
- led_state |= LED_STATE_CLAIMED;
- hw_led_state = LED_GREEN;
- break;
-
- case led_release:
- led_state &= ~LED_STATE_CLAIMED;
- hw_led_state = LED_GREEN;
- break;
-
-#ifdef CONFIG_LEDS_TIMER
- case led_timer:
- if (!(led_state & LED_STATE_CLAIMED))
- hw_led_state ^= LED_GREEN;
- break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
- case led_idle_start:
- break;
-
- case led_idle_end:
- break;
-#endif
-
- case led_halted:
- break;
-
- case led_green_on:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state |= LED_GREEN;
- break;
-
- case led_green_off:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state &= ~LED_GREEN;
- break;
-
- case led_amber_on:
- break;
-
- case led_amber_off:
- break;
-
- case led_red_on:
- break;
-
- case led_red_off:
- break;
-
- default:
- break;
- }
-
- if (led_state & LED_STATE_ENABLED)
- set_cs3_bit(LED2_ON);
- else
- clear_cs3_bit(LED2_ON);
-}
-
leds_event = adsbitsy_leds_event;
if (machine_is_pt_system3())
leds_event = system3_leds_event;
- if (machine_is_simpad())
- leds_event = simpad_leds_event; /* what about machine registry? including led, apm... -zecke */
leds_event(led_start);
return 0;
extern void graphicsmaster_leds_event(led_event_t evt);
extern void adsbitsy_leds_event(led_event_t evt);
extern void system3_leds_event(led_event_t evt);
-extern void simpad_leds_event(led_event_t evt);
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/serial_core.h>
#include <linux/ioport.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <linux/i2c-gpio.h>
#include "generic.h"
-long cs3_shadow;
+/*
+ * CS3 support
+ */
-long get_cs3_shadow(void)
+static long cs3_shadow;
+static spinlock_t cs3_lock;
+static struct gpio_chip cs3_gpio;
+
+long simpad_get_cs3_ro(void)
+{
+ return readl(CS3_BASE);
+}
+EXPORT_SYMBOL(simpad_get_cs3_ro);
+
+long simpad_get_cs3_shadow(void)
{
return cs3_shadow;
}
+EXPORT_SYMBOL(simpad_get_cs3_shadow);
-void set_cs3(long value)
+static void __simpad_write_cs3(void)
{
- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
+ writel(cs3_shadow, CS3_BASE);
}
-void set_cs3_bit(int value)
+void simpad_set_cs3_bit(int value)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cs3_lock, flags);
cs3_shadow |= value;
- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ __simpad_write_cs3();
+ spin_unlock_irqrestore(&cs3_lock, flags);
}
+EXPORT_SYMBOL(simpad_set_cs3_bit);
-void clear_cs3_bit(int value)
+void simpad_clear_cs3_bit(int value)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cs3_lock, flags);
cs3_shadow &= ~value;
- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ __simpad_write_cs3();
+ spin_unlock_irqrestore(&cs3_lock, flags);
}
+EXPORT_SYMBOL(simpad_clear_cs3_bit);
+
+static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ if (offset > 15)
+ return;
+ if (value)
+ simpad_set_cs3_bit(1 << offset);
+ else
+ simpad_clear_cs3_bit(1 << offset);
+};
+
+static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset > 15)
+ return simpad_get_cs3_ro() & (1 << (offset - 16));
+ return simpad_get_cs3_shadow() & (1 << offset);
+};
-EXPORT_SYMBOL(set_cs3_bit);
-EXPORT_SYMBOL(clear_cs3_bit);
+static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset > 15)
+ return 0;
+ return -EINVAL;
+};
+
+static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ if (offset > 15)
+ return -EINVAL;
+ cs3_gpio_set(chip, offset, value);
+ return 0;
+};
static struct map_desc simpad_io_desc[] __initdata = {
{ /* MQ200 */
.pfn = __phys_to_pfn(0x4b800000),
.length = 0x00800000,
.type = MT_DEVICE
- }, { /* Paules CS3, write only */
- .virtual = 0xf1000000,
- .pfn = __phys_to_pfn(0x18000000),
+ }, { /* Simpad CS3 */
+ .virtual = CS3_BASE,
+ .pfn = __phys_to_pfn(SA1100_CS3_PHYS),
.length = 0x00100000,
.type = MT_DEVICE
},
if (port->mapbase == (u_int)&Ser1UTCR0) {
if (state)
{
- clear_cs3_bit(RS232_ON);
- clear_cs3_bit(DECT_POWER_ON);
+ simpad_clear_cs3_bit(RS232_ON);
+ simpad_clear_cs3_bit(DECT_POWER_ON);
}else
{
- set_cs3_bit(RS232_ON);
- set_cs3_bit(DECT_POWER_ON);
+ simpad_set_cs3_bit(RS232_ON);
+ simpad_set_cs3_bit(DECT_POWER_ON);
}
}
}
static struct mcp_plat_data simpad_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
+ .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
};
iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
- set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
- ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
-
+ /* Initialize CS3 */
+ cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON |
+ RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+ __simpad_write_cs3(); /* Spinlocks not yet initialized */
sa1100_register_uart_fns(&simpad_port_fns);
sa1100_register_uart(0, 3); /* serial interface */
static void simpad_power_off(void)
{
- local_irq_disable(); // was cli
- set_cs3(0x800); /* only SD_MEDIAQ */
+ local_irq_disable();
+ cs3_shadow = SD_MEDIAQ;
+ __simpad_write_cs3(); /* Bypass spinlock here */
/* disable internal oscillator, float CS lines */
PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
- /* enable wake-up on GPIO0 (Assabet...) */
- PWER = GFER = GRER = 1;
+ /* enable wake-up on GPIO0 */
+ PWER = GFER = GRER = PWER_GPIO0;
/*
* set scratchpad to zero, just in case it is used as a
* restart address by the bootloader.
}
+/*
+ * gpio_keys
+*/
+
+static struct gpio_keys_button simpad_button_table[] = {
+ { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
+};
+
+static struct gpio_keys_platform_data simpad_keys_data = {
+ .buttons = simpad_button_table,
+ .nbuttons = ARRAY_SIZE(simpad_button_table),
+};
+
+static struct platform_device simpad_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &simpad_keys_data,
+ },
+};
+
+static struct gpio_keys_button simpad_polled_button_table[] = {
+ { KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" },
+ { KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" },
+ { KEY_UP, SIMPAD_UCB1X00_GPIO_UP, 1, "up button" },
+ { KEY_DOWN, SIMPAD_UCB1X00_GPIO_DOWN, 1, "down button" },
+ { KEY_LEFT, SIMPAD_UCB1X00_GPIO_LEFT, 1, "left button" },
+ { KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" },
+};
+
+static struct gpio_keys_platform_data simpad_polled_keys_data = {
+ .buttons = simpad_polled_button_table,
+ .nbuttons = ARRAY_SIZE(simpad_polled_button_table),
+ .poll_interval = 50,
+};
+
+static struct platform_device simpad_polled_keys = {
+ .name = "gpio-keys-polled",
+ .dev = {
+ .platform_data = &simpad_polled_keys_data,
+ },
+};
+
+/*
+ * GPIO LEDs
+ */
+
+static struct gpio_led simpad_leds[] = {
+ {
+ .name = "simpad:power",
+ .gpio = SIMPAD_CS3_LED2_ON,
+ .active_low = 0,
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led_platform_data simpad_led_data = {
+ .num_leds = ARRAY_SIZE(simpad_leds),
+ .leds = simpad_leds,
+};
+
+static struct platform_device simpad_gpio_leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &simpad_led_data,
+ },
+};
+
+/*
+ * i2c
+ */
+static struct i2c_gpio_platform_data simpad_i2c_data = {
+ .sda_pin = GPIO_GPIO21,
+ .scl_pin = GPIO_GPIO25,
+ .udelay = 10,
+ .timeout = HZ,
+};
+
+static struct platform_device simpad_i2c = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &simpad_i2c_data,
+ },
+};
/*
* MediaQ Video Device
};
static struct platform_device *devices[] __initdata = {
- &simpad_mq200fb
+ &simpad_keys,
+ &simpad_polled_keys,
+ &simpad_mq200fb,
+ &simpad_gpio_leds,
+ &simpad_i2c,
};
{
int ret;
+ spin_lock_init(&cs3_lock);
+
+ cs3_gpio.label = "simpad_cs3";
+ cs3_gpio.base = SIMPAD_CS3_GPIO_BASE;
+ cs3_gpio.ngpio = 24;
+ cs3_gpio.set = cs3_gpio_set;
+ cs3_gpio.get = cs3_gpio_get;
+ cs3_gpio.direction_input = cs3_gpio_direction_input;
+ cs3_gpio.direction_output = cs3_gpio_direction_output;
+ ret = gpiochip_add(&cs3_gpio);
+ if (ret)
+ printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
+
pm_power_off = simpad_power_off;
sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
- zreladdr-y := 0x08008000
+ zreladdr-y += 0x08008000
__ZRELADDR := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_MEMORY_START) + 0x8000]')
- zreladdr-y := $(__ZRELADDR)
+ zreladdr-y += $(__ZRELADDR)
# Unsupported legacy stuff
#
static struct sh_mobile_sdhi_info sdhi0_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
+ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
.tmio_caps = MMC_CAP_SD_HIGHSPEED,
.tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
};
}
static struct sh_mobile_sdhi_info sh_sdhi1_info = {
- .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
.tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
.tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.set_pwr = ag5evm_sdhi1_set_pwr,
},
.driver_param = {
.buswait_bwait = 4,
+ .d0_tx_id = SHDMA_SLAVE_USB0_TX,
+ .d1_rx_id = SHDMA_SLAVE_USB0_RX,
},
},
};
.buswait_bwait = 4,
.pipe_type = usbhs1_pipe_cfg,
.pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg),
+ .d0_tx_id = SHDMA_SLAVE_USB1_TX,
+ .d1_rx_id = SHDMA_SLAVE_USB1_RX,
},
},
};
&sh7372_fsidivb_clk,
};
-enum { MSTP001,
+enum { MSTP001, MSTP000,
MSTP131, MSTP130,
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
MSTP118, MSTP117, MSTP116, MSTP113,
MSTP106, MSTP101, MSTP100,
MSTP223,
- MSTP218, MSTP217, MSTP216,
- MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
- MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
- MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
+ MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
+ MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
+ MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
+ MSTP405, MSTP404, MSTP403, MSTP400,
MSTP_NR };
#define MSTP(_parent, _reg, _bit, _flags) \
static struct clk mstp_clks[MSTP_NR] = {
[MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */
[MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
[MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
[MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
[MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
+ [MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
+ [MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */
[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */
[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
- [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
[MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
[MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
[MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
+ [MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
[MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
+ [MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
+ [MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+ [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
};
static struct clk_lookup lookups[] = {
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
+ CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
+ CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
- CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
+ CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
+ CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
+ CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+ CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
&div6_reparent_clks[DIV6_HDMI]),
__raw_writel(0x108, SD2CKCR);
/* detect main clock parent */
- switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
+ switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
case 0:
main_clk.parent = &sh73a0_extal1_clk;
break;
#ifdef CONFIG_GPIOLIB
-static inline int gpio_get_value(unsigned gpio)
-{
- return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
- return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
- return __gpio_to_irq(gpio);
-}
-
static inline int irq_to_gpio(unsigned int irq)
{
return -ENOSYS;
}
+#else
+
+#define __ARM_GPIOLIB_COMPLEX
+
#endif /* CONFIG_GPIOLIB */
#endif /* __ASM_ARCH_GPIO_H */
SHDMA_SLAVE_SDHI2_TX,
SHDMA_SLAVE_MMCIF_RX,
SHDMA_SLAVE_MMCIF_TX,
+ SHDMA_SLAVE_USB0_TX,
+ SHDMA_SLAVE_USB0_RX,
+ SHDMA_SLAVE_USB1_TX,
+ SHDMA_SLAVE_USB1_RX,
};
extern struct clk sh7372_extal1_clk;
/* BBIF2 */
VPU,
TSIF1,
- _3DG_SGX530,
+ /* 3DG */
_2DDMAC,
IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
IPMMU_IPMMUR, IPMMU_IPMMUR2,
/* BBIF2 */
INTCS_VECT(VPU, 0x980),
INTCS_VECT(TSIF1, 0x9a0),
- INTCS_VECT(_3DG_SGX530, 0x9e0),
+ /* 3DG */
INTCS_VECT(_2DDMAC, 0xa00),
INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
{ 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
{ 0, 0, MSIOF, 0,
- _3DG_SGX530, 0, 0, 0 } },
+ 0, 0, 0, 0 } },
{ 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
{ 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
0, 0, 0, 0 } },
TMU_TUNI2, TSIF1 } },
{ 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } },
{ 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } },
- { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } },
{ 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } },
{ 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } },
{ 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
};
/* CMT */
-static struct sh_timer_config cmt10_platform_data = {
- .name = "CMT10",
- .channel_offset = 0x10,
- .timer_bit = 0,
+static struct sh_timer_config cmt2_platform_data = {
+ .name = "CMT2",
+ .channel_offset = 0x40,
+ .timer_bit = 5,
.clockevent_rating = 125,
.clocksource_rating = 125,
};
-static struct resource cmt10_resources[] = {
+static struct resource cmt2_resources[] = {
[0] = {
- .name = "CMT10",
- .start = 0xe6138010,
- .end = 0xe613801b,
+ .name = "CMT2",
+ .start = 0xe6130040,
+ .end = 0xe613004b,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = evt2irq(0x0b00), /* CMT1_CMT10 */
+ .start = evt2irq(0x0b80), /* CMT2 */
.flags = IORESOURCE_IRQ,
},
};
-static struct platform_device cmt10_device = {
+static struct platform_device cmt2_device = {
.name = "sh_cmt",
- .id = 10,
+ .id = 2,
.dev = {
- .platform_data = &cmt10_platform_data,
+ .platform_data = &cmt2_platform_data,
},
- .resource = cmt10_resources,
- .num_resources = ARRAY_SIZE(cmt10_resources),
+ .resource = cmt2_resources,
+ .num_resources = ARRAY_SIZE(cmt2_resources),
};
/* TMU */
},
};
+/*
+ * USB-DMAC
+ */
+
+unsigned int usbts_shift[] = {3, 4, 5};
+
+enum {
+ XMIT_SZ_8BYTE = 0,
+ XMIT_SZ_16BYTE = 1,
+ XMIT_SZ_32BYTE = 2,
+};
+
+#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
+
+static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = {
+ {
+ .offset = 0,
+ }, {
+ .offset = 0x20,
+ },
+};
+
+/* USB DMAC0 */
+static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_USB0_TX,
+ .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ }, {
+ .slave_id = SHDMA_SLAVE_USB0_RX,
+ .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ },
+};
+
+static struct sh_dmae_pdata usb_dma0_platform_data = {
+ .slave = sh7372_usb_dmae0_slaves,
+ .slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves),
+ .channel = sh7372_usb_dmae_channels,
+ .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels),
+ .ts_low_shift = 6,
+ .ts_low_mask = 0xc0,
+ .ts_high_shift = 0,
+ .ts_high_mask = 0,
+ .ts_shift = usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(usbts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chcr_offset = 0x14,
+ .chcr_ie_bit = 1 << 5,
+ .dmaor_is_32bit = 1,
+ .needs_tend_set = 1,
+ .no_dmars = 1,
+};
+
+static struct resource sh7372_usb_dmae0_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xe68a0020,
+ .end = 0xe68a0064 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VCR/SWR/DMICR */
+ .start = 0xe68a0000,
+ .end = 0xe68a0014 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* IRQ for channels */
+ .start = evt2irq(0x0a00),
+ .end = evt2irq(0x0a00),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 3,
+ .resource = sh7372_usb_dmae0_resources,
+ .num_resources = ARRAY_SIZE(sh7372_usb_dmae0_resources),
+ .dev = {
+ .platform_data = &usb_dma0_platform_data,
+ },
+};
+
+/* USB DMAC1 */
+static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_USB1_TX,
+ .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ }, {
+ .slave_id = SHDMA_SLAVE_USB1_RX,
+ .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ },
+};
+
+static struct sh_dmae_pdata usb_dma1_platform_data = {
+ .slave = sh7372_usb_dmae1_slaves,
+ .slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves),
+ .channel = sh7372_usb_dmae_channels,
+ .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels),
+ .ts_low_shift = 6,
+ .ts_low_mask = 0xc0,
+ .ts_high_shift = 0,
+ .ts_high_mask = 0,
+ .ts_shift = usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(usbts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chcr_offset = 0x14,
+ .chcr_ie_bit = 1 << 5,
+ .dmaor_is_32bit = 1,
+ .needs_tend_set = 1,
+ .no_dmars = 1,
+};
+
+static struct resource sh7372_usb_dmae1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xe68c0020,
+ .end = 0xe68c0064 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VCR/SWR/DMICR */
+ .start = 0xe68c0000,
+ .end = 0xe68c0014 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* IRQ for channels */
+ .start = evt2irq(0x1d00),
+ .end = evt2irq(0x1d00),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 4,
+ .resource = sh7372_usb_dmae1_resources,
+ .num_resources = ARRAY_SIZE(sh7372_usb_dmae1_resources),
+ .dev = {
+ .platform_data = &usb_dma1_platform_data,
+ },
+};
+
/* VPU */
static struct uio_info vpu_platform_data = {
.name = "VPU5HG",
&scif4_device,
&scif5_device,
&scif6_device,
- &cmt10_device,
+ &cmt2_device,
&tmu00_device,
&tmu01_device,
};
&dma0_device,
&dma1_device,
&dma2_device,
+ &usb_dma0_device,
+ &usb_dma1_device,
&vpu_device,
&veu0_device,
&veu1_device,
-zreladdr-y := 0x00008000
+zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
-zreladdr-y := 0x00008000
+zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
- zreladdr-y := 0x20008000
+ zreladdr-y += 0x20008000
params_phys-y := 0x20000100
initrd_phys-y := 0x20800000
-zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000
+zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) += 0x00008000
params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
* GNU General Public License for more details.
*
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <mach/pinmux.h>
-#include <mach/gpio.h>
#include "gpio-names.h"
#include "board-trimslice.h"
#ifndef __MACH_TEGRA_GPIO_H
#define __MACH_TEGRA_GPIO_H
-#include <linux/init.h>
+#include <linux/types.h>
#include <mach/irqs.h>
#define TEGRA_NR_GPIOS INT_GPIO_NR
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-
#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
-#define TEGRA_IRQ_TO_GPIO(irq) ((irq) - INT_GPIO_BASE)
-
-static inline int gpio_to_irq(unsigned int gpio)
-{
- if (gpio < TEGRA_NR_GPIOS)
- return INT_GPIO_BASE + gpio;
- return -EINVAL;
-}
-
-static inline int irq_to_gpio(unsigned int irq)
-{
- if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR))
- return irq - INT_GPIO_BASE;
- return -EINVAL;
-}
struct tegra_gpio_table {
int gpio; /* GPIO number */
config MACH_U300
bool "U300"
+ select GPIO_U300
comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
# INITRD_PHYS must be in RAM
ifdef CONFIG_MACH_U300_SINGLE_RAM
- zreladdr-y := 0x28E08000
+ zreladdr-y += 0x28E08000
params_phys-y := 0x28E00100
else
- zreladdr-y := 0x48008000
+ zreladdr-y += 0x48008000
params_phys-y := 0x48000100
endif
#include <mach/hardware.h>
#include <mach/syscon.h>
#include <mach/dma_channels.h>
+#include <mach/gpio-u300.h>
#include "clock.h"
#include "mmc.h"
.end = IRQ_U300_GPIO_PORT2,
.flags = IORESOURCE_IRQ,
},
-#ifdef U300_COH901571_3
+#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
{
.name = "gpio3",
.start = IRQ_U300_GPIO_PORT3,
.end = IRQ_U300_GPIO_PORT4,
.flags = IORESOURCE_IRQ,
},
+#endif
#ifdef CONFIG_MACH_U300_BS335
{
.name = "gpio5",
.flags = IORESOURCE_IRQ,
},
#endif /* CONFIG_MACH_U300_BS335 */
-#endif /* U300_COH901571_3 */
};
static struct resource keypad_resources[] = {
.resource = i2c1_resources,
};
+/*
+ * The different variants have a few different versions of the
+ * GPIO block, with different number of ports.
+ */
+static struct u300_gpio_platform u300_gpio_plat = {
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+ .variant = U300_GPIO_COH901335,
+ .ports = 3,
+#endif
+#ifdef CONFIG_MACH_U300_BS335
+ .variant = U300_GPIO_COH901571_3_BS335,
+ .ports = 7,
+#endif
+#ifdef CONFIG_MACH_U300_BS365
+ .variant = U300_GPIO_COH901571_3_BS365,
+ .ports = 5,
+#endif
+ .gpio_base = 0,
+ .gpio_irq_base = IRQ_U300_GPIO_BASE,
+};
+
static struct platform_device gpio_device = {
.name = "u300-gpio",
.id = -1,
.num_resources = ARRAY_SIZE(gpio_resources),
.resource = gpio_resources,
+ .dev = {
+ .platform_data = &u300_gpio_plat,
+ },
};
static struct platform_device keypad_device = {
BUG_ON(IS_ERR(clk));
clk_enable(clk);
- for (i = 0; i < NR_IRQS; i++)
+ for (i = 0; i < U300_VIC_IRQS_END; i++)
set_bit(i, (unsigned long *) &mask[0]);
vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]);
vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]);
--- /dev/null
+/*
+ * Copyright (C) 2007-2011 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * GPIO block resgister definitions and inline macros for
+ * U300 GPIO COH 901 335 or COH 901 571/3
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_U300_GPIO_U300_H
+#define __MACH_U300_GPIO_U300_H
+
+/*
+ * Individual pin assignments for the B26/S26. Notice that the
+ * actual usage of these pins depends on the PAD MUX settings, that
+ * is why the same number can potentially appear several times.
+ * In the reference design each pin is only used for one purpose.
+ * These were determined by inspecting the B26/S26 schematic:
+ * 2/1911-ROA 128 1603
+ */
+#ifdef CONFIG_MACH_U300_BS2X
+#define U300_GPIO_PIN_UART_RX 0
+#define U300_GPIO_PIN_UART_TX 1
+#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
+#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
+#define U300_GPIO_PIN_CAM_SLEEP 4
+#define U300_GPIO_PIN_CAM_REG_EN 5
+#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
+#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
+#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
+#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
+#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
+#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
+#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
+#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
+#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
+#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
+#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
+#endif
+
+/*
+ * Individual pin assignments for the B330/S330 and B365/S365.
+ * Notice that the actual usage of these pins depends on the
+ * PAD MUX settings, that is why the same number can potentially
+ * appear several times. In the reference design each pin is only
+ * used for one purpose. These were determined by inspecting the
+ * S365 schematic.
+ */
+#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
+ defined(CONFIG_MACH_U300_BS335)
+#define U300_GPIO_PIN_UART_RX 0
+#define U300_GPIO_PIN_UART_TX 1
+#define U300_GPIO_PIN_UART_CTS 2
+#define U300_GPIO_PIN_UART_RTS 3
+#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
+#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
+#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
+#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
+
+#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
+#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
+#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
+#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
+#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
+#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
+#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
+#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
+#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
+#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
+#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
+#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
+#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
+#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
+#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
+#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
+#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
+#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
+#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
+#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
+#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
+#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
+#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
+#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
+
+#ifdef CONFIG_MACH_U300_BS335
+
+#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
+#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
+#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
+#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
+#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
+#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
+#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
+#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
+#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
+#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
+#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
+#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
+#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
+#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
+#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
+#endif
+
+#endif
+
+/**
+ * enum u300_gpio_variant - the type of U300 GPIO employed
+ */
+enum u300_gpio_variant {
+ U300_GPIO_COH901335,
+ U300_GPIO_COH901571_3_BS335,
+ U300_GPIO_COH901571_3_BS365,
+};
+
+/**
+ * struct u300_gpio_platform - U300 GPIO platform data
+ * @variant: IP block variant
+ * @ports: number of GPIO block ports
+ * @gpio_base: first GPIO number for this block (use a free range)
+ * @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
+ */
+struct u300_gpio_platform {
+ enum u300_gpio_variant variant;
+ u8 ports;
+ int gpio_base;
+ int gpio_irq_base;
+};
+
+#endif /* __MACH_U300_GPIO_U300_H */
-/*
- *
- * arch/arm/mach-u300/include/mach/gpio.h
- *
- *
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * GPIO block resgister definitions and inline macros for
- * U300 GPIO COH 901 335 or COH 901 571/3
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-
-#ifndef __MACH_U300_GPIO_H
-#define __MACH_U300_GPIO_H
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-/* Switch type depending on platform/chip variant */
-#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
-#define U300_COH901335
-#endif
-#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
-#define U300_COH901571_3
-#endif
-
-/* Get base address for regs here */
-#include "u300-regs.h"
-/* IRQ numbers */
-#include "irqs.h"
-
-/*
- * This is the GPIO block definitions. GPIO (General Purpose I/O) can be
- * used for anything, and often is. The event/enable etc figures are for
- * the lowermost pin (pin 0 on each port), shift this left to match your
- * pin if you're gonna use these values.
- */
-#ifdef U300_COH901335
-#define U300_GPIO_PORTX_SPACING (0x1C)
-/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
-#define U300_GPIO_PXPDIR (0x00)
-#define U300_GPIO_PXPDOR (0x00)
-/* Port X Pin Config Register 32bit (R/W) */
-#define U300_GPIO_PXPCR (0x04)
-#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
-#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
-#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
-/* Port X Interrupt Event Register 32bit (R/W) */
-#define U300_GPIO_PXIEV (0x08)
-#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
-#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
-/* Port X Interrupt Enable Register 32bit (R/W) */
-#define U300_GPIO_PXIEN (0x0C)
-#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
-#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
-/* Port X Interrupt Force Register 32bit (R/W) */
-#define U300_GPIO_PXIFR (0x10)
-#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
-#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
-/* Port X Interrupt Config Register 32bit (R/W) */
-#define U300_GPIO_PXICR (0x14)
-#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
-/* Port X Pull-up Enable Register 32bit (R/W) */
-#define U300_GPIO_PXPER (0x18)
-#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
-#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
-/* Control Register 32bit (R/W) */
-#define U300_GPIO_CR (0x54)
-#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE (0x00000001UL)
-/* three ports of 8 bits each = GPIO pins 0..23 */
-#define U300_GPIO_NUM_PORTS 3
-#define U300_GPIO_PINS_PER_PORT 8
-#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
-#endif
-
-#ifdef U300_COH901571_3
-/*
- * Control Register 32bit (R/W)
- * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
- * gives the number of GPIO pins.
- * bit 8-2 (mask 0x000001FC) contains the core version ID.
- */
-#define U300_GPIO_CR (0x00)
-#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL)
-#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL)
-#define U300_GPIO_PORTX_SPACING (0x30)
-/* Port X Pin Data INPUT Register 32bit (R/W) */
-#define U300_GPIO_PXPDIR (0x04)
-/* Port X Pin Data OUTPUT Register 32bit (R/W) */
-#define U300_GPIO_PXPDOR (0x08)
-/* Port X Pin Config Register 32bit (R/W) */
-#define U300_GPIO_PXPCR (0x0C)
-#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
-#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
-#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
-/* Port X Pull-up Enable Register 32bit (R/W) */
-#define U300_GPIO_PXPER (0x10)
-#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
-#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
-/* Port X Interrupt Event Register 32bit (R/W) */
-#define U300_GPIO_PXIEV (0x14)
-#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
-#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
-/* Port X Interrupt Enable Register 32bit (R/W) */
-#define U300_GPIO_PXIEN (0x18)
-#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
-#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
-/* Port X Interrupt Force Register 32bit (R/W) */
-#define U300_GPIO_PXIFR (0x1C)
-#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
-#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
-/* Port X Interrupt Config Register 32bit (R/W) */
-#define U300_GPIO_PXICR (0x20)
-#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
-#ifdef CONFIG_MACH_U300_BS335
-/* seven ports of 8 bits each = GPIO pins 0..55 */
-#define U300_GPIO_NUM_PORTS 7
-#else
-/* five ports of 8 bits each = GPIO pins 0..39 */
-#define U300_GPIO_NUM_PORTS 5
-#endif
-#define U300_GPIO_PINS_PER_PORT 8
-#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
-#endif
-
-/*
- * Individual pin assignments for the B26/S26. Notice that the
- * actual usage of these pins depends on the PAD MUX settings, that
- * is why the same number can potentially appear several times.
- * In the reference design each pin is only used for one purpose.
- * These were determined by inspecting the B26/S26 schematic:
- * 2/1911-ROA 128 1603
- */
-#ifdef CONFIG_MACH_U300_BS2X
-#define U300_GPIO_PIN_UART_RX 0
-#define U300_GPIO_PIN_UART_TX 1
-#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
-#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
-#define U300_GPIO_PIN_CAM_SLEEP 4
-#define U300_GPIO_PIN_CAM_REG_EN 5
-#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
-#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
-#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
-#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
-#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
-#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
-#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
-#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
-#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
-#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
-#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
-#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
-#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
-#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
-#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
-#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
-#endif
-
-/*
- * Individual pin assignments for the B330/S330 and B365/S365.
- * Notice that the actual usage of these pins depends on the
- * PAD MUX settings, that is why the same number can potentially
- * appear several times. In the reference design each pin is only
- * used for one purpose. These were determined by inspecting the
- * S365 schematic.
- */
-#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
- defined(CONFIG_MACH_U300_BS335)
-#define U300_GPIO_PIN_UART_RX 0
-#define U300_GPIO_PIN_UART_TX 1
-#define U300_GPIO_PIN_UART_CTS 2
-#define U300_GPIO_PIN_UART_RTS 3
-#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
-#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
-#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
-#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
-
-#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
-#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
-#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
-#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
-#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
-#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
-#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
-#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
-#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
-#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
-#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
-#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
-#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
-#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
-#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
-#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
-#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
-#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
-#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
-#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
-#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
-#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
-#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
-#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
-#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
-#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
-#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
-#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
-#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
-
-#ifdef CONFIG_MACH_U300_BS335
-
-#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
-#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
-#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
-#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
-#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
-#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
-#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
-#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
-#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
-#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
-#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
-#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
-#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
-#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
-#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
-#endif
-
-#endif
-
-/* translates a pin number to a port number */
-#define PIN_TO_PORT(val) (val >> 3)
-
-/* These can be found in arch/arm/mach-u300/gpio.c */
-extern int gpio_is_valid(int number);
-extern int gpio_request(unsigned gpio, const char *label);
-extern void gpio_free(unsigned gpio);
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-extern int gpio_register_callback(unsigned gpio,
- int (*func)(void *arg),
- void *);
-extern int gpio_unregister_callback(unsigned gpio);
-extern void enable_irq_on_gpio_pin(unsigned gpio, int edge);
-extern void disable_irq_on_gpio_pin(unsigned gpio);
-extern void gpio_pullup(unsigned gpio, int value);
-extern int gpio_get_value(unsigned gpio);
-extern void gpio_set_value(unsigned gpio, int value);
-
-#define gpio_get_value_cansleep gpio_get_value
-#define gpio_set_value_cansleep gpio_set_value
-
-/* wrappers to sleep-enable the previous two functions */
-static inline unsigned gpio_to_irq(unsigned gpio)
-{
- return PIN_TO_PORT(gpio) + IRQ_U300_GPIO_PORT0;
-}
-
-static inline unsigned irq_to_gpio(unsigned irq)
-{
- /*
- * FIXME: This is no 1-1 mapping at all, it points to the
- * whole block of 8 pins.
- */
- return (irq - IRQ_U300_GPIO_PORT0) << 3;
-}
-
-#endif
/* DB3150 and DB3200 have only 45 IRQs */
#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
-#define U300_NR_IRQS 45
+#define U300_VIC_IRQS_END 45
#endif
/* The DB3350-specific interrupt lines */
#define IRQ_U300_GPIO_PORT4 53
#define IRQ_U300_GPIO_PORT5 54
#define IRQ_U300_GPIO_PORT6 55
-#define U300_NR_IRQS 56
+#define U300_VIC_IRQS_END 56
#endif
/* The DB3210-specific interrupt lines */
#define IRQ_U300_NFIF 45
#define IRQ_U300_NFIF2 46
#define IRQ_U300_SYSCON_PLL_LOCK 47
-#define U300_NR_IRQS 48
+#define U300_VIC_IRQS_END 48
#endif
-#ifdef CONFIG_AB3550_CORE
-#define IRQ_AB3550_BASE (U300_NR_IRQS)
-#define IRQ_AB3550_END (IRQ_AB3550_BASE + 37)
+/* Maximum 8*7 GPIO lines */
+#ifdef CONFIG_GPIO_U300
+#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END)
+#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56)
+#else
+#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END)
+#endif
-#define NR_IRQS (IRQ_AB3550_END + 1)
+/* Optional AB3550 mixsig chip */
+#ifdef CONFIG_AB3550_CORE
+#define IRQ_AB3550_BASE (IRQ_U300_GPIO_END)
+#define IRQ_AB3550_END (IRQ_AB3550_BASE + 38)
#else
-#define NR_IRQS U300_NR_IRQS
+#define IRQ_AB3550_END (IRQ_U300_GPIO_END)
#endif
+#define NR_IRQS (IRQ_AB3550_END)
+
#endif
#include <linux/device.h>
#include <linux/amba/bus.h>
#include <linux/mmc/host.h>
-#include <linux/gpio.h>
#include <linux/dmaengine.h>
#include <linux/amba/mmci.h>
#include <linux/slab.h>
#include <mach/coh901318.h>
#include <mach/dma_channels.h>
+#include <mach/gpio-u300.h>
#include "mmc.h"
#include "padmux.h"
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include "pins-db8500.h"
* Board data for the U8500 UIB, also known as the New UIB
* License terms: GNU General Public License (GPL), version 2
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/mfd/tc3589x.h>
#include <linux/input/matrix_keypad.h>
-#include <mach/gpio.h>
#include <mach/irqs.h>
#include "board-mop500.h"
#include <plat/i2c.h>
#include <plat/ste_dma40.h>
#include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <linux/amba/mmci.h>
#include <linux/mmc/host.h>
-#include <linux/gpio.h>
#include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
#include <mach/db5500-regs.h>
#include <plat/ste_dma40.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
-#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/i2c.h>
#include <plat/pincfg.h>
#include <plat/i2c.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/devices.h>
#include <asm/mach/map.h>
#include <asm/pmu.h>
-#include <plat/gpio.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/devices.h>
#include <linux/amba/bus.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/mach/map.h>
#include <asm/pmu.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
-#include <plat/gpio.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
*/
#define ARCH_NR_GPIOS 350
-#include <plat/gpio.h>
-
#endif /* __ASM_ARCH_GPIO_H */
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
+/* empty */
- zreladdr-y := 0x60008000
+ zreladdr-y += 0x60008000
params_phys-y := 0x60000100
initrd_phys-y := 0x60800000
#include <linux/smp.h>
#include <asm/cacheflush.h>
+#include <asm/system.h>
extern volatile int pen_release;
* code will have already disabled interrupts
*/
for (;;) {
- /*
- * here's the WFI
- */
- asm(".word 0xe320f003\n"
- :
- :
- : "memory", "cc");
+ wfi();
if (pen_release == cpu) {
/*
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define IO_SPACE_LIMIT 0xffffffff
-
#define __io(a) __typesafe_io(a)
#define __mem_pci(a) (a)
.rate = 1000000,
};
+static struct clk v2m_ref_clk = {
+ .rate = 32768,
+};
+
static struct clk dummy_apb_pclk;
static struct clk_lookup v2m_lookups[] = {
}, { /* CLCD */
.dev_id = "mb:clcd",
.clk = &osc1_clk,
+ }, { /* SP805 WDT */
+ .dev_id = "mb:wdt",
+ .clk = &v2m_ref_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "v2m-timer0",
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x01000000
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
+/* empty */
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define IO_SPACE_LIMIT 0xffff
-
#define __io(a) __typesafe_io((a) + 0xf0000000)
#define __mem_pci(a) (a)
-zreladdr-y := 0x00008000
+zreladdr-y += 0x00008000
params_phys-y := 0x00000100
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
static inline int gpio_to_irq(unsigned gpio)
{
return gpio;
}
+#define gpio_to_irq gpio_to_irq
static inline int irq_to_gpio(unsigned irq)
{
- zreladdr-y := 0x00008000
+ zreladdr-y += 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
cmp \tmp, # 0x5600 @ Is it ldrsb?
orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes
tst \tmp, #1 << 11 @ L = 0 -> write
- orreq \psr, \psr, #1 << 11 @ yes.
+ orreq \fsr, \fsr, #1 << 11 @ yes.
b do_DataAbort
not_thumb:
.endm
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
{
/* wait for cache operation by line or way to complete */
while (readl_relaxed(reg) & mask)
- ;
+ cpu_relax();
}
#ifdef CONFIG_CACHE_PL310
spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static void __init l2x0_unlock(__u32 cache_id)
+{
+ int lockregs;
+ int i;
+
+ if (cache_id == L2X0_CACHE_ID_PART_L310)
+ lockregs = 8;
+ else
+ /* L210 and unknown types */
+ lockregs = 1;
+
+ for (i = 0; i < lockregs; i++) {
+ writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
+ i * L2X0_LOCKDOWN_STRIDE);
+ writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
+ i * L2X0_LOCKDOWN_STRIDE);
+ }
+}
+
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
* accessing the below registers will fault.
*/
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ /* Make sure that I&D is not locked down when starting */
+ l2x0_unlock(cache_id);
/* l2x0 controller is disabled */
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
ways, cache_id, aux, l2x0_size);
}
+
+#ifdef CONFIG_OF
+static void __init l2x0_of_setup(const struct device_node *np,
+ __u32 *aux_val, __u32 *aux_mask)
+{
+ u32 data[2] = { 0, 0 };
+ u32 tag = 0;
+ u32 dirty = 0;
+ u32 val = 0, mask = 0;
+
+ of_property_read_u32(np, "arm,tag-latency", &tag);
+ if (tag) {
+ mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
+ val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
+ }
+
+ of_property_read_u32_array(np, "arm,data-latency",
+ data, ARRAY_SIZE(data));
+ if (data[0] && data[1]) {
+ mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
+ L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
+ val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
+ ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
+ }
+
+ of_property_read_u32(np, "arm,dirty-latency", &dirty);
+ if (dirty) {
+ mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
+ val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
+ }
+
+ *aux_val &= ~mask;
+ *aux_val |= val;
+ *aux_mask &= ~mask;
+}
+
+static void __init pl310_of_setup(const struct device_node *np,
+ __u32 *aux_val, __u32 *aux_mask)
+{
+ u32 data[3] = { 0, 0, 0 };
+ u32 tag[3] = { 0, 0, 0 };
+ u32 filter[2] = { 0, 0 };
+
+ of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
+ if (tag[0] && tag[1] && tag[2])
+ writel_relaxed(
+ ((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
+ ((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
+ ((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
+ l2x0_base + L2X0_TAG_LATENCY_CTRL);
+
+ of_property_read_u32_array(np, "arm,data-latency",
+ data, ARRAY_SIZE(data));
+ if (data[0] && data[1] && data[2])
+ writel_relaxed(
+ ((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
+ ((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
+ ((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
+ l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+ of_property_read_u32_array(np, "arm,filter-ranges",
+ filter, ARRAY_SIZE(filter));
+ if (filter[1]) {
+ writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
+ l2x0_base + L2X0_ADDR_FILTER_END);
+ writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
+ l2x0_base + L2X0_ADDR_FILTER_START);
+ }
+}
+
+static const struct of_device_id l2x0_ids[] __initconst = {
+ { .compatible = "arm,pl310-cache", .data = pl310_of_setup },
+ { .compatible = "arm,l220-cache", .data = l2x0_of_setup },
+ { .compatible = "arm,l210-cache", .data = l2x0_of_setup },
+ {}
+};
+
+int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask)
+{
+ struct device_node *np;
+ void (*l2_setup)(const struct device_node *np,
+ __u32 *aux_val, __u32 *aux_mask);
+
+ np = of_find_matching_node(NULL, l2x0_ids);
+ if (!np)
+ return -ENODEV;
+ l2x0_base = of_iomap(np, 0);
+ if (!l2x0_base)
+ return -ENOMEM;
+
+ /* L2 configuration can only be changed if the cache is disabled */
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ l2_setup = of_match_node(l2x0_ids, np)->data;
+ if (l2_setup)
+ l2_setup(np, &aux_val, &aux_mask);
+ }
+ l2x0_init(l2x0_base, aux_val, aux_mask);
+ return 0;
+}
+#endif
#ifdef CONFIG_MMU
-
#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT)
-#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PGDIR_SHIFT)
+#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT)
/*
* These are the page tables (2MB each) covering uncached, DMA consistent allocations
}
consistent_pte[i++] = pte;
- base += (1 << PGDIR_SHIFT);
+ base += PMD_SIZE;
} while (base < CONSISTENT_END);
return ret;
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
int pfn_valid(unsigned long pfn)
{
- return memblock_is_memory(pfn << PAGE_SHIFT);
+ return memblock_is_memory(__pfn_to_phys(pfn));
}
EXPORT_SYMBOL(pfn_valid);
#endif
struct mem_type {
pteval_t prot_pte;
- unsigned int prot_l1;
- unsigned int prot_sect;
+ pmdval_t prot_l1;
+ pmdval_t prot_sect;
unsigned int domain;
};
struct cachepolicy {
const char policy[16];
unsigned int cr_mask;
- unsigned int pmd;
+ pmdval_t pmd;
pteval_t pte;
};
{
struct cachepolicy *cp;
unsigned int cr = get_cr();
- unsigned int user_pgprot, kern_pgprot, vecs_pgprot;
+ pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
int cpu_arch = cpu_architecture();
int i;
/*
* Clear out all the mappings below the kernel image.
*/
- for (addr = 0; addr < MODULES_VADDR; addr += PGDIR_SIZE)
+ for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
#ifdef CONFIG_XIP_KERNEL
/* The XIP kernel is mapped in the module area -- skip over it */
- addr = ((unsigned long)_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+ addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
#endif
- for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+ for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
/*
* memory bank, up to the end of the vmalloc region.
*/
for (addr = __phys_to_virt(end);
- addr < VMALLOC_END; addr += PGDIR_SIZE)
+ addr < VMALLOC_END; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
}
+#define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
+
/*
* Reserve the special regions of memory
*/
* Reserve the page tables. These are already in use,
* and can only be in node 0.
*/
- memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
+ memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE);
#ifdef CONFIG_SA1111
/*
*/
vectors_page = early_alloc(PAGE_SIZE);
- for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
+ for (addr = VMALLOC_END; addr; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
/*
.equ cpu_arm920_suspend_size, 4 * 3
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_arm920_do_suspend)
- stmfd sp!, {r4 - r7, lr}
+ stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 0 @ TTB address
- mrc p15, 0, r7, c1, c0, 0 @ Control register
- stmia r0, {r4 - r7}
- ldmfd sp!, {r4 - r7, pc}
+ mrc p15, 0, r6, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r6}
+ ldmfd sp!, {r4 - r6, pc}
ENDPROC(cpu_arm920_do_suspend)
ENTRY(cpu_arm920_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
- ldmia r0, {r4 - r7}
+ ldmia r0, {r4 - r6}
mcr p15, 0, r4, c13, c0, 0 @ PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r6, c2, c0, 0 @ TTB address
- mov r0, r7 @ control register
- mov r2, r6, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ mcr p15, 0, r1, c2, c0, 0 @ TTB address
+ mov r0, r6 @ control register
b cpu_resume_mmu
ENDPROC(cpu_arm920_do_resume)
#endif
.equ cpu_arm926_suspend_size, 4 * 3
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_arm926_do_suspend)
- stmfd sp!, {r4 - r7, lr}
+ stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 0 @ TTB address
- mrc p15, 0, r7, c1, c0, 0 @ Control register
- stmia r0, {r4 - r7}
- ldmfd sp!, {r4 - r7, pc}
+ mrc p15, 0, r6, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r6}
+ ldmfd sp!, {r4 - r6, pc}
ENDPROC(cpu_arm926_do_suspend)
ENTRY(cpu_arm926_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
- ldmia r0, {r4 - r7}
+ ldmia r0, {r4 - r6}
mcr p15, 0, r4, c13, c0, 0 @ PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r6, c2, c0, 0 @ TTB address
- mov r0, r7 @ control register
- mov r2, r6, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ mcr p15, 0, r1, c2, c0, 0 @ TTB address
+ mov r0, r6 @ control register
b cpu_resume_mmu
ENDPROC(cpu_arm926_do_resume)
#endif
mov pc, lr
.globl cpu_sa1100_suspend_size
-.equ cpu_sa1100_suspend_size, 4*4
+.equ cpu_sa1100_suspend_size, 4 * 3
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_sa1100_do_suspend)
- stmfd sp!, {r4 - r7, lr}
+ stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c3, c0, 0 @ domain ID
- mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
- mrc p15, 0, r6, c13, c0, 0 @ PID
- mrc p15, 0, r7, c1, c0, 0 @ control reg
- stmia r0, {r4 - r7} @ store cp regs
- ldmfd sp!, {r4 - r7, pc}
+ mrc p15, 0, r5, c13, c0, 0 @ PID
+ mrc p15, 0, r6, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r6} @ store cp regs
+ ldmfd sp!, {r4 - r6, pc}
ENDPROC(cpu_sa1100_do_suspend)
ENTRY(cpu_sa1100_do_resume)
- ldmia r0, {r4 - r7} @ load cp regs
- mov r1, #0
- mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
- mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
- mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
- mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
+ ldmia r0, {r4 - r6} @ load cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB
mcr p15, 0, r4, c3, c0, 0 @ domain ID
- mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r6, c13, c0, 0 @ PID
- mov r0, r7 @ control register
- mov r2, r5, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r5, c13, c0, 0 @ PID
+ mov r0, r6 @ control register
b cpu_resume_mmu
ENDPROC(cpu_sa1100_do_resume)
#endif
/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
.globl cpu_v6_suspend_size
-.equ cpu_v6_suspend_size, 4 * 8
+.equ cpu_v6_suspend_size, 4 * 6
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_v6_do_suspend)
- stmfd sp!, {r4 - r11, lr}
+ stmfd sp!, {r4 - r9, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c13, c0, 1 @ Context ID
- mrc p15, 0, r6, c3, c0, 0 @ Domain ID
- mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0
- mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1
- mrc p15, 0, r9, c1, c0, 1 @ auxiliary control register
- mrc p15, 0, r10, c1, c0, 2 @ co-processor access control
- mrc p15, 0, r11, c1, c0, 0 @ control register
- stmia r0, {r4 - r11}
- ldmfd sp!, {r4- r11, pc}
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r7, c1, c0, 1 @ auxiliary control register
+ mrc p15, 0, r8, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r9, c1, c0, 0 @ control register
+ stmia r0, {r4 - r9}
+ ldmfd sp!, {r4- r9, pc}
ENDPROC(cpu_v6_do_suspend)
ENTRY(cpu_v6_do_resume)
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
- ldmia r0, {r4 - r11}
+ mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
+ ldmia r0, {r4 - r9}
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c13, c0, 1 @ Context ID
- mcr p15, 0, r6, c3, c0, 0 @ Domain ID
- mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0
- mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1
- mcr p15, 0, r9, c1, c0, 1 @ auxiliary control register
- mcr p15, 0, r10, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
+ ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
+ mcr p15, 0, r1, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r6, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r7, c1, c0, 1 @ auxiliary control register
+ mcr p15, 0, r8, c1, c0, 2 @ co-processor access control
mcr p15, 0, ip, c2, c0, 2 @ TTB control register
mcr p15, 0, ip, c7, c5, 4 @ ISB
- mov r0, r11 @ control register
- mov r2, r7, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, cpu_resume_l1_flags
+ mov r0, r9 @ control register
b cpu_resume_mmu
ENDPROC(cpu_v6_do_resume)
-cpu_resume_l1_flags:
- ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
- ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
#endif
string cpu_v6_name, "ARMv6-compatible processor"
mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r0, r0, r5 @ clear bits them
orr r0, r0, r6 @ set them
+#ifdef CONFIG_ARM_ERRATA_364296
+ /*
+ * Workaround for the 364296 ARM1136 r0p2 erratum (possible cache data
+ * corruption with hit-under-miss enabled). The conditional code below
+ * (setting the undocumented bit 31 in the auxiliary control register
+ * and the FI bit in the control register) disables hit-under-miss
+ * without putting the processor into full low interrupt latency mode.
+ */
+ ldr r6, =0x4107b362 @ id for ARM1136 r0p2
+ mrc p15, 0, r5, c0, c0, 0 @ get processor id
+ teq r5, r6 @ check for the faulty core
+ mrceq p15, 0, r5, c1, c0, 1 @ load aux control reg
+ orreq r5, r5, #(1 << 31) @ set the undocumented bit 31
+ mcreq p15, 0, r5, c1, c0, 1 @ write aux control reg
+ orreq r0, r0, #(1 << 21) @ low interrupt latency configuration
+#endif
mov pc, lr @ return to head.S:__ret
/*
ENTRY(cpu_v7_reset)
mrc p15, 0, r1, c1, c0, 0 @ ctrl register
bic r1, r1, #0x1 @ ...............m
+ THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
mcr p15, 0, r1, c1, c0, 0 @ disable MMU
isb
mov pc, r0
/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
.globl cpu_v7_suspend_size
-.equ cpu_v7_suspend_size, 4 * 9
+.equ cpu_v7_suspend_size, 4 * 7
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_v7_do_suspend)
- stmfd sp!, {r4 - r11, lr}
+ stmfd sp!, {r4 - r10, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c13, c0, 1 @ Context ID
- mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID
- stmia r0!, {r4 - r6}
+ mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID
+ stmia r0!, {r4 - r5}
mrc p15, 0, r6, c3, c0, 0 @ Domain ID
- mrc p15, 0, r7, c2, c0, 0 @ TTB 0
- mrc p15, 0, r8, c2, c0, 1 @ TTB 1
- mrc p15, 0, r9, c1, c0, 0 @ Control register
- mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
- mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
- stmia r0, {r6 - r11}
- ldmfd sp!, {r4 - r11, pc}
+ mrc p15, 0, r7, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r8, c1, c0, 0 @ Control register
+ mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r6 - r10}
+ ldmfd sp!, {r4 - r10, pc}
ENDPROC(cpu_v7_do_suspend)
ENTRY(cpu_v7_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
- ldmia r0!, {r4 - r6}
+ mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
+ ldmia r0!, {r4 - r5}
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c13, c0, 1 @ Context ID
- mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID
- ldmia r0, {r6 - r11}
+ mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID
+ ldmia r0, {r6 - r10}
mcr p15, 0, r6, c3, c0, 0 @ Domain ID
- mcr p15, 0, r7, c2, c0, 0 @ TTB 0
- mcr p15, 0, r8, c2, c0, 1 @ TTB 1
+ ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
+ ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
+ mcr p15, 0, r1, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r7, c2, c0, 1 @ TTB 1
mcr p15, 0, ip, c2, c0, 2 @ TTB control register
- mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
- mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control
+ mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register
+ teq r4, r9 @ Is it already set?
+ mcrne p15, 0, r9, c1, c0, 1 @ No, so write it
+ mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
ldr r4, =PRRR @ PRRR
ldr r5, =NMRR @ NMRR
mcr p15, 0, r4, c10, c2, 0 @ write PRRR
mcr p15, 0, r5, c10, c2, 1 @ write NMRR
isb
- mov r0, r9 @ control register
- mov r2, r7, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, cpu_resume_l1_flags
+ dsb
+ mov r0, r8 @ control register
b cpu_resume_mmu
ENDPROC(cpu_v7_do_resume)
-cpu_resume_l1_flags:
- ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
- ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
#endif
__CPUINIT
.align
.globl cpu_xsc3_suspend_size
-.equ cpu_xsc3_suspend_size, 4 * 8
+.equ cpu_xsc3_suspend_size, 4 * 6
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_xsc3_do_suspend)
- stmfd sp!, {r4 - r10, lr}
+ stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
mrc p15, 0, r6, c13, c0, 0 @ PID
mrc p15, 0, r7, c3, c0, 0 @ domain ID
- mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
- mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
- mrc p15, 0, r10, c1, c0, 0 @ control reg
+ mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r9, c1, c0, 0 @ control reg
bic r4, r4, #2 @ clear frequency change bit
- stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
- ldmia sp!, {r4 - r10, pc}
+ stmia r0, {r4 - r9} @ store cp regs
+ ldmia sp!, {r4 - r9, pc}
ENDPROC(cpu_xsc3_do_suspend)
ENTRY(cpu_xsc3_do_resume)
- ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
+ ldmia r0, {r4 - r9} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
mcr p15, 0, r5, c15, c1, 0 @ CP access reg
mcr p15, 0, r6, c13, c0, 0 @ PID
mcr p15, 0, r7, c3, c0, 0 @ domain ID
- mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
-
- @ temporarily map resume_turn_on_mmu into the page table,
- @ otherwise prefetch abort occurs after MMU is turned on
- mov r0, r10 @ control register
- mov r2, r8, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, =0x542e @ section flags
+ orr r1, r1, #0x18 @ cache the page table in L2
+ mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
+ mov r0, r9 @ control register
b cpu_resume_mmu
ENDPROC(cpu_xsc3_do_resume)
#endif
.align
.globl cpu_xscale_suspend_size
-.equ cpu_xscale_suspend_size, 4 * 7
+.equ cpu_xscale_suspend_size, 4 * 6
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_xscale_do_suspend)
- stmfd sp!, {r4 - r10, lr}
+ stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
mrc p15, 0, r6, c13, c0, 0 @ PID
mrc p15, 0, r7, c3, c0, 0 @ domain ID
- mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
- mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
- mrc p15, 0, r10, c1, c0, 0 @ control reg
+ mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r9, c1, c0, 0 @ control reg
bic r4, r4, #2 @ clear frequency change bit
- stmia r0, {r4 - r10} @ store cp regs
- ldmfd sp!, {r4 - r10, pc}
+ stmia r0, {r4 - r9} @ store cp regs
+ ldmfd sp!, {r4 - r9, pc}
ENDPROC(cpu_xscale_do_suspend)
ENTRY(cpu_xscale_do_resume)
- ldmia r0, {r4 - r10} @ load cp regs
+ ldmia r0, {r4 - r9} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
mcr p15, 0, r5, c15, c1, 0 @ CP access reg
mcr p15, 0, r6, c13, c0, 0 @ PID
mcr p15, 0, r7, c3, c0, 0 @ domain ID
- mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
- mov r0, r10 @ control register
- mov r2, r8, lsr #14 @ get TTB0 base
- mov r2, r2, lsl #14
- ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg
+ mov r0, r9 @ control register
b cpu_resume_mmu
ENDPROC(cpu_xscale_do_resume)
#endif
#include <linux/spinlock.h>
#include <mach/hardware.h>
-#include <asm-generic/gpio.h>
/* There's a off-by-one betweem the gpio bank number and the gpiochip */
/* range e.g. GPIO_1_5 is gpio 5 under linux */
#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr))
-/* use gpiolib dispatchers */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-
#define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio))
#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START)
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#ifndef __ASM_PLAT_GPIO_H
-#define __ASM_PLAT_GPIO_H
-#include <asm-generic/gpio.h>
-
-/*
- * These currently cause a function call to happen, they may be optimized
- * if needed by adding cpu-specific defines to identify blocks
- * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
- */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
+#ifndef __PLAT_NOMADIK_GPIO
+#define __PLAT_NOMADIK_GPIO
/*
* "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
bool supports_sleepmode;
};
-#endif /* __ASM_PLAT_GPIO_H */
+#endif /* __PLAT_NOMADIK_GPIO */
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <plat/board.h>
-#include <mach/gpio.h>
/* Many OMAP development platforms reuse the same "debug board"; these
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <plat/fpga.h>
-#include <mach/gpio.h>
/* Many OMAP development platforms reuse the same "debug board"; these
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mmc.h>
-#include <mach/gpio.h>
#include <plat/menelaus.h>
#include <plat/mcbsp.h>
#include <plat/omap44xx.h>
#include <linux/errno.h>
#include <asm-generic/gpio.h>
-static inline int gpio_get_value(unsigned gpio)
-{
- return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
- return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
- return __gpio_to_irq(gpio);
-}
-
static inline int irq_to_gpio(unsigned irq)
{
int tmp;
return pm_generic_resume_noirq(dev);
}
+#else
+#define _od_suspend_noirq NULL
+#define _od_resume_noirq NULL
#endif
static struct dev_pm_domain omap_device_pm_domain = {
#define __PLAT_GPIO_H
#include <linux/init.h>
-#include <asm-generic/gpio.h>
-
-/*
- * GENERIC_GPIO primitives.
- */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
+#include <linux/types.h>
/*
* Orion-specific GPIO API extensions.
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/syscore_ops.h>
#include <linux/slab.h>
-#include <mach/gpio.h>
-
int pxa_last_gpio;
struct pxa_gpio_chip {
#ifndef __PLAT_GPIO_H
#define __PLAT_GPIO_H
+#define __ARM_GPIOLIB_COMPLEX
+
struct irq_data;
/*
if (IS_ERR(pclk))
return -EINVAL;
- rate = pclk->ops->get_rate(clk);
+ rate = pclk->ops->get_rate(pclk);
clk_put(pclk);
return rate;
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
+#include <asm/mach/irq.h>
+
#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u)
#define CON_OFFSET 0x700
int group, pend_offset, mask_offset;
unsigned int pend, mask;
+ struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
+
for (group = 0; group < bank->nr_groups; group++) {
struct s3c_gpio_chip *chip = bank->chips[group];
if (!chip)
pend &= ~BIT(offset);
}
}
+ chained_irq_exit(chip, desc);
}
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
int func;
};
-extern void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
struct platform_pwm_backlight_data *bl_data);
#endif /* __ASM_PLAT_BACKLIGHT_H */
#include <plat/irq-vic-timer.h>
#include <plat/regs-timer.h>
+#include <asm/mach/irq.h>
+
static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
{
+ struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
generic_handle_irq((int)desc->irq_data.handler_data);
+ chained_irq_exit(chip, desc);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-/*
- * arch/arm/plat-spear/include/plat/gpio.h
- *
- * GPIO macros for SPEAr platform
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_GPIO_H
-#define __PLAT_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
-#endif /* __PLAT_GPIO_H */
+/* empty */
nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955
omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967
cpuat9260 MACH_CPUAT9260 CPUAT9260 1973
-eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975
+eukrea_cpuimx27 MACH_EUKREA_CPUIMX27 EUKREA_CPUIMX27 1975
acs5k MACH_ACS5K ACS5K 1982
snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987
dsm320 MACH_DSM320 DSM320 1988
omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791
ti8168evm MACH_TI8168EVM TI8168EVM 2800
teton_bga MACH_TETON_BGA TETON_BGA 2816
-eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820
-eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821
+eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25SD EUKREA_CPUIMX25SD 2820
+eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821
eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
smdkc210 MACH_SMDKC210 SMDKC210 2838
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs);
+int or1k_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs);
+void or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs);
void or1k_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction dir);
debug_dma_unmap_page(dev, addr, size, dir, true);
}
+static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ int i, ents;
+ struct scatterlist *s;
+
+ for_each_sg(sg, s, nents, i)
+ kmemcheck_mark_initialized(sg_virt(s), s->length);
+ BUG_ON(!valid_dma_direction(dir));
+ ents = or1k_map_sg(dev, sg, nents, dir, NULL);
+ debug_dma_map_sg(dev, sg, nents, ents, dir);
+
+ return ents;
+}
+
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+ debug_dma_unmap_sg(dev, sg, nents, dir);
+ or1k_unmap_sg(dev, sg, nents, dir, NULL);
+}
+
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ size_t offset, size_t size,
+ enum dma_data_direction dir)
+{
+ dma_addr_t addr;
+
+ kmemcheck_mark_initialized(page_address(page) + offset, size);
+ BUG_ON(!valid_dma_direction(dir));
+ addr = or1k_map_page(dev, page, offset, size, dir, NULL);
+ debug_dma_map_page(dev, page, offset, size, dir, addr, false);
+
+ return addr;
+}
+
+static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+ or1k_unmap_page(dev, addr, size, dir, NULL);
+ debug_dma_unmap_page(dev, addr, size, dir, true);
+}
+
static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
size_t size,
enum dma_data_direction dir)
static inline int dma_supported(struct device *dev, u64 dma_mask)
{
/* Support 32 bit DMA mask exclusively */
- return dma_mask == 0xffffffffULL;
+ return dma_mask == DMA_BIT_MASK(32);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
}
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
/* This struct is saved by setup_frame in signal.c, to keep the current
context while a signal handler is executed. It's restored by sys_sigreturn.
-
- To keep things simple, we use pt_regs here even though normally you just
- specify the list of regs to save. Then we can use copy_from_user on the
- entire regs instead of a bunch of get_user's as well...
*/
struct sigcontext {
- struct pt_regs regs; /* needs to be first */
+ struct user_regs_struct regs; /* needs to be first */
unsigned long oldmask;
- unsigned long usp; /* usp before stacking this gunk on it */
};
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
/* Nothing special to do here... */
}
+int or1k_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ s->dma_address = or1k_map_page(dev, sg_page(s), s->offset,
+ s->length, dir, NULL);
+ }
+
+ return nents;
+}
+
+void or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, NULL);
+ }
+}
+
void or1k_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction dir)
return 0;
}
-
fs_initcall(dma_init);
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
unsigned int err = 0;
- unsigned long old_usp;
/* Alwys make any pending restarted system call return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- /* restore the regs from &sc->regs (same as sc, since regs is first)
+ /*
+ * Restore the regs from &sc->regs.
* (sc is already checked for VERIFY_READ since the sigframe was
* checked in sys_sigreturn previously)
*/
-
- if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
+ if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
+ goto badframe;
+ if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long)))
+ goto badframe;
+ if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long)))
goto badframe;
/* make sure the SM-bit is cleared so user-mode cannot fool us */
regs->sr &= ~SPR_SR_SM;
- /* restore the old USP as it was before we stacked the sc etc.
- * (we cannot just pop the sigcontext since we aligned the sp and
- * stuff after pushing it)
- */
-
- err |= __get_user(old_usp, &sc->usp);
-
- regs->sp = old_usp;
-
/* TODO: the other ports use regs->orig_XX to disable syscall checks
* after this completes, but we don't use that mechanism. maybe we can
* use it now ?
unsigned long mask)
{
int err = 0;
- unsigned long usp = regs->sp;
- /* copy the regs. they are first in sc so we can use sc directly */
+ /* copy the regs */
- err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
+ err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
+ err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long));
+ err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long));
/* then some other stuff */
err |= __put_user(mask, &sc->oldmask);
- err |= __put_user(usp, &sc->usp);
-
return err;
}
ENTRY_SAME(ni_syscall) /* query_module */
ENTRY_SAME(poll)
/* structs contain pointers and an in_addr... */
- ENTRY_COMP(nfsservctl)
+ ENTRY_SAME(ni_syscall) /* was nfsservctl */
ENTRY_SAME(setresgid) /* 170 */
ENTRY_SAME(getresgid)
ENTRY_SAME(prctl)
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x0 0x0 0x02000000>;
- bank-width = <1>;
+ bank-width = <2>;
device-width = <1>;
partition@0 {
label = "ramdisk";
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_VIRQ_DEBUG=y
CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_DEV_TALITOS=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_SND_INTEL8X0=y
# CONFIG_SND_PPC is not set
# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_SND_INTEL8X0=y
# CONFIG_SND_PPC is not set
# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
SYSCALL_SPU(getresuid)
SYSCALL(ni_syscall)
SYSCALL_SPU(poll)
-COMPAT_SYS(nfsservctl)
+SYSCALL(ni_syscall)
SYSCALL_SPU(setresgid)
SYSCALL_SPU(getresgid)
COMPAT_SYS_SPU(prctl)
struct perf_event;
struct perf_sample_data;
-extern void ptrace_triggered(struct perf_event *bp, int nmi,
+extern void ptrace_triggered(struct perf_event *bp,
struct perf_sample_data *data, struct pt_regs *regs);
#define task_pt_regs(task) \
#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/mm.h>
+#include <linux/dma-mapping.h>
#include <linux/sh_timer.h>
#include <linux/sh_dma.h>
#include <linux/atomic.h>
#include <asm/smp.h>
-static void (*pm_idle)(void);
+void (*pm_idle)(void);
static int hlt_counter;
break;
}
break;
+
+ case 9: /* mov.w @(disp,PC),Rn */
+ srcu = (unsigned char __user *)regs->pc;
+ srcu += 4;
+ srcu += (instruction & 0x00FF) << 1;
+ dst = (unsigned char *)rn;
+ *(unsigned long *)dst = 0;
+
+#if !defined(__LITTLE_ENDIAN__)
+ dst += 2;
+#endif
+
+ if (ma->from(dst, srcu, 2))
+ goto fetch_fault;
+ sign_extend(2, dst);
+ ret = 0;
+ break;
+
+ case 0xd: /* mov.l @(disp,PC),Rn */
+ srcu = (unsigned char __user *)(regs->pc & ~0x3);
+ srcu += 4;
+ srcu += (instruction & 0x00FF) << 2;
+ dst = (unsigned char *)rn;
+ *(unsigned long *)dst = 0;
+
+ if (ma->from(dst, srcu, 4))
+ goto fetch_fault;
+ ret = 0;
+ break;
}
return ret;
case 0x0500: /* mov.w @(disp,Rm),R0 */
goto simple;
case 0x0B00: /* bf lab - no delayslot*/
+ ret = 0;
break;
case 0x0F00: /* bf/s lab */
ret = handle_delayslot(regs, instruction, ma);
}
break;
case 0x0900: /* bt lab - no delayslot */
+ ret = 0;
break;
case 0x0D00: /* bt/s lab */
ret = handle_delayslot(regs, instruction, ma);
}
break;
+ case 0x9000: /* mov.w @(disp,Rm),Rn */
+ goto simple;
+
case 0xA000: /* bra label */
ret = handle_delayslot(regs, instruction, ma);
if (ret==0)
regs->pc += SH_PC_12BIT_OFFSET(instruction);
}
break;
+
+ case 0xD000: /* mov.l @(disp,Rm),Rn */
+ goto simple;
}
return ret;
#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
-#define SUN4D_IPI_IRQ 14
+#define SUN4D_IPI_IRQ 13
extern void sun4d_ipi_interrupt(void);
cap |= AV_SPARC_VIS;
if (tlb_type == cheetah || tlb_type == cheetah_plus)
cap |= AV_SPARC_VIS | AV_SPARC_VIS2;
- if (tlb_type == cheetah_plus)
- cap |= AV_SPARC_POPC;
+ if (tlb_type == cheetah_plus) {
+ unsigned long impl, ver;
+
+ __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver));
+ impl = ((ver >> 32) & 0xffff);
+ if (impl == PANTHER_IMPL)
+ cap |= AV_SPARC_POPC;
+ }
if (tlb_type == hypervisor) {
if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1)
cap |= AV_SPARC_ASI_BLK_INIT;
.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
/*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
-/*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
+/*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys_nis_syscall
.word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
bool
default n
+config CMPXCHG_DOUBLE
+ bool
+ default n
+
source "arch/x86/Kconfig.cpu"
endmenu
KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
-Din6addr_loopback=kernel_in6addr_loopback \
- -Din6addr_any=kernel_in6addr_any
+ -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
KBUILD_AFLAGS += $(ARCH_INCLUDE)
* is done under a spinlock. Checking whether the device is in use is
* line->tty->count > 1, also under the spinlock.
*
- * tty->count serves to decide whether the device should be enabled or
- * disabled on the host. If it's equal to 1, then we are doing the
+ * line->count serves to decide whether the device should be enabled or
+ * disabled on the host. If it's equal to 0, then we are doing the
* first open or last close. Otherwise, open and close just return.
*/
goto out_unlock;
err = 0;
- if (tty->count > 1)
+ if (line->count++)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
+ BUG_ON(tty->driver_data);
tty->driver_data = line;
line->tty = tty;
+ spin_unlock(&line->count_lock);
err = enable_chan(line);
- if (err)
+ if (err) /* line_close() will be called by our caller */
return err;
INIT_DELAYED_WORK(&line->task, line_timer_cb);
chan_window_size(&line->chan_list, &tty->winsize.ws_row,
&tty->winsize.ws_col);
- return err;
+ return 0;
out_unlock:
spin_unlock(&line->count_lock);
flush_buffer(line);
spin_lock(&line->count_lock);
- if (!line->valid)
- goto out_unlock;
+ BUG_ON(!line->valid);
- if (tty->count > 1)
+ if (--line->count)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
line->tty = NULL;
tty->driver_data = NULL;
+ spin_unlock(&line->count_lock);
+
if (line->sigio) {
unregister_winch(tty);
line->sigio = 0;
spin_lock(&line->count_lock);
- if (line->tty != NULL) {
+ if (line->count) {
*error_out = "Device is already open";
goto out;
}
int pid;
struct tty_struct *tty;
unsigned long stack;
+ struct work_struct work;
};
-static void free_winch(struct winch *winch, int free_irq_ok)
+static void __free_winch(struct work_struct *work)
{
- if (free_irq_ok)
- free_irq(WINCH_IRQ, winch);
-
- list_del(&winch->list);
+ struct winch *winch = container_of(work, struct winch, work);
+ free_irq(WINCH_IRQ, winch);
if (winch->pid != -1)
os_kill_process(winch->pid, 1);
- if (winch->fd != -1)
- os_close_file(winch->fd);
if (winch->stack != 0)
free_stack(winch->stack, 0);
kfree(winch);
}
+static void free_winch(struct winch *winch)
+{
+ int fd = winch->fd;
+ winch->fd = -1;
+ if (fd != -1)
+ os_close_file(fd);
+ list_del(&winch->list);
+ __free_winch(&winch->work);
+}
+
static irqreturn_t winch_interrupt(int irq, void *data)
{
struct winch *winch = data;
struct tty_struct *tty;
struct line *line;
+ int fd = winch->fd;
int err;
char c;
- if (winch->fd != -1) {
- err = generic_read(winch->fd, &c, NULL);
+ if (fd != -1) {
+ err = generic_read(fd, &c, NULL);
if (err < 0) {
if (err != -EAGAIN) {
+ winch->fd = -1;
+ list_del(&winch->list);
+ os_close_file(fd);
printk(KERN_ERR "winch_interrupt : "
"read failed, errno = %d\n", -err);
printk(KERN_ERR "fd %d is losing SIGWINCH "
"support\n", winch->tty_fd);
- free_winch(winch, 0);
+ INIT_WORK(&winch->work, __free_winch);
+ schedule_work(&winch->work);
return IRQ_HANDLED;
}
goto out;
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
if (winch->tty == tty) {
- free_winch(winch, 1);
+ free_winch(winch);
break;
}
}
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
- free_winch(winch, 1);
+ free_winch(winch);
}
spin_unlock(&winch_handler_lock);
err = -errno;
printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n",
errno);
+ close(fd);
return err;
}
close(fd);
unsigned long addr, unsigned long data);
extern unsigned long getreg(struct task_struct *child, int regno);
extern int putreg(struct task_struct *child, int regno, unsigned long value);
-extern int get_fpregs(struct user_i387_struct __user *buf,
- struct task_struct *child);
-extern int set_fpregs(struct user_i387_struct __user *buf,
- struct task_struct *child);
extern int arch_copy_tls(struct task_struct *new);
extern void clear_flushed_tls(struct task_struct *task);
struct line {
struct tty_struct *tty;
spinlock_t count_lock;
+ unsigned long count;
int valid;
char *init_str;
extern int save_registers(int pid, struct uml_pt_regs *regs);
extern int restore_registers(int pid, struct uml_pt_regs *regs);
extern int init_registers(int pid);
-extern void get_safe_registers(unsigned long *regs);
+extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
extern int get_fp_registers(int pid, unsigned long *regs);
extern int put_fp_registers(int pid, unsigned long *regs);
arch_copy_thread(¤t->thread.arch, &p->thread.arch);
}
else {
- get_safe_registers(p->thread.regs.regs.gp);
+ get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler;
}
void __user *vp = p;
switch (request) {
- /* read word at location addr. */
- case PTRACE_PEEKTEXT:
- case PTRACE_PEEKDATA:
- ret = generic_ptrace_peekdata(child, addr, data);
- break;
-
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
ret = peek_user(child, addr, data);
break;
- /* write the word at location addr. */
- case PTRACE_POKETEXT:
- case PTRACE_POKEDATA:
- ret = generic_ptrace_pokedata(child, addr, data);
- break;
-
/* write the word at location addr in the USER area */
case PTRACE_POKEUSR:
ret = poke_user(child, addr, data);
ret = 0;
break;
}
-#endif
-#ifdef PTRACE_GETFPREGS
- case PTRACE_GETFPREGS: /* Get the child FPU state. */
- ret = get_fpregs(vp, child);
- break;
-#endif
-#ifdef PTRACE_SETFPREGS
- case PTRACE_SETFPREGS: /* Set the child FPU state. */
- ret = set_fpregs(vp, child);
- break;
#endif
case PTRACE_GET_THREAD_AREA:
ret = ptrace_get_thread_area(child, addr, vp);
ret = -EIO;
break;
}
-#endif
-#ifdef PTRACE_ARCH_PRCTL
- case PTRACE_ARCH_PRCTL:
- /* XXX Calls ptrace on the host - needs some SMP thinking */
- ret = arch_prctl(child, data, (void __user *) addr);
- break;
#endif
default:
ret = ptrace_request(child, request, addr, data);
#include <string.h>
#include <sys/ptrace.h>
#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
+#include "registers.h"
int save_registers(int pid, struct uml_pt_regs *regs)
{
/* This is set once at boot time and not changed thereafter */
static unsigned long exec_regs[MAX_REG_NR];
+static unsigned long exec_fp_regs[FP_SIZE];
int init_registers(int pid)
{
return -errno;
arch_init_registers(pid);
+ get_fp_registers(pid, exec_fp_regs);
return 0;
}
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, sizeof(exec_regs));
+
+ if (fp_regs)
+ memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
}
static int __init init_syscall_regs(void)
{
- get_safe_registers(syscall_regs);
+ get_safe_registers(syscall_regs, NULL);
syscall_regs[REGS_IP_INDEX] = STUB_CODE +
((unsigned long) &batch_syscall_stub -
(unsigned long) &__syscall_stub_start);
if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
fatal_sigsegv();
+ if (put_fp_registers(pid, regs->fp))
+ fatal_sigsegv();
+
/* Now we set local_using_sysemu to be used for one loop */
local_using_sysemu = get_using_sysemu();
fatal_sigsegv();
}
+ if (get_fp_registers(pid, regs->fp)) {
+ printk(UM_KERN_ERR "userspace - get_fp_registers failed, "
+ "errno = %d\n", errno);
+ fatal_sigsegv();
+ }
+
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if (WIFSTOPPED(status)) {
}
static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[FP_SIZE];
static int __init init_thread_regs(void)
{
- get_safe_registers(thread_regs);
+ get_safe_registers(thread_regs, thread_fp_regs);
/* Set parent's instruction pointer to start of clone-stub */
thread_regs[REGS_IP_INDEX] = STUB_CODE +
(unsigned long) stub_clone_handler -
return err;
}
+ err = put_fp_registers(pid, thread_fp_regs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
+ "failed, pid = %d, err = %d\n", pid, err);
+ return err;
+ }
+
/* set a well known return code for detection of child write failure */
child_data->err = 12345678;
*/
struct user_desc;
-extern int get_fpxregs(struct user_fxsr_struct __user *buf,
- struct task_struct *child);
-extern int set_fpxregs(struct user_fxsr_struct __user *buf,
- struct task_struct *tsk);
-
extern int ptrace_get_thread_area(struct task_struct *child, int idx,
struct user_desc __user *user_desc);
return put_user(tmp, (unsigned long __user *) data);
}
-int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
struct user_i387_struct fpregs;
return n;
}
-int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
int n, cpu = ((struct thread_info *) child->stack)->cpu;
struct user_i387_struct fpregs;
(unsigned long *) &fpregs);
}
-int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
{
int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
struct user_fxsr_struct fpregs;
return n;
}
-int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
{
int n, cpu = ((struct thread_info *) child->stack)->cpu;
struct user_fxsr_struct fpregs;
long subarch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- return -EIO;
+ int ret = -EIO;
+ void __user *datap = (void __user *) data;
+ switch (request) {
+ case PTRACE_GETFPREGS: /* Get the child FPU state. */
+ ret = get_fpregs(datap, child);
+ break;
+ case PTRACE_SETFPREGS: /* Set the child FPU state. */
+ ret = set_fpregs(datap, child);
+ break;
+ case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+ ret = get_fpxregs(datap, child);
+ break;
+ case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+ ret = set_fpxregs(datap, child);
+ break;
+ default:
+ ret = -EIO;
+ }
+ return ret;
}
struct uml_pt_regs {
unsigned long gp[MAX_REG_NR];
+ unsigned long fp[HOST_FPX_SIZE];
struct faultinfo faultinfo;
long syscall;
int is_user;
return instr == 0x050f;
}
-int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
long fpregs[HOST_FP_SIZE];
return n;
}
-int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
int n, cpu = ((struct thread_info *) child->stack)->cpu;
long fpregs[HOST_FP_SIZE];
void __user *datap = (void __user *) data;
switch (request) {
- case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+ case PTRACE_GETFPREGS: /* Get the child FPU state. */
ret = get_fpregs(datap, child);
break;
- case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+ case PTRACE_SETFPREGS: /* Set the child FPU state. */
ret = set_fpregs(datap, child);
break;
+ case PTRACE_ARCH_PRCTL:
+ /* XXX Calls ptrace on the host - needs some SMP thinking */
+ ret = arch_prctl(child, data, (void __user *) addr);
+ break;
}
return ret;
struct uml_pt_regs {
unsigned long gp[MAX_REG_NR];
+ unsigned long fp[HOST_FP_SIZE];
struct faultinfo faultinfo;
long syscall;
int is_user;
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
#elif defined(__x86_64__)
__asm__ (
- "mul %[mul_frac] ; shrd $32, %[hi], %[lo]"
+ "mulq %[mul_frac] ; shrd $32, %[hi], %[lo]"
: [lo]"=a"(product),
[hi]"=d"(tmp)
: "0"(delta),
perf_callchain_store(entry, regs->ip);
+ if (!current->mm)
+ return;
+
if (perf_callchain_user32(regs, entry))
return;
*/
if (bus) {
struct pci_bus *child;
- list_for_each_entry(child, &bus->children, node)
- pcie_bus_configure_settings(child, child->self->pcie_mpss);
+ list_for_each_entry(child, &bus->children, node) {
+ struct pci_dev *self = child->self;
+ if (!self)
+ continue;
+
+ pcie_bus_configure_settings(child, self->pcie_mpss);
+ }
}
if (!bus)
PFN_UP(start_pci), PFN_DOWN(last));
return identity;
}
+
+static unsigned long __init xen_get_max_pages(void)
+{
+ unsigned long max_pages = MAX_DOMAIN_PAGES;
+ domid_t domid = DOMID_SELF;
+ int ret;
+
+ ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid);
+ if (ret > 0)
+ max_pages = ret;
+ return min(max_pages, MAX_DOMAIN_PAGES);
+}
+
/**
* machine_specific_memory_setup - Hook for machine specific memory setup.
**/
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+ extra_limit = xen_get_max_pages();
+ if (extra_limit >= max_pfn)
+ extra_pages = extra_limit - max_pfn;
+ else
+ extra_pages = 0;
+
extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
/*
#include <xen/page.h>
#include <xen/events.h>
+#include <xen/hvc-console.h>
#include "xen-ops.h"
#include "mmu.h"
unsigned cpu;
unsigned int i;
+ if (skip_ioapic_setup) {
+ char *m = (max_cpus == 0) ?
+ "The nosmp parameter is incompatible with Xen; " \
+ "use Xen dom0_max_vcpus=1 parameter" :
+ "The noapic parameter is incompatible with Xen";
+
+ xen_raw_printk(m);
+ panic(m);
+ }
xen_init_lock_cpu(0);
smp_store_cpu_info(0);
struct pvclock_vcpu_time_info *src;
cycle_t ret;
- src = &get_cpu_var(xen_vcpu)->time;
+ preempt_disable_notrace();
+ src = &__get_cpu_var(xen_vcpu)->time;
ret = pvclock_clocksource_read(src);
- put_cpu_var(xen_vcpu);
+ preempt_enable_notrace();
return ret;
}
/*
* If there's something pending, mask events again so we can
- * jump back into xen_hypervisor_callback
+ * jump back into xen_hypervisor_callback. Otherwise do not
+ * touch XEN_vcpu_info_mask.
*/
- sete XEN_vcpu_info_mask(%eax)
+ jne 1f
+ movb $1, XEN_vcpu_info_mask(%eax)
- popl %eax
+1: popl %eax
/*
* From this point on the registers are restored and the stack
/* Maximum sleep allowed via Sleep() operator */
-#define ACPI_MAX_SLEEP 20000 /* Two seconds */
+#define ACPI_MAX_SLEEP 2000 /* Two seconds */
/******************************************************************************
*
bool "APEI Generic Hardware Error Source"
depends on ACPI_APEI && X86
select ACPI_HED
+ select IRQ_WORK
select LLIST
select GENERIC_ALLOCATOR
help
};
capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
- capbuf[OSC_SUPPORT_TYPE] = 0;
+ capbuf[OSC_SUPPORT_TYPE] = 1;
capbuf[OSC_CONTROL_TYPE] = 0;
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))
#endif /* !CONFIG_HIBERNATE_CALLBACKS */
+#ifdef CONFIG_PM_RUNTIME
+/*
+ * Hooks to provide runtime PM of the pclk (bus clock). It is safe to
+ * enable/disable the bus clock at runtime PM suspend/resume as this
+ * does not result in loss of context. However, disabling vcore power
+ * would do, so we leave that to the driver.
+ */
+static int amba_pm_runtime_suspend(struct device *dev)
+{
+ struct amba_device *pcdev = to_amba_device(dev);
+ int ret = pm_generic_runtime_suspend(dev);
+
+ if (ret == 0 && dev->driver)
+ clk_disable(pcdev->pclk);
+
+ return ret;
+}
+
+static int amba_pm_runtime_resume(struct device *dev)
+{
+ struct amba_device *pcdev = to_amba_device(dev);
+ int ret;
+
+ if (dev->driver) {
+ ret = clk_enable(pcdev->pclk);
+ /* Failure is probably fatal to the system, but... */
+ if (ret)
+ return ret;
+ }
+
+ return pm_generic_runtime_resume(dev);
+}
+#endif
+
#ifdef CONFIG_PM
static const struct dev_pm_ops amba_pm = {
.poweroff_noirq = amba_pm_poweroff_noirq,
.restore_noirq = amba_pm_restore_noirq,
SET_RUNTIME_PM_OPS(
- pm_generic_runtime_suspend,
- pm_generic_runtime_resume,
+ amba_pm_runtime_suspend,
+ amba_pm_runtime_resume,
pm_generic_runtime_idle
)
};
if (ret)
break;
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
ret = pcdrv->probe(pcdev, id);
if (ret == 0)
break;
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+
amba_put_disable_pclk(pcdev);
amba_put_disable_vcore(pcdev);
} while (0);
{
struct amba_device *pcdev = to_amba_device(dev);
struct amba_driver *drv = to_amba_driver(dev->driver);
- int ret = drv->remove(pcdev);
+ int ret;
+
+ pm_runtime_get_sync(dev);
+ ret = drv->remove(pcdev);
+ pm_runtime_put_noidle(dev);
+
+ /* Undo the runtime PM settings in amba_probe() */
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
amba_put_disable_pclk(pcdev);
amba_put_disable_vcore(pcdev);
#include <mach/at91sam9_smc.h>
#include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#define DRV_NAME "pata_at91"
#define DRV_VERSION "0.3"
map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL);
if (map->work_buf == NULL) {
ret = -ENOMEM;
- goto err_bus;
+ goto err_map;
}
return map;
-err_bus:
- module_put(map->bus->owner);
err_map:
kfree(map);
err:
void regmap_exit(struct regmap *map)
{
kfree(map->work_buf);
- module_put(map->bus->owner);
kfree(map);
}
EXPORT_SYMBOL_GPL(regmap_exit);
static int bcma_bus_match(struct device *dev, struct device_driver *drv);
static int bcma_device_probe(struct device *dev);
static int bcma_device_remove(struct device *dev);
+static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
{
.match = bcma_bus_match,
.probe = bcma_device_probe,
.remove = bcma_device_remove,
+ .uevent = bcma_device_uevent,
.dev_attrs = bcma_device_attrs,
};
return 0;
}
+static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+
+ return add_uevent_var(env,
+ "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
+ core->id.manuf, core->id.id,
+ core->id.rev, core->id.class);
+}
+
static int __init bcma_modinit(void)
{
int err;
/* Atheros AR3011 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3002) },
{ USB_DEVICE(0x13d3, 0x3304) },
+ { USB_DEVICE(0x0930, 0x0215) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
/* Atheros 3011 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
+ { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- if (err != -EPERM)
+ /* -EPERM: urb is being killed;
+ * -ENODEV: device got disconnected */
+ if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- if (err != -EPERM)
+ /* -EPERM: urb is being killed;
+ * -ENODEV: device got disconnected */
+ if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- if (err != -EPERM)
+ /* -EPERM: urb is being killed;
+ * -ENODEV: device got disconnected */
+ if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/err.h>
+#include <linux/delay.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/sh_timer.h>
static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
{
- int ret;
+ int k, ret;
/* enable clock */
ret = clk_enable(p->clk);
if (ret) {
dev_err(&p->pdev->dev, "cannot enable clock\n");
- return ret;
+ goto err0;
}
/* make sure channel is disabled */
sh_cmt_write(p, CMCOR, 0xffffffff);
sh_cmt_write(p, CMCNT, 0);
+ /*
+ * According to the sh73a0 user's manual, as CMCNT can be operated
+ * only by the RCLK (Pseudo 32 KHz), there's one restriction on
+ * modifying CMCNT register; two RCLK cycles are necessary before
+ * this register is either read or any modification of the value
+ * it holds is reflected in the LSI's actual operation.
+ *
+ * While at it, we're supposed to clear out the CMCNT as of this
+ * moment, so make sure it's processed properly here. This will
+ * take RCLKx2 at maximum.
+ */
+ for (k = 0; k < 100; k++) {
+ if (!sh_cmt_read(p, CMCNT))
+ break;
+ udelay(1);
+ }
+
+ if (sh_cmt_read(p, CMCNT)) {
+ dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
+ ret = -ETIMEDOUT;
+ goto err1;
+ }
+
/* enable channel */
sh_cmt_start_stop_ch(p, 1);
return 0;
+ err1:
+ /* stop clock */
+ clk_disable(p->clk);
+
+ err0:
+ return ret;
}
static void sh_cmt_disable(struct sh_cmt_priv *p)
pr = per_cpu(processors, cpu);
pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+ if (!pr)
+ return -ENODEV;
+
status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
if (ACPI_FAILURE(status))
return -ENODEV;
* @tasklet: Tasklet that gets scheduled from interrupt context to complete a
* transfer and call client callback.
* @client: Cliented owned descriptor list.
+ * @pending_queue: Submitted jobs, to be issued by issue_pending()
* @active: Active descriptor.
* @queue: Queued jobs.
+ * @prepare_queue: Prepared jobs.
* @dma_cfg: The client configuration of this dma channel.
* @configured: whether the dma_cfg configuration is valid
* @base: Pointer to the device instance struct.
struct list_head pending_queue;
struct list_head active;
struct list_head queue;
+ struct list_head prepare_queue;
struct stedma40_chan_cfg dma_cfg;
bool configured;
struct d40_base *base;
list_for_each_entry_safe(d, _d, &d40c->client, node)
if (async_tx_test_ack(&d->txd)) {
- d40_pool_lli_free(d40c, d);
d40_desc_remove(d);
desc = d;
memset(desc, 0, sizeof(*desc));
return d;
}
+/* remove desc from current queue and add it to the pending_queue */
static void d40_desc_queue(struct d40_chan *d40c, struct d40_desc *desc)
{
+ d40_desc_remove(desc);
+ desc->is_in_client_list = false;
list_add_tail(&desc->node, &d40c->pending_queue);
}
static void d40_term_all(struct d40_chan *d40c)
{
struct d40_desc *d40d;
+ struct d40_desc *_d;
/* Release active descriptors */
while ((d40d = d40_first_active_get(d40c))) {
d40_desc_free(d40c, d40d);
}
+ /* Release client owned descriptors */
+ if (!list_empty(&d40c->client))
+ list_for_each_entry_safe(d40d, _d, &d40c->client, node) {
+ d40_desc_remove(d40d);
+ d40_desc_free(d40c, d40d);
+ }
+
+ /* Release descriptors in prepare queue */
+ if (!list_empty(&d40c->prepare_queue))
+ list_for_each_entry_safe(d40d, _d,
+ &d40c->prepare_queue, node) {
+ d40_desc_remove(d40d);
+ d40_desc_free(d40c, d40d);
+ }
+
d40c->pending_tx = 0;
d40c->busy = false;
}
if (!d40d->cyclic) {
if (async_tx_test_ack(&d40d->txd)) {
- d40_pool_lli_free(d40c, d40d);
d40_desc_remove(d40d);
d40_desc_free(d40c, d40d);
} else {
u32 event;
struct d40_phy_res *phy = d40c->phy_chan;
bool is_src;
- struct d40_desc *d;
- struct d40_desc *_d;
-
/* Terminate all queued and active transfers */
d40_term_all(d40c);
- /* Release client owned descriptors */
- if (!list_empty(&d40c->client))
- list_for_each_entry_safe(d, _d, &d40c->client, node) {
- d40_pool_lli_free(d40c, d);
- d40_desc_remove(d);
- d40_desc_free(d40c, d);
- }
-
if (phy == NULL) {
chan_err(d40c, "phy == null\n");
return -EINVAL;
goto err;
}
+ /*
+ * add descriptor to the prepare queue in order to be able
+ * to free them later in terminate_all
+ */
+ list_add_tail(&desc->node, &chan->prepare_queue);
+
spin_unlock_irqrestore(&chan->lock, flags);
return &desc->txd;
INIT_LIST_HEAD(&d40c->queue);
INIT_LIST_HEAD(&d40c->pending_queue);
INIT_LIST_HEAD(&d40c->client);
+ INIT_LIST_HEAD(&d40c->prepare_queue);
tasklet_init(&d40c->tasklet, dma_tasklet,
(unsigned long) d40c);
The Intel Tunnel Creek processor has 5 GPIOs powered by the
core power rail and 9 from suspend power supply.
+config GPIO_U300
+ bool "ST-Ericsson U300 COH 901 335/571 GPIO"
+ depends on GPIOLIB && ARCH_U300
+ help
+ Say yes here to support GPIO interface on ST-Ericsson U300.
+ The names of the two IP block variants supported are
+ COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
+ ports of 8 GPIO pins each.
+
config GPIO_VX855
tristate "VIA VX855/VX875 GPIO"
depends on MFD_SUPPORT && PCI
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
+obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
+obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o
+obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
-
+obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
+#include <linux/gpio.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <mach/gpio.h>
-
#include <asm/mach/irq.h>
struct davinci_gpio_regs {
static int gpio_irq_type(struct irq_data *d, unsigned trigger)
{
- struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
- u32 mask = (u32) irq_data_get_irq_handler_data(d);
-
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
return 0;
}
+/*
+ * Map GPIO A0..A7 (0..7) to irq 64..71,
+ * B0..B7 (7..15) to irq 72..79, and
+ * F0..F7 (16..24) to irq 80..87.
+ */
+static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+
+ if (gpio > EP93XX_GPIO_LINE_MAX_IRQ)
+ return -EINVAL;
+
+ return 64 + gpio;
+}
+
static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
{
bgc->gc.label = bank->label;
bgc->gc.base = bank->base;
- if (bank->has_debounce)
+ if (bank->has_debounce) {
bgc->gc.set_debounce = ep93xx_gpio_set_debounce;
+ bgc->gc.to_irq = ep93xx_gpio_to_irq;
+ }
return gpiochip_add(&bgc->gc);
}
return 0;
}
-int __devexit bgpio_remove(struct bgpio_chip *bgc)
+int bgpio_remove(struct bgpio_chip *bgc)
{
int err = gpiochip_remove(&bgc->gc);
}
EXPORT_SYMBOL_GPL(bgpio_remove);
-int __devinit bgpio_init(struct bgpio_chip *bgc,
- struct device *dev,
- unsigned long sz,
- void __iomem *dat,
- void __iomem *set,
- void __iomem *clr,
- void __iomem *dirout,
- void __iomem *dirin,
- bool big_endian)
+int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
+ unsigned long sz, void __iomem *dat, void __iomem *set,
+ void __iomem *clr, void __iomem *dirout, void __iomem *dirin,
+ bool big_endian)
{
int ret;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <asm/mach/irq.h>
#include <mach/regs-gpio.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
/*
* Configure a GPIO line for either GPIO function, or its internal
#include <mach/hardware.h>
#include <mach/platform.h>
-#include "common.h"
+#include <mach/gpio-lpc32xx.h>
#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000)
#define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004)
#include <asm/mach/irq.h>
#include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
/*
* The GPIO module in the Nomadik family of Systems-on-Chip is an
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <asm/mach/irq.h>
struct gpio_bank {
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <asm/gpio.h>
#include <mach/hardware.h>
-#include "generic.h"
static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
{
return 0;
}
-
+static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return TEGRA_GPIO_TO_IRQ(offset);
+}
static struct gpio_chip tegra_gpio_chip = {
.label = "tegra-gpio",
.get = tegra_gpio_get,
.direction_output = tegra_gpio_direction_output,
.set = tegra_gpio_set,
+ .to_irq = tegra_gpio_to_irq,
.base = 0,
.ngpio = TEGRA_NR_GPIOS,
};
static int __init tegra_gpio_init(void)
{
struct tegra_gpio_bank *bank;
+ int gpio;
int i;
int j;
gpiochip_add(&tegra_gpio_chip);
- for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
- bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
+ for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
+ int irq = TEGRA_GPIO_TO_IRQ(gpio);
+ /* No validity check; all Tegra GPIOs are valid IRQs */
+
+ bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
- irq_set_lockdep_class(i, &gpio_lock_class);
- irq_set_chip_data(i, bank);
- irq_set_chip_and_handler(i, &tegra_gpio_irq_chip,
+ irq_set_lockdep_class(irq, &gpio_lock_class);
+ irq_set_chip_data(irq, bank);
+ irq_set_chip_and_handler(irq, &tegra_gpio_irq_chip,
handle_simple_irq);
- set_irq_flags(i, IRQF_VALID);
+ set_irq_flags(irq, IRQF_VALID);
}
for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
/*
* U300 GPIO module.
*
- * Copyright (C) 2007-2009 ST-Ericsson AB
+ * Copyright (C) 2007-2011 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* This can driver either of the two basic GPIO cores
* available in the U300 platforms:
* COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
* COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
- * Notice that you also have inline macros in <asm-arch/gpio.h>
- * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Linus Walleij <linus.walleij@linaro.org>
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- *
*/
#include <linux/module.h>
+#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <mach/gpio-u300.h>
-/* Reference to GPIO block clock */
-static struct clk *clk;
+/*
+ * Bias modes for U300 GPIOs
+ *
+ * GPIO_U300_CONFIG_BIAS_UNKNOWN: this bias mode is not known to us
+ * GPIO_U300_CONFIG_BIAS_FLOAT: no specific bias, the GPIO will float or state
+ * is not controlled by software
+ * GPIO_U300_CONFIG_BIAS_PULL_UP: the GPIO will be pulled up (usually with high
+ * impedance to VDD)
+ */
+#define GPIO_U300_CONFIG_BIAS_UNKNOWN 0x1000
+#define GPIO_U300_CONFIG_BIAS_FLOAT 0x1001
+#define GPIO_U300_CONFIG_BIAS_PULL_UP 0x1002
-/* Memory resource */
-static struct resource *memres;
-static void __iomem *virtbase;
-static struct device *gpiodev;
+/*
+ * Drive modes for U300 GPIOs (output)
+ *
+ * GPIO_U300_CONFIG_DRIVE_PUSH_PULL: the GPIO will be driven actively high and
+ * low, this is the most typical case and is typically achieved with two
+ * active transistors on the output
+ * GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: the GPIO will be driven with open drain
+ * (open collector) which means it is usually wired with other output
+ * ports which are then pulled up with an external resistor
+ * GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: the GPIO will be driven with open drain
+ * (open emitter) which is the same as open drain mutatis mutandis but
+ * pulled to ground
+ */
+#define GPIO_U300_CONFIG_DRIVE_PUSH_PULL 0x2000
+#define GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN 0x2001
+#define GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE 0x2002
+
+/*
+ * Register definitions for COH 901 335 variant
+ */
+#define U300_335_PORT_STRIDE (0x1C)
+/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
+#define U300_335_PXPDIR (0x00)
+#define U300_335_PXPDOR (0x00)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_335_PXPCR (0x04)
+/* This register layout is the same in both blocks */
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_335_PXIEV (0x08)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_335_PXIEN (0x0C)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_335_PXIFR (0x10)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_335_PXICR (0x14)
+/* This register layout is the same in both blocks */
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_335_PXPER (0x18)
+/* This register layout is the same in both blocks */
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
+/* Control Register 32bit (R/W) */
+#define U300_335_CR (0x54)
+#define U300_335_CR_BLOCK_CLOCK_ENABLE (0x00000001UL)
+
+/*
+ * Register definitions for COH 901 571 / 3 variant
+ */
+#define U300_571_PORT_STRIDE (0x30)
+/*
+ * Control Register 32bit (R/W)
+ * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
+ * gives the number of GPIO pins.
+ * bit 8-2 (mask 0x000001FC) contains the core version ID.
+ */
+#define U300_571_CR (0x00)
+#define U300_571_CR_SYNC_SEL_ENABLE (0x00000002UL)
+#define U300_571_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL)
+/*
+ * These registers have the same layout and function as the corresponding
+ * COH 901 335 registers, just at different offset.
+ */
+#define U300_571_PXPDIR (0x04)
+#define U300_571_PXPDOR (0x08)
+#define U300_571_PXPCR (0x0C)
+#define U300_571_PXPER (0x10)
+#define U300_571_PXIEV (0x14)
+#define U300_571_PXIEN (0x18)
+#define U300_571_PXIFR (0x1C)
+#define U300_571_PXICR (0x20)
+
+/* 8 bits per port, no version has more than 7 ports */
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * 7)
+
+struct u300_gpio {
+ struct gpio_chip chip;
+ struct list_head port_list;
+ struct clk *clk;
+ struct resource *memres;
+ void __iomem *base;
+ struct device *dev;
+ int irq_base;
+ u32 stride;
+ /* Register offsets */
+ u32 pcr;
+ u32 dor;
+ u32 dir;
+ u32 per;
+ u32 icr;
+ u32 ien;
+ u32 iev;
+};
struct u300_gpio_port {
- const char *name;
+ struct list_head node;
+ struct u300_gpio *gpio;
+ char name[8];
int irq;
int number;
+ u8 toggle_edge_mode;
};
+/*
+ * Macro to expand to read a specific register found in the "gpio"
+ * struct. It requires the struct u300_gpio *gpio variable to exist in
+ * its context. It calculates the port offset from the given pin
+ * offset, muliplies by the port stride and adds the register offset
+ * so it provides a pointer to the desired register.
+ */
+#define U300_PIN_REG(pin, reg) \
+ (gpio->base + (pin >> 3) * gpio->stride + gpio->reg)
-static struct u300_gpio_port gpio_ports[] = {
- {
- .name = "gpio0",
- .number = 0,
- },
- {
- .name = "gpio1",
- .number = 1,
- },
- {
- .name = "gpio2",
- .number = 2,
- },
-#ifdef U300_COH901571_3
- {
- .name = "gpio3",
- .number = 3,
- },
- {
- .name = "gpio4",
- .number = 4,
- },
-#ifdef CONFIG_MACH_U300_BS335
- {
- .name = "gpio5",
- .number = 5,
- },
- {
- .name = "gpio6",
- .number = 6,
- },
-#endif
-#endif
+/*
+ * Provides a bitmask for a specific gpio pin inside an 8-bit GPIO
+ * register.
+ */
+#define U300_PIN_BIT(pin) \
+ (1 << (pin & 0x07))
+struct u300_gpio_confdata {
+ u16 bias_mode;
+ bool output;
+ int outval;
};
+/* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */
+#define BS335_GPIO_NUM_PORTS 7
+/* BS365 has five ports of 8 bits each = GPIO pins 0..39 */
+#define BS365_GPIO_NUM_PORTS 5
-#ifdef U300_COH901571_3
+#define U300_FLOATING_INPUT { \
+ .bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \
+ .output = false, \
+}
-/* Default input value */
-#define DEFAULT_OUTPUT_LOW 0
-#define DEFAULT_OUTPUT_HIGH 1
+#define U300_PULL_UP_INPUT { \
+ .bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \
+ .output = false, \
+}
-/* GPIO Pull-Up status */
-#define DISABLE_PULL_UP 0
-#define ENABLE_PULL_UP 1
+#define U300_OUTPUT_LOW { \
+ .output = true, \
+ .outval = 0, \
+}
-#define GPIO_NOT_USED 0
-#define GPIO_IN 1
-#define GPIO_OUT 2
+#define U300_OUTPUT_HIGH { \
+ .output = true, \
+ .outval = 1, \
+}
-struct u300_gpio_configuration_data {
- unsigned char pin_usage;
- unsigned char default_output_value;
- unsigned char pull_up;
-};
/* Initial configuration */
-const struct u300_gpio_configuration_data
-u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
-#ifdef CONFIG_MACH_U300_BS335
+static const struct __initdata u300_gpio_confdata
+bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
/* Port 0, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_HIGH,
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
},
/* Port 1, pins 0-7 */
{
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_PULL_UP_INPUT,
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_HIGH,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
},
/* Port 2, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_LOW,
+ U300_PULL_UP_INPUT,
+ U300_OUTPUT_LOW,
+ U300_PULL_UP_INPUT,
},
/* Port 3, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_PULL_UP_INPUT,
+ U300_OUTPUT_LOW,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
},
/* Port 4, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
},
/* Port 5, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
},
/* Port 6, pind 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
}
-#endif
+};
-#ifdef CONFIG_MACH_U300_BS365
+static const struct __initdata u300_gpio_confdata
+bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
/* Port 0, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_LOW,
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_PULL_UP_INPUT,
+ U300_FLOATING_INPUT,
},
/* Port 1, pins 0-7 */
{
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ U300_OUTPUT_LOW,
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_LOW,
+ U300_FLOATING_INPUT,
+ U300_FLOATING_INPUT,
+ U300_OUTPUT_HIGH,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
},
/* Port 2, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ U300_FLOATING_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
},
/* Port 3, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
},
/* Port 4, pins 0-7 */
{
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
+ U300_PULL_UP_INPUT,
/* These 4 pins doesn't exist on DB3210 */
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
- {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
+ U300_OUTPUT_LOW,
}
-#endif
};
-#endif
-
-/* No users == we can power down GPIO */
-static int gpio_users;
-
-struct gpio_struct {
- int (*callback)(void *);
- void *data;
- int users;
-};
-
-static struct gpio_struct gpio_pin[U300_GPIO_MAX];
-
-/*
- * Let drivers register callback in order to get notified when there is
- * an interrupt on the gpio pin
+/**
+ * to_u300_gpio() - get the pointer to u300_gpio
+ * @chip: the gpio chip member of the structure u300_gpio
*/
-int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
+static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip)
{
- if (gpio_pin[gpio].callback)
- dev_warn(gpiodev, "%s: WARNING: callback already "
- "registered for gpio pin#%d\n", __func__, gpio);
- gpio_pin[gpio].callback = func;
- gpio_pin[gpio].data = data;
-
- return 0;
+ return container_of(chip, struct u300_gpio, chip);
}
-EXPORT_SYMBOL(gpio_register_callback);
-int gpio_unregister_callback(unsigned gpio)
+static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- if (!gpio_pin[gpio].callback)
- dev_warn(gpiodev, "%s: WARNING: callback already "
- "unregistered for gpio pin#%d\n", __func__, gpio);
- gpio_pin[gpio].callback = NULL;
- gpio_pin[gpio].data = NULL;
+ struct u300_gpio *gpio = to_u300_gpio(chip);
- return 0;
+ return readl(U300_PIN_REG(offset, dir)) & U300_PIN_BIT(offset);
}
-EXPORT_SYMBOL(gpio_unregister_callback);
-/* Non-zero means valid */
-int gpio_is_valid(int number)
+static void u300_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
- if (number >= 0 &&
- number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
- return 1;
- return 0;
-}
-EXPORT_SYMBOL(gpio_is_valid);
+ struct u300_gpio *gpio = to_u300_gpio(chip);
+ unsigned long flags;
+ u32 val;
-int gpio_request(unsigned gpio, const char *label)
-{
- if (gpio_pin[gpio].users)
- return -EINVAL;
- else
- gpio_pin[gpio].users++;
+ local_irq_save(flags);
- gpio_users++;
+ val = readl(U300_PIN_REG(offset, dor));
+ if (value)
+ writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, dor));
+ else
+ writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, dor));
- return 0;
+ local_irq_restore(flags);
}
-EXPORT_SYMBOL(gpio_request);
-void gpio_free(unsigned gpio)
+static int u300_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
- gpio_users--;
- gpio_pin[gpio].users--;
- if (unlikely(gpio_pin[gpio].users < 0)) {
- dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
- gpio);
- gpio_pin[gpio].users = 0;
- }
-
- return;
-}
-EXPORT_SYMBOL(gpio_free);
+ struct u300_gpio *gpio = to_u300_gpio(chip);
+ unsigned long flags;
+ u32 val;
-/* This returns zero or nonzero */
-int gpio_get_value(unsigned gpio)
-{
- return readl(virtbase + U300_GPIO_PXPDIR +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
+ local_irq_save(flags);
+ val = readl(U300_PIN_REG(offset, pcr));
+ /* Mask out this pin, note 2 bits per setting */
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1));
+ writel(val, U300_PIN_REG(offset, pcr));
+ local_irq_restore(flags);
+ return 0;
}
-EXPORT_SYMBOL(gpio_get_value);
-/*
- * We hope that the compiler will optimize away the unused branch
- * in case "value" is a constant
- */
-void gpio_set_value(unsigned gpio, int value)
+static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
{
- u32 val;
+ struct u300_gpio *gpio = to_u300_gpio(chip);
unsigned long flags;
+ u32 oldmode;
+ u32 val;
local_irq_save(flags);
- if (value) {
- /* set */
- val = readl(virtbase + U300_GPIO_PXPDOR +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
- & (1 << (gpio & 0x07));
- writel(val | (1 << (gpio & 0x07)), virtbase +
- U300_GPIO_PXPDOR +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
- } else {
- /* clear */
- val = readl(virtbase + U300_GPIO_PXPDOR +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
- & (1 << (gpio & 0x07));
- writel(val & ~(1 << (gpio & 0x07)), virtbase +
- U300_GPIO_PXPDOR +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+ val = readl(U300_PIN_REG(offset, pcr));
+ /*
+ * Drive mode must be set by the special mode set function, set
+ * push/pull mode by default if no mode has been selected.
+ */
+ oldmode = val & (U300_GPIO_PXPCR_PIN_MODE_MASK <<
+ ((offset & 0x07) << 1));
+ /* mode = 0 means input, else some mode is already set */
+ if (oldmode == 0) {
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK <<
+ ((offset & 0x07) << 1));
+ val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
+ << ((offset & 0x07) << 1));
+ writel(val, U300_PIN_REG(offset, pcr));
}
+ u300_gpio_set(chip, offset, value);
local_irq_restore(flags);
+ return 0;
}
-EXPORT_SYMBOL(gpio_set_value);
-int gpio_direction_input(unsigned gpio)
+static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
+ struct u300_gpio *gpio = to_u300_gpio(chip);
+ int retirq = gpio->irq_base + offset;
+
+ dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset,
+ retirq);
+ return retirq;
+}
+
+static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
+ u16 param, unsigned long *data)
+{
+ struct u300_gpio *gpio = to_u300_gpio(chip);
unsigned long flags;
u32 val;
- if (gpio > U300_GPIO_MAX)
- return -EINVAL;
-
local_irq_save(flags);
- val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- /* Mask out this pin*/
- val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
- /* This is not needed since it sets the bits to zero.*/
- /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
- writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
+ switch (param) {
+ case GPIO_U300_CONFIG_BIAS_UNKNOWN:
+ case GPIO_U300_CONFIG_BIAS_FLOAT:
+ val = readl(U300_PIN_REG(offset, per));
+ writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
+ break;
+ case GPIO_U300_CONFIG_BIAS_PULL_UP:
+ val = readl(U300_PIN_REG(offset, per));
+ writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
+ break;
+ case GPIO_U300_CONFIG_DRIVE_PUSH_PULL:
+ val = readl(U300_PIN_REG(offset, pcr));
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
+ << ((offset & 0x07) << 1));
+ val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
+ << ((offset & 0x07) << 1));
+ writel(val, U300_PIN_REG(offset, pcr));
+ break;
+ case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN:
+ val = readl(U300_PIN_REG(offset, pcr));
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
+ << ((offset & 0x07) << 1));
+ val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN
+ << ((offset & 0x07) << 1));
+ writel(val, U300_PIN_REG(offset, pcr));
+ break;
+ case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE:
+ val = readl(U300_PIN_REG(offset, pcr));
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
+ << ((offset & 0x07) << 1));
+ val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE
+ << ((offset & 0x07) << 1));
+ writel(val, U300_PIN_REG(offset, pcr));
+ break;
+ default:
+ local_irq_restore(flags);
+ dev_err(gpio->dev, "illegal configuration requested\n");
+ return -EINVAL;
+ }
local_irq_restore(flags);
return 0;
}
-EXPORT_SYMBOL(gpio_direction_input);
-int gpio_direction_output(unsigned gpio, int value)
+static struct gpio_chip u300_gpio_chip = {
+ .label = "u300-gpio-chip",
+ .owner = THIS_MODULE,
+ .get = u300_gpio_get,
+ .set = u300_gpio_set,
+ .direction_input = u300_gpio_direction_input,
+ .direction_output = u300_gpio_direction_output,
+ .to_irq = u300_gpio_to_irq,
+};
+
+static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset)
{
- unsigned long flags;
u32 val;
- if (gpio > U300_GPIO_MAX)
- return -EINVAL;
-
- local_irq_save(flags);
- val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- /* Mask out this pin */
- val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
- /*
- * FIXME: configure for push/pull, open drain or open source per pin
- * in setup. The current driver will only support push/pull.
- */
- val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
- << ((gpio & 0x07) << 1));
- writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- gpio_set_value(gpio, value);
- local_irq_restore(flags);
- return 0;
+ val = readl(U300_PIN_REG(offset, icr));
+ /* Set mode depending on state */
+ if (u300_gpio_get(&gpio->chip, offset)) {
+ /* High now, let's trigger on falling edge next then */
+ writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr));
+ dev_dbg(gpio->dev, "next IRQ on falling edge on pin %d\n",
+ offset);
+ } else {
+ /* Low now, let's trigger on rising edge next then */
+ writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr));
+ dev_dbg(gpio->dev, "next IRQ on rising edge on pin %d\n",
+ offset);
+ }
}
-EXPORT_SYMBOL(gpio_direction_output);
-/*
- * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
- */
-void enable_irq_on_gpio_pin(unsigned gpio, int edge)
+static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger)
{
+ struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
+ struct u300_gpio *gpio = port->gpio;
+ int offset = d->irq - gpio->irq_base;
u32 val;
- unsigned long flags;
- local_irq_save(flags);
- val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- val |= (1 << (gpio & 0x07));
- writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- if (edge)
- val |= (1 << (gpio & 0x07));
- else
- val &= ~(1 << (gpio & 0x07));
- writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- local_irq_restore(flags);
+ if ((trigger & IRQF_TRIGGER_RISING) &&
+ (trigger & IRQF_TRIGGER_FALLING)) {
+ /*
+ * The GPIO block can only trigger on falling OR rising edges,
+ * not both. So we need to toggle the mode whenever the pin
+ * goes from one state to the other with a special state flag
+ */
+ dev_dbg(gpio->dev,
+ "trigger on both rising and falling edge on pin %d\n",
+ offset);
+ port->toggle_edge_mode |= U300_PIN_BIT(offset);
+ u300_toggle_trigger(gpio, offset);
+ } else if (trigger & IRQF_TRIGGER_RISING) {
+ dev_dbg(gpio->dev, "trigger on rising edge on pin %d\n",
+ offset);
+ val = readl(U300_PIN_REG(offset, icr));
+ writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr));
+ port->toggle_edge_mode &= ~U300_PIN_BIT(offset);
+ } else if (trigger & IRQF_TRIGGER_FALLING) {
+ dev_dbg(gpio->dev, "trigger on falling edge on pin %d\n",
+ offset);
+ val = readl(U300_PIN_REG(offset, icr));
+ writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr));
+ port->toggle_edge_mode &= ~U300_PIN_BIT(offset);
+ }
+
+ return 0;
}
-EXPORT_SYMBOL(enable_irq_on_gpio_pin);
-void disable_irq_on_gpio_pin(unsigned gpio)
+static void u300_gpio_irq_enable(struct irq_data *d)
{
+ struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
+ struct u300_gpio *gpio = port->gpio;
+ int offset = d->irq - gpio->irq_base;
u32 val;
unsigned long flags;
local_irq_save(flags);
- val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- val &= ~(1 << (gpio & 0x07));
- writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
+ val = readl(U300_PIN_REG(offset, ien));
+ writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien));
local_irq_restore(flags);
}
-EXPORT_SYMBOL(disable_irq_on_gpio_pin);
-/* Enable (value == 0) or disable (value == 1) internal pullup */
-void gpio_pullup(unsigned gpio, int value)
+static void u300_gpio_irq_disable(struct irq_data *d)
{
+ struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
+ struct u300_gpio *gpio = port->gpio;
+ int offset = d->irq - gpio->irq_base;
u32 val;
unsigned long flags;
local_irq_save(flags);
- if (value) {
- val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
- } else {
- val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
- U300_GPIO_PORTX_SPACING);
- writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
- PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
- }
+ val = readl(U300_PIN_REG(offset, ien));
+ writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, ien));
local_irq_restore(flags);
}
-EXPORT_SYMBOL(gpio_pullup);
-static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
+static struct irq_chip u300_gpio_irqchip = {
+ .name = "u300-gpio-irqchip",
+ .irq_enable = u300_gpio_irq_enable,
+ .irq_disable = u300_gpio_irq_disable,
+ .irq_set_type = u300_gpio_irq_type,
+
+};
+
+static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct u300_gpio_port *port = dev_id;
- u32 val;
- int pin;
+ struct u300_gpio_port *port = irq_get_handler_data(irq);
+ struct u300_gpio *gpio = port->gpio;
+ int pinoffset = port->number << 3; /* get the right stride */
+ unsigned long val;
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
/* Read event register */
- val = readl(virtbase + U300_GPIO_PXIEV + port->number *
- U300_GPIO_PORTX_SPACING);
- /* Mask with enable register */
- val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
- U300_GPIO_PORTX_SPACING);
+ val = readl(U300_PIN_REG(pinoffset, iev));
/* Mask relevant bits */
- val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
+ val &= 0xFFU; /* 8 bits per port */
/* ACK IRQ (clear event) */
- writel(val, virtbase + U300_GPIO_PXIEV + port->number *
- U300_GPIO_PORTX_SPACING);
- /* Print message */
- while (val != 0) {
- unsigned gpio;
-
- pin = __ffs(val);
- /* mask off this pin */
- val &= ~(1 << pin);
- gpio = (port->number << 3) + pin;
-
- if (gpio_pin[gpio].callback)
- (void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
- else
- dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
- gpio);
+ writel(val, U300_PIN_REG(pinoffset, iev));
+
+ /* Call IRQ handler */
+ if (val != 0) {
+ int irqoffset;
+
+ for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) {
+ int pin_irq = gpio->irq_base + (port->number << 3)
+ + irqoffset;
+ int offset = pinoffset + irqoffset;
+
+ dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n",
+ pin_irq, offset);
+ generic_handle_irq(pin_irq);
+ /*
+ * Triggering IRQ on both rising and falling edge
+ * needs mockery
+ */
+ if (port->toggle_edge_mode & U300_PIN_BIT(offset))
+ u300_toggle_trigger(gpio, offset);
+ }
}
- return IRQ_HANDLED;
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
-static void gpio_set_initial_values(void)
+static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
+ int offset,
+ const struct u300_gpio_confdata *conf)
{
-#ifdef U300_COH901571_3
- int i, j;
- unsigned long flags;
- u32 val;
+ /* Set mode: input or output */
+ if (conf->output) {
+ u300_gpio_direction_output(&gpio->chip, offset, conf->outval);
- /* Write default values to all pins */
- for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
- val = 0;
- for (j = 0; j < 8; j++)
- val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
- local_irq_save(flags);
- writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
- local_irq_restore(flags);
+ /* Deactivate bias mode for output */
+ u300_gpio_config(&gpio->chip, offset,
+ GPIO_U300_CONFIG_BIAS_FLOAT,
+ NULL);
+
+ /* Set drive mode for output */
+ u300_gpio_config(&gpio->chip, offset,
+ GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL);
+
+ dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n",
+ offset, conf->outval);
+ } else {
+ u300_gpio_direction_input(&gpio->chip, offset);
+
+ /* Always set output low on input pins */
+ u300_gpio_set(&gpio->chip, offset, 0);
+
+ /* Set bias mode for input */
+ u300_gpio_config(&gpio->chip, offset, conf->bias_mode, NULL);
+
+ dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n",
+ offset, conf->bias_mode);
}
+}
- /*
- * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
- * to output and 'GPIO_IN' to input for each port. And initialize
- * default value on outputs.
- */
- for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
- for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
- local_irq_save(flags);
- val = readl(virtbase + U300_GPIO_PXPCR +
- i * U300_GPIO_PORTX_SPACING);
- /* Mask out this pin */
- val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
-
- if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
- val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
- writel(val, virtbase + U300_GPIO_PXPCR +
- i * U300_GPIO_PORTX_SPACING);
- local_irq_restore(flags);
+static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio,
+ struct u300_gpio_platform *plat)
+{
+ int i, j;
+
+ /* Write default config and values to all pins */
+ for (i = 0; i < plat->ports; i++) {
+ for (j = 0; j < 8; j++) {
+ const struct u300_gpio_confdata *conf;
+ int offset = (i*8) + j;
+
+ if (plat->variant == U300_GPIO_COH901571_3_BS335)
+ conf = &bs335_gpio_config[i][j];
+ else if (plat->variant == U300_GPIO_COH901571_3_BS365)
+ conf = &bs365_gpio_config[i][j];
+ else
+ break;
+
+ u300_gpio_init_pin(gpio, offset, conf);
}
}
+}
- /* Enable or disable the internal pull-ups in the GPIO ASIC block */
- for (i = 0; i < U300_GPIO_MAX; i++) {
- val = 0;
- for (j = 0; j < 8; j++)
- val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j);
- local_irq_save(flags);
- writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
- local_irq_restore(flags);
+static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
+{
+ struct u300_gpio_port *port;
+ struct list_head *p, *n;
+
+ list_for_each_safe(p, n, &gpio->port_list) {
+ port = list_entry(p, struct u300_gpio_port, node);
+ list_del(&port->node);
+ free_irq(port->irq, port);
+ kfree(port);
}
-#endif
}
-static int __init gpio_probe(struct platform_device *pdev)
+static int __init u300_gpio_probe(struct platform_device *pdev)
{
- u32 val;
+ struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev);
+ struct u300_gpio *gpio;
int err = 0;
+ int portno;
+ u32 val;
+ u32 ifr;
int i;
- int num_irqs;
- gpiodev = &pdev->dev;
- memset(gpio_pin, 0, sizeof(gpio_pin));
+ gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL);
+ if (gpio == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ gpio->chip = u300_gpio_chip;
+ gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT;
+ gpio->irq_base = plat->gpio_irq_base;
+ gpio->chip.dev = &pdev->dev;
+ gpio->chip.base = plat->gpio_base;
+ gpio->dev = &pdev->dev;
/* Get GPIO clock */
- clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(clk)) {
- err = PTR_ERR(clk);
- dev_err(gpiodev, "could not get GPIO clock\n");
+ gpio->clk = clk_get(gpio->dev, NULL);
+ if (IS_ERR(gpio->clk)) {
+ err = PTR_ERR(gpio->clk);
+ dev_err(gpio->dev, "could not get GPIO clock\n");
goto err_no_clk;
}
- err = clk_enable(clk);
+ err = clk_enable(gpio->clk);
if (err) {
- dev_err(gpiodev, "could not enable GPIO clock\n");
+ dev_err(gpio->dev, "could not enable GPIO clock\n");
goto err_no_clk_enable;
}
- memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!memres)
+ gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!gpio->memres) {
+ dev_err(gpio->dev, "could not get GPIO memory resource\n");
+ err = -ENODEV;
goto err_no_resource;
+ }
- if (!request_mem_region(memres->start, resource_size(memres),
+ if (!request_mem_region(gpio->memres->start,
+ resource_size(gpio->memres),
"GPIO Controller")) {
err = -ENODEV;
goto err_no_ioregion;
}
- virtbase = ioremap(memres->start, resource_size(memres));
- if (!virtbase) {
+ gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres));
+ if (!gpio->base) {
err = -ENOMEM;
goto err_no_ioremap;
}
- dev_info(gpiodev, "remapped 0x%08x to %p\n",
- memres->start, virtbase);
-
-#ifdef U300_COH901335
- dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
- /* Turn on the GPIO block */
- writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
-#endif
-
-#ifdef U300_COH901571_3
- dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
- val = readl(virtbase + U300_GPIO_CR);
- dev_info(gpiodev, "COH901571/3 block version: %d, " \
- "number of cores: %d\n",
- ((val & 0x0000FE00) >> 9),
- ((val & 0x000001FC) >> 2));
- writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
-#endif
-
- gpio_set_initial_values();
-
- for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
-
- gpio_ports[num_irqs].irq =
- platform_get_irq_byname(pdev,
- gpio_ports[num_irqs].name);
-
- err = request_irq(gpio_ports[num_irqs].irq,
- gpio_irq_handler, IRQF_DISABLED,
- gpio_ports[num_irqs].name,
- &gpio_ports[num_irqs]);
- if (err) {
- dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
- gpio_ports[num_irqs].name);
- goto err_no_irq;
+
+ if (plat->variant == U300_GPIO_COH901335) {
+ dev_info(gpio->dev,
+ "initializing GPIO Controller COH 901 335\n");
+ gpio->stride = U300_335_PORT_STRIDE;
+ gpio->pcr = U300_335_PXPCR;
+ gpio->dor = U300_335_PXPDOR;
+ gpio->dir = U300_335_PXPDIR;
+ gpio->per = U300_335_PXPER;
+ gpio->icr = U300_335_PXICR;
+ gpio->ien = U300_335_PXIEN;
+ gpio->iev = U300_335_PXIEV;
+ ifr = U300_335_PXIFR;
+
+ /* Turn on the GPIO block */
+ writel(U300_335_CR_BLOCK_CLOCK_ENABLE,
+ gpio->base + U300_335_CR);
+ } else if (plat->variant == U300_GPIO_COH901571_3_BS335 ||
+ plat->variant == U300_GPIO_COH901571_3_BS365) {
+ dev_info(gpio->dev,
+ "initializing GPIO Controller COH 901 571/3\n");
+ gpio->stride = U300_571_PORT_STRIDE;
+ gpio->pcr = U300_571_PXPCR;
+ gpio->dor = U300_571_PXPDOR;
+ gpio->dir = U300_571_PXPDIR;
+ gpio->per = U300_571_PXPER;
+ gpio->icr = U300_571_PXICR;
+ gpio->ien = U300_571_PXIEN;
+ gpio->iev = U300_571_PXIEV;
+ ifr = U300_571_PXIFR;
+
+ val = readl(gpio->base + U300_571_CR);
+ dev_info(gpio->dev, "COH901571/3 block version: %d, " \
+ "number of cores: %d totalling %d pins\n",
+ ((val & 0x000001FC) >> 2),
+ ((val & 0x0000FE00) >> 9),
+ ((val & 0x0000FE00) >> 9) * 8);
+ writel(U300_571_CR_BLOCK_CLKRQ_ENABLE,
+ gpio->base + U300_571_CR);
+ u300_gpio_init_coh901571(gpio, plat);
+ } else {
+ dev_err(gpio->dev, "unknown block variant\n");
+ err = -ENODEV;
+ goto err_unknown_variant;
+ }
+
+ /* Add each port with its IRQ separately */
+ INIT_LIST_HEAD(&gpio->port_list);
+ for (portno = 0 ; portno < plat->ports; portno++) {
+ struct u300_gpio_port *port =
+ kmalloc(sizeof(struct u300_gpio_port), GFP_KERNEL);
+
+ if (!port) {
+ dev_err(gpio->dev, "out of memory\n");
+ err = -ENOMEM;
+ goto err_no_port;
}
- /* Turns off PortX_irq_force */
- writel(0x0, virtbase + U300_GPIO_PXIFR +
- num_irqs * U300_GPIO_PORTX_SPACING);
+
+ snprintf(port->name, 8, "gpio%d", portno);
+ port->number = portno;
+ port->gpio = gpio;
+
+ port->irq = platform_get_irq_byname(pdev,
+ port->name);
+
+ dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq,
+ port->name);
+
+ irq_set_chained_handler(port->irq, u300_gpio_irq_handler);
+ irq_set_handler_data(port->irq, port);
+
+ /* For each GPIO pin set the unique IRQ handler */
+ for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) {
+ int irqno = gpio->irq_base + (portno << 3) + i;
+
+ dev_dbg(gpio->dev, "handler for IRQ %d on %s\n",
+ irqno, port->name);
+ irq_set_chip_and_handler(irqno, &u300_gpio_irqchip,
+ handle_simple_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ irq_set_chip_data(irqno, port);
+ }
+
+ /* Turns off irq force (test register) for this port */
+ writel(0x0, gpio->base + portno * gpio->stride + ifr);
+
+ list_add_tail(&port->node, &gpio->port_list);
}
+ dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno);
+
+ err = gpiochip_add(&gpio->chip);
+ if (err) {
+ dev_err(gpio->dev, "unable to add gpiochip: %d\n", err);
+ goto err_no_chip;
+ }
+
+ platform_set_drvdata(pdev, gpio);
return 0;
- err_no_irq:
- for (i = 0; i < num_irqs; i++)
- free_irq(gpio_ports[i].irq, &gpio_ports[i]);
- iounmap(virtbase);
- err_no_ioremap:
- release_mem_region(memres->start, resource_size(memres));
- err_no_ioregion:
- err_no_resource:
- clk_disable(clk);
- err_no_clk_enable:
- clk_put(clk);
- err_no_clk:
- dev_info(gpiodev, "module ERROR:%d\n", err);
+err_no_chip:
+err_no_port:
+ u300_gpio_free_ports(gpio);
+err_unknown_variant:
+ iounmap(gpio->base);
+err_no_ioremap:
+ release_mem_region(gpio->memres->start, resource_size(gpio->memres));
+err_no_ioregion:
+err_no_resource:
+ clk_disable(gpio->clk);
+err_no_clk_enable:
+ clk_put(gpio->clk);
+err_no_clk:
+ kfree(gpio);
+ dev_info(&pdev->dev, "module ERROR:%d\n", err);
return err;
}
-static int __exit gpio_remove(struct platform_device *pdev)
+static int __exit u300_gpio_remove(struct platform_device *pdev)
{
- int i;
+ struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev);
+ struct u300_gpio *gpio = platform_get_drvdata(pdev);
+ int err;
/* Turn off the GPIO block */
- writel(0x00000000U, virtbase + U300_GPIO_CR);
- for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
- free_irq(gpio_ports[i].irq, &gpio_ports[i]);
- iounmap(virtbase);
- release_mem_region(memres->start, resource_size(memres));
- clk_disable(clk);
- clk_put(clk);
+ if (plat->variant == U300_GPIO_COH901335)
+ writel(0x00000000U, gpio->base + U300_335_CR);
+ if (plat->variant == U300_GPIO_COH901571_3_BS335 ||
+ plat->variant == U300_GPIO_COH901571_3_BS365)
+ writel(0x00000000U, gpio->base + U300_571_CR);
+
+ err = gpiochip_remove(&gpio->chip);
+ if (err < 0) {
+ dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err);
+ return err;
+ }
+ u300_gpio_free_ports(gpio);
+ iounmap(gpio->base);
+ release_mem_region(gpio->memres->start,
+ resource_size(gpio->memres));
+ clk_disable(gpio->clk);
+ clk_put(gpio->clk);
+ platform_set_drvdata(pdev, NULL);
+ kfree(gpio);
return 0;
}
-static struct platform_driver gpio_driver = {
+static struct platform_driver u300_gpio_driver = {
.driver = {
.name = "u300-gpio",
},
- .remove = __exit_p(gpio_remove),
+ .remove = __exit_p(u300_gpio_remove),
};
static int __init u300_gpio_init(void)
{
- return platform_driver_probe(&gpio_driver, gpio_probe);
+ return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
}
static void __exit u300_gpio_exit(void)
{
- platform_driver_unregister(&gpio_driver);
+ platform_driver_unregister(&u300_gpio_driver);
}
arch_initcall(u300_gpio_init);
module_exit(u300_gpio_exit);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
-
-#ifdef U300_COH901571_3
-MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
-#endif
-
-#ifdef U300_COH901335
-MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
-#endif
-
+MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver");
MODULE_LICENSE("GPL");
mutex_lock(&dev->mode_config.mutex);
drm_mode_object_put(dev, &connector->base);
list_del(&connector->head);
+ dev->mode_config.num_connector--;
mutex_unlock(&dev->mode_config.mutex);
}
EXPORT_SYMBOL(drm_connector_cleanup);
mutex_lock(&dev->mode_config.mutex);
drm_mode_object_put(dev, &encoder->base);
list_del(&encoder->head);
+ dev->mode_config.num_encoder--;
mutex_unlock(&dev->mode_config.mutex);
}
EXPORT_SYMBOL(drm_encoder_cleanup);
{
printk(KERN_ERR "panic occurred, switching back to text console\n");
return drm_fb_helper_force_kernel_mode();
- return 0;
}
EXPORT_SYMBOL(drm_fb_helper_panic);
nouveau_gpuobj_ref(NULL, &obj);
if (ret)
return ret;
- } else {
+ } else
+ if (USE_SEMA(dev)) {
/* map fence bo into channel's vm */
ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm,
&chan->fence.vma);
return -ENOMEM;
nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL);
- if (!nvbe->ttm_alloced)
+ if (!nvbe->ttm_alloced) {
+ kfree(nvbe->pages);
+ nvbe->pages = NULL;
return -ENOMEM;
+ }
nvbe->nr_pages = 0;
while (num_pages--) {
for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) {
nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3);
- dma_offset += NV_CTXDMA_PAGE_SIZE;
+ offset_l += NV_CTXDMA_PAGE_SIZE;
}
}
struct drm_device *dev = crtc->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
- struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
- struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+ struct drm_framebuffer *drm_fb;
+ struct nouveau_framebuffer *fb;
int arb_burst, arb_lwm;
int ret;
+ NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+
+ /* no fb bound */
+ if (!atomic && !crtc->fb) {
+ NV_DEBUG_KMS(dev, "No FB bound\n");
+ return 0;
+ }
+
+
/* If atomic, we want to switch to the fb we were passed, so
* now we update pointers to do that. (We don't pin; just
* assume we're already pinned and update the base address.)
drm_fb = passed_fb;
fb = nouveau_framebuffer(passed_fb);
} else {
+ drm_fb = crtc->fb;
+ fb = nouveau_framebuffer(crtc->fb);
/* If not atomic, we can go ahead and pin, and unpin the
* old fb we were passed.
*/
struct drm_device *dev = nv_crtc->base.dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *evo = nv50_display(dev)->master;
- struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
- struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+ struct drm_framebuffer *drm_fb;
+ struct nouveau_framebuffer *fb;
int ret;
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ /* no fb bound */
+ if (!atomic && !crtc->fb) {
+ NV_DEBUG_KMS(dev, "No FB bound\n");
+ return 0;
+ }
+
/* If atomic, we want to switch to the fb we were passed, so
* now we update pointers to do that. (We don't pin; just
* assume we're already pinned and update the base address.)
drm_fb = passed_fb;
fb = nouveau_framebuffer(passed_fb);
} else {
+ drm_fb = crtc->fb;
+ fb = nouveau_framebuffer(crtc->fb);
/* If not atomic, we can go ahead and pin, and unpin the
* old fb we were passed.
*/
void evergreen_fini(struct radeon_device *rdev);
static void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
+void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
+{
+ u16 ctl, v;
+ int cap, err;
+
+ cap = pci_pcie_cap(rdev->pdev);
+ if (!cap)
+ return;
+
+ err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ if (err)
+ return;
+
+ v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12;
+
+ /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
+ * to avoid hangs or perfomance issues
+ */
+ if ((v == 0) || (v == 6) || (v == 7)) {
+ ctl &= ~PCI_EXP_DEVCTL_READRQ;
+ ctl |= (2 << 12);
+ pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl);
+ }
+}
+
void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
{
/* enable the pflip int */
SOFT_RESET_PA |
SOFT_RESET_SH |
SOFT_RESET_VGT |
+ SOFT_RESET_SPI |
SOFT_RESET_SX));
RREG32(GRBM_SOFT_RESET);
mdelay(15);
WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+ evergreen_fix_pci_max_read_req_size(rdev);
+
cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2;
cc_gc_shader_pipe_config |=
extern void evergreen_mc_program(struct radeon_device *rdev);
extern void evergreen_irq_suspend(struct radeon_device *rdev);
extern int evergreen_mc_init(struct radeon_device *rdev);
+extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
#define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376
WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+ evergreen_fix_pci_max_read_req_size(rdev);
+
mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
SOFT_RESET_PA |
SOFT_RESET_SH |
SOFT_RESET_VGT |
+ SOFT_RESET_SPI |
SOFT_RESET_SX));
RREG32(GRBM_SOFT_RESET);
mdelay(15);
} else {
DRM_INFO("Using generic clock info\n");
+ /* may need to be per card */
+ rdev->clock.max_pixel_clock = 35000;
+
if (rdev->flags & RADEON_IS_IGP) {
p1pll->reference_freq = 1432;
p2pll->reference_freq = 1432;
rdev->pdev->subsystem_device == 0x30a4)
return;
+ /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume
+ * - it hangs on resume inside the dynclk 1 table.
+ */
+ if (rdev->family == CHIP_RS480 &&
+ rdev->pdev->subsystem_vendor == 0x103c &&
+ rdev->pdev->subsystem_device == 0x30ae)
+ return;
+
/* DYN CLK 1 */
table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
if (table)
if (!radeon_dig_connector->edp_on)
atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF);
- } else {
- /* need to setup ddc on the bridge */
- if (radeon_connector_encoder_is_dp_bridge(connector)) {
+ } else if (radeon_connector_encoder_is_dp_bridge(connector)) {
+ /* DP bridges are always DP */
+ radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
+ /* get the DPCD from the bridge */
+ radeon_dp_getdpcd(radeon_connector);
+
+ if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
+ ret = connector_status_connected;
+ else {
+ /* need to setup ddc on the bridge */
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
+ if (radeon_ddc_probe(radeon_connector,
+ radeon_connector->requires_extended_probe))
+ ret = connector_status_connected;
+ }
+
+ if ((ret == connector_status_disconnected) &&
+ radeon_connector->dac_load_detect) {
+ struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ if (encoder) {
+ encoder_funcs = encoder->helper_private;
+ ret = encoder_funcs->detect(encoder, connector);
+ }
}
+ } else {
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
ret = connector_status_connected;
ret = connector_status_connected;
}
}
-
- if ((ret == connector_status_disconnected) &&
- radeon_connector->dac_load_detect) {
- struct drm_encoder *encoder = radeon_best_single_encoder(connector);
- struct drm_encoder_helper_funcs *encoder_funcs;
- if (encoder) {
- encoder_funcs = encoder->helper_private;
- ret = encoder_funcs->detect(encoder, connector);
- }
- }
}
radeon_connector_update_scratch_regs(connector, ret);
radeon_router_select_ddc_port(radeon_connector);
if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
- (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) ||
+ radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) {
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
- radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter);
- }
- if (!radeon_connector->ddc_bus)
- return -1;
- if (!radeon_connector->edid) {
- radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &dig->dp_i2c_bus->adapter);
+ else if (radeon_connector->ddc_bus && !radeon_connector->edid)
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &radeon_connector->ddc_bus->adapter);
+ } else {
+ if (radeon_connector->ddc_bus && !radeon_connector->edid)
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &radeon_connector->ddc_bus->adapter);
}
if (!radeon_connector->edid) {
#define USB_DEVICE_ID_PENPOWER 0x00f4
#define USB_VENDOR_ID_GREENASIA 0x0e8f
+#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
#define NO_TOUCHES -1
#define SINGLE_TOUCH_UP -2
+/* Touch surface information. Dimension is in hundredths of a mm, min and max
+ * are in units. */
+#define MOUSE_DIMENSION_X (float)9056
+#define MOUSE_MIN_X -1100
+#define MOUSE_MAX_X 1258
+#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100))
+#define MOUSE_DIMENSION_Y (float)5152
+#define MOUSE_MIN_Y -1589
+#define MOUSE_MAX_Y 2047
+#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100))
+
+#define TRACKPAD_DIMENSION_X (float)13000
+#define TRACKPAD_MIN_X -2909
+#define TRACKPAD_MAX_X 3167
+#define TRACKPAD_RES_X \
+ ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100))
+#define TRACKPAD_DIMENSION_Y (float)11000
+#define TRACKPAD_MIN_Y -2456
+#define TRACKPAD_MAX_Y 2565
+#define TRACKPAD_RES_Y \
+ ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
+
/**
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
* @input: Input device through which we report events.
* inverse of the reported Y.
*/
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
- input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
- 1358, 4, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
- 2047, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_X,
+ MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y,
+ MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
+
+ input_abs_set_res(input, ABS_MT_POSITION_X,
+ MOUSE_RES_X);
+ input_abs_set_res(input, ABS_MT_POSITION_Y,
+ MOUSE_RES_Y);
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
- input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
- input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
- 3167, 4, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
- 2565, 4, 0);
+ input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
+ TRACKPAD_MAX_X, 4, 0);
+ input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
+ TRACKPAD_MAX_Y, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_X,
+ TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y,
+ TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
+
+ input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
+ input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
+ input_abs_set_res(input, ABS_MT_POSITION_X,
+ TRACKPAD_RES_X);
+ input_abs_set_res(input, ABS_MT_POSITION_Y,
+ TRACKPAD_RES_Y);
}
input_set_events_per_packet(input, 60);
}
report->size = 6;
+ /*
+ * Some devices repond with 'invalid report id' when feature
+ * report switching it into multitouch mode is sent to it.
+ *
+ * This results in -EIO from the _raw low-level transport callback,
+ * but there seems to be no other way of switching the mode.
+ * Thus the super-ugly hacky success check below.
+ */
ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
HID_FEATURE_REPORT);
- if (ret != sizeof(feature)) {
+ if (ret != -EIO && ret != sizeof(feature)) {
hid_err(hdev, "unable to request touch data (%d)\n", ret);
goto err_stop_hw;
}
if (ret) {
hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
ret);
- /*
- * battery attribute is not critical for the tablet, but if it
- * failed then there is no need to create ac attribute
- */
- goto move_on;
+ goto err_battery;
}
wdata->ac.properties = wacom_ac_props;
if (ret) {
hid_warn(hdev,
"can't create ac battery attribute, err: %d\n", ret);
- /*
- * ac attribute is not critical for the tablet, but if it
- * failed then we don't want to battery attribute to exist
- */
- power_supply_unregister(&wdata->battery);
+ goto err_ac;
}
-
-move_on:
#endif
hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
input = hidinput->input;
return 0;
+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+err_ac:
+ power_supply_unregister(&wdata->battery);
+err_battery:
+ device_remove_file(&hdev->dev, &dev_attr_speed);
+ hid_hw_stop(hdev);
+#endif
err_free:
kfree(wdata);
return ret;
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
struct wacom_data *wdata = hid_get_drvdata(hdev);
#endif
+ device_remove_file(&hdev->dev, &dev_attr_speed);
hid_hw_stop(hdev);
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
static inline int ADC_TO_CURR(int adc, int gain)
{
- return adc * 1400000 / gain * 255;
+ return adc * 1400000 / (gain * 255);
}
/*
block_buffer[ret] = '\0';
dev_info(&client->dev, "Device ID %s\n", block_buffer);
- mid = NULL;
- for (i = 0; i < ARRAY_SIZE(ucd9000_id); i++) {
- mid = &ucd9000_id[i];
+ for (mid = ucd9000_id; mid->name[0]; mid++) {
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
break;
}
- if (!mid || !strlen(mid->name)) {
+ if (!mid->name[0]) {
dev_err(&client->dev, "Unsupported device\n");
return -ENODEV;
}
block_buffer[ret] = '\0';
dev_info(&client->dev, "Device ID %s\n", block_buffer);
- mid = NULL;
- for (i = 0; i < ARRAY_SIZE(ucd9200_id); i++) {
- mid = &ucd9200_id[i];
+ for (mid = ucd9200_id; mid->name[0]; mid++) {
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
break;
}
- if (!mid || !strlen(mid->name)) {
+ if (!mid->name[0]) {
dev_err(&client->dev, "Unsupported device\n");
return -ENODEV;
}
#include <linux/slab.h>
#include <mach/hardware.h> /* Pick up IXP2000-specific bits */
-#include <mach/gpio.h>
+#include <mach/gpio-ixp2000.h>
static inline int ixp2000_scl_pin(void *data)
{
return -EINVAL;
}
sds = kzalloc(sizeof(*sds), GFP_KERNEL);
- if (!sds)
+ if (!sds) {
+ ret = -ENOMEM;
goto err_mem;
+ }
for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
sds->pdev[i] = add_i2c_device(dev, i);
if (IS_ERR(sds->pdev[i])) {
+ ret = PTR_ERR(sds->pdev[i]);
while (--i >= 0)
platform_device_unregister(sds->pdev[i]);
goto err_dev_add;
/* Rounds down to not include partial word at the end of buf */
words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
- if (words_to_transfer > tx_fifo_avail)
- words_to_transfer = tx_fifo_avail;
- i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
-
- buf += words_to_transfer * BYTES_PER_FIFO_WORD;
- buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
- tx_fifo_avail -= words_to_transfer;
+ /* It's very common to have < 4 bytes, so optimize that case. */
+ if (words_to_transfer) {
+ if (words_to_transfer > tx_fifo_avail)
+ words_to_transfer = tx_fifo_avail;
+
+ /*
+ * Update state before writing to FIFO. If this casues us
+ * to finish writing all bytes (AKA buf_remaining goes to 0) we
+ * have a potential for an interrupt (PACKET_XFER_COMPLETE is
+ * not maskable). We need to make sure that the isr sees
+ * buf_remaining as 0 and doesn't call us back re-entrantly.
+ */
+ buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
+ tx_fifo_avail -= words_to_transfer;
+ i2c_dev->msg_buf_remaining = buf_remaining;
+ i2c_dev->msg_buf = buf +
+ words_to_transfer * BYTES_PER_FIFO_WORD;
+ barrier();
+
+ i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+
+ buf += words_to_transfer * BYTES_PER_FIFO_WORD;
+ }
/*
* If there is a partial word at the end of buf, handle it manually to
if (tx_fifo_avail > 0 && buf_remaining > 0) {
BUG_ON(buf_remaining > 3);
memcpy(&val, buf, buf_remaining);
+
+ /* Again update before writing to FIFO to make sure isr sees. */
+ i2c_dev->msg_buf_remaining = 0;
+ i2c_dev->msg_buf = NULL;
+ barrier();
+
i2c_writel(i2c_dev, val, I2C_TX_FIFO);
- buf_remaining = 0;
- tx_fifo_avail--;
}
- BUG_ON(tx_fifo_avail > 0 && buf_remaining > 0);
- i2c_dev->msg_buf_remaining = buf_remaining;
- i2c_dev->msg_buf = buf;
return 0;
}
tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);
}
- if ((status & I2C_INT_PACKET_XFER_COMPLETE) &&
- !i2c_dev->msg_buf_remaining)
+ if (status & I2C_INT_PACKET_XFER_COMPLETE) {
+ BUG_ON(i2c_dev->msg_buf_remaining);
complete(&i2c_dev->msg_complete);
+ }
i2c_writel(i2c_dev, status, I2C_INT_STATUS);
if (i2c_dev->is_dvc)
static u32 tegra_i2c_func(struct i2c_adapter *adap)
{
- return I2C_FUNC_I2C;
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static const struct i2c_algorithm tegra_i2c_algo = {
}
#endif
+#if defined(CONFIG_OF)
+/* Match table for of_platform binding */
+static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
+ { .compatible = "nvidia,tegra20-i2c", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
+#else
+#define tegra_i2c_of_match NULL
+#endif
+
static struct platform_driver tegra_i2c_driver = {
.probe = tegra_i2c_probe,
.remove = tegra_i2c_remove,
.driver = {
.name = "tegra-i2c",
.owner = THIS_MODULE,
+ .of_match_table = tegra_i2c_of_match,
},
};
#include <linux/platform_device.h>
#include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/at91sam9_smc.h>
#define DRV_NAME "at91_ide"
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/keypad.h>
#include <plat/menelaus.h>
#include <asm/irq.h>
* Writes the command to the IOMMUs command buffer and informs the
* hardware about the new command.
*/
-static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
+static int iommu_queue_command_sync(struct amd_iommu *iommu,
+ struct iommu_cmd *cmd,
+ bool sync)
{
u32 left, tail, head, next_tail;
unsigned long flags;
copy_cmd_to_buffer(iommu, cmd, tail);
/* We need to sync now to make sure all commands are processed */
- iommu->need_sync = true;
+ iommu->need_sync = sync;
spin_unlock_irqrestore(&iommu->lock, flags);
return 0;
}
+static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
+{
+ return iommu_queue_command_sync(iommu, cmd, true);
+}
+
/*
* This function queues a completion wait command into the command
* buffer of an IOMMU
build_completion_wait(&cmd, (u64)&sem);
- ret = iommu_queue_command(iommu, &cmd);
+ ret = iommu_queue_command_sync(iommu, &cmd, false);
if (ret)
return ret;
static void domain_flush_devices(struct protection_domain *domain)
{
struct iommu_dev_data *dev_data;
- unsigned long flags;
-
- spin_lock_irqsave(&domain->lock, flags);
list_for_each_entry(dev_data, &domain->dev_list, list)
device_flush_dte(dev_data);
-
- spin_unlock_irqrestore(&domain->lock, flags);
}
/****************************************************************************
if (count == size) {
led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off);
+ led_cdev->blink_delay_on = state;
ret = count;
}
if (count == size) {
led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state);
+ led_cdev->blink_delay_off = state;
ret = count;
}
struct linear_private_data
{
+ struct rcu_head rcu;
sector_t array_sectors;
dev_info_t disks[0];
- struct rcu_head rcu;
};
bio->bi_end_io = super_written;
atomic_inc(&mddev->pending_writes);
- submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio);
+ submit_bio(WRITE_FLUSH_FUA, bio);
}
void md_super_wait(mddev_t *mddev)
ret = 0;
}
rdev->sectors = rdev->sb_start;
+ /* Limit to 4TB as metadata cannot record more than that */
+ if (rdev->sectors >= (2ULL << 32))
+ rdev->sectors = (2ULL << 32) - 2;
- if (rdev->sectors < sb->size * 2 && sb->level > 1)
+ if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1)
/* "this cannot possibly happen" ... */
ret = -EINVAL;
mddev->clevel[0] = 0;
mddev->layout = sb->layout;
mddev->raid_disks = sb->raid_disks;
- mddev->dev_sectors = sb->size * 2;
+ mddev->dev_sectors = ((sector_t)sb->size) * 2;
mddev->events = ev1;
mddev->bitmap_info.offset = 0;
mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
rdev->sb_start = calc_dev_sboffset(rdev);
if (!num_sectors || num_sectors > rdev->sb_start)
num_sectors = rdev->sb_start;
+ /* Limit to 4TB as metadata cannot record more than that.
+ * 4TB == 2^32 KB, or 2*2^32 sectors.
+ */
+ if (num_sectors >= (2ULL << 32))
+ num_sectors = (2ULL << 32) - 2;
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
rdev->sb_page);
md_super_wait(rdev->mddev);
sb->level = cpu_to_le32(mddev->level);
sb->layout = cpu_to_le32(mddev->layout);
+ if (test_bit(WriteMostly, &rdev->flags))
+ sb->devflags |= WriteMostly1;
+ else
+ sb->devflags &= ~WriteMostly1;
+
if (mddev->bitmap && mddev->bitmap_info.file == NULL) {
sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset);
sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
int err = -EINVAL;
if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
md_error(rdev->mddev, rdev);
- err = 0;
+ if (test_bit(Faulty, &rdev->flags))
+ err = 0;
+ else
+ err = -EBUSY;
} else if (cmd_match(buf, "remove")) {
if (rdev->raid_disk >= 0)
err = -EBUSY;
err = 0;
} else if (cmd_match(buf, "-blocked")) {
if (!test_bit(Faulty, &rdev->flags) &&
- test_bit(BlockedBadBlocks, &rdev->flags)) {
+ rdev->badblocks.unacked_exist) {
/* metadata handler doesn't understand badblocks,
* so we need to fail the device
*/
return -ENODEV;
md_error(mddev, rdev);
+ if (!test_bit(Faulty, &rdev->flags))
+ return -EBUSY;
return 0;
}
bio_list_add(&conf->pending_bio_list, mbio);
spin_unlock_irqrestore(&conf->device_lock, flags);
}
- r1_bio_write_done(r1_bio);
-
- /* In case raid1d snuck in to freeze_array */
- wake_up(&conf->wait_barrier);
-
+ /* Mustn't call r1_bio_write_done before this next test,
+ * as it could result in the bio being freed.
+ */
if (sectors_handled < (bio->bi_size >> 9)) {
+ r1_bio_write_done(r1_bio);
/* We need another r1_bio. It has already been counted
* in bio->bi_phys_segments
*/
goto retry_write;
}
+ r1_bio_write_done(r1_bio);
+
+ /* In case raid1d snuck in to freeze_array */
+ wake_up(&conf->wait_barrier);
+
if (do_sync || !bitmap || !plugged)
md_wakeup_thread(mddev->thread);
md_write_end(r10_bio->mddev);
}
+static void one_write_done(r10bio_t *r10_bio)
+{
+ if (atomic_dec_and_test(&r10_bio->remaining)) {
+ if (test_bit(R10BIO_WriteError, &r10_bio->state))
+ reschedule_retry(r10_bio);
+ else {
+ close_write(r10_bio);
+ if (test_bit(R10BIO_MadeGood, &r10_bio->state))
+ reschedule_retry(r10_bio);
+ else
+ raid_end_bio_io(r10_bio);
+ }
+ }
+}
+
static void raid10_end_write_request(struct bio *bio, int error)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
* Let's see if all mirrored write operations have finished
* already.
*/
- if (atomic_dec_and_test(&r10_bio->remaining)) {
- if (test_bit(R10BIO_WriteError, &r10_bio->state))
- reschedule_retry(r10_bio);
- else {
- close_write(r10_bio);
- if (test_bit(R10BIO_MadeGood, &r10_bio->state))
- reschedule_retry(r10_bio);
- else
- raid_end_bio_io(r10_bio);
- }
- }
+ one_write_done(r10_bio);
if (dec_rdev)
rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
}
spin_unlock_irqrestore(&conf->device_lock, flags);
}
- if (atomic_dec_and_test(&r10_bio->remaining)) {
- /* This matches the end of raid10_end_write_request() */
- bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
- r10_bio->sectors,
- !test_bit(R10BIO_Degraded, &r10_bio->state),
- 0);
- md_write_end(mddev);
- raid_end_bio_io(r10_bio);
- }
-
- /* In case raid10d snuck in to freeze_array */
- wake_up(&conf->wait_barrier);
+ /* Don't remove the bias on 'remaining' (one_write_done) until
+ * after checking if we need to go around again.
+ */
if (sectors_handled < (bio->bi_size >> 9)) {
+ one_write_done(r10_bio);
/* We need another r10_bio. It has already been counted
* in bio->bi_phys_segments.
*/
r10_bio->state = 0;
goto retry_write;
}
+ one_write_done(r10_bio);
+
+ /* In case raid10d snuck in to freeze_array */
+ wake_up(&conf->wait_barrier);
if (do_sync || !mddev->bitmap || !plugged)
md_wakeup_thread(mddev->thread);
finish:
/* wait for this device to become unblocked */
- if (unlikely(s.blocked_rdev))
+ if (conf->mddev->external && unlikely(s.blocked_rdev))
md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev);
if (s.handle_bad_blocks)
static int vp7045_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- struct dvb_usb_device *d;
- int ret = dvb_usb_device_init(intf, &vp7045_properties,
- THIS_MODULE, &d, adapter_nr);
- if (ret)
- return ret;
-
- d->priv = kmalloc(20, GFP_KERNEL);
- if (!d->priv) {
- dvb_usb_device_exit(intf);
- return -ENOMEM;
- }
-
- return ret;
-}
-
-static void vp7045_usb_disconnect(struct usb_interface *intf)
-{
- struct dvb_usb_device *d = usb_get_intfdata(intf);
- kfree(d->priv);
- dvb_usb_device_exit(intf);
+ return dvb_usb_device_init(intf, &vp7045_properties,
+ THIS_MODULE, NULL, adapter_nr);
}
static struct usb_device_id vp7045_usb_table [] = {
static struct dvb_usb_device_properties vp7045_properties = {
.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-vp7045-01.fw",
- .size_of_priv = sizeof(u8 *),
+ .size_of_priv = 20,
.num_adapters = 1,
.adapter = {
static struct usb_driver vp7045_usb_driver = {
.name = "dvb_usb_vp7045",
.probe = vp7045_usb_probe,
- .disconnect = vp7045_usb_disconnect,
+ .disconnect = dvb_usb_device_exit,
.id_table = vp7045_usb_table,
};
static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
{
DEFINE_IR_RAW_EVENT(rawir);
- unsigned int count;
u32 carrier;
u8 sample;
int i;
if (nvt->carrier_detect_enabled)
carrier = nvt_rx_carrier_detect(nvt);
- count = nvt->pkts;
- nvt_dbg_verbose("Processing buffer of len %d", count);
+ nvt_dbg_verbose("Processing buffer of len %d", nvt->pkts);
init_ir_raw_event(&rawir);
- for (i = 0; i < count; i++) {
- nvt->pkts--;
+ for (i = 0; i < nvt->pkts; i++) {
sample = nvt->buf[i];
rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
rawir.duration = US_TO_NS((sample & BUF_LEN_MASK)
* SAMPLE_PERIOD);
- if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) {
- if (nvt->rawir.pulse == rawir.pulse)
- nvt->rawir.duration += rawir.duration;
- else {
- nvt->rawir.duration = rawir.duration;
- nvt->rawir.pulse = rawir.pulse;
- }
- continue;
- }
-
- rawir.duration += nvt->rawir.duration;
+ nvt_dbg("Storing %s with duration %d",
+ rawir.pulse ? "pulse" : "space", rawir.duration);
- init_ir_raw_event(&nvt->rawir);
- nvt->rawir.duration = 0;
- nvt->rawir.pulse = rawir.pulse;
-
- if (sample == BUF_PULSE_BIT)
- rawir.pulse = false;
-
- if (rawir.duration) {
- nvt_dbg("Storing %s with duration %d",
- rawir.pulse ? "pulse" : "space",
- rawir.duration);
-
- ir_raw_event_store_with_filter(nvt->rdev, &rawir);
- }
+ ir_raw_event_store_with_filter(nvt->rdev, &rawir);
/*
* BUF_PULSE_BIT indicates end of IR data, BUF_REPEAT_BYTE
* indicates end of IR signal, but new data incoming. In both
* cases, it means we're ready to call ir_raw_event_handle
*/
- if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
+ if ((sample == BUF_PULSE_BIT) && (i + 1 < nvt->pkts)) {
nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
ir_raw_event_handle(nvt->rdev);
}
}
+ nvt->pkts = 0;
+
nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
ir_raw_event_handle(nvt->rdev);
- if (nvt->pkts) {
- nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
- nvt->pkts = 0;
- }
-
nvt_dbg_verbose("%s done", __func__);
}
spin_lock_init(&nvt->nvt_lock);
spin_lock_init(&nvt->tx.lock);
- init_ir_raw_event(&nvt->rawir);
ret = -EBUSY;
/* now claim resources */
struct nvt_dev {
struct pnp_dev *pdev;
struct rc_dev *rdev;
- struct ir_raw_event rawir;
spinlock_t nvt_lock;
case 0x60:
PDEBUG(D_PROBE, "Sensor is a OV7660");
sd->sensor = SEN_OV7660;
- sd->invert_led = 0;
break;
default:
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
case BRIDGE_OV519:
cam->cam_mode = ov519_vga_mode;
cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- sd->invert_led = !sd->invert_led;
break;
case BRIDGE_OVFX2:
cam->cam_mode = ov519_vga_mode;
/* -- module initialisation -- */
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
- {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x405f),
+ {USB_DEVICE(0x041e, 0x4052),
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4064),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4068),
+ {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
+ {USB_DEVICE(0x045e, 0x028c),
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
- {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x054c, 0x0155),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
- {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
+ {USB_DEVICE(0x05a9, 0x0519),
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ {USB_DEVICE(0x05a9, 0x0530),
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
reg_w1(gspca_dev, 0x01, 0x22);
msleep(100);
reg01 = SCL_SEL_OD | S_PDN_INV;
- reg17 &= MCK_SIZE_MASK;
+ reg17 &= ~MCK_SIZE_MASK;
reg17 |= 0x04; /* clock / 4 */
break;
}
if (!mode) { /* if 640x480 */
reg17 &= ~MCK_SIZE_MASK;
reg17 |= 0x04; /* clock / 4 */
+ } else {
+ reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x02; /* clock / 2 */
}
break;
case SENSOR_OV7630:
if (pdev->restore_factory)
pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
- if (!pdev->features & FEATURE_MOTOR_PANTILT)
+ if (!(pdev->features & FEATURE_MOTOR_PANTILT))
return hdl->error;
/* Motor pan / tilt / reset */
struct pci_bus *pbus = pci_find_bus(0, 0);
u8 cbyte;
+ if (!pbus)
+ return false;
pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
VIACAM_SERIAL_CREG, &cbyte);
if ((cbyte & VIACAM_SERIAL_BIT) == 0)
#include <asm/mach/irq.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/menelaus.h>
#define DRIVER_NAME "menelaus"
static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc,
const char *thread_name)
{
+ /*
+ * Since we access the comm member in current's task_struct, we only
+ * need to be as large as what 'comm' in that structure is.
+ */
+ char comm[TASK_COMM_LEN];
struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
.channel = 0};
const char *thread_name_p;
u8 control_frame[CONTROL_FRAME_LEN];
if (!thread_name) {
- /*
- * Since we access the comm member in current's task_struct,
- * we only need to be as large as what 'comm' in that
- * structure is.
- */
- char comm[TASK_COMM_LEN];
-
if (!in_interrupt())
get_task_comm(comm, current);
else
if (mrq->done)
mrq->done(mrq);
- mmc_host_clk_gate(host);
+ mmc_host_clk_release(host);
}
}
mrq->stop->mrq = mrq;
}
}
- mmc_host_clk_ungate(host);
+ mmc_host_clk_hold(host);
led_trigger_event(host->led, LED_FULL);
host->ops->request(host, mrq);
}
*/
void mmc_set_chip_select(struct mmc_host *host, int mode)
{
+ mmc_host_clk_hold(host);
host->ios.chip_select = mode;
mmc_set_ios(host);
+ mmc_host_clk_release(host);
}
/*
* Sets the host clock to the highest possible frequency that
* is below "hz".
*/
-void mmc_set_clock(struct mmc_host *host, unsigned int hz)
+static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
{
WARN_ON(hz < host->f_min);
mmc_set_ios(host);
}
+void mmc_set_clock(struct mmc_host *host, unsigned int hz)
+{
+ mmc_host_clk_hold(host);
+ __mmc_set_clock(host, hz);
+ mmc_host_clk_release(host);
+}
+
#ifdef CONFIG_MMC_CLKGATE
/*
* This gates the clock by setting it to 0 Hz.
if (host->clk_old) {
BUG_ON(host->ios.clock);
/* This call will also set host->clk_gated to false */
- mmc_set_clock(host, host->clk_old);
+ __mmc_set_clock(host, host->clk_old);
}
}
*/
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
{
+ mmc_host_clk_hold(host);
host->ios.bus_mode = mode;
mmc_set_ios(host);
+ mmc_host_clk_release(host);
}
/*
*/
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
{
+ mmc_host_clk_hold(host);
host->ios.bus_width = width;
mmc_set_ios(host);
+ mmc_host_clk_release(host);
}
/**
ocr &= 3 << bit;
+ mmc_host_clk_hold(host);
host->ios.vdd = bit;
mmc_set_ios(host);
+ mmc_host_clk_release(host);
} else {
pr_warning("%s: host doesn't support card's voltages\n",
mmc_hostname(host));
*/
void mmc_set_timing(struct mmc_host *host, unsigned int timing)
{
+ mmc_host_clk_hold(host);
host->ios.timing = timing;
mmc_set_ios(host);
+ mmc_host_clk_release(host);
}
/*
*/
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
{
+ mmc_host_clk_hold(host);
host->ios.drv_type = drv_type;
mmc_set_ios(host);
+ mmc_host_clk_release(host);
}
/*
{
int bit;
+ mmc_host_clk_hold(host);
+
/* If ocr is set, we use it */
if (host->ocr)
bit = ffs(host->ocr) - 1;
* time required to reach a stable voltage.
*/
mmc_delay(10);
+
+ mmc_host_clk_release(host);
}
static void mmc_power_off(struct mmc_host *host)
{
+ mmc_host_clk_hold(host);
+
host->ios.clock = 0;
host->ios.vdd = 0;
host->ios.bus_width = MMC_BUS_WIDTH_1;
host->ios.timing = MMC_TIMING_LEGACY;
mmc_set_ios(host);
+
+ mmc_host_clk_release(host);
}
/*
}
/**
- * mmc_host_clk_ungate - ungate hardware MCI clocks
+ * mmc_host_clk_hold - ungate hardware MCI clocks
* @host: host to ungate.
*
* Makes sure the host ios.clock is restored to a non-zero value
* past this call. Increase clock reference count and ungate clock
* if we're the first user.
*/
-void mmc_host_clk_ungate(struct mmc_host *host)
+void mmc_host_clk_hold(struct mmc_host *host)
{
unsigned long flags;
}
/**
- * mmc_host_clk_gate - gate off hardware MCI clocks
+ * mmc_host_clk_release - gate off hardware MCI clocks
* @host: host to gate.
*
* Calls the host driver with ios.clock set to zero as often as possible
* in order to gate off hardware MCI clocks. Decrease clock reference
* count and schedule disabling of clock.
*/
-void mmc_host_clk_gate(struct mmc_host *host)
+void mmc_host_clk_release(struct mmc_host *host)
{
unsigned long flags;
host->clk_requests--;
if (mmc_host_may_gate_card(host->card) &&
!host->clk_requests)
- schedule_work(&host->clk_gate_work);
+ queue_work(system_nrt_wq, &host->clk_gate_work);
spin_unlock_irqrestore(&host->clk_lock, flags);
}
if (cancel_work_sync(&host->clk_gate_work))
mmc_host_clk_gate_delayed(host);
if (host->clk_gated)
- mmc_host_clk_ungate(host);
+ mmc_host_clk_hold(host);
/* There should be only one user now */
WARN_ON(host->clk_requests > 1);
}
void mmc_unregister_host_class(void);
#ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_ungate(struct mmc_host *host);
-void mmc_host_clk_gate(struct mmc_host *host);
+void mmc_host_clk_hold(struct mmc_host *host);
+void mmc_host_clk_release(struct mmc_host *host);
unsigned int mmc_host_clk_rate(struct mmc_host *host);
#else
-static inline void mmc_host_clk_ungate(struct mmc_host *host)
+static inline void mmc_host_clk_hold(struct mmc_host *host)
{
}
-static inline void mmc_host_clk_gate(struct mmc_host *host)
+static inline void mmc_host_clk_release(struct mmc_host *host)
{
}
return 0;
}
-static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
+static void sd_update_bus_speed_mode(struct mmc_card *card)
{
- unsigned int bus_speed = 0, timing = 0;
- int err;
-
/*
* If the host doesn't support any of the UHS-I modes, fallback on
* default speed.
*/
if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
- return 0;
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) {
+ card->sd_bus_speed = 0;
+ return;
+ }
if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
- bus_speed = UHS_SDR104_BUS_SPEED;
- timing = MMC_TIMING_UHS_SDR104;
- card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
- bus_speed = UHS_DDR50_BUS_SPEED;
- timing = MMC_TIMING_UHS_DDR50;
- card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+ card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR50)) {
- bus_speed = UHS_SDR50_BUS_SPEED;
- timing = MMC_TIMING_UHS_SDR50;
- card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
- bus_speed = UHS_SDR25_BUS_SPEED;
- timing = MMC_TIMING_UHS_SDR25;
- card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR12)) {
- bus_speed = UHS_SDR12_BUS_SPEED;
- timing = MMC_TIMING_UHS_SDR12;
- card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
+ }
+}
+
+static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
+{
+ int err;
+ unsigned int timing = 0;
+
+ switch (card->sd_bus_speed) {
+ case UHS_SDR104_BUS_SPEED:
+ timing = MMC_TIMING_UHS_SDR104;
+ card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+ break;
+ case UHS_DDR50_BUS_SPEED:
+ timing = MMC_TIMING_UHS_DDR50;
+ card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+ break;
+ case UHS_SDR50_BUS_SPEED:
+ timing = MMC_TIMING_UHS_SDR50;
+ card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+ break;
+ case UHS_SDR25_BUS_SPEED:
+ timing = MMC_TIMING_UHS_SDR25;
+ card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+ break;
+ case UHS_SDR12_BUS_SPEED:
+ timing = MMC_TIMING_UHS_SDR12;
+ card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+ break;
+ default:
+ return 0;
}
- card->sd_bus_speed = bus_speed;
- err = mmc_sd_switch(card, 1, 0, bus_speed, status);
+ err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status);
if (err)
return err;
- if ((status[16] & 0xF) != bus_speed)
+ if ((status[16] & 0xF) != card->sd_bus_speed)
printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
mmc_hostname(card->host));
else {
mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
}
+ /*
+ * Select the bus speed mode depending on host
+ * and card capability.
+ */
+ sd_update_bus_speed_mode(card);
+
/* Set the driver strength for the card */
err = sd_select_driver_type(card, status);
if (err)
goto out;
- /* Set bus speed mode of the card */
- err = sd_set_bus_speed_mode(card, status);
+ /* Set current limit for the card */
+ err = sd_set_current_limit(card, status);
if (err)
goto out;
- /* Set current limit for the card */
- err = sd_set_current_limit(card, status);
+ /* Set bus speed mode of the card */
+ err = sd_set_bus_speed_mode(card, status);
if (err)
goto out;
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/amba/mmci.h>
+#include <linux/pm_runtime.h>
#include <asm/div64.h>
#include <asm/io.h>
* back into the driver...
*/
spin_unlock(&host->lock);
+ pm_runtime_put(mmc_dev(host->mmc));
mmc_request_done(host->mmc, mrq);
spin_lock(&host->lock);
}
return;
}
+ pm_runtime_get_sync(mmc_dev(mmc));
+
spin_lock_irqsave(&host->lock, flags);
host->mrq = mrq;
mmci_dma_setup(host);
+ pm_runtime_put(&dev->dev);
+
mmc_add_host(mmc);
return 0;
if (mmc) {
struct mmci_host *host = mmc_priv(mmc);
+ /*
+ * Undo pm_runtime_put() in probe. We use the _sync
+ * version here so that we can access the primecell.
+ */
+ pm_runtime_get_sync(&dev->dev);
+
mmc_remove_host(mmc);
writel(0, host->base + MMCIMASK0);
#include <plat/board.h>
#include <plat/mmc.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/dma.h>
#include <plat/mux.h>
#include <plat/fpga.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
ctrl &= ~SDHCI_CTRL_8BITBUS;
break;
default:
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ ctrl &= ~SDHCI_CTRL_8BITBUS;
break;
}
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/sdhci.h>
#include "sdhci-pltfm.h"
mmc_data->hclk = clk_get_rate(priv->clk);
mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
mmc_data->get_cd = sh_mobile_sdhi_get_cd;
- if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
- mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
if (p) {
mmc_data->flags = p->tmio_flags;
+ if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
+ mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
mmc_data->ocr_mask = p->tmio_ocr_mask;
mmc_data->capabilities |= p->tmio_caps;
#include <asm/io.h>
#include <mach/hardware.h>
#include <asm/sizes.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/board-ams-delta.h>
/*
#include <asm/mach/flash.h>
#include <plat/gpmc.h>
#include <plat/onenand.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/dma.h>
#define ubi_dbg_msg(fmt, ...) do { \
if (0) \
- pr_debug(fmt "\n", ##__VA_ARGS__); \
+ printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \
} while (0)
#define dbg_msg(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
struct net_device *dev = (struct net_device *)data;
struct dev_priv *priv = netdev_priv(dev);
unsigned int lnkstat, carrier;
+ unsigned long flags;
+ spin_lock_irqsave(&priv->chip_lock, flags);
lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
carrier = netif_carrier_ok(dev);
if (lnkstat && !carrier) {
#include <asm/mach-types.h>
#include <mach/at91rm9200_emac.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/board.h>
#include "at91_ether.h"
spin_unlock_irqrestore(&priv->mbx_lock, flags);
/* Prepare mailbox for transmission */
+ data = cf->can_dlc | (get_tx_head_prio(priv) << 8);
if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
data |= HECC_CANMCF_RTR;
- data |= get_tx_head_prio(priv) << 8;
hecc_write_mbx(priv, mbxno, HECC_CANMCF, data);
if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
priv->can.do_get_state = ti_hecc_get_state;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+ spin_lock_init(&priv->mbx_lock);
ndev->irq = irq->start;
ndev->flags |= IFF_ECHO;
platform_set_drvdata(pdev, ndev);
struct net_device *dev = dev_id;
struct cas *cp = netdev_priv(dev);
unsigned long flags;
- int ring;
+ int ring = (irq == cp->pci_irq_INTC) ? 2 : 3;
u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring));
/* check for shared irq */
if (status == 0)
return IRQ_NONE;
- ring = (irq == cp->pci_irq_INTC) ? 2 : 3;
spin_lock_irqsave(&cp->lock, flags);
if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
#ifdef USE_NAPI
}
/* recycle the current buffer on the rx queue */
-static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
+static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
{
u32 q_index = adapter->rx_queue.index;
u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator;
unsigned int index = correlator & 0xffffffffUL;
union ibmveth_buf_desc desc;
unsigned long lpar_rc;
+ int ret = 1;
BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
BUG_ON(index >= adapter->rx_buff_pool[pool].size);
if (!adapter->rx_buff_pool[pool].active) {
ibmveth_rxq_harvest_buffer(adapter);
ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
- return;
+ goto out;
}
desc.fields.flags_len = IBMVETH_BUF_VALID |
netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed "
"during recycle rc=%ld", lpar_rc);
ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
+ ret = 0;
}
if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
adapter->rx_queue.index = 0;
adapter->rx_queue.toggle = !adapter->rx_queue.toggle;
}
+
+out:
+ return ret;
}
static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
if (rx_flush)
ibmveth_flush_buffer(skb->data,
length + offset);
+ if (!ibmveth_rxq_recycle_buffer(adapter))
+ kfree_skb(skb);
skb = new_skb;
- ibmveth_rxq_recycle_buffer(adapter);
} else {
ibmveth_rxq_harvest_buffer(adapter);
skb_reserve(skb, offset);
/* DP83865 phy identifier values */
#define DP83865_PHY_ID 0x20005c7a
-#define DP83865_INT_MASK_REG 0x15
-#define DP83865_INT_MASK_STATUS 0x14
+#define DP83865_INT_STATUS 0x14
+#define DP83865_INT_MASK 0x15
+#define DP83865_INT_CLEAR 0x17
#define DP83865_INT_REMOTE_FAULT 0x0008
#define DP83865_INT_ANE_COMPLETED 0x0010
int err;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
- err = phy_write(phydev, DP83865_INT_MASK_REG,
+ err = phy_write(phydev, DP83865_INT_MASK,
DP83865_INT_MASK_DEFAULT);
else
- err = phy_write(phydev, DP83865_INT_MASK_REG, 0);
+ err = phy_write(phydev, DP83865_INT_MASK, 0);
return err;
}
static int ns_ack_interrupt(struct phy_device *phydev)
{
- int ret = phy_read(phydev, DP83865_INT_MASK_STATUS);
+ int ret = phy_read(phydev, DP83865_INT_STATUS);
if (ret < 0)
return ret;
- return 0;
+ /* Clear the interrupt status bit by writing a “1”
+ * to the corresponding bit in INT_CLEAR (2:0 are reserved) */
+ ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7);
+
+ return ret;
}
static void ns_giga_speed_fallback(struct phy_device *phydev, int mode)
#include <linux/phy.h>
#include <linux/cache.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/ethtool.h>
static const struct ar9300_eeprom ar9300_default = {
.eepromVersion = 2,
.templateVersion = 2,
- .macAddr = {1, 2, 3, 4, 5, 6},
+ .macAddr = {0, 2, 3, 4, 5, 6},
.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
.baseEepHeader = {
mutex_lock(&sc->mutex);
ah->coverage_class = coverage_class;
+
+ ath9k_ps_wakeup(sc);
ath9k_hw_init_global_settings(ah);
+ ath9k_ps_restore(sc);
+
mutex_unlock(&sc->mutex);
}
* the high througput speed in 802.11n networks.
*/
- if (!is_main_vif(ar, vif))
+ if (!is_main_vif(ar, vif)) {
+ mutex_lock(&ar->mutex);
goto err_softw;
+ }
/*
* While the hardware supports *catch-all* key, for offloading
{
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
struct rt2x00_dev *rt2x00dev = hw->priv;
- int retval;
-
- retval = rt2x00lib_suspend(rt2x00dev, state);
- if (retval)
- return retval;
- /*
- * Decrease usbdev refcount.
- */
- usb_put_dev(interface_to_usbdev(usb_intf));
-
- return 0;
+ return rt2x00lib_suspend(rt2x00dev, state);
}
EXPORT_SYMBOL_GPL(rt2x00usb_suspend);
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
struct rt2x00_dev *rt2x00dev = hw->priv;
- usb_get_dev(interface_to_usbdev(usb_intf));
-
return rt2x00lib_resume(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00usb_resume);
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
wl->hw->wiphy->max_scan_ssids = 1;
+ wl->hw->wiphy->max_sched_scan_ssids = 1;
/*
* Maximum length of elements in scanning probe request templates
* should be the maximum length possible for a template, without
/* If enabled, tell runtime PM not to power off the card */
if (pm_runtime_enabled(&func->dev)) {
ret = pm_runtime_get_sync(&func->dev);
- if (ret)
+ if (ret < 0)
goto out;
} else {
/* Runtime PM is disabled: power up the card manually */
WL1271_TM_CMD_TEST,
WL1271_TM_CMD_INTERROGATE,
WL1271_TM_CMD_CONFIGURE,
- WL1271_TM_CMD_NVS_PUSH,
WL1271_TM_CMD_SET_PLT_MODE,
WL1271_TM_CMD_RECOVER,
return 0;
}
-static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
-{
- int ret = 0;
- size_t len;
- void *buf;
-
- wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push");
-
- if (!tb[WL1271_TM_ATTR_DATA])
- return -EINVAL;
-
- buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
- len = nla_len(tb[WL1271_TM_ATTR_DATA]);
-
- mutex_lock(&wl->mutex);
-
- kfree(wl->nvs);
-
- if ((wl->chip.id == CHIP_ID_1283_PG20) &&
- (len != sizeof(struct wl128x_nvs_file)))
- return -EINVAL;
- else if (len != sizeof(struct wl1271_nvs_file))
- return -EINVAL;
-
- wl->nvs = kzalloc(len, GFP_KERNEL);
- if (!wl->nvs) {
- wl1271_error("could not allocate memory for the nvs file");
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(wl->nvs, buf, len);
- wl->nvs_len = len;
-
- wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
{
u32 val;
return wl1271_tm_cmd_interrogate(wl, tb);
case WL1271_TM_CMD_CONFIGURE:
return wl1271_tm_cmd_configure(wl, tb);
- case WL1271_TM_CMD_NVS_PUSH:
- return wl1271_tm_cmd_nvs_push(wl, tb);
case WL1271_TM_CMD_SET_PLT_MODE:
return wl1271_tm_cmd_set_plt_mode(wl, tb);
case WL1271_TM_CMD_RECOVER:
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
return;
- pcie_bus_configure_settings(dev->bus, dev->bus->self->pcie_mpss);
+ if (dev->bus && dev->bus->self)
+ pcie_bus_configure_settings(dev->bus,
+ dev->bus->self->pcie_mpss);
memset(&hpp, 0, sizeof(hpp));
ret = pci_get_hp_params(dev, &hpp);
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
-enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE;
/*
* The default CLS is used if arch didn't set CLS explicitly and not
* will occur as normal.
*/
if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) ||
- dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT))
+ (dev->bus->self &&
+ dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT)))
*smpss = 0;
if (*smpss > dev->pcie_mpss)
static void pcie_write_mrrs(struct pci_dev *dev, int mps)
{
- int rc, mrrs;
+ int rc, mrrs, dev_mpss;
- if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
- int dev_mpss = 128 << dev->pcie_mpss;
+ /* In the "safe" case, do not configure the MRRS. There appear to be
+ * issues with setting MRRS to 0 on a number of devices.
+ */
- /* For Max performance, the MRRS must be set to the largest
- * supported value. However, it cannot be configured larger
- * than the MPS the device or the bus can support. This assumes
- * that the largest MRRS available on the device cannot be
- * smaller than the device MPSS.
- */
- mrrs = mps < dev_mpss ? mps : dev_mpss;
- } else
- /* In the "safe" case, configure the MRRS for fairness on the
- * bus by making all devices have the same size
- */
- mrrs = mps;
+ if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
+ return;
+ dev_mpss = 128 << dev->pcie_mpss;
+
+ /* For Max performance, the MRRS must be set to the largest supported
+ * value. However, it cannot be configured larger than the MPS the
+ * device or the bus can support. This assumes that the largest MRRS
+ * available on the device cannot be smaller than the device MPSS.
+ */
+ mrrs = min(mps, dev_mpss);
/* MRRS is a R/W register. Invalid values can be written, but a
- * subsiquent read will verify if the value is acceptable or not.
+ * subsequent read will verify if the value is acceptable or not.
* If the MRRS value provided is not acceptable (e.g., too large),
* shrink the value until it is acceptable to the HW.
*/
while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) {
+ dev_warn(&dev->dev, "Attempting to modify the PCI-E MRRS value"
+ " to %d. If any issues are encountered, please try "
+ "running with pci=pcie_bus_safe\n", mrrs);
rc = pcie_set_readrq(dev, mrrs);
if (rc)
- dev_err(&dev->dev, "Failed attempting to set the MRRS\n");
+ dev_err(&dev->dev,
+ "Failed attempting to set the MRRS\n");
mrrs /= 2;
}
if (!pci_is_pcie(dev))
return 0;
- dev_info(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
+ dev_dbg(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
pcie_write_mps(dev, mps);
pcie_write_mrrs(dev, mps);
- dev_info(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
+ dev_dbg(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
return 0;
{
u8 smpss = mpss;
- if (!bus->self)
- return;
-
if (!pci_is_pcie(bus->self))
return;
#include <asm/mach-types.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/vpac270.h>
#include "soc_common.h"
#include <mach/simpad.h>
#include "sa1100_generic.h"
-extern long get_cs3_shadow(void);
-extern void set_cs3_bit(int value);
-extern void clear_cs3_bit(int value);
-
static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_GPIO_CF_CD, "CF_CD" },
};
static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+ simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */
- //set_cs3_bit(PCMCIA_BUFF_DIS);
- clear_cs3_bit(PCMCIA_RESET);
+ /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
+ simpad_clear_cs3_bit(PCMCIA_RESET);
}
static void
struct pcmcia_state *state)
{
unsigned long levels = GPLR;
- long cs3reg = get_cs3_shadow();
+ long cs3reg = simpad_get_cs3_ro();
state->detect=((levels & GPIO_CF_CD)==0)?1:0;
state->ready=(levels & GPIO_CF_IRQ)?1:0;
- state->bvd1=1; /* Not available on Simpad. */
- state->bvd2=1; /* Not available on Simpad. */
+ state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
+ state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
state->wrprot=0; /* Not available on Simpad. */
-
- if((cs3reg & 0x0c) == 0x0c) {
+
+ if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
+ (PCMCIA_VS1|PCMCIA_VS2)) {
state->vs_3v=0;
state->vs_Xv=0;
} else {
/* Murphy: see table of MIC2562a-1 */
switch (state->Vcc) {
case 0:
- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+ simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
break;
case 33:
- clear_cs3_bit(VCC_3V_EN|EN1);
- set_cs3_bit(VCC_5V_EN|EN0);
+ simpad_clear_cs3_bit(VCC_3V_EN|EN1);
+ simpad_set_cs3_bit(VCC_5V_EN|EN0);
break;
case 50:
- clear_cs3_bit(VCC_5V_EN|EN1);
- set_cs3_bit(VCC_3V_EN|EN0);
+ simpad_clear_cs3_bit(VCC_5V_EN|EN1);
+ simpad_set_cs3_bit(VCC_3V_EN|EN0);
break;
default:
printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
__func__, state->Vcc);
- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+ simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
local_irq_restore(flags);
return -1;
}
static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
- set_cs3_bit(PCMCIA_RESET);
+ simpad_set_cs3_bit(PCMCIA_RESET);
}
static struct pcmcia_low_level simpad_pcmcia_ops = {
*/
struct ep93xx_rtc {
void __iomem *mmio_base;
+ struct rtc_device *rtc;
};
static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
{
struct ep93xx_rtc *ep93xx_rtc;
struct resource *res;
- struct rtc_device *rtc;
int err;
ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
return -ENXIO;
pdev->dev.platform_data = ep93xx_rtc;
- platform_set_drvdata(pdev, rtc);
+ platform_set_drvdata(pdev, ep93xx_rtc);
- rtc = rtc_device_register(pdev->name,
+ ep93xx_rtc->rtc = rtc_device_register(pdev->name,
&pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- err = PTR_ERR(rtc);
+ if (IS_ERR(ep93xx_rtc->rtc)) {
+ err = PTR_ERR(ep93xx_rtc->rtc);
goto exit;
}
return 0;
fail:
- rtc_device_unregister(rtc);
+ rtc_device_unregister(ep93xx_rtc->rtc);
exit:
platform_set_drvdata(pdev, NULL);
pdev->dev.platform_data = NULL;
static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
+ struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev);
sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
platform_set_drvdata(pdev, NULL);
- rtc_device_unregister(rtc);
+ rtc_device_unregister(ep93xx_rtc->rtc);
pdev->dev.platform_data = NULL;
return 0;
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
+#include <linux/sched.h>
#include <linux/workqueue.h>
/* DryIce Register Definitions */
time -= tm->tm_hour * 3600;
tm->tm_min = time / 60;
tm->tm_sec = time - tm->tm_min * 60;
+
+ tm->tm_isdst = 0;
}
EXPORT_SYMBOL(rtc_time_to_tm);
static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
+static void s3c_rtc_alarm_clk_enable(bool enable)
+{
+ static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock);
+ static bool alarm_clk_enabled;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags);
+ if (enable) {
+ if (!alarm_clk_enabled) {
+ clk_enable(rtc_clk);
+ alarm_clk_enabled = true;
+ }
+ } else {
+ if (alarm_clk_enabled) {
+ clk_disable(rtc_clk);
+ alarm_clk_enabled = false;
+ }
+ }
+ spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags);
+}
+
/* IRQ Handlers */
static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
clk_disable(rtc_clk);
+
+ s3c_rtc_alarm_clk_enable(false);
+
return IRQ_HANDLED;
}
writeb(tmp, s3c_rtc_base + S3C2410_RTCALM);
clk_disable(rtc_clk);
+ s3c_rtc_alarm_clk_enable(enabled);
+
return 0;
}
int res;
u8 rd_reg;
-#ifdef CONFIG_LOCKDEP
- /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
- * we don't want and can't tolerate. Although it might be
- * friendlier not to borrow this thread context...
- */
- local_irq_enable();
-#endif
-
res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
if (res)
goto out;
static int __devinit twl_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
- int ret = 0;
+ int ret = -EINVAL;
int irq = platform_get_irq(pdev, 0);
u8 rd_reg;
if (irq <= 0)
- return -EINVAL;
-
- rtc = rtc_device_register(pdev->name,
- &pdev->dev, &twl_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- ret = PTR_ERR(rtc);
- dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
- PTR_ERR(rtc));
- goto out0;
-
- }
-
- platform_set_drvdata(pdev, rtc);
+ goto out1;
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
if (ret < 0)
if (ret < 0)
goto out1;
- ret = request_irq(irq, twl_rtc_interrupt,
- IRQF_TRIGGER_RISING,
- dev_name(&rtc->dev), rtc);
- if (ret < 0) {
- dev_err(&pdev->dev, "IRQ is not free.\n");
- goto out1;
- }
-
if (twl_class_is_6030()) {
twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
REG_INT_MSK_LINE_A);
/* Check RTC module status, Enable if it is off */
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
if (ret < 0)
- goto out2;
+ goto out1;
if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
if (ret < 0)
- goto out2;
+ goto out1;
}
/* init cached IRQ enable bits */
ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
if (ret < 0)
+ goto out1;
+
+ rtc = rtc_device_register(pdev->name,
+ &pdev->dev, &twl_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ ret = PTR_ERR(rtc);
+ dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+ PTR_ERR(rtc));
+ goto out1;
+ }
+
+ ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
+ IRQF_TRIGGER_RISING,
+ dev_name(&rtc->dev), rtc);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "IRQ is not free.\n");
goto out2;
+ }
- return ret;
+ platform_set_drvdata(pdev, rtc);
+ return 0;
out2:
- free_irq(irq, rtc);
-out1:
rtc_device_unregister(rtc);
-out0:
+out1:
return ret;
}
nopout_wqe->itt = ((u16)task->itt |
(ISCSI_TASK_TYPE_MPATH <<
ISCSI_TMF_REQUEST_TYPE_SHIFT));
- nopout_wqe->ttt = nopout_hdr->ttt;
+ nopout_wqe->ttt = be32_to_cpu(nopout_hdr->ttt);
nopout_wqe->flags = 0;
if (!unsol)
nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;
u8 flogi_maddr[ETH_ALEN];
const struct net_device_ops *ops;
+ rtnl_lock();
+
/*
* Don't listen for Ethernet packets anymore.
* synchronize_net() ensures that the packet handlers are not running
" specific feature for LLD.\n");
}
+ rtnl_unlock();
+
/* Release the self-reference taken during fcoe_interface_create() */
fcoe_interface_put(fcoe);
}
fcoe_if_destroy(port->lport);
/* Do not tear down the fcoe interface for NPIV port */
- if (!npiv) {
- rtnl_lock();
+ if (!npiv)
fcoe_interface_cleanup(fcoe);
- rtnl_unlock();
- }
mutex_unlock(&fcoe_config_mutex);
}
printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
netdev->name);
rc = -EIO;
+ rtnl_unlock();
fcoe_interface_cleanup(fcoe);
- goto out_nodev;
+ goto out_nortnl;
}
/* Make this the "master" N_Port */
out_nodev:
rtnl_unlock();
+out_nortnl:
mutex_unlock(&fcoe_config_mutex);
return rc;
}
BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
removed[*nremoved] = h->dev[entry];
(*nremoved)++;
+
+ /*
+ * New physical devices won't have target/lun assigned yet
+ * so we need to preserve the values in the slot we are replacing.
+ */
+ if (new_entry->target == -1) {
+ new_entry->target = h->dev[entry]->target;
+ new_entry->lun = h->dev[entry]->lun;
+ }
+
h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;
}
static int hpsa_update_device_info(struct ctlr_info *h,
- unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
+ unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
+ unsigned char *is_OBDR_device)
{
-#define OBDR_TAPE_INQ_SIZE 49
+
+#define OBDR_SIG_OFFSET 43
+#define OBDR_TAPE_SIG "$DR-10"
+#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1)
+#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN)
+
unsigned char *inq_buff;
+ unsigned char *obdr_sig;
inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
if (!inq_buff)
else
this_device->raid_level = RAID_UNKNOWN;
+ if (is_OBDR_device) {
+ /* See if this is a One-Button-Disaster-Recovery device
+ * by looking for "$DR-10" at offset 43 in inquiry data.
+ */
+ obdr_sig = &inq_buff[OBDR_SIG_OFFSET];
+ *is_OBDR_device = (this_device->devtype == TYPE_ROM &&
+ strncmp(obdr_sig, OBDR_TAPE_SIG,
+ OBDR_SIG_LEN) == 0);
+ }
+
kfree(inq_buff);
return 0;
return 0;
}
- if (hpsa_update_device_info(h, scsi3addr, this_device))
+ if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
return 0;
(*nmsa2xxx_enclosures)++;
hpsa_set_bus_target_lun(this_device, bus, target, 0);
*/
struct ReportLUNdata *physdev_list = NULL;
struct ReportLUNdata *logdev_list = NULL;
- unsigned char *inq_buff = NULL;
u32 nphysicals = 0;
u32 nlogicals = 0;
u32 ndev_allocated = 0;
GFP_KERNEL);
physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
- inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
- if (!currentsd || !physdev_list || !logdev_list ||
- !inq_buff || !tmpdevice) {
+ if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) {
dev_err(&h->pdev->dev, "out of memory\n");
goto out;
}
/* adjust our table of devices */
nmsa2xxx_enclosures = 0;
for (i = 0; i < nphysicals + nlogicals + 1; i++) {
- u8 *lunaddrbytes;
+ u8 *lunaddrbytes, is_OBDR = 0;
/* Figure out where the LUN ID info is coming from */
lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
continue;
/* Get device type, vendor, model, device id */
- if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice))
+ if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
+ &is_OBDR))
continue; /* skip it if we can't talk to it. */
figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
tmpdevice);
hpsa_set_bus_target_lun(this_device, bus, target, lun);
switch (this_device->devtype) {
- case TYPE_ROM: {
+ case TYPE_ROM:
/* We don't *really* support actual CD-ROM devices,
* just "One Button Disaster Recovery" tape drive
* which temporarily pretends to be a CD-ROM drive.
* device by checking for "$DR-10" in bytes 43-48 of
* the inquiry data.
*/
- char obdr_sig[7];
-#define OBDR_TAPE_SIG "$DR-10"
- strncpy(obdr_sig, &inq_buff[43], 6);
- obdr_sig[6] = '\0';
- if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
- /* Not OBDR device, ignore it. */
- break;
- }
- ncurrent++;
+ if (is_OBDR)
+ ncurrent++;
break;
case TYPE_DISK:
if (i < nphysicals)
for (i = 0; i < ndev_allocated; i++)
kfree(currentsd[i]);
kfree(currentsd);
- kfree(inq_buff);
kfree(physdev_list);
kfree(logdev_list);
}
break;
case SCU_COMPLETION_TYPE_EVENT:
+ sci_controller_event_completion(ihost, ent);
+ break;
+
case SCU_COMPLETION_TYPE_NOTIFY: {
event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) <<
(SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT);
struct isci_request *request;
struct isci_request *next_request;
struct sas_task *task;
+ u16 active;
INIT_LIST_HEAD(&completed_request_list);
INIT_LIST_HEAD(&errored_request_list);
}
}
+ /* the coalesence timeout doubles at each encoding step, so
+ * update it based on the ilog2 value of the outstanding requests
+ */
+ active = isci_tci_active(ihost);
+ writel(SMU_ICC_GEN_VAL(NUMBER, active) |
+ SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
+ &ihost->smu_registers->interrupt_coalesce_control);
}
/**
struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
/* set the default interrupt coalescence number and timeout value. */
- sci_controller_set_interrupt_coalescence(ihost, 0x10, 250);
+ sci_controller_set_interrupt_coalescence(ihost, 0, 0);
}
static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))
+/* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */
+#define ISCI_COALESCE_BASE 9
+
/* expander attached sata devices require 3 rnc slots */
static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
{
#include <linux/firmware.h>
#include <linux/efi.h>
#include <asm/string.h>
+#include <scsi/scsi_host.h>
#include "isci.h"
#include "task.h"
#include "probe_roms.h"
+#define MAJ 1
+#define MIN 0
+#define BUILD 0
+#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
+ __stringify(BUILD)
+
+MODULE_VERSION(DRV_VERSION);
+
static struct scsi_transport_template *isci_transport_template;
static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = {
module_param(max_concurr_spinup, byte, 0);
MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");
+static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
+ struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+ struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
+}
+
+static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);
+
+struct device_attribute *isci_host_attrs[] = {
+ &dev_attr_isci_id,
+ NULL
+};
+
static struct scsi_host_template isci_sht = {
.module = THIS_MODULE,
.slave_alloc = sas_slave_alloc,
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
+ .shost_attrs = isci_host_attrs,
};
static struct sas_domain_function_template isci_transport_ops = {
return 0;
}
-static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
- struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
- struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);
-
- return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
-}
-
-static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);
-
static void isci_unregister(struct isci_host *isci_host)
{
struct Scsi_Host *shost;
return;
shost = isci_host->shost;
- device_remove_file(&shost->shost_dev, &dev_attr_isci_id);
sas_unregister_ha(&isci_host->sas_ha);
if (err)
goto err_shost_remove;
- err = device_create_file(&shost->shost_dev, &dev_attr_isci_id);
- if (err)
- goto err_unregister_ha;
-
return isci_host;
- err_unregister_ha:
- sas_unregister_ha(&(isci_host->sas_ha));
err_shost_remove:
scsi_remove_host(shost);
err_shost:
{
int err;
- pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME);
+ pr_info("%s: Intel(R) C600 SAS Controller Driver - version %s\n",
+ DRV_NAME, DRV_VERSION);
isci_transport_template = sas_domain_attach_transport(&isci_transport_ops);
if (!isci_transport_template)
u32 parity_count = 0;
u32 llctl, link_rate;
u32 clksm_value = 0;
+ u32 sp_timeouts = 0;
iphy->link_layer_registers = reg;
llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
writel(llctl, &iphy->link_layer_registers->link_layer_control);
+ sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
+
+ /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
+ sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
+
+ /* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can
+ * lock with 3Gb drive when SCU max rate is set to 1.5Gb.
+ */
+ sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
+
+ writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
+
if (is_a2(ihost->pdev)) {
/* Program the max ARB time for the PHY to 700us so we inter-operate with
* the PMC expander which shuts down PHYs if the expander PHY generates too
#define SCU_AFE_XCVRCR_OFFSET 0x00DC
#define SCU_AFE_LUTCR_OFFSET 0x00E0
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT (0UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK (0x000000FFUL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT (8UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK (0x0000FF00UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT (16UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK (0x00FF0000UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT (24UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK (0xFF000000UL)
+
+#define SCU_SAS_PHYTOV_GEN_VAL(name, value) \
+ SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value)
+
#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0)
#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003)
#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0)
sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
return SCI_SUCCESS;
case SCI_REQ_TASK_WAIT_TC_RESP:
+ /* The task frame was already confirmed to have been
+ * sent by the SCU HW. Since the state machine is
+ * now only waiting for the task response itself,
+ * abort the request and complete it immediately
+ * and don't wait for the task response.
+ */
sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
return SCI_SUCCESS;
case SCI_REQ_ABORTING:
- sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
- return SCI_SUCCESS;
+ /* If a request has a termination requested twice, return
+ * a failure indication, since HW confirmation of the first
+ * abort is still outstanding.
+ */
case SCI_REQ_COMPLETED:
default:
dev_warn(&ireq->owning_controller->pdev->dev,
}
}
-static void isci_request_process_stp_response(struct sas_task *task,
- void *response_buffer)
+static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis)
{
- struct dev_to_host_fis *d2h_reg_fis = response_buffer;
struct task_status_struct *ts = &task->task_status;
struct ata_task_resp *resp = (void *)&ts->buf[0];
- resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6));
- memcpy(&resp->ending_fis[0], response_buffer + 16, 24);
+ resp->frame_len = sizeof(*fis);
+ memcpy(resp->ending_fis, fis, sizeof(*fis));
ts->buf_valid_size = sizeof(*resp);
- /**
- * If the device fault bit is set in the status register, then
+ /* If the device fault bit is set in the status register, then
* set the sense data and return.
*/
- if (d2h_reg_fis->status & ATA_DF)
+ if (fis->status & ATA_DF)
ts->stat = SAS_PROTO_RESPONSE;
else
ts->stat = SAM_STAT_GOOD;
{
struct sas_task *task = isci_request_access_task(request);
struct ssp_response_iu *resp_iu;
- void *resp_buf;
unsigned long task_flags;
struct isci_remote_device *idev = isci_lookup_device(task->dev);
enum service_response response = SAS_TASK_UNDELIVERED;
task);
if (sas_protocol_ata(task->task_proto)) {
- resp_buf = &request->stp.rsp;
- isci_request_process_stp_response(task,
- resp_buf);
+ isci_process_stp_response(task, &request->stp.rsp);
} else if (SAS_PROTOCOL_SSP == task->task_proto) {
/* crack the iu response buffer. */
*/
buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header);
- size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t);
+ size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]);
/*
* The Unsolicited Frame buffers are set at the start of the UF
* starting address of the UF address table.
* 64-bit pointers are required by the hardware.
*/
- dma_addr_t *array;
+ u64 *array;
/**
* This field specifies the physical address location for the UF
*/
error = lport->tt.frame_send(lport, fp);
+ if (fh->fh_type == FC_TYPE_BLS)
+ return error;
+
/*
* Update the exchange and sequence flags,
* assuming all frames for the sequence have been sent.
}
/**
- * fc_seq_exch_abort() - Abort an exchange and sequence
- * @req_sp: The sequence to be aborted
+ * fc_exch_abort_locked() - Abort an exchange
+ * @ep: The exchange to be aborted
* @timer_msec: The period of time to wait before aborting
*
- * Generally called because of a timeout or an abort from the upper layer.
+ * Locking notes: Called with exch lock held
+ *
+ * Return value: 0 on success else error code
*/
-static int fc_seq_exch_abort(const struct fc_seq *req_sp,
- unsigned int timer_msec)
+static int fc_exch_abort_locked(struct fc_exch *ep,
+ unsigned int timer_msec)
{
struct fc_seq *sp;
- struct fc_exch *ep;
struct fc_frame *fp;
int error;
- ep = fc_seq_exch(req_sp);
-
- spin_lock_bh(&ep->ex_lock);
if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) ||
- ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) {
- spin_unlock_bh(&ep->ex_lock);
+ ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP))
return -ENXIO;
- }
/*
* Send the abort on a new sequence if possible.
*/
sp = fc_seq_start_next_locked(&ep->seq);
- if (!sp) {
- spin_unlock_bh(&ep->ex_lock);
+ if (!sp)
return -ENOMEM;
- }
ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL;
if (timer_msec)
fc_exch_timer_set_locked(ep, timer_msec);
- spin_unlock_bh(&ep->ex_lock);
/*
* If not logged into the fabric, don't send ABTS but leave
return error;
}
+/**
+ * fc_seq_exch_abort() - Abort an exchange and sequence
+ * @req_sp: The sequence to be aborted
+ * @timer_msec: The period of time to wait before aborting
+ *
+ * Generally called because of a timeout or an abort from the upper layer.
+ *
+ * Return value: 0 on success else error code
+ */
+static int fc_seq_exch_abort(const struct fc_seq *req_sp,
+ unsigned int timer_msec)
+{
+ struct fc_exch *ep;
+ int error;
+
+ ep = fc_seq_exch(req_sp);
+ spin_lock_bh(&ep->ex_lock);
+ error = fc_exch_abort_locked(ep, timer_msec);
+ spin_unlock_bh(&ep->ex_lock);
+ return error;
+}
+
/**
* fc_exch_timeout() - Handle exchange timer expiration
* @work: The work_struct identifying the exchange that timed out
int rc = 1;
spin_lock_bh(&ep->ex_lock);
+ fc_exch_abort_locked(ep, 0);
ep->state |= FC_EX_RST_CLEANUP;
if (cancel_delayed_work(&ep->timeout_work))
atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
struct fc_exch *ep;
struct fc_seq *sp = NULL;
struct fc_frame_header *fh;
+ struct fc_fcp_pkt *fsp = NULL;
int rc = 1;
ep = fc_exch_alloc(lport, fp);
fc_exch_setup_hdr(ep, fp, ep->f_ctl);
sp->cnt++;
- if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD)
+ if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) {
+ fsp = fr_fsp(fp);
fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
+ }
if (unlikely(lport->tt.frame_send(lport, fp)))
goto err;
spin_unlock_bh(&ep->ex_lock);
return sp;
err:
- fc_fcp_ddp_done(fr_fsp(fp));
+ if (fsp)
+ fc_fcp_ddp_done(fsp);
rc = fc_exch_done_locked(ep);
spin_unlock_bh(&ep->ex_lock);
if (!rc)
struct fc_fcp_internal *si;
int rc = FAILED;
unsigned long flags;
+ int rval;
+
+ rval = fc_block_scsi_eh(sc_cmd);
+ if (rval)
+ return rval;
lport = shost_priv(sc_cmd->device->host);
if (lport->state != LPORT_ST_READY)
int rc = FAILED;
int rval;
- rval = fc_remote_port_chkready(rport);
+ rval = fc_block_scsi_eh(sc_cmd);
if (rval)
- goto out;
+ return rval;
lport = shost_priv(sc_cmd->device->host);
FC_SCSI_DBG(lport, "Resetting host\n");
+ fc_block_scsi_eh(sc_cmd);
+
lport->tt.lport_reset(lport);
wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT;
while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies,
*/
#include <linux/timer.h>
+#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
FCH_EVT_LIPRESET, 0);
fc_vports_linkchange(lport);
fc_lport_reset_locked(lport);
- if (lport->link_up)
+ if (lport->link_up) {
+ /*
+ * Wait upto resource allocation time out before
+ * doing re-login since incomplete FIP exchanged
+ * from last session may collide with exchanges
+ * in new session.
+ */
+ msleep(lport->r_a_tov);
fc_lport_enter_flogi(lport);
+ }
}
/**
fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
}
- if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) {
+ if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4) {
+ int prot = 0;
vha->flags.difdix_supported = 1;
ql_dbg(ql_dbg_user, vha, 0x7082,
"Registered for DIF/DIX type 1 and 3 protection.\n");
+ if (ql2xenabledif == 1)
+ prot = SHOST_DIX_TYPE0_PROTECTION;
scsi_host_set_prot(vha->host,
- SHOST_DIF_TYPE1_PROTECTION
+ prot | SHOST_DIF_TYPE1_PROTECTION
| SHOST_DIF_TYPE2_PROTECTION
| SHOST_DIF_TYPE3_PROTECTION
| SHOST_DIX_TYPE1_PROTECTION
/*
* Table for showing the current message id in use for particular level
* Change this table for addition of log/debug messages.
- * -----------------------------------------------------
- * | Level | Last Value Used |
- * -----------------------------------------------------
- * | Module Init and Probe | 0x0116 |
- * | Mailbox commands | 0x111e |
- * | Device Discovery | 0x2083 |
- * | Queue Command and IO tracing | 0x302e |
- * | DPC Thread | 0x401c |
- * | Async Events | 0x5059 |
- * | Timer Routines | 0x600d |
- * | User Space Interactions | 0x709c |
- * | Task Management | 0x8043 |
- * | AER/EEH | 0x900f |
- * | Virtual Port | 0xa007 |
- * | ISP82XX Specific | 0xb027 |
- * | MultiQ | 0xc00b |
- * | Misc | 0xd00b |
- * -----------------------------------------------------
+ * ----------------------------------------------------------------------
+ * | Level | Last Value Used | Holes |
+ * ----------------------------------------------------------------------
+ * | Module Init and Probe | 0x0116 | |
+ * | Mailbox commands | 0x1126 | |
+ * | Device Discovery | 0x2083 | |
+ * | Queue Command and IO tracing | 0x302e | 0x3008 |
+ * | DPC Thread | 0x401c | |
+ * | Async Events | 0x5059 | |
+ * | Timer Routines | 0x600d | |
+ * | User Space Interactions | 0x709d | |
+ * | Task Management | 0x8041 | |
+ * | AER/EEH | 0x900f | |
+ * | Virtual Port | 0xa007 | |
+ * | ISP82XX Specific | 0xb04f | |
+ * | MultiQ | 0xc00b | |
+ * | Misc | 0xd00b | |
+ * ----------------------------------------------------------------------
*/
#include "qla_def.h"
#define DT_ISP8021 BIT_14
#define DT_ISP_LAST (DT_ISP8021 << 1)
+#define DT_T10_PI BIT_25
#define DT_IIDMA BIT_26
#define DT_FWI2 BIT_27
#define DT_ZIO_SUPPORTED BIT_28
#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha))
#define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
+#define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI)
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
#define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED)
/*
* If DIF Error is set in comp_status, these additional fields are
* defined:
+ *
+ * !!! NOTE: Firmware sends expected/actual DIF data in big endian
+ * format; but all of the "data" field gets swab32-d in the beginning
+ * of qla2x00_status_entry().
+ *
* &data[10] : uint8_t report_runt_bg[2]; - computed guard
* &data[12] : uint8_t actual_dif[8]; - DIF Data received
* &data[20] : uint8_t expected_dif[8]; - DIF Data computed
req = vha->req;
rsp = req->rsp;
- atomic_set(&vha->loop_state, LOOP_UPDATE);
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
if (vha->flags.online) {
if (!(rval = qla2x00_fw_ready(vha))) {
/* Wait at most MAX_TARGET RSCNs for a stable link. */
wait_time = 256;
do {
- atomic_set(&vha->loop_state, LOOP_UPDATE);
-
/* Issue a marker after FW becomes ready. */
qla2x00_marker(vha, req, rsp, 0, 0,
MK_SYNC_ALL);
fcport->d_id.b.al_pa);
}
}
+
+static inline int
+qla2x00_hba_err_chk_enabled(srb_t *sp)
+{
+ /*
+ * Uncomment when corresponding SCSI changes are done.
+ *
+ if (!sp->cmd->prot_chk)
+ return 0;
+ *
+ */
+
+ switch (scsi_get_prot_op(sp->cmd)) {
+ case SCSI_PROT_READ_STRIP:
+ case SCSI_PROT_WRITE_INSERT:
+ if (ql2xenablehba_err_chk >= 1)
+ return 1;
+ break;
+ case SCSI_PROT_READ_PASS:
+ case SCSI_PROT_WRITE_PASS:
+ if (ql2xenablehba_err_chk >= 2)
+ return 1;
+ break;
+ case SCSI_PROT_READ_INSERT:
+ case SCSI_PROT_WRITE_STRIP:
+ return 1;
+ }
+ return 0;
+}
*
*/
static inline void
-qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt,
+qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
unsigned int protcnt)
{
- struct sd_dif_tuple *spt;
+ struct scsi_cmnd *cmd = sp->cmd;
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
- unsigned char op = scsi_get_prot_op(cmd);
switch (scsi_get_prot_type(cmd)) {
- /* For TYPE 0 protection: no checking */
case SCSI_PROT_DIF_TYPE0:
- pkt->ref_tag_mask[0] = 0x00;
- pkt->ref_tag_mask[1] = 0x00;
- pkt->ref_tag_mask[2] = 0x00;
- pkt->ref_tag_mask[3] = 0x00;
+ /*
+ * No check for ql2xenablehba_err_chk, as it would be an
+ * I/O error if hba tag generation is not done.
+ */
+ pkt->ref_tag = cpu_to_le32((uint32_t)
+ (0xffffffff & scsi_get_lba(cmd)));
+
+ if (!qla2x00_hba_err_chk_enabled(sp))
+ break;
+
+ pkt->ref_tag_mask[0] = 0xff;
+ pkt->ref_tag_mask[1] = 0xff;
+ pkt->ref_tag_mask[2] = 0xff;
+ pkt->ref_tag_mask[3] = 0xff;
break;
/*
* match LBA in CDB + N
*/
case SCSI_PROT_DIF_TYPE2:
- if (!ql2xenablehba_err_chk)
- break;
-
- if (scsi_prot_sg_count(cmd)) {
- spt = page_address(sg_page(scsi_prot_sglist(cmd))) +
- scsi_prot_sglist(cmd)[0].offset;
- pkt->app_tag = swab32(spt->app_tag);
- pkt->app_tag_mask[0] = 0xff;
- pkt->app_tag_mask[1] = 0xff;
- }
+ pkt->app_tag = __constant_cpu_to_le16(0);
+ pkt->app_tag_mask[0] = 0x0;
+ pkt->app_tag_mask[1] = 0x0;
pkt->ref_tag = cpu_to_le32((uint32_t)
(0xffffffff & scsi_get_lba(cmd)));
+ if (!qla2x00_hba_err_chk_enabled(sp))
+ break;
+
/* enable ALL bytes of the ref tag */
pkt->ref_tag_mask[0] = 0xff;
pkt->ref_tag_mask[1] = 0xff;
* 16 bit app tag.
*/
case SCSI_PROT_DIF_TYPE1:
- if (!ql2xenablehba_err_chk)
+ pkt->ref_tag = cpu_to_le32((uint32_t)
+ (0xffffffff & scsi_get_lba(cmd)));
+ pkt->app_tag = __constant_cpu_to_le16(0);
+ pkt->app_tag_mask[0] = 0x0;
+ pkt->app_tag_mask[1] = 0x0;
+
+ if (!qla2x00_hba_err_chk_enabled(sp))
break;
- if (protcnt && (op == SCSI_PROT_WRITE_STRIP ||
- op == SCSI_PROT_WRITE_PASS)) {
- spt = page_address(sg_page(scsi_prot_sglist(cmd))) +
- scsi_prot_sglist(cmd)[0].offset;
- ql_dbg(ql_dbg_io, vha, 0x3008,
- "LBA from user %p, lba = 0x%x for cmd=%p.\n",
- spt, (int)spt->ref_tag, cmd);
- pkt->ref_tag = swab32(spt->ref_tag);
- pkt->app_tag_mask[0] = 0x0;
- pkt->app_tag_mask[1] = 0x0;
- } else {
- pkt->ref_tag = cpu_to_le32((uint32_t)
- (0xffffffff & scsi_get_lba(cmd)));
- pkt->app_tag = __constant_cpu_to_le16(0);
- pkt->app_tag_mask[0] = 0x0;
- pkt->app_tag_mask[1] = 0x0;
- }
/* enable ALL bytes of the ref tag */
pkt->ref_tag_mask[0] = 0xff;
pkt->ref_tag_mask[1] = 0xff;
scsi_get_prot_type(cmd), cmd);
}
+struct qla2_sgx {
+ dma_addr_t dma_addr; /* OUT */
+ uint32_t dma_len; /* OUT */
+
+ uint32_t tot_bytes; /* IN */
+ struct scatterlist *cur_sg; /* IN */
+
+ /* for book keeping, bzero on initial invocation */
+ uint32_t bytes_consumed;
+ uint32_t num_bytes;
+ uint32_t tot_partial;
+
+ /* for debugging */
+ uint32_t num_sg;
+ srb_t *sp;
+};
+static int
+qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx,
+ uint32_t *partial)
+{
+ struct scatterlist *sg;
+ uint32_t cumulative_partial, sg_len;
+ dma_addr_t sg_dma_addr;
+
+ if (sgx->num_bytes == sgx->tot_bytes)
+ return 0;
+
+ sg = sgx->cur_sg;
+ cumulative_partial = sgx->tot_partial;
+
+ sg_dma_addr = sg_dma_address(sg);
+ sg_len = sg_dma_len(sg);
+
+ sgx->dma_addr = sg_dma_addr + sgx->bytes_consumed;
+
+ if ((cumulative_partial + (sg_len - sgx->bytes_consumed)) >= blk_sz) {
+ sgx->dma_len = (blk_sz - cumulative_partial);
+ sgx->tot_partial = 0;
+ sgx->num_bytes += blk_sz;
+ *partial = 0;
+ } else {
+ sgx->dma_len = sg_len - sgx->bytes_consumed;
+ sgx->tot_partial += sgx->dma_len;
+ *partial = 1;
+ }
+
+ sgx->bytes_consumed += sgx->dma_len;
+
+ if (sg_len == sgx->bytes_consumed) {
+ sg = sg_next(sg);
+ sgx->num_sg++;
+ sgx->cur_sg = sg;
+ sgx->bytes_consumed = 0;
+ }
+
+ return 1;
+}
+
+static int
+qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
+ uint32_t *dsd, uint16_t tot_dsds)
+{
+ void *next_dsd;
+ uint8_t avail_dsds = 0;
+ uint32_t dsd_list_len;
+ struct dsd_dma *dsd_ptr;
+ struct scatterlist *sg_prot;
+ uint32_t *cur_dsd = dsd;
+ uint16_t used_dsds = tot_dsds;
+
+ uint32_t prot_int;
+ uint32_t partial;
+ struct qla2_sgx sgx;
+ dma_addr_t sle_dma;
+ uint32_t sle_dma_len, tot_prot_dma_len = 0;
+ struct scsi_cmnd *cmd = sp->cmd;
+
+ prot_int = cmd->device->sector_size;
+
+ memset(&sgx, 0, sizeof(struct qla2_sgx));
+ sgx.tot_bytes = scsi_bufflen(sp->cmd);
+ sgx.cur_sg = scsi_sglist(sp->cmd);
+ sgx.sp = sp;
+
+ sg_prot = scsi_prot_sglist(sp->cmd);
+
+ while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {
+
+ sle_dma = sgx.dma_addr;
+ sle_dma_len = sgx.dma_len;
+alloc_and_fill:
+ /* Allocate additional continuation packets? */
+ if (avail_dsds == 0) {
+ avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
+ QLA_DSDS_PER_IOCB : used_dsds;
+ dsd_list_len = (avail_dsds + 1) * 12;
+ used_dsds -= avail_dsds;
+
+ /* allocate tracking DS */
+ dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC);
+ if (!dsd_ptr)
+ return 1;
+
+ /* allocate new list */
+ dsd_ptr->dsd_addr = next_dsd =
+ dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
+ &dsd_ptr->dsd_list_dma);
+
+ if (!next_dsd) {
+ /*
+ * Need to cleanup only this dsd_ptr, rest
+ * will be done by sp_free_dma()
+ */
+ kfree(dsd_ptr);
+ return 1;
+ }
+
+ list_add_tail(&dsd_ptr->list,
+ &((struct crc_context *)sp->ctx)->dsd_list);
+
+ sp->flags |= SRB_CRC_CTX_DSD_VALID;
+
+ /* add new list to cmd iocb or last list */
+ *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
+ *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
+ *cur_dsd++ = dsd_list_len;
+ cur_dsd = (uint32_t *)next_dsd;
+ }
+ *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
+ *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
+ *cur_dsd++ = cpu_to_le32(sle_dma_len);
+ avail_dsds--;
+
+ if (partial == 0) {
+ /* Got a full protection interval */
+ sle_dma = sg_dma_address(sg_prot) + tot_prot_dma_len;
+ sle_dma_len = 8;
+
+ tot_prot_dma_len += sle_dma_len;
+ if (tot_prot_dma_len == sg_dma_len(sg_prot)) {
+ tot_prot_dma_len = 0;
+ sg_prot = sg_next(sg_prot);
+ }
+
+ partial = 1; /* So as to not re-enter this block */
+ goto alloc_and_fill;
+ }
+ }
+ /* Null termination */
+ *cur_dsd++ = 0;
+ *cur_dsd++ = 0;
+ *cur_dsd++ = 0;
+ return 0;
+}
static int
qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
uint16_t tot_dsds)
struct scsi_cmnd *cmd;
struct scatterlist *cur_seg;
int sgc;
- uint32_t total_bytes;
+ uint32_t total_bytes = 0;
uint32_t data_bytes;
uint32_t dif_bytes;
uint8_t bundling = 1;
__constant_cpu_to_le16(CF_READ_DATA);
}
- tot_prot_dsds = scsi_prot_sg_count(cmd);
- if (!tot_prot_dsds)
+ if ((scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_INSERT) ||
+ (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_STRIP) ||
+ (scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_STRIP) ||
+ (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_INSERT))
bundling = 0;
/* Allocate CRC context from global pool */
INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list);
- qla24xx_set_t10dif_tags(cmd, (struct fw_dif_context *)
+ qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *)
&crc_ctx_pkt->ref_tag, tot_prot_dsds);
cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma));
fcp_cmnd->additional_cdb_len |= 2;
int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
- host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun));
memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */
/* Compute dif len and adjust data len to incude protection */
- total_bytes = data_bytes;
dif_bytes = 0;
blk_size = cmd->device->sector_size;
- if (scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) {
- dif_bytes = (data_bytes / blk_size) * 8;
- total_bytes += dif_bytes;
+ dif_bytes = (data_bytes / blk_size) * 8;
+
+ switch (scsi_get_prot_op(sp->cmd)) {
+ case SCSI_PROT_READ_INSERT:
+ case SCSI_PROT_WRITE_STRIP:
+ total_bytes = data_bytes;
+ data_bytes += dif_bytes;
+ break;
+
+ case SCSI_PROT_READ_STRIP:
+ case SCSI_PROT_WRITE_INSERT:
+ case SCSI_PROT_READ_PASS:
+ case SCSI_PROT_WRITE_PASS:
+ total_bytes = data_bytes + dif_bytes;
+ break;
+ default:
+ BUG();
}
- if (!ql2xenablehba_err_chk)
+ if (!qla2x00_hba_err_chk_enabled(sp))
fw_prot_opts |= 0x10; /* Disable Guard tag checking */
if (!bundling) {
cmd_pkt->control_flags |=
__constant_cpu_to_le16(CF_DATA_SEG_DESCR_ENABLE);
- if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd,
+
+ if (!bundling && tot_prot_dsds) {
+ if (qla24xx_walk_and_build_sglist_no_difb(ha, sp,
+ cur_dsd, tot_dsds))
+ goto crc_queuing_error;
+ } else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd,
(tot_dsds - tot_prot_dsds)))
goto crc_queuing_error;
goto queuing_error;
else
sp->flags |= SRB_DMA_VALID;
+
+ if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
+ (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) {
+ struct qla2_sgx sgx;
+ uint32_t partial;
+
+ memset(&sgx, 0, sizeof(struct qla2_sgx));
+ sgx.tot_bytes = scsi_bufflen(cmd);
+ sgx.cur_sg = scsi_sglist(cmd);
+ sgx.sp = sp;
+
+ nseg = 0;
+ while (qla24xx_get_one_block_sg(
+ cmd->device->sector_size, &sgx, &partial))
+ nseg++;
+ }
} else
nseg = 0;
goto queuing_error;
else
sp->flags |= SRB_CRC_PROT_DMA_VALID;
+
+ if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
+ (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) {
+ nseg = scsi_bufflen(cmd) / cmd->device->sector_size;
+ }
} else {
nseg = 0;
}
/* Build header part of command packet (excluding the OPCODE). */
req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp;
+ sp->handle = handle;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt;
vha->flags.rscn_queue_overflow = 1;
}
- atomic_set(&vha->loop_state, LOOP_UPDATE);
atomic_set(&vha->loop_down_timer, 0);
vha->flags.management_server_logged_in = 0;
* ASC/ASCQ fields in the sense buffer with ILLEGAL_REQUEST
* to indicate to the kernel that the HBA detected error.
*/
-static inline void
+static inline int
qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
{
struct scsi_qla_host *vha = sp->fcport->vha;
struct scsi_cmnd *cmd = sp->cmd;
- struct scsi_dif_tuple *ep =
- (struct scsi_dif_tuple *)&sts24->data[20];
- struct scsi_dif_tuple *ap =
- (struct scsi_dif_tuple *)&sts24->data[12];
+ uint8_t *ap = &sts24->data[12];
+ uint8_t *ep = &sts24->data[20];
uint32_t e_ref_tag, a_ref_tag;
uint16_t e_app_tag, a_app_tag;
uint16_t e_guard, a_guard;
- e_ref_tag = be32_to_cpu(ep->ref_tag);
- a_ref_tag = be32_to_cpu(ap->ref_tag);
- e_app_tag = be16_to_cpu(ep->app_tag);
- a_app_tag = be16_to_cpu(ap->app_tag);
- e_guard = be16_to_cpu(ep->guard);
- a_guard = be16_to_cpu(ap->guard);
+ /*
+ * swab32 of the "data" field in the beginning of qla2x00_status_entry()
+ * would make guard field appear at offset 2
+ */
+ a_guard = le16_to_cpu(*(uint16_t *)(ap + 2));
+ a_app_tag = le16_to_cpu(*(uint16_t *)(ap + 0));
+ a_ref_tag = le32_to_cpu(*(uint32_t *)(ap + 4));
+ e_guard = le16_to_cpu(*(uint16_t *)(ep + 2));
+ e_app_tag = le16_to_cpu(*(uint16_t *)(ep + 0));
+ e_ref_tag = le32_to_cpu(*(uint32_t *)(ep + 4));
ql_dbg(ql_dbg_io, vha, 0x3023,
"iocb(s) %p Returned STATUS.\n", sts24);
cmd->cmnd[0], (u64)scsi_get_lba(cmd), a_ref_tag, e_ref_tag,
a_app_tag, e_app_tag, a_guard, e_guard);
+ /*
+ * Ignore sector if:
+ * For type 3: ref & app tag is all 'f's
+ * For type 0,1,2: app tag is all 'f's
+ */
+ if ((a_app_tag == 0xffff) &&
+ ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) ||
+ (a_ref_tag == 0xffffffff))) {
+ uint32_t blocks_done, resid;
+ sector_t lba_s = scsi_get_lba(cmd);
+
+ /* 2TB boundary case covered automatically with this */
+ blocks_done = e_ref_tag - (uint32_t)lba_s + 1;
+
+ resid = scsi_bufflen(cmd) - (blocks_done *
+ cmd->device->sector_size);
+
+ scsi_set_resid(cmd, resid);
+ cmd->result = DID_OK << 16;
+
+ /* Update protection tag */
+ if (scsi_prot_sg_count(cmd)) {
+ uint32_t i, j = 0, k = 0, num_ent;
+ struct scatterlist *sg;
+ struct sd_dif_tuple *spt;
+
+ /* Patch the corresponding protection tags */
+ scsi_for_each_prot_sg(cmd, sg,
+ scsi_prot_sg_count(cmd), i) {
+ num_ent = sg_dma_len(sg) / 8;
+ if (k + num_ent < blocks_done) {
+ k += num_ent;
+ continue;
+ }
+ j = blocks_done - k - 1;
+ k = blocks_done;
+ break;
+ }
+
+ if (k != blocks_done) {
+ qla_printk(KERN_WARNING, sp->fcport->vha->hw,
+ "unexpected tag values tag:lba=%x:%lx)\n",
+ e_ref_tag, lba_s);
+ return 1;
+ }
+
+ spt = page_address(sg_page(sg)) + sg->offset;
+ spt += j;
+
+ spt->app_tag = 0xffff;
+ if (scsi_get_prot_type(cmd) == SCSI_PROT_DIF_TYPE3)
+ spt->ref_tag = 0xffffffff;
+ }
+
+ return 0;
+ }
+
/* check guard */
if (e_guard != a_guard) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
- return;
+ return 1;
}
- /* check appl tag */
- if (e_app_tag != a_app_tag) {
+ /* check ref tag */
+ if (e_ref_tag != a_ref_tag) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
- 0x10, 0x2);
+ 0x10, 0x3);
set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
- return;
+ return 1;
}
- /* check ref tag */
- if (e_ref_tag != a_ref_tag) {
+ /* check appl tag */
+ if (e_app_tag != a_app_tag) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
- 0x10, 0x3);
+ 0x10, 0x2);
set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
- return;
+ return 1;
}
+
+ return 1;
}
/**
break;
case CS_DIF_ERROR:
- qla2x00_handle_dif_error(sp, sts24);
+ logit = qla2x00_handle_dif_error(sp, sts24);
break;
default:
cp->result = DID_ERROR << 16;
goto skip_msi;
}
- if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX ||
- !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
+ if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX)) {
ql_log(ql_log_warn, vha, 0x0035,
"MSI-X; Unsupported ISP2432 (0x%X, 0x%X).\n",
- ha->pdev->revision, ha->fw_attributes);
+ ha->pdev->revision, QLA_MSIX_CHIP_REV_24XX);
goto skip_msix;
}
host->can_queue = base_vha->req->length + 128;
host->this_id = 255;
host->cmd_per_lun = 3;
- if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif)
+ if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
host->max_cmd_len = 32;
else
host->max_cmd_len = MAX_CMDSZ;
struct qla_hw_data *ha;
struct rsp_que *rsp;
struct device_reg_82xx __iomem *reg;
+ unsigned long flags;
rsp = (struct rsp_que *) dev_id;
if (!rsp) {
ha = rsp->hw;
reg = &ha->iobase->isp82;
- spin_lock_irq(&ha->hardware_lock);
+ spin_lock_irqsave(&ha->hardware_lock, flags);
vha = pci_get_drvdata(ha->pdev);
qla24xx_process_response_queue(vha, rsp);
WRT_REG_DWORD(®->host_int, 0);
- spin_unlock_irq(&ha->hardware_lock);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
return IRQ_HANDLED;
}
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
+ /* build FCP_CMND IU */
+ memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
+ int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun);
+ ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
+
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ ctx->fcp_cmnd->additional_cdb_len |= 1;
+ else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+ ctx->fcp_cmnd->additional_cdb_len |= 2;
+
/*
* Update tagged queuing modifier -- default is TSK_SIMPLE (0).
*/
}
}
- /* build FCP_CMND IU */
- memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
- int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun);
- ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
-
- if (cmd->sc_data_direction == DMA_TO_DEVICE)
- ctx->fcp_cmnd->additional_cdb_len |= 1;
- else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
- ctx->fcp_cmnd->additional_cdb_len |= 2;
-
memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
fcp_dl = (uint32_t *)(ctx->fcp_cmnd->cdb + 16 +
"Maximum queue depth to report for target devices.");
/* Do not change the value of this after module load */
-int ql2xenabledif = 1;
+int ql2xenabledif = 0;
module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xenabledif,
" Enable T10-CRC-DIF "
- " Default is 0 - No DIF Support. 1 - Enable it");
+ " Default is 0 - No DIF Support. 1 - Enable it"
+ ", 2 - Enable DIF for all types, except Type 0.");
-int ql2xenablehba_err_chk;
+int ql2xenablehba_err_chk = 2;
module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xenablehba_err_chk,
- " Enable T10-CRC-DIF Error isolation by HBA"
- " Default is 0 - Error isolation disabled, 1 - Enable it");
+ " Enable T10-CRC-DIF Error isolation by HBA:\n"
+ " Default is 1.\n"
+ " 0 -- Error isolation disabled\n"
+ " 1 -- Error isolation enabled only for DIX Type 0\n"
+ " 2 -- Error isolation enabled for all Types\n");
int ql2xiidmaenable=1;
module_param(ql2xiidmaenable, int, S_IRUGO);
"Abort command mbx success.\n");
wait = 1;
}
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
qla2x00_sp_compl(ha, sp);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ /* Did the command return during mailbox execution? */
+ if (ret == FAILED && !CMD_SP(cmd))
+ ret = SUCCESS;
/* Wait for the command to be returned. */
if (wait) {
host->this_id = 255;
host->cmd_per_lun = 3;
host->unique_id = host->host_no;
- if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif)
+ if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
host->max_cmd_len = 32;
else
host->max_cmd_len = MAX_CMDSZ;
"Detected hba at address=%p.\n",
ha);
- if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) {
+ if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4) {
+ int prot = 0;
base_vha->flags.difdix_supported = 1;
ql_dbg(ql_dbg_init, base_vha, 0x00f1,
"Registering for DIF/DIX type 1 and 3 protection.\n");
+ if (ql2xenabledif == 1)
+ prot = SHOST_DIX_TYPE0_PROTECTION;
scsi_host_set_prot(host,
- SHOST_DIF_TYPE1_PROTECTION
+ prot | SHOST_DIF_TYPE1_PROTECTION
| SHOST_DIF_TYPE2_PROTECTION
| SHOST_DIF_TYPE3_PROTECTION
| SHOST_DIX_TYPE1_PROTECTION
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.07.03-k"
+#define QLA2XXX_VERSION "8.03.07.07-k"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
config SCSI_QLA_ISCSI
tristate "QLogic ISP4XXX and ISP82XX host adapter family support"
- depends on PCI && SCSI
+ depends on PCI && SCSI && NET
select SCSI_ISCSI_ATTRS
---help---
This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX)
!defined(CONFIG_CPU_SUBTYPE_SH7709)
[IRQ_TYPE_LEVEL_HIGH] = VALID(3),
#endif
+#if defined(CONFIG_ARCH_SH7372)
+ [IRQ_TYPE_EDGE_BOTH] = VALID(4),
+#endif
};
static int intc_set_type(struct irq_data *data, unsigned int type)
#include <asm/io.h>
#include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/cpu.h>
/* SPI register offsets */
if (msg->complete)
msg->complete(msg->context);
/* This message is completed, so let's turn off the clocks & power */
- clk_disable(pl022->clk);
- amba_pclk_disable(pl022->adev);
- amba_vcore_disable(pl022->adev);
pm_runtime_put(&pl022->adev->dev);
}
* (poll/interrupt/DMA)
*/
pm_runtime_get_sync(&pl022->adev->dev);
- amba_vcore_enable(pl022->adev);
- amba_pclk_enable(pl022->adev);
- clk_enable(pl022->clk);
restore_state(pl022);
flush(pl022);
}
printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
adev->res.start, pl022->virtbase);
- pm_runtime_enable(dev);
- pm_runtime_resume(dev);
pl022->clk = clk_get(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
goto err_no_clk;
}
-
/* Disable SSP */
writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
SSP_CR1(pl022->virtbase));
goto err_spi_register;
}
dev_dbg(dev, "probe succeeded\n");
- /*
- * Disable the silicon block pclk and any voltage domain and just
- * power it up and clock it when it's needed
- */
- amba_pclk_disable(adev);
- amba_vcore_disable(adev);
+
+ /* let runtime pm put suspend */
+ pm_runtime_put(dev);
return 0;
err_spi_register:
destroy_queue(pl022);
pl022_dma_remove(pl022);
free_irq(adev->irq[0], pl022);
- pm_runtime_disable(&adev->dev);
err_no_irq:
clk_put(pl022->clk);
err_no_clk:
if (!pl022)
return 0;
+ /*
+ * undo pm_runtime_put() in probe. I assume that we're not
+ * accessing the primecell here.
+ */
+ pm_runtime_get_noresume(&adev->dev);
+
/* Remove the queue */
if (destroy_queue(pl022) != 0)
dev_err(&adev->dev, "queue remove failed\n");
return 0;
}
-#ifdef CONFIG_PM
-static int pl022_suspend(struct amba_device *adev, pm_message_t state)
+#ifdef CONFIG_SUSPEND
+static int pl022_suspend(struct device *dev)
{
- struct pl022 *pl022 = amba_get_drvdata(adev);
+ struct pl022 *pl022 = dev_get_drvdata(dev);
int status = 0;
status = stop_queue(pl022);
if (status) {
- dev_warn(&adev->dev, "suspend cannot stop queue\n");
+ dev_warn(dev, "suspend cannot stop queue\n");
return status;
}
- amba_vcore_enable(adev);
- amba_pclk_enable(adev);
+ amba_vcore_enable(pl022->adev);
+ amba_pclk_enable(pl022->adev);
load_ssp_default_config(pl022);
- amba_pclk_disable(adev);
- amba_vcore_disable(adev);
- dev_dbg(&adev->dev, "suspended\n");
+ amba_pclk_disable(pl022->adev);
+ amba_vcore_disable(pl022->adev);
+ dev_dbg(dev, "suspended\n");
return 0;
}
-static int pl022_resume(struct amba_device *adev)
+static int pl022_resume(struct device *dev)
{
- struct pl022 *pl022 = amba_get_drvdata(adev);
+ struct pl022 *pl022 = dev_get_drvdata(dev);
int status = 0;
/* Start the queue running */
status = start_queue(pl022);
if (status)
- dev_err(&adev->dev, "problem starting queue (%d)\n", status);
+ dev_err(dev, "problem starting queue (%d)\n", status);
else
- dev_dbg(&adev->dev, "resumed\n");
+ dev_dbg(dev, "resumed\n");
return status;
}
-#else
-#define pl022_suspend NULL
-#define pl022_resume NULL
#endif /* CONFIG_PM */
+#ifdef CONFIG_PM_RUNTIME
+static int pl022_runtime_suspend(struct device *dev)
+{
+ struct pl022 *pl022 = dev_get_drvdata(dev);
+
+ clk_disable(pl022->clk);
+ amba_vcore_disable(pl022->adev);
+
+ return 0;
+}
+
+static int pl022_runtime_resume(struct device *dev)
+{
+ struct pl022 *pl022 = dev_get_drvdata(dev);
+
+ amba_vcore_enable(pl022->adev);
+ clk_enable(pl022->clk);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops pl022_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
+ SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
+};
+
static struct vendor_data vendor_arm = {
.fifodepth = 8,
.max_bpw = 16,
static struct amba_driver pl022_driver = {
.drv = {
.name = "ssp-pl022",
+ .pm = &pl022_dev_pm_ops,
},
.id_table = pl022_ids,
.probe = pl022_probe,
.remove = __devexit_p(pl022_remove),
- .suspend = pl022_suspend,
- .resume = pl022_resume,
};
#ifdef CONFIG_ARM
#include <mach/cpu.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#endif
#define PDC_BUFFER_SIZE 512
#if defined(CONFIG_ETRAX_RS485)
#if defined(CONFIG_ETRAX_RS485_ON_PA)
- if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit,
+ if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit,
rs485_pa_bit)) {
printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
"RS485 pin\n");
}
#endif
#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
- if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit,
+ if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit,
rs485_port_g_bit)) {
printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
"RS485 pin\n");
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#endif
struct notifier_block freq_transition;
+
+#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
+ unsigned short saved_smr;
+ unsigned short saved_fcr;
+ unsigned char saved_brr;
+#endif
};
/* Function prototypes */
/* This routine is used for getting signals of: DTR, DCD, DSR, RI,
and CTS/RTS */
- return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR;
+ return TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
}
#ifdef CONFIG_SERIAL_SH_SCI_DMA
return ((freq + 16 * bps) / (32 * bps) - 1);
}
+static void sci_reset(struct uart_port *port)
+{
+ unsigned int status;
+
+ do {
+ status = sci_in(port, SCxSR);
+ } while (!(status & SCxSR_TEND(port)));
+
+ sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
+
+ if (port->type != PORT_SCI)
+ sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+}
+
static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct sci_port *s = to_sci_port(port);
- unsigned int status, baud, smr_val, max_baud;
+ unsigned int baud, smr_val, max_baud;
int t = -1;
u16 scfcr = 0;
sci_port_enable(s);
- do {
- status = sci_in(port, SCxSR);
- } while (!(status & SCxSR_TEND(port)));
-
- sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
-
- if (port->type != PORT_SCI)
- sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST);
+ sci_reset(port);
smr_val = sci_in(port, SCSMR) & 3;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
- /* TODO: disable clock */
+ sci_port_disable(sci_port);
+
return uart_set_options(port, co, baud, parity, bits, flow);
}
return 0;
}
+#define uart_console(port) ((port)->cons->index == (port)->line)
+
+static int sci_runtime_suspend(struct device *dev)
+{
+ struct sci_port *sci_port = dev_get_drvdata(dev);
+ struct uart_port *port = &sci_port->port;
+
+ if (uart_console(port)) {
+ sci_port->saved_smr = sci_in(port, SCSMR);
+ sci_port->saved_brr = sci_in(port, SCBRR);
+ sci_port->saved_fcr = sci_in(port, SCFCR);
+ }
+ return 0;
+}
+
+static int sci_runtime_resume(struct device *dev)
+{
+ struct sci_port *sci_port = dev_get_drvdata(dev);
+ struct uart_port *port = &sci_port->port;
+
+ if (uart_console(port)) {
+ sci_reset(port);
+ sci_out(port, SCSMR, sci_port->saved_smr);
+ sci_out(port, SCBRR, sci_port->saved_brr);
+ sci_out(port, SCFCR, sci_port->saved_fcr);
+ sci_out(port, SCSCR, sci_port->cfg->scscr);
+ }
+ return 0;
+}
+
#define SCI_CONSOLE (&serial_console)
#else
}
#define SCI_CONSOLE NULL
+#define sci_runtime_suspend NULL
+#define sci_runtime_resume NULL
#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
}
static const struct dev_pm_ops sci_dev_pm_ops = {
+ .runtime_suspend = sci_runtime_suspend,
+ .runtime_resume = sci_runtime_resume,
.suspend = sci_suspend,
.resume = sci_resume,
};
#include <mach/platform.h>
#include <mach/irqs.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
#include <mach/hardware.h>
#include <mach/memory.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/cputype.h>
#include <asm/mach-types.h>
#include <mach/board.h>
#include <mach/cpu.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <video/atmel_lcdc.h>
#include <asm/backlight.h>
#endif
-static const char const *backlight_types[] = {
+static const char *const backlight_types[] = {
[BACKLIGHT_RAW] = "raw",
[BACKLIGHT_PLATFORM] = "platform",
[BACKLIGHT_FIRMWARE] = "firmware",
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include "omapfb.h"
#include <linux/platform_device.h>
#include <linux/i2c/tps65010.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include "omapfb.h"
#define MODULE_NAME "omapfb-lcd_h3"
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include "omapfb.h"
#define MODULE_NAME "omapfb-lcd_h3"
#include <linux/delay.h>
#include <linux/i2c/twl.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/mux.h>
#include <asm/mach-types.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/mux.h>
#include "omapfb.h"
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <plat/mux.h>
#include <asm/mach-types.h>
#include <linux/module.h>
#include <linux/io.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include "omapfb.h"
static int palmtt_panel_init(struct lcd_panel *panel,
#include <linux/clk.h>
#include <linux/gfp.h>
#include <asm/uaccess.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include "sdum.h"
#include "fbcommon.h"
struct inode *v9fs_alloc_inode(struct super_block *sb);
void v9fs_destroy_inode(struct inode *inode);
-struct inode *v9fs_get_inode(struct super_block *sb, int mode);
+struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t);
int v9fs_init_inode(struct v9fs_session_info *v9ses,
- struct inode *inode, int mode);
+ struct inode *inode, int mode, dev_t);
void v9fs_evict_inode(struct inode *inode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
return;
}
+
+int v9fs_open_to_dotl_flags(int flags);
#endif
v9inode = V9FS_I(inode);
v9ses = v9fs_inode2v9ses(inode);
if (v9fs_proto_dotl(v9ses))
- omode = file->f_flags;
+ omode = v9fs_open_to_dotl_flags(file->f_flags);
else
omode = v9fs_uflags2omode(file->f_flags,
v9fs_proto_dotu(v9ses));
/* convert posix lock to p9 tlock args */
memset(&flock, 0, sizeof(flock));
- flock.type = fl->fl_type;
+ /* map the lock type */
+ switch (fl->fl_type) {
+ case F_RDLCK:
+ flock.type = P9_LOCK_TYPE_RDLCK;
+ break;
+ case F_WRLCK:
+ flock.type = P9_LOCK_TYPE_WRLCK;
+ break;
+ case F_UNLCK:
+ flock.type = P9_LOCK_TYPE_UNLCK;
+ break;
+ }
flock.start = fl->fl_start;
if (fl->fl_end == OFFSET_MAX)
flock.length = 0;
/* convert posix lock to p9 tgetlock args */
memset(&glock, 0, sizeof(glock));
- glock.type = fl->fl_type;
+ glock.type = P9_LOCK_TYPE_UNLCK;
glock.start = fl->fl_start;
if (fl->fl_end == OFFSET_MAX)
glock.length = 0;
res = p9_client_getlock_dotl(fid, &glock);
if (res < 0)
return res;
- if (glock.type != F_UNLCK) {
- fl->fl_type = glock.type;
+ /* map 9p lock type to os lock type */
+ switch (glock.type) {
+ case P9_LOCK_TYPE_RDLCK:
+ fl->fl_type = F_RDLCK;
+ break;
+ case P9_LOCK_TYPE_WRLCK:
+ fl->fl_type = F_WRLCK;
+ break;
+ case P9_LOCK_TYPE_UNLCK:
+ fl->fl_type = F_UNLCK;
+ break;
+ }
+ if (glock.type != P9_LOCK_TYPE_UNLCK) {
fl->fl_start = glock.start;
if (glock.length == 0)
fl->fl_end = OFFSET_MAX;
else
fl->fl_end = glock.start + glock.length - 1;
fl->fl_pid = glock.proc_id;
- } else
- fl->fl_type = F_UNLCK;
-
+ }
return res;
}
/**
* p9mode2unixmode- convert plan9 mode bits to unix mode bits
* @v9ses: v9fs session information
- * @mode: mode to convert
+ * @stat: p9_wstat from which mode need to be derived
+ * @rdev: major number, minor number in case of device files.
*
*/
-
-static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
+static int p9mode2unixmode(struct v9fs_session_info *v9ses,
+ struct p9_wstat *stat, dev_t *rdev)
{
int res;
+ int mode = stat->mode;
- res = mode & 0777;
+ res = mode & S_IALLUGO;
+ *rdev = 0;
if ((mode & P9_DMDIR) == P9_DMDIR)
res |= S_IFDIR;
&& (v9ses->nodev == 0))
res |= S_IFIFO;
else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
- && (v9ses->nodev == 0))
- res |= S_IFBLK;
- else
+ && (v9ses->nodev == 0)) {
+ char type = 0, ext[32];
+ int major = -1, minor = -1;
+
+ strncpy(ext, stat->extension, sizeof(ext));
+ sscanf(ext, "%c %u %u", &type, &major, &minor);
+ switch (type) {
+ case 'c':
+ res |= S_IFCHR;
+ break;
+ case 'b':
+ res |= S_IFBLK;
+ break;
+ default:
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "Unknown special type %c %s\n", type,
+ stat->extension);
+ };
+ *rdev = MKDEV(major, minor);
+ } else
res |= S_IFREG;
if (v9fs_proto_dotu(v9ses)) {
if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
res |= S_ISVTX;
}
-
return res;
}
}
int v9fs_init_inode(struct v9fs_session_info *v9ses,
- struct inode *inode, int mode)
+ struct inode *inode, int mode, dev_t rdev)
{
int err = 0;
inode_init_owner(inode, NULL, mode);
inode->i_blocks = 0;
- inode->i_rdev = 0;
+ inode->i_rdev = rdev;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_mapping->a_ops = &v9fs_addr_operations;
*
*/
-struct inode *v9fs_get_inode(struct super_block *sb, int mode)
+struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t rdev)
{
int err;
struct inode *inode;
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
return ERR_PTR(-ENOMEM);
}
- err = v9fs_init_inode(v9ses, inode, mode);
+ err = v9fs_init_inode(v9ses, inode, mode, rdev);
if (err) {
iput(inode);
return ERR_PTR(err);
static int v9fs_test_inode(struct inode *inode, void *data)
{
int umode;
+ dev_t rdev;
struct v9fs_inode *v9inode = V9FS_I(inode);
struct p9_wstat *st = (struct p9_wstat *)data;
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
- umode = p9mode2unixmode(v9ses, st->mode);
+ umode = p9mode2unixmode(v9ses, st, &rdev);
/* don't match inode of different type */
if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
return 0;
struct p9_wstat *st,
int new)
{
+ dev_t rdev;
int retval, umode;
unsigned long i_ino;
struct inode *inode;
* later.
*/
inode->i_ino = i_ino;
- umode = p9mode2unixmode(v9ses, st->mode);
- retval = v9fs_init_inode(v9ses, inode, umode);
+ umode = p9mode2unixmode(v9ses, st, &rdev);
+ retval = v9fs_init_inode(v9ses, inode, umode, rdev);
if (retval)
goto error;
return inode;
}
+/**
+ * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
+ * plan 9 AT flag.
+ * @flags: flags to convert
+ */
+static int v9fs_at_to_dotl_flags(int flags)
+{
+ int rflags = 0;
+ if (flags & AT_REMOVEDIR)
+ rflags |= P9_DOTL_AT_REMOVEDIR;
+ return rflags;
+}
+
/**
* v9fs_remove - helper function to remove files and directories
* @dir: directory inode that is being deleted
return retval;
}
if (v9fs_proto_dotl(v9ses))
- retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags);
+ retval = p9_client_unlinkat(dfid, dentry->d_name.name,
+ v9fs_at_to_dotl_flags(flags));
if (retval == -EOPNOTSUPP) {
/* Try the one based on path */
v9fid = v9fs_fid_clone(dentry);
P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
goto error;
}
- d_instantiate(dentry, inode);
err = v9fs_fid_add(dentry, fid);
if (err < 0)
goto error;
-
+ d_instantiate(dentry, inode);
return ofid;
-
error:
if (ofid)
p9_client_clunk(ofid);
struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nameidata)
{
+ struct dentry *res;
struct super_block *sb;
struct v9fs_session_info *v9ses;
struct p9_fid *dfid, *fid;
return ERR_PTR(result);
}
-
- inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
+ /*
+ * Make sure we don't use a wrong inode due to parallel
+ * unlink. For cached mode create calls request for new
+ * inode. But with cache disabled, lookup should do this.
+ */
+ if (v9ses->cache)
+ inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
+ else
+ inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
result = PTR_ERR(inode);
inode = NULL;
goto error;
}
-
result = v9fs_fid_add(dentry, fid);
if (result < 0)
goto error_iput;
-
inst_out:
- d_add(dentry, inode);
- return NULL;
-
+ /*
+ * If we had a rename on the server and a parallel lookup
+ * for the new name, then make sure we instantiate with
+ * the new name. ie look up for a/b, while on server somebody
+ * moved b under k and client parallely did a lookup for
+ * k/b.
+ */
+ res = d_materialise_unique(dentry, inode);
+ if (!IS_ERR(res))
+ return res;
+ result = PTR_ERR(res);
error_iput:
iput(inode);
error:
return PTR_ERR(st);
v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb);
- generic_fillattr(dentry->d_inode, stat);
+ generic_fillattr(dentry->d_inode, stat);
p9stat_free(st);
kfree(st);
v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
struct super_block *sb)
{
+ mode_t mode;
char ext[32];
char tag_name[14];
unsigned int i_nlink;
inode->i_nlink = i_nlink;
}
}
- inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
- if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
- char type = 0;
- int major = -1;
- int minor = -1;
-
- strncpy(ext, stat->extension, sizeof(ext));
- sscanf(ext, "%c %u %u", &type, &major, &minor);
- switch (type) {
- case 'c':
- inode->i_mode &= ~S_IFBLK;
- inode->i_mode |= S_IFCHR;
- break;
- case 'b':
- break;
- default:
- P9_DPRINTK(P9_DEBUG_ERROR,
- "Unknown special type %c %s\n", type,
- stat->extension);
- };
- inode->i_rdev = MKDEV(major, minor);
- init_special_inode(inode, inode->i_mode, inode->i_rdev);
- } else
- inode->i_rdev = 0;
-
+ mode = stat->mode & S_IALLUGO;
+ mode |= inode->i_mode & ~S_IALLUGO;
+ inode->i_mode = mode;
i_size_write(inode, stat->length);
/* not real number of blocks, but 512 byte ones ... */
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
{
+ int umode;
+ dev_t rdev;
loff_t i_size;
struct p9_wstat *st;
struct v9fs_session_info *v9ses;
st = p9_client_stat(fid);
if (IS_ERR(st))
return PTR_ERR(st);
+ /*
+ * Don't update inode if the file type is different
+ */
+ umode = p9mode2unixmode(v9ses, st, &rdev);
+ if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
+ goto out;
spin_lock(&inode->i_lock);
/*
if (v9ses->cache)
inode->i_size = i_size;
spin_unlock(&inode->i_lock);
+out:
p9stat_free(st);
kfree(st);
return 0;
* later.
*/
inode->i_ino = i_ino;
- retval = v9fs_init_inode(v9ses, inode, st->st_mode);
+ retval = v9fs_init_inode(v9ses, inode,
+ st->st_mode, new_decode_dev(st->st_rdev));
if (retval)
goto error;
return inode;
}
+struct dotl_openflag_map {
+ int open_flag;
+ int dotl_flag;
+};
+
+static int v9fs_mapped_dotl_flags(int flags)
+{
+ int i;
+ int rflags = 0;
+ struct dotl_openflag_map dotl_oflag_map[] = {
+ { O_CREAT, P9_DOTL_CREATE },
+ { O_EXCL, P9_DOTL_EXCL },
+ { O_NOCTTY, P9_DOTL_NOCTTY },
+ { O_TRUNC, P9_DOTL_TRUNC },
+ { O_APPEND, P9_DOTL_APPEND },
+ { O_NONBLOCK, P9_DOTL_NONBLOCK },
+ { O_DSYNC, P9_DOTL_DSYNC },
+ { FASYNC, P9_DOTL_FASYNC },
+ { O_DIRECT, P9_DOTL_DIRECT },
+ { O_LARGEFILE, P9_DOTL_LARGEFILE },
+ { O_DIRECTORY, P9_DOTL_DIRECTORY },
+ { O_NOFOLLOW, P9_DOTL_NOFOLLOW },
+ { O_NOATIME, P9_DOTL_NOATIME },
+ { O_CLOEXEC, P9_DOTL_CLOEXEC },
+ { O_SYNC, P9_DOTL_SYNC},
+ };
+ for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
+ if (flags & dotl_oflag_map[i].open_flag)
+ rflags |= dotl_oflag_map[i].dotl_flag;
+ }
+ return rflags;
+}
+
+/**
+ * v9fs_open_to_dotl_flags- convert Linux specific open flags to
+ * plan 9 open flag.
+ * @flags: flags to convert
+ */
+int v9fs_open_to_dotl_flags(int flags)
+{
+ int rflags = 0;
+
+ /*
+ * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
+ * and P9_DOTL_NOACCESS
+ */
+ rflags |= flags & O_ACCMODE;
+ rflags |= v9fs_mapped_dotl_flags(flags);
+
+ return rflags;
+}
+
/**
* v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
* @dir: directory inode that is being created
"Failed to get acl values in creat %d\n", err);
goto error;
}
- err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
+ err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
+ mode, gid, &qid);
if (err < 0) {
P9_DPRINTK(P9_DEBUG_VFS,
"p9_client_open_dotl failed in creat %d\n",
P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
goto error;
}
- d_instantiate(dentry, inode);
err = v9fs_fid_add(dentry, fid);
if (err < 0)
goto error;
+ d_instantiate(dentry, inode);
/* Now set the ACL based on the default value */
v9fs_set_create_acl(dentry, &dacl, &pacl);
err);
goto error;
}
- d_instantiate(dentry, inode);
err = v9fs_fid_add(dentry, fid);
if (err < 0)
goto error;
+ d_instantiate(dentry, inode);
fid = NULL;
} else {
/*
* inode with stat. We need to get an inode
* so that we can set the acl with dentry
*/
- inode = v9fs_get_inode(dir->i_sb, mode);
+ inode = v9fs_get_inode(dir->i_sb, mode, 0);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto error;
void
v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
{
+ mode_t mode;
struct v9fs_inode *v9inode = V9FS_I(inode);
if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
inode->i_uid = stat->st_uid;
inode->i_gid = stat->st_gid;
inode->i_nlink = stat->st_nlink;
- inode->i_mode = stat->st_mode;
- inode->i_rdev = new_decode_dev(stat->st_rdev);
- if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
- init_special_inode(inode, inode->i_mode, inode->i_rdev);
+ mode = stat->st_mode & S_IALLUGO;
+ mode |= inode->i_mode & ~S_IALLUGO;
+ inode->i_mode = mode;
i_size_write(inode, stat->st_size);
inode->i_blocks = stat->st_blocks;
err);
goto error;
}
- d_instantiate(dentry, inode);
err = v9fs_fid_add(dentry, fid);
if (err < 0)
goto error;
+ d_instantiate(dentry, inode);
fid = NULL;
} else {
/* Not in cached mode. No need to populate inode with stat */
- inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
+ inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto error;
err);
goto error;
}
- d_instantiate(dentry, inode);
err = v9fs_fid_add(dentry, fid);
if (err < 0)
goto error;
+ d_instantiate(dentry, inode);
fid = NULL;
} else {
/*
* Not in cached mode. No need to populate inode with stat.
* socket syscall returns a fd, so we need instantiate
*/
- inode = v9fs_get_inode(dir->i_sb, mode);
+ inode = v9fs_get_inode(dir->i_sb, mode, rdev);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto error;
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
if (IS_ERR(st))
return PTR_ERR(st);
+ /*
+ * Don't update inode if the file type is different
+ */
+ if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
+ goto out;
spin_lock(&inode->i_lock);
/*
if (v9ses->cache)
inode->i_size = i_size;
spin_unlock(&inode->i_lock);
+out:
kfree(st);
return 0;
}
else
sb->s_d_op = &v9fs_dentry_operations;
- inode = v9fs_get_inode(sb, S_IFDIR | mode);
+ inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);
if (IS_ERR(inode)) {
retval = PTR_ERR(inode);
goto release_sb;
WARN_ON_ONCE(bdev->bd_holders);
sync_blockdev(bdev);
kill_bdev(bdev);
+ /* ->release can cause the old bdi to disappear,
+ * so must switch it out first
+ */
+ bdev_inode_switch_bdi(bdev->bd_inode,
+ &default_backing_dev_info);
}
if (bdev->bd_contains == bdev) {
if (disk->fops->release)
disk_put_part(bdev->bd_part);
bdev->bd_part = NULL;
bdev->bd_disk = NULL;
- bdev_inode_switch_bdi(bdev->bd_inode,
- &default_backing_dev_info);
if (bdev != bdev->bd_contains)
victim = bdev->bd_contains;
bdev->bd_contains = NULL;
{
u64 ino = BTRFS_I(inode)->location.objectid;
- if (ino <= BTRFS_FIRST_FREE_OBJECTID)
+ /*
+ * !ino: btree_inode
+ * type == BTRFS_ROOT_ITEM_KEY: subvol dir
+ */
+ if (!ino || BTRFS_I(inode)->location.type == BTRFS_ROOT_ITEM_KEY)
ino = inode->i_ino;
return ino;
}
* read from the commit root and sidestep a nasty deadlock
* between reading the free space cache and updating the csum tree.
*/
- if (btrfs_is_free_space_inode(root, inode))
+ if (btrfs_is_free_space_inode(root, inode)) {
path->search_commit_root = 1;
+ path->skip_locking = 1;
+ }
disk_bytenr = (u64)bio->bi_sector << 9;
if (dio)
start_pos = pos & ~((u64)root->sectorsize - 1);
last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT;
- if (start_pos > inode->i_size) {
- err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
- if (err)
- return err;
- }
-
again:
for (i = 0; i < num_pages; i++) {
pages[i] = find_or_create_page(inode->i_mapping, index + i,
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
loff_t *ppos = &iocb->ki_pos;
+ u64 start_pos;
ssize_t num_written = 0;
ssize_t err = 0;
size_t count, ocount;
file_update_time(file);
BTRFS_I(inode)->sequence++;
+ start_pos = round_down(pos, root->sectorsize);
+ if (start_pos > i_size_read(inode)) {
+ err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
+ if (err) {
+ mutex_unlock(&inode->i_mutex);
+ goto out;
+ }
+ }
+
if (unlikely(file->f_flags & O_DIRECT)) {
num_written = __btrfs_direct_write(iocb, iov, nr_segs,
pos, ppos, count, ocount);
struct btrfs_path *path,
struct inode *inode)
{
+ struct btrfs_block_rsv *rsv;
loff_t oldsize;
int ret = 0;
+ rsv = trans->block_rsv;
trans->block_rsv = root->orphan_block_rsv;
ret = btrfs_block_rsv_check(trans, root,
root->orphan_block_rsv,
*/
ret = btrfs_truncate_inode_items(trans, root, inode,
0, BTRFS_EXTENT_DATA_KEY);
+
+ trans->block_rsv = rsv;
if (ret) {
WARN_ON(1);
return ret;
&ordered_extent->list);
ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
- if (!ret) {
+ if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
ret = btrfs_update_inode(trans, root, inode);
BUG_ON(ret);
}
err = btrfs_drop_extents(trans, inode, cur_offset,
cur_offset + hole_size,
&hint_byte, 1);
- if (err)
+ if (err) {
+ btrfs_end_transaction(trans, root);
break;
+ }
err = btrfs_insert_file_extent(trans, root,
btrfs_ino(inode), cur_offset, 0,
0, hole_size, 0, hole_size,
0, 0, 0);
- if (err)
+ if (err) {
+ btrfs_end_transaction(trans, root);
break;
+ }
btrfs_drop_extent_cache(inode, hole_start,
last_byte - 1, 0);
struct btrfs_root *root, int *new)
{
struct inode *inode;
- int bad_inode = 0;
inode = btrfs_iget_locked(s, location->objectid, root);
if (!inode)
if (new)
*new = 1;
} else {
- bad_inode = 1;
+ unlock_new_inode(inode);
+ iput(inode);
+ inode = ERR_PTR(-ESTALE);
}
}
- if (bad_inode) {
- iput(inode);
- inode = ERR_PTR(-ESTALE);
- }
-
return inode;
}
add_pending_csums(trans, inode, ordered->file_offset, &ordered->list);
ret = btrfs_ordered_update_i_size(inode, 0, ordered);
- if (!ret)
+ if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags))
btrfs_update_inode(trans, root, inode);
ret = 0;
out_unlock:
!IS_ALIGNED(destoff, bs))
goto out_unlock;
+ if (destoff > inode->i_size) {
+ ret = btrfs_cont_expand(inode, inode->i_size, destoff);
+ if (ret)
+ goto out_unlock;
+ }
+
/* do any pending delalloc/csum calc on src, one way or
another, and lock file content */
while (1) {
if (type == BTRFS_FILE_EXTENT_REG ||
type == BTRFS_FILE_EXTENT_PREALLOC) {
+ /*
+ * a | --- range to clone ---| b
+ * | ------------- extent ------------- |
+ */
+
+ /* substract range b */
+ if (key.offset + datal > off + len)
+ datal = off + len - key.offset;
+
+ /* substract range a */
if (off > key.offset) {
datao += off - key.offset;
datal -= off - key.offset;
}
- if (key.offset + datal > off + len)
- datal = off + len - key.offset;
-
ret = btrfs_drop_extents(trans, inode,
new_key.offset,
new_key.offset + datal,
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_root *root = pending->root;
struct btrfs_root *parent_root;
+ struct btrfs_block_rsv *rsv;
struct inode *parent_inode;
struct dentry *parent;
struct dentry *dentry;
u64 objectid;
u64 root_flags;
+ rsv = trans->block_rsv;
+
new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
if (!new_root_item) {
pending->error = -ENOMEM;
btrfs_orphan_post_snapshot(trans, pending);
fail:
kfree(new_root_item);
+ trans->block_rsv = rsv;
btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
return 0;
}
if (ret)
goto out;
btrfs_release_path(path);
+
+ /*
+ * remove the attribute
+ */
+ if (!value)
+ goto out;
}
again:
return ret;
}
+/*
+ * @value: "" makes the attribute to empty, NULL removes it
+ */
int __btrfs_setxattr(struct btrfs_trans_handle *trans,
struct inode *inode, const char *name,
const void *value, size_t size, int flags)
r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
*ppath);
- } else if (rpath) {
+ } else if (rpath || rino) {
*ino = rino;
*ppath = rpath;
*pathlen = strlen(rpath);
fsc = create_fs_client(fsopt, opt);
if (IS_ERR(fsc)) {
res = ERR_CAST(fsc);
- kfree(fsopt);
- kfree(opt);
+ destroy_mount_options(fsopt);
+ ceph_destroy_options(opt);
goto out_final;
}
*/
#define EXT4_IO_END_UNWRITTEN 0x0001
#define EXT4_IO_END_ERROR 0x0002
+#define EXT4_IO_END_QUEUED 0x0004
struct ext4_io_page {
struct page *p_page;
trace_ext4_evict_inode(inode);
- mutex_lock(&inode->i_mutex);
- ext4_flush_completed_IO(inode);
- mutex_unlock(&inode->i_mutex);
ext4_ioend_wait(inode);
if (inode->i_nlink) {
unsigned long flags;
int ret;
- mutex_lock(&inode->i_mutex);
+ if (!mutex_trylock(&inode->i_mutex)) {
+ /*
+ * Requeue the work instead of waiting so that the work
+ * items queued after this can be processed.
+ */
+ queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
+ /*
+ * To prevent the ext4-dio-unwritten thread from keeping
+ * requeueing end_io requests and occupying cpu for too long,
+ * yield the cpu if it sees an end_io request that has already
+ * been requeued.
+ */
+ if (io->flag & EXT4_IO_END_QUEUED)
+ yield();
+ io->flag |= EXT4_IO_END_QUEUED;
+ return;
+ }
ret = ext4_end_io_nolock(io);
if (ret < 0) {
mutex_unlock(&inode->i_mutex);
forget->forget_one.nlookup = nlookup;
spin_lock(&fc->lock);
- fc->forget_list_tail->next = forget;
- fc->forget_list_tail = forget;
- wake_up(&fc->waitq);
- kill_fasync(&fc->fasync, SIGIO, POLL_IN);
+ if (fc->connected) {
+ fc->forget_list_tail->next = forget;
+ fc->forget_list_tail = forget;
+ wake_up(&fc->waitq);
+ kill_fasync(&fc->fasync, SIGIO, POLL_IN);
+ } else {
+ kfree(forget);
+ }
spin_unlock(&fc->lock);
}
if (arg->minor >= 17) {
if (!(arg->flags & FUSE_FLOCK_LOCKS))
fc->no_flock = 1;
+ } else {
+ if (!(arg->flags & FUSE_POSIX_LOCKS))
+ fc->no_flock = 1;
}
if (arg->flags & FUSE_ATOMIC_O_TRUNC)
fc->atomic_o_trunc = 1;
if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_PARENT))
return -EISDIR; /* we actually want to stop here */
- /*
- * We don't want to mount if someone's just doing a stat and they've
- * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and
- * appended a '/' to the name.
+ /* We don't want to mount if someone's just doing a stat -
+ * unless they're stat'ing a directory and appended a '/' to
+ * the name.
+ *
+ * We do, however, want to mount if someone wants to open or
+ * create a file of any type under the mountpoint, wants to
+ * traverse through the mountpoint or wants to open the
+ * mounted directory. Also, autofs may mark negative dentries
+ * as being automount points. These will need the attentions
+ * of the daemon to instantiate them before they can be used.
*/
- if (!(flags & LOOKUP_FOLLOW)) {
- /* We do, however, want to mount if someone wants to open or
- * create a file of any type under the mountpoint, wants to
- * traverse through the mountpoint or wants to open the mounted
- * directory.
- * Also, autofs may mark negative dentries as being automount
- * points. These will need the attentions of the daemon to
- * instantiate them before they can be used.
- */
- if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
- LOOKUP_OPEN | LOOKUP_CREATE)) &&
- path->dentry->d_inode)
- return -EISDIR;
- }
+ if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
+ LOOKUP_OPEN | LOOKUP_CREATE)) &&
+ path->dentry->d_inode)
+ return -EISDIR;
+
current->total_link_count++;
if (current->total_link_count >= 40)
return -ELOOP;
if (!dir->i_op->rmdir)
return -EPERM;
+ dget(dentry);
mutex_lock(&dentry->d_inode->i_mutex);
error = -EBUSY;
out:
mutex_unlock(&dentry->d_inode->i_mutex);
+ dput(dentry);
if (!error)
d_delete(dentry);
return error;
if (error)
return error;
+ dget(new_dentry);
if (target)
mutex_lock(&target->i_mutex);
out:
if (target)
mutex_unlock(&target->i_mutex);
+ dput(new_dentry);
if (!error)
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
d_move(old_dentry,new_dentry);
#define DBGKEY(key) ((char *)(key))
#define DBGKEY1(key) ((char *)(key))
-#define ubifs_dbg_msg(fmt, ...) do { \
- if (0) \
- pr_debug(fmt "\n", ##__VA_ARGS__); \
+#define ubifs_dbg_msg(fmt, ...) do { \
+ if (0) \
+ printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \
} while (0)
#define dbg_dump_stack()
bool is_async)
{
struct xfs_ioend *ioend = iocb->private;
+ struct inode *inode = ioend->io_inode;
/*
* blockdev_direct_IO can return an error even after the I/O
}
/* XXX: probably should move into the real I/O completion handler */
- inode_dio_done(ioend->io_inode);
+ inode_dio_done(inode);
}
STATIC ssize_t
}
/*
- * If the linux inode is valid, mark it dirty.
- * Used when committing a dirty inode into a transaction so that
- * the inode will get written back by the linux code
+ * If the linux inode is valid, mark it dirty, else mark the dirty state
+ * in the XFS inode to make sure we pick it up when reclaiming the inode.
*/
void
xfs_mark_inode_dirty_sync(
if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
mark_inode_dirty_sync(inode);
+ else {
+ barrier();
+ ip->i_update_core = 1;
+ }
}
void
if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
mark_inode_dirty(inode);
+ else {
+ barrier();
+ ip->i_update_core = 1;
+ }
+
}
/*
mp->m_flags |= XFS_MOUNT_DELAYLOG;
} else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
mp->m_flags &= ~XFS_MOUNT_DELAYLOG;
+ xfs_warn(mp,
+ "nodelaylog is deprecated and will be removed in Linux 3.3");
} else if (!strcmp(this_char, MNTOPT_DISCARD)) {
mp->m_flags |= XFS_MOUNT_DISCARD;
} else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
struct xfs_trans *tp;
int error;
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
-
if (error) {
xfs_trans_cancel(tp, 0);
- /* we need to return with the lock hold shared */
- xfs_ilock(ip, XFS_ILOCK_SHARED);
return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- /*
- * Note - it's possible that we might have pushed ourselves out of the
- * way during trans_reserve which would flush the inode. But there's
- * no guarantee that the inode buffer has actually gone out yet (it's
- * delwri). Plus the buffer could be pinned anyway if it's part of
- * an inode in another recent transaction. So we play it safe and
- * fire off the transaction anyway.
- */
- xfs_trans_ijoin(tp, ip);
+ xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- error = xfs_trans_commit(tp, 0);
- xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
-
- return error;
+ return xfs_trans_commit(tp, 0);
}
STATIC int
trace_xfs_write_inode(ip);
if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
+ return -XFS_ERROR(EIO);
+ if (!ip->i_update_core)
+ return 0;
if (wbc->sync_mode == WB_SYNC_ALL) {
/*
* of synchronous log foces dramatically.
*/
xfs_ioend_wait(ip);
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- if (ip->i_update_core) {
- error = xfs_log_inode(ip);
- if (error)
- goto out_unlock;
- }
+ error = xfs_log_inode(ip);
+ if (error)
+ goto out;
+ return 0;
} else {
/*
* We make this non-blocking if the inode is contended, return
return container_of(gc, struct bgpio_chip, gc);
}
-int __devexit bgpio_remove(struct bgpio_chip *bgc);
-int __devinit bgpio_init(struct bgpio_chip *bgc,
- struct device *dev,
- unsigned long sz,
- void __iomem *dat,
- void __iomem *set,
- void __iomem *clr,
- void __iomem *dirout,
- void __iomem *dirin,
- bool big_endian);
+int bgpio_remove(struct bgpio_chip *bgc);
+int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
+ unsigned long sz, void __iomem *dat, void __iomem *set,
+ void __iomem *clr, void __iomem *dirout, void __iomem *dirin,
+ bool big_endian);
#endif /* __BASIC_MMIO_GPIO_H */
struct mem_cgroup *mem_cont,
int active, int file);
-struct memcg_scanrecord {
- struct mem_cgroup *mem; /* scanend memory cgroup */
- struct mem_cgroup *root; /* scan target hierarchy root */
- int context; /* scanning context (see memcontrol.c) */
- unsigned long nr_scanned[2]; /* the number of scanned pages */
- unsigned long nr_rotated[2]; /* the number of rotated pages */
- unsigned long nr_freed[2]; /* the number of freed pages */
- unsigned long elapsed; /* nsec of time elapsed while scanning */
-};
-
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
/*
* All "charge" functions with gfp_mask should use GFP_KERNEL or
extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg,
struct task_struct *p);
-extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem,
- gfp_t gfp_mask, bool noswap,
- struct memcg_scanrecord *rec);
-extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,
- gfp_t gfp_mask, bool noswap,
- struct zone *zone,
- struct memcg_scanrecord *rec,
- unsigned long *nr_scanned);
-
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
extern int do_swap_account;
#endif
extern int perf_num_counters(void);
extern const char *perf_pmu_name(void);
-extern void __perf_event_task_sched_in(struct task_struct *task);
-extern void __perf_event_task_sched_out(struct task_struct *task, struct task_struct *next);
+extern void __perf_event_task_sched_in(struct task_struct *prev,
+ struct task_struct *task);
+extern void __perf_event_task_sched_out(struct task_struct *prev,
+ struct task_struct *next);
extern int perf_event_init_task(struct task_struct *child);
extern void perf_event_exit_task(struct task_struct *child);
extern void perf_event_free_task(struct task_struct *task);
extern struct jump_label_key perf_sched_events;
-static inline void perf_event_task_sched_in(struct task_struct *task)
+static inline void perf_event_task_sched_in(struct task_struct *prev,
+ struct task_struct *task)
{
if (static_branch(&perf_sched_events))
- __perf_event_task_sched_in(task);
+ __perf_event_task_sched_in(prev, task);
}
-static inline void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next)
+static inline void perf_event_task_sched_out(struct task_struct *prev,
+ struct task_struct *next)
{
perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, NULL, 0);
- __perf_event_task_sched_out(task, next);
+ if (static_branch(&perf_sched_events))
+ __perf_event_task_sched_out(prev, next);
}
extern void perf_event_mmap(struct vm_area_struct *vma);
extern void perf_event_task_tick(void);
#else
static inline void
-perf_event_task_sched_in(struct task_struct *task) { }
+perf_event_task_sched_in(struct task_struct *prev,
+ struct task_struct *task) { }
static inline void
-perf_event_task_sched_out(struct task_struct *task,
- struct task_struct *next) { }
+perf_event_task_sched_out(struct task_struct *prev,
+ struct task_struct *next) { }
static inline int perf_event_init_task(struct task_struct *child) { return 0; }
static inline void perf_event_exit_task(struct task_struct *child) { }
static inline void perf_event_free_task(struct task_struct *task) { }
const char *supply;
struct regulator *consumer;
- /* Internal use */
+ /* private: Internal use */
int ret;
};
extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
gfp_t gfp_mask, nodemask_t *mask);
extern int __isolate_lru_page(struct page *page, int mode, int file);
+extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem,
+ gfp_t gfp_mask, bool noswap);
+extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,
+ gfp_t gfp_mask, bool noswap,
+ struct zone *zone,
+ unsigned long *nr_scanned);
extern unsigned long shrink_all_memory(unsigned long nr_pages);
extern int vm_swappiness;
extern int remove_mapping(struct address_space *mapping, struct page *page);
P9_DMSETVTX = 0x00010000,
};
+/* 9p2000.L open flags */
+#define P9_DOTL_RDONLY 00000000
+#define P9_DOTL_WRONLY 00000001
+#define P9_DOTL_RDWR 00000002
+#define P9_DOTL_NOACCESS 00000003
+#define P9_DOTL_CREATE 00000100
+#define P9_DOTL_EXCL 00000200
+#define P9_DOTL_NOCTTY 00000400
+#define P9_DOTL_TRUNC 00001000
+#define P9_DOTL_APPEND 00002000
+#define P9_DOTL_NONBLOCK 00004000
+#define P9_DOTL_DSYNC 00010000
+#define P9_DOTL_FASYNC 00020000
+#define P9_DOTL_DIRECT 00040000
+#define P9_DOTL_LARGEFILE 00100000
+#define P9_DOTL_DIRECTORY 00200000
+#define P9_DOTL_NOFOLLOW 00400000
+#define P9_DOTL_NOATIME 01000000
+#define P9_DOTL_CLOEXEC 02000000
+#define P9_DOTL_SYNC 04000000
+
+/* 9p2000.L at flags */
+#define P9_DOTL_AT_REMOVEDIR 0x200
+
+/* 9p2000.L lock type */
+#define P9_LOCK_TYPE_RDLCK 0
+#define P9_LOCK_TYPE_WRLCK 1
+#define P9_LOCK_TYPE_UNLCK 2
+
/**
* enum p9_qid_t - QID types
* @P9_QTDIR: directory
* by default for perm_addr. In this case, the mask should be set to
* all-zeroes. In this case it is assumed that the device can handle
* the same number of arbitrary MAC addresses.
+ * @registered: protects ->resume and ->suspend sysfs callbacks against
+ * unregister hardware
* @debugfsdir: debugfs directory used for this wiphy, will be renamed
* automatically on wiphy renames
* @dev: (virtual) struct device for this wiphy
* you need use set_wiphy_dev() (see below) */
struct device dev;
+ /* protects ->resume, ->suspend sysfs callbacks against unregister hw */
+ bool registered;
+
/* dir in debugfs: ieee80211/<wiphyname> */
struct dentry *debugfsdir;
local_irq_restore(flags);
}
-static inline void perf_cgroup_sched_out(struct task_struct *task)
+static inline void perf_cgroup_sched_out(struct task_struct *task,
+ struct task_struct *next)
{
- perf_cgroup_switch(task, PERF_CGROUP_SWOUT);
+ struct perf_cgroup *cgrp1;
+ struct perf_cgroup *cgrp2 = NULL;
+
+ /*
+ * we come here when we know perf_cgroup_events > 0
+ */
+ cgrp1 = perf_cgroup_from_task(task);
+
+ /*
+ * next is NULL when called from perf_event_enable_on_exec()
+ * that will systematically cause a cgroup_switch()
+ */
+ if (next)
+ cgrp2 = perf_cgroup_from_task(next);
+
+ /*
+ * only schedule out current cgroup events if we know
+ * that we are switching to a different cgroup. Otherwise,
+ * do no touch the cgroup events.
+ */
+ if (cgrp1 != cgrp2)
+ perf_cgroup_switch(task, PERF_CGROUP_SWOUT);
}
-static inline void perf_cgroup_sched_in(struct task_struct *task)
+static inline void perf_cgroup_sched_in(struct task_struct *prev,
+ struct task_struct *task)
{
- perf_cgroup_switch(task, PERF_CGROUP_SWIN);
+ struct perf_cgroup *cgrp1;
+ struct perf_cgroup *cgrp2 = NULL;
+
+ /*
+ * we come here when we know perf_cgroup_events > 0
+ */
+ cgrp1 = perf_cgroup_from_task(task);
+
+ /* prev can never be NULL */
+ cgrp2 = perf_cgroup_from_task(prev);
+
+ /*
+ * only need to schedule in cgroup events if we are changing
+ * cgroup during ctxsw. Cgroup events were not scheduled
+ * out of ctxsw out if that was not the case.
+ */
+ if (cgrp1 != cgrp2)
+ perf_cgroup_switch(task, PERF_CGROUP_SWIN);
}
static inline int perf_cgroup_connect(int fd, struct perf_event *event,
{
}
-static inline void perf_cgroup_sched_out(struct task_struct *task)
+static inline void perf_cgroup_sched_out(struct task_struct *task,
+ struct task_struct *next)
{
}
-static inline void perf_cgroup_sched_in(struct task_struct *task)
+static inline void perf_cgroup_sched_in(struct task_struct *prev,
+ struct task_struct *task)
{
}
* cgroup event are system-wide mode only
*/
if (atomic_read(&__get_cpu_var(perf_cgroup_events)))
- perf_cgroup_sched_out(task);
+ perf_cgroup_sched_out(task, next);
}
static void task_ctx_sched_out(struct perf_event_context *ctx)
* accessing the event control register. If a NMI hits, then it will
* keep the event running.
*/
-void __perf_event_task_sched_in(struct task_struct *task)
+void __perf_event_task_sched_in(struct task_struct *prev,
+ struct task_struct *task)
{
struct perf_event_context *ctx;
int ctxn;
* cgroup event are system-wide mode only
*/
if (atomic_read(&__get_cpu_var(perf_cgroup_events)))
- perf_cgroup_sched_in(task);
+ perf_cgroup_sched_in(prev, task);
}
static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count)
* ctxswin cgroup events which are already scheduled
* in.
*/
- perf_cgroup_sched_out(current);
+ perf_cgroup_sched_out(current, NULL);
raw_spin_lock(&ctx->lock);
task_ctx_sched_out(ctx);
}
static void calc_timer_values(struct perf_event *event,
- u64 *running,
- u64 *enabled)
+ u64 *enabled,
+ u64 *running)
{
u64 now, ctx_time;
#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
local_irq_disable();
#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
- perf_event_task_sched_in(current);
+ perf_event_task_sched_in(prev, current);
#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
local_irq_enable();
#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
}
/*
- * schedule() is the main scheduler function.
+ * __schedule() is the main scheduler function.
*/
-asmlinkage void __sched schedule(void)
+static void __sched __schedule(void)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
if (to_wakeup)
try_to_wake_up_local(to_wakeup);
}
-
- /*
- * If we are going to sleep and we have plugged IO
- * queued, make sure to submit it to avoid deadlocks.
- */
- if (blk_needs_flush_plug(prev)) {
- raw_spin_unlock(&rq->lock);
- blk_schedule_flush_plug(prev);
- raw_spin_lock(&rq->lock);
- }
}
switch_count = &prev->nvcsw;
}
if (need_resched())
goto need_resched;
}
+
+static inline void sched_submit_work(struct task_struct *tsk)
+{
+ if (!tsk->state)
+ return;
+ /*
+ * If we are going to sleep and we have plugged IO queued,
+ * make sure to submit it to avoid deadlocks.
+ */
+ if (blk_needs_flush_plug(tsk))
+ blk_schedule_flush_plug(tsk);
+}
+
+asmlinkage void schedule(void)
+{
+ struct task_struct *tsk = current;
+
+ sched_submit_work(tsk);
+ __schedule();
+}
EXPORT_SYMBOL(schedule);
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
do {
add_preempt_count_notrace(PREEMPT_ACTIVE);
- schedule();
+ __schedule();
sub_preempt_count_notrace(PREEMPT_ACTIVE);
/*
do {
add_preempt_count(PREEMPT_ACTIVE);
local_irq_enable();
- schedule();
+ __schedule();
local_irq_disable();
sub_preempt_count(PREEMPT_ACTIVE);
static void __cond_resched(void)
{
add_preempt_count(PREEMPT_ACTIVE);
- schedule();
+ __schedule();
sub_preempt_count(PREEMPT_ACTIVE);
}
struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j);
if (sd && (sd->flags & SD_OVERLAP))
free_sched_groups(sd->groups, 0);
+ kfree(*per_cpu_ptr(sdd->sd, j));
kfree(*per_cpu_ptr(sdd->sg, j));
kfree(*per_cpu_ptr(sdd->sgp, j));
}
static void alarm_timer_get(struct k_itimer *timr,
struct itimerspec *cur_setting)
{
+ memset(cur_setting, 0, sizeof(struct itimerspec));
+
cur_setting->it_interval =
ktime_to_timespec(timr->it.alarmtimer.period);
cur_setting->it_value =
if (!rtcdev)
return -ENOTSUPP;
- /* Save old values */
- old_setting->it_interval =
- ktime_to_timespec(timr->it.alarmtimer.period);
- old_setting->it_value =
- ktime_to_timespec(timr->it.alarmtimer.node.expires);
+ /*
+ * XXX HACK! Currently we can DOS a system if the interval
+ * period on alarmtimers is too small. Cap the interval here
+ * to 100us and solve this properly in a future patch! -jstultz
+ */
+ if ((new_setting->it_interval.tv_sec == 0) &&
+ (new_setting->it_interval.tv_nsec < 100000))
+ new_setting->it_interval.tv_nsec = 100000;
+
+ if (old_setting)
+ alarm_timer_get(timr, old_setting);
/* If the timer was already set, cancel it */
alarm_cancel(&timr->it.alarmtimer);
for_each_cwq_cpu(cpu, wq) {
struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
+ bool drained;
- if (!cwq->nr_active && list_empty(&cwq->delayed_works))
+ spin_lock_irq(&cwq->gcwq->lock);
+ drained = !cwq->nr_active && list_empty(&cwq->delayed_works);
+ spin_unlock_irq(&cwq->gcwq->lock);
+
+ if (drained)
continue;
if (++flush_cnt == 10 ||
idr.o int_sqrt.o extable.o prio_tree.o \
sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
proportions.o prio_heap.o ratelimit.o show_mem.o \
- is_single_threaded.o plist.o decompress.o find_next_bit.o
+ is_single_threaded.o plist.o decompress.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \
- bsearch.o find_last_bit.o
+ bsearch.o find_last_bit.o find_next_bit.o
obj-y += kstrtox.o
obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/bitops.h>
+#include <linux/cryptohash.h>
#include <asm/unaligned.h>
/*
{
unsigned int i;
unsigned int ret;
- unsigned int nr_found;
+ unsigned int nr_found, nr_skip;
rcu_read_lock();
restart:
nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree,
(void ***)pages, NULL, start, nr_pages);
ret = 0;
+ nr_skip = 0;
for (i = 0; i < nr_found; i++) {
struct page *page;
repeat:
* here as an exceptional entry: so skip over it -
* we only reach this from invalidate_mapping_pages().
*/
+ nr_skip++;
continue;
}
* If all entries were removed before we could secure them,
* try again, because callers stop trying once 0 is returned.
*/
- if (unlikely(!ret && nr_found))
+ if (unlikely(!ret && nr_found > nr_skip))
goto restart;
rcu_read_unlock();
return ret;
static void mem_cgroup_threshold(struct mem_cgroup *mem);
static void mem_cgroup_oom_notify(struct mem_cgroup *mem);
-enum {
- SCAN_BY_LIMIT,
- SCAN_BY_SYSTEM,
- NR_SCAN_CONTEXT,
- SCAN_BY_SHRINK, /* not recorded now */
-};
-
-enum {
- SCAN,
- SCAN_ANON,
- SCAN_FILE,
- ROTATE,
- ROTATE_ANON,
- ROTATE_FILE,
- FREED,
- FREED_ANON,
- FREED_FILE,
- ELAPSED,
- NR_SCANSTATS,
-};
-
-struct scanstat {
- spinlock_t lock;
- unsigned long stats[NR_SCAN_CONTEXT][NR_SCANSTATS];
- unsigned long rootstats[NR_SCAN_CONTEXT][NR_SCANSTATS];
-};
-
-const char *scanstat_string[NR_SCANSTATS] = {
- "scanned_pages",
- "scanned_anon_pages",
- "scanned_file_pages",
- "rotated_pages",
- "rotated_anon_pages",
- "rotated_file_pages",
- "freed_pages",
- "freed_anon_pages",
- "freed_file_pages",
- "elapsed_ns",
-};
-#define SCANSTAT_WORD_LIMIT "_by_limit"
-#define SCANSTAT_WORD_SYSTEM "_by_system"
-#define SCANSTAT_WORD_HIERARCHY "_under_hierarchy"
-
-
/*
* The memory controller data structure. The memory controller controls both
* page cache and RSS per cgroup. We would eventually like to provide
/* For oom notifier event fd */
struct list_head oom_notify;
- /* For recording LRU-scan statistics */
- struct scanstat scanstat;
+
/*
* Should we move charges of a task when a task is moved into this
* mem_cgroup ? And what type of charges should we move ?
}
#endif
-static void __mem_cgroup_record_scanstat(unsigned long *stats,
- struct memcg_scanrecord *rec)
-{
-
- stats[SCAN] += rec->nr_scanned[0] + rec->nr_scanned[1];
- stats[SCAN_ANON] += rec->nr_scanned[0];
- stats[SCAN_FILE] += rec->nr_scanned[1];
-
- stats[ROTATE] += rec->nr_rotated[0] + rec->nr_rotated[1];
- stats[ROTATE_ANON] += rec->nr_rotated[0];
- stats[ROTATE_FILE] += rec->nr_rotated[1];
-
- stats[FREED] += rec->nr_freed[0] + rec->nr_freed[1];
- stats[FREED_ANON] += rec->nr_freed[0];
- stats[FREED_FILE] += rec->nr_freed[1];
-
- stats[ELAPSED] += rec->elapsed;
-}
-
-static void mem_cgroup_record_scanstat(struct memcg_scanrecord *rec)
-{
- struct mem_cgroup *mem;
- int context = rec->context;
-
- if (context >= NR_SCAN_CONTEXT)
- return;
-
- mem = rec->mem;
- spin_lock(&mem->scanstat.lock);
- __mem_cgroup_record_scanstat(mem->scanstat.stats[context], rec);
- spin_unlock(&mem->scanstat.lock);
-
- mem = rec->root;
- spin_lock(&mem->scanstat.lock);
- __mem_cgroup_record_scanstat(mem->scanstat.rootstats[context], rec);
- spin_unlock(&mem->scanstat.lock);
-}
-
/*
* Scan the hierarchy if needed to reclaim memory. We remember the last child
* we reclaimed from, so that we don't end up penalizing one child extensively
bool noswap = reclaim_options & MEM_CGROUP_RECLAIM_NOSWAP;
bool shrink = reclaim_options & MEM_CGROUP_RECLAIM_SHRINK;
bool check_soft = reclaim_options & MEM_CGROUP_RECLAIM_SOFT;
- struct memcg_scanrecord rec;
unsigned long excess;
- unsigned long scanned;
+ unsigned long nr_scanned;
excess = res_counter_soft_limit_excess(&root_mem->res) >> PAGE_SHIFT;
if (!check_soft && !shrink && root_mem->memsw_is_minimum)
noswap = true;
- if (shrink)
- rec.context = SCAN_BY_SHRINK;
- else if (check_soft)
- rec.context = SCAN_BY_SYSTEM;
- else
- rec.context = SCAN_BY_LIMIT;
-
- rec.root = root_mem;
-
while (1) {
victim = mem_cgroup_select_victim(root_mem);
if (victim == root_mem) {
css_put(&victim->css);
continue;
}
- rec.mem = victim;
- rec.nr_scanned[0] = 0;
- rec.nr_scanned[1] = 0;
- rec.nr_rotated[0] = 0;
- rec.nr_rotated[1] = 0;
- rec.nr_freed[0] = 0;
- rec.nr_freed[1] = 0;
- rec.elapsed = 0;
/* we use swappiness of local cgroup */
if (check_soft) {
ret = mem_cgroup_shrink_node_zone(victim, gfp_mask,
- noswap, zone, &rec, &scanned);
- *total_scanned += scanned;
+ noswap, zone, &nr_scanned);
+ *total_scanned += nr_scanned;
} else
ret = try_to_free_mem_cgroup_pages(victim, gfp_mask,
- noswap, &rec);
- mem_cgroup_record_scanstat(&rec);
+ noswap);
css_put(&victim->css);
/*
* At shrinking usage, we can't check we should stop here or
/* try to free all pages in this cgroup */
shrink = 1;
while (nr_retries && mem->res.usage > 0) {
- struct memcg_scanrecord rec;
int progress;
if (signal_pending(current)) {
ret = -EINTR;
goto out;
}
- rec.context = SCAN_BY_SHRINK;
- rec.mem = mem;
- rec.root = mem;
progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL,
- false, &rec);
+ false);
if (!progress) {
nr_retries--;
/* maybe some writeback is necessary */
}
#endif /* CONFIG_NUMA */
-static int mem_cgroup_vmscan_stat_read(struct cgroup *cgrp,
- struct cftype *cft,
- struct cgroup_map_cb *cb)
-{
- struct mem_cgroup *mem = mem_cgroup_from_cont(cgrp);
- char string[64];
- int i;
-
- for (i = 0; i < NR_SCANSTATS; i++) {
- strcpy(string, scanstat_string[i]);
- strcat(string, SCANSTAT_WORD_LIMIT);
- cb->fill(cb, string, mem->scanstat.stats[SCAN_BY_LIMIT][i]);
- }
-
- for (i = 0; i < NR_SCANSTATS; i++) {
- strcpy(string, scanstat_string[i]);
- strcat(string, SCANSTAT_WORD_SYSTEM);
- cb->fill(cb, string, mem->scanstat.stats[SCAN_BY_SYSTEM][i]);
- }
-
- for (i = 0; i < NR_SCANSTATS; i++) {
- strcpy(string, scanstat_string[i]);
- strcat(string, SCANSTAT_WORD_LIMIT);
- strcat(string, SCANSTAT_WORD_HIERARCHY);
- cb->fill(cb, string, mem->scanstat.rootstats[SCAN_BY_LIMIT][i]);
- }
- for (i = 0; i < NR_SCANSTATS; i++) {
- strcpy(string, scanstat_string[i]);
- strcat(string, SCANSTAT_WORD_SYSTEM);
- strcat(string, SCANSTAT_WORD_HIERARCHY);
- cb->fill(cb, string, mem->scanstat.rootstats[SCAN_BY_SYSTEM][i]);
- }
- return 0;
-}
-
-static int mem_cgroup_reset_vmscan_stat(struct cgroup *cgrp,
- unsigned int event)
-{
- struct mem_cgroup *mem = mem_cgroup_from_cont(cgrp);
-
- spin_lock(&mem->scanstat.lock);
- memset(&mem->scanstat.stats, 0, sizeof(mem->scanstat.stats));
- memset(&mem->scanstat.rootstats, 0, sizeof(mem->scanstat.rootstats));
- spin_unlock(&mem->scanstat.lock);
- return 0;
-}
-
-
static struct cftype mem_cgroup_files[] = {
{
.name = "usage_in_bytes",
.mode = S_IRUGO,
},
#endif
- {
- .name = "vmscan_stat",
- .read_map = mem_cgroup_vmscan_stat_read,
- .trigger = mem_cgroup_reset_vmscan_stat,
- },
};
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
atomic_set(&mem->refcnt, 1);
mem->move_charge_at_immigrate = 0;
mutex_init(&mem->thresholds_lock);
- spin_lock_init(&mem->scanstat.lock);
return &mem->css;
free_out:
__mem_cgroup_free(mem);
struct vm_area_struct *prev;
struct vm_area_struct *vma;
int err = 0;
- pgoff_t pgoff;
unsigned long vmstart;
unsigned long vmend;
vmstart = max(start, vma->vm_start);
vmend = min(end, vma->vm_end);
- pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
- vma->anon_vma, vma->vm_file, pgoff, new_pol);
+ vma->anon_vma, vma->vm_file, vma->vm_pgoff,
+ new_pol);
if (prev) {
vma = prev;
next = vma->vm_next;
err = sys_get_mempolicy(policy, nm, nr_bits+1, addr, flags);
if (!err && nmask) {
- err = copy_from_user(bm, nm, alloc_size);
+ unsigned long copy_size;
+ copy_size = min_t(unsigned long, sizeof(bm), alloc_size);
+ err = copy_from_user(bm, nm, copy_size);
/* ensure entire bitmap is zeroed */
err |= clear_user(nmask, ALIGN(maxnode-1, 8) / 8);
err |= compat_put_bitmap(nmask, bm, nr_bits);
return NULL;
}
+ /*
+ * If the allocated address space is passed to a hypercall
+ * before being used then we cannot rely on a page fault to
+ * trigger an update of the page tables. So sync all the page
+ * tables here.
+ */
+ vmalloc_sync_all();
+
return area;
}
EXPORT_SYMBOL_GPL(alloc_vm_area);
/* Which cgroup do we reclaim from */
struct mem_cgroup *mem_cgroup;
- struct memcg_scanrecord *memcg_record;
/*
* Nodemask of nodes allowed by the caller. If NULL, all nodes
int file = is_file_lru(lru);
int numpages = hpage_nr_pages(page);
reclaim_stat->recent_rotated[file] += numpages;
- if (!scanning_global_lru(sc))
- sc->memcg_record->nr_rotated[file] += numpages;
}
if (!pagevec_add(&pvec, page)) {
spin_unlock_irq(&zone->lru_lock);
reclaim_stat->recent_scanned[0] += *nr_anon;
reclaim_stat->recent_scanned[1] += *nr_file;
- if (!scanning_global_lru(sc)) {
- sc->memcg_record->nr_scanned[0] += *nr_anon;
- sc->memcg_record->nr_scanned[1] += *nr_file;
- }
}
/*
nr_reclaimed += shrink_page_list(&page_list, zone, sc);
}
- if (!scanning_global_lru(sc))
- sc->memcg_record->nr_freed[file] += nr_reclaimed;
-
local_irq_disable();
if (current_is_kswapd())
__count_vm_events(KSWAPD_STEAL, nr_reclaimed);
}
reclaim_stat->recent_scanned[file] += nr_taken;
- if (!scanning_global_lru(sc))
- sc->memcg_record->nr_scanned[file] += nr_taken;
__count_zone_vm_events(PGREFILL, zone, pgscanned);
if (file)
* get_scan_ratio.
*/
reclaim_stat->recent_rotated[file] += nr_rotated;
- if (!scanning_global_lru(sc))
- sc->memcg_record->nr_rotated[file] += nr_rotated;
move_active_pages_to_lru(zone, &l_active,
LRU_ACTIVE + file * LRU_FILE);
u64 fraction[2], denominator;
enum lru_list l;
int noswap = 0;
- int force_scan = 0;
+ bool force_scan = false;
unsigned long nr_force_scan[2];
-
- anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) +
- zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON);
- file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) +
- zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE);
-
- if (((anon + file) >> priority) < SWAP_CLUSTER_MAX) {
- /* kswapd does zone balancing and need to scan this zone */
- if (scanning_global_lru(sc) && current_is_kswapd())
- force_scan = 1;
- /* memcg may have small limit and need to avoid priority drop */
- if (!scanning_global_lru(sc))
- force_scan = 1;
- }
+ /* kswapd does zone balancing and needs to scan this zone */
+ if (scanning_global_lru(sc) && current_is_kswapd())
+ force_scan = true;
+ /* memcg may have small limit and need to avoid priority drop */
+ if (!scanning_global_lru(sc))
+ force_scan = true;
/* If we have no swap space, do not bother scanning anon pages. */
if (!sc->may_swap || (nr_swap_pages <= 0)) {
goto out;
}
+ anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) +
+ zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON);
+ file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) +
+ zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE);
+
if (scanning_global_lru(sc)) {
free = zone_page_state(zone, NR_FREE_PAGES);
/* If we have very few page cache pages,
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,
- gfp_t gfp_mask, bool noswap,
- struct zone *zone,
- struct memcg_scanrecord *rec,
- unsigned long *scanned)
+ gfp_t gfp_mask, bool noswap,
+ struct zone *zone,
+ unsigned long *nr_scanned)
{
struct scan_control sc = {
.nr_scanned = 0,
.may_swap = !noswap,
.order = 0,
.mem_cgroup = mem,
- .memcg_record = rec,
};
- ktime_t start, end;
sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
(GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK);
sc.may_writepage,
sc.gfp_mask);
- start = ktime_get();
/*
* NOTE: Although we can get the priority field, using it
* here is not a good idea, since it limits the pages we can scan.
* the priority and make it zero.
*/
shrink_zone(0, zone, &sc);
- end = ktime_get();
-
- if (rec)
- rec->elapsed += ktime_to_ns(ktime_sub(end, start));
- *scanned = sc.nr_scanned;
trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed);
+ *nr_scanned = sc.nr_scanned;
return sc.nr_reclaimed;
}
unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont,
gfp_t gfp_mask,
- bool noswap,
- struct memcg_scanrecord *rec)
+ bool noswap)
{
struct zonelist *zonelist;
unsigned long nr_reclaimed;
- ktime_t start, end;
int nid;
struct scan_control sc = {
.may_writepage = !laptop_mode,
.nr_to_reclaim = SWAP_CLUSTER_MAX,
.order = 0,
.mem_cgroup = mem_cont,
- .memcg_record = rec,
.nodemask = NULL, /* we don't care the placement */
.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
(GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK),
.gfp_mask = sc.gfp_mask,
};
- start = ktime_get();
/*
* Unlike direct reclaim via alloc_pages(), memcg's reclaim doesn't
* take care of from where we get pages. So the node where we start the
sc.gfp_mask);
nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink);
- end = ktime_get();
- if (rec)
- rec->elapsed += ktime_to_ns(ktime_sub(end, start));
trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
}
#endif
-#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS)
+#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || defined(CONFIG_NUMA)
#ifdef CONFIG_ZONE_DMA
#define TEXT_FOR_DMA(xx) xx "_dma",
#else
#endif /* CONFIG_VM_EVENTS_COUNTERS */
};
-#endif /* CONFIG_PROC_FS || CONFIG_SYSFS */
+#endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA */
#ifdef CONFIG_PROC_FS
{
int in, out, inp, outp;
struct virtio_chan *chan = client->trans;
- char *rdata = (char *)req->rc+sizeof(struct p9_fcall);
unsigned long flags;
size_t pdata_off = 0;
struct trans_rpage_info *rpinfo = NULL;
* Arrange in such a way that server places header in the
* alloced memory and payload onto the user buffer.
*/
- inp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, 11);
+ inp = pack_sg_list(chan->sg, out,
+ VIRTQUEUE_NUM, req->rc->sdata, 11);
/*
* Running executables in the filesystem may result in
* a read request with kernel buffer as opposed to user buffer.
}
in += inp;
} else {
- in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata,
- req->rc->capacity);
+ in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM,
+ req->rc->sdata, req->rc->capacity);
}
err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
.close = p9_virtio_close,
.request = p9_virtio_request,
.cancel = p9_virtio_cancel,
- .maxsize = PAGE_SIZE*VIRTQUEUE_NUM,
+
+ /*
+ * We leave one entry for input and one entry for response
+ * headers. We also skip one more entry to accomodate, address
+ * that are not at page boundary, that can result in an extra
+ * page in zero copy.
+ */
+ .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
.pref = P9_TRANS_PREF_PAYLOAD_SEP,
.def = 0,
.owner = THIS_MODULE,
BT_DBG("sk %p", sk);
add_wait_queue(sk_sleep(sk), &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
while (sk->sk_state != state) {
- set_current_state(TASK_INTERRUPTIBLE);
-
if (!timeo) {
err = -EINPROGRESS;
break;
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
+ set_current_state(TASK_INTERRUPTIBLE);
err = sock_error(sk);
if (err)
break;
}
- set_current_state(TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
return err;
}
unsigned int role;
unsigned long state;
unsigned long flags;
+ atomic_t terminate;
struct task_struct *task;
struct ethhdr eh;
init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait);
- while (!kthread_should_stop()) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
+ if (atomic_read(&s->terminate))
+ break;
/* RX */
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb);
schedule();
}
- set_current_state(TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
/* Cleanup session */
down_read(&bnep_session_sem);
s = __bnep_get_session(req->dst);
- if (s)
- kthread_stop(s->task);
- else
+ if (s) {
+ atomic_inc(&s->terminate);
+ wake_up_process(s->task);
+ } else
err = -ENOENT;
up_read(&bnep_session_sem);
capi_ctr_down(ctrl);
- kthread_stop(session->task);
+ atomic_inc(&session->terminate);
+ wake_up_process(session->task);
}
static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
char name[BTNAMSIZ];
+ atomic_t terminate;
struct task_struct *task;
wait_queue_head_t wait;
init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait);
- while (!kthread_should_stop()) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
+ if (atomic_read(&session->terminate))
+ break;
if (sk->sk_state != BT_CONNECTED)
break;
schedule();
}
- set_current_state(TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
down_write(&cmtp_session_sem);
if (!(session->flags & (1 << CMTP_LOOPBACK))) {
err = cmtp_attach_device(session);
- if (err < 0)
- goto detach;
+ if (err < 0) {
+ atomic_inc(&session->terminate);
+ wake_up_process(session->task);
+ up_write(&cmtp_session_sem);
+ return err;
+ }
}
up_write(&cmtp_session_sem);
return 0;
-detach:
- cmtp_detach_device(session);
-
unlink:
__cmtp_unlink_session(session);
skb_queue_purge(&session->transmit);
/* Stop session thread */
- kthread_stop(session->task);
+ atomic_inc(&session->terminate);
+ wake_up_process(session->task);
} else
err = -ENOENT;
BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1);
- clear_bit(HCI_RESET, &hdev->flags);
tasklet_schedule(&hdev->cmd_task);
}
entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
if (!entry) {
- return -ENOMEM;
+ err = -ENOMEM;
goto err;
}
if (hdev->sent_cmd) {
atomic_dec(&hdev->cmd_cnt);
hci_send_frame(skb);
- mod_timer(&hdev->cmd_timer,
+ if (test_bit(HCI_RESET, &hdev->flags))
+ del_timer(&hdev->cmd_timer);
+ else
+ mod_timer(&hdev->cmd_timer,
jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
} else {
skb_queue_head(&hdev->cmd_q, skb);
up_write(&hidp_session_sem);
+ kfree(session->rd_data);
kfree(session);
return 0;
}
err = input_register_device(input);
if (err < 0) {
- hci_conn_put_device(session->conn);
+ input_free_device(input);
+ session->input = NULL;
return err;
}
}
err = hid_add_device(session->hid);
- if (err < 0)
- goto err_add_device;
+ if (err < 0) {
+ atomic_inc(&session->terminate);
+ wake_up_process(session->task);
+ up_write(&hidp_session_sem);
+ return err;
+ }
if (session->input) {
hidp_send_ctrl_message(session,
up_write(&hidp_session_sem);
return 0;
-err_add_device:
- hid_destroy_device(session->hid);
- session->hid = NULL;
- atomic_inc(&session->terminate);
- wake_up_process(session->task);
-
unlink:
hidp_del_timer(session);
failed:
up_write(&hidp_session_sem);
- input_free_device(session->input);
kfree(session);
return err;
}
int timeo = HZ/5;
add_wait_queue(sk_sleep(sk), &wait);
- while ((chan->unacked_frames > 0 && chan->conn)) {
- set_current_state(TASK_INTERRUPTIBLE);
-
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (chan->unacked_frames > 0 && chan->conn) {
if (!timeo)
timeo = HZ/5;
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
+ set_current_state(TASK_INTERRUPTIBLE);
err = sock_error(sk);
if (err)
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
- goto done;
- }
-
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
BT_DBG("sk %p timeo %ld", sk, timeo);
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
- while (!(nsk = bt_accept_dequeue(sk, newsock))) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
- if (!timeo) {
- err = -EAGAIN;
+
+ if (sk->sk_state != BT_LISTEN) {
+ err = -EBADFD;
break;
}
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+ nsk = bt_accept_dequeue(sk, newsock);
+ if (nsk)
+ break;
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
+ if (!timeo) {
+ err = -EAGAIN;
break;
}
err = sock_intr_errno(timeo);
break;
}
+
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
}
- set_current_state(TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct;
- sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
+ sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
sock_reset_flag(sk, SOCK_ZAPPED);
#define rfcomm_lock() mutex_lock(&rfcomm_mutex)
#define rfcomm_unlock() mutex_unlock(&rfcomm_mutex)
-static unsigned long rfcomm_event;
static LIST_HEAD(session_list);
{
if (!rfcomm_thread)
return;
- set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
wake_up_process(rfcomm_thread);
}
rfcomm_add_listener(BDADDR_ANY);
- while (!kthread_should_stop()) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
- if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
- /* No pending events. Let's sleep.
- * Incoming connections and data will wake us up. */
- schedule();
- }
- set_current_state(TASK_RUNNING);
+
+ if (kthread_should_stop())
+ break;
/* Process stuff */
- clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
rfcomm_process_sessions();
+
+ schedule();
}
+ __set_current_state(TASK_RUNNING);
rfcomm_kill_listener();
lock_sock(sk);
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
- goto done;
- }
-
if (sk->sk_type != SOCK_STREAM) {
err = -EINVAL;
goto done;
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
- while (!(nsk = bt_accept_dequeue(sk, newsock))) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
- if (!timeo) {
- err = -EAGAIN;
+
+ if (sk->sk_state != BT_LISTEN) {
+ err = -EBADFD;
break;
}
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
+ nsk = bt_accept_dequeue(sk, newsock);
+ if (nsk)
+ break;
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
+ if (!timeo) {
+ err = -EAGAIN;
break;
}
err = sock_intr_errno(timeo);
break;
}
+
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
}
- set_current_state(TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
lock_sock(sk);
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
- goto done;
- }
-
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
BT_DBG("sk %p timeo %ld", sk, timeo);
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
- while (!(ch = bt_accept_dequeue(sk, newsock))) {
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
- if (!timeo) {
- err = -EAGAIN;
+
+ if (sk->sk_state != BT_LISTEN) {
+ err = -EBADFD;
break;
}
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
+ ch = bt_accept_dequeue(sk, newsock);
+ if (ch)
+ break;
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
+ if (!timeo) {
+ err = -EAGAIN;
break;
}
err = sock_intr_errno(timeo);
break;
}
+
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
}
- set_current_state(TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
{
struct sk_buff *skb2;
const struct ipv6hdr *ip6h;
- struct icmp6hdr *icmp6h;
+ u8 icmp6_type;
u8 nexthdr;
unsigned len;
int offset;
__skb_pull(skb2, offset);
skb_reset_transport_header(skb2);
- icmp6h = icmp6_hdr(skb2);
+ icmp6_type = icmp6_hdr(skb2)->icmp6_type;
- switch (icmp6h->icmp6_type) {
+ switch (icmp6_type) {
case ICMPV6_MGM_QUERY:
case ICMPV6_MGM_REPORT:
case ICMPV6_MGM_REDUCTION:
err = pskb_trim_rcsum(skb2, len);
if (err)
goto out;
+ err = -EINVAL;
}
+ ip6h = ipv6_hdr(skb2);
+
switch (skb2->ip_summed) {
case CHECKSUM_COMPLETE:
- if (!csum_fold(skb2->csum))
+ if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len,
+ IPPROTO_ICMPV6, skb2->csum))
break;
/*FALLTHROUGH*/
case CHECKSUM_NONE:
- skb2->csum = 0;
- if (skb_checksum_complete(skb2))
+ skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
+ &ip6h->daddr,
+ skb2->len,
+ IPPROTO_ICMPV6, 0));
+ if (__skb_checksum_complete(skb2))
goto out;
}
BR_INPUT_SKB_CB(skb)->igmp = 1;
- switch (icmp6h->icmp6_type) {
+ switch (icmp6_type) {
case ICMPV6_MGM_REPORT:
{
struct mld_msg *mld;
#include <linux/ceph/msgpool.h>
-static void *alloc_fn(gfp_t gfp_mask, void *arg)
+static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
{
struct ceph_msgpool *pool = arg;
- void *p;
+ struct ceph_msg *msg;
- p = ceph_msg_new(0, pool->front_len, gfp_mask);
- if (!p)
- pr_err("msgpool %s alloc failed\n", pool->name);
- return p;
+ msg = ceph_msg_new(0, pool->front_len, gfp_mask);
+ if (!msg) {
+ dout("msgpool_alloc %s failed\n", pool->name);
+ } else {
+ dout("msgpool_alloc %s %p\n", pool->name, msg);
+ msg->pool = pool;
+ }
+ return msg;
}
-static void free_fn(void *element, void *arg)
+static void msgpool_free(void *element, void *arg)
{
- ceph_msg_put(element);
+ struct ceph_msgpool *pool = arg;
+ struct ceph_msg *msg = element;
+
+ dout("msgpool_release %s %p\n", pool->name, msg);
+ msg->pool = NULL;
+ ceph_msg_put(msg);
}
int ceph_msgpool_init(struct ceph_msgpool *pool,
int front_len, int size, bool blocking, const char *name)
{
+ dout("msgpool %s init\n", name);
pool->front_len = front_len;
- pool->pool = mempool_create(size, alloc_fn, free_fn, pool);
+ pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool);
if (!pool->pool)
return -ENOMEM;
pool->name = name;
void ceph_msgpool_destroy(struct ceph_msgpool *pool)
{
+ dout("msgpool %s destroy\n", pool->name);
mempool_destroy(pool->pool);
}
struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool,
int front_len)
{
+ struct ceph_msg *msg;
+
if (front_len > pool->front_len) {
- pr_err("msgpool_get pool %s need front %d, pool size is %d\n",
+ dout("msgpool_get %s need front %d, pool size is %d\n",
pool->name, front_len, pool->front_len);
WARN_ON(1);
return ceph_msg_new(0, front_len, GFP_NOFS);
}
- return mempool_alloc(pool->pool, GFP_NOFS);
+ msg = mempool_alloc(pool->pool, GFP_NOFS);
+ dout("msgpool_get %s %p\n", pool->name, msg);
+ return msg;
}
void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
{
+ dout("msgpool_put %s %p\n", pool->name, msg);
+
/* reset msg front_len; user may have changed it */
msg->front.iov_len = pool->front_len;
msg->hdr.front_len = cpu_to_le32(pool->front_len);
kref_init(&msg->kref); /* retake single ref */
+ mempool_free(msg, pool->pool);
}
put_osd(osd);
}
+static void remove_all_osds(struct ceph_osd_client *osdc)
+{
+ dout("__remove_old_osds %p\n", osdc);
+ mutex_lock(&osdc->request_mutex);
+ while (!RB_EMPTY_ROOT(&osdc->osds)) {
+ struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds),
+ struct ceph_osd, o_node);
+ __remove_osd(osdc, osd);
+ }
+ mutex_unlock(&osdc->request_mutex);
+}
+
static void __move_osd_to_lru(struct ceph_osd_client *osdc,
struct ceph_osd *osd)
{
list_del_init(&osd->o_osd_lru);
}
-static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all)
+static void remove_old_osds(struct ceph_osd_client *osdc)
{
struct ceph_osd *osd, *nosd;
dout("__remove_old_osds %p\n", osdc);
mutex_lock(&osdc->request_mutex);
list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
- if (!remove_all && time_before(jiffies, osd->lru_ttl))
+ if (time_before(jiffies, osd->lru_ttl))
break;
__remove_osd(osdc, osd);
}
struct rb_node *parent = NULL;
struct ceph_osd *osd = NULL;
+ dout("__insert_osd %p osd%d\n", new, new->o_osd);
while (*p) {
parent = *p;
osd = rb_entry(parent, struct ceph_osd, o_node);
dout("osds timeout\n");
down_read(&osdc->map_sem);
- remove_old_osds(osdc, 0);
+ remove_old_osds(osdc);
up_read(&osdc->map_sem);
schedule_delayed_work(&osdc->osds_timeout_work,
ceph_osdmap_destroy(osdc->osdmap);
osdc->osdmap = NULL;
}
- remove_old_osds(osdc, 1);
- WARN_ON(!RB_EMPTY_ROOT(&osdc->osds));
+ remove_all_osds(osdc);
mempool_destroy(osdc->req_mempool);
ceph_msgpool_destroy(&osdc->msgpool_op);
ceph_msgpool_destroy(&osdc->msgpool_op_reply);
if (tdif <= 0) {
struct net_device *dev = skb->dev;
+
__skb_unlink(skb, &tbl->proxy_queue);
- if (tbl->proxy_redo && netif_running(dev))
+ if (tbl->proxy_redo && netif_running(dev)) {
+ rcu_read_lock();
tbl->proxy_redo(skb);
- else
+ rcu_read_unlock();
+ } else {
kfree_skb(skb);
+ }
dev_put(dev);
} else if (!sched_next || tdif < sched_next)
if (skb_shared(skb))
goto out;
- iph = (struct iphdr *)skb->data;
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
goto out;
+ iph = (struct iphdr *)skb->data;
if (iph->ihl < 5 || iph->version != 4)
goto out;
if (!pskb_may_pull(skb, iph->ihl*4))
goto out;
+ iph = (struct iphdr *)skb->data;
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
goto out;
if (pskb_trim_rcsum(skb, len))
goto out;
+ iph = (struct iphdr *)skb->data;
if (iph->protocol != IPPROTO_UDP)
goto out;
break;
for (i=0; i<nsrcs; i++) {
/* skip inactive filters */
- if (pmc->sfcount[MCAST_INCLUDE] ||
+ if (psf->sf_count[MCAST_INCLUDE] ||
pmc->sfcount[MCAST_EXCLUDE] !=
psf->sf_count[MCAST_EXCLUDE])
continue;
break;
for (i=0; i<nsrcs; i++) {
/* skip inactive filters */
- if (pmc->mca_sfcount[MCAST_INCLUDE] ||
+ if (psf->sf_count[MCAST_INCLUDE] ||
pmc->mca_sfcount[MCAST_EXCLUDE] !=
psf->sf_count[MCAST_EXCLUDE])
continue;
cancel_work_sync(&local->reconfig_filter);
ieee80211_clear_tx_pending(local);
- sta_info_stop(local);
rate_control_deinitialize(local);
if (skb_queue_len(&local->skb_queue) ||
destroy_workqueue(local->workqueue);
wiphy_unregister(local->hw.wiphy);
+ sta_info_stop(local);
ieee80211_wep_free(local);
ieee80211_led_exit(local);
kfree(local->int_scan_req);
* used_address->name_len is initialized to UINT_MAX so that the first
* destination address never matches.
*/
- if (used_address && used_address->name_len == msg_sys->msg_namelen &&
- !memcmp(&used_address->name, msg->msg_name,
+ if (used_address && msg_sys->msg_name &&
+ used_address->name_len == msg_sys->msg_namelen &&
+ !memcmp(&used_address->name, msg_sys->msg_name,
used_address->name_len)) {
err = sock_sendmsg_nosec(sock, msg_sys, total_len);
goto out_freectl;
*/
if (used_address && err >= 0) {
used_address->name_len = msg_sys->msg_namelen;
- memcpy(&used_address->name, msg->msg_name,
- used_address->name_len);
+ if (msg_sys->msg_name)
+ memcpy(&used_address->name, msg_sys->msg_name,
+ used_address->name_len);
}
out_freectl:
if (res)
goto out_rm_dev;
+ rtnl_lock();
+ rdev->wiphy.registered = true;
+ rtnl_unlock();
return 0;
out_rm_dev:
{
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ rtnl_lock();
+ rdev->wiphy.registered = false;
+ rtnl_unlock();
+
rfkill_unregister(rdev->rfkill);
/* protect the device list */
if (rdev->ops->suspend) {
rtnl_lock();
- ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
+ if (rdev->wiphy.registered)
+ ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
rtnl_unlock();
}
if (rdev->ops->resume) {
rtnl_lock();
- ret = rdev->ops->resume(&rdev->wiphy);
+ if (rdev->wiphy.registered)
+ ret = rdev->ops->resume(&rdev->wiphy);
rtnl_unlock();
}
* published by the Free Software Foundation.
*/
+#include <stdlib.h>
+#ifndef __UCLIBC__
#include <libio.h>
+#endif
#include <dwarf-regs.h>
struct pt_regs_dwarfnum {