Kay Sievers <kay.sievers@vrfy.org>
Kenneth W Chen <kenneth.w.chen@intel.com>
Koushik <raghavendra.koushik@neterion.com>
+Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Leonid I Ananiev <leonid.i.ananiev@intel.com>
Linas Vepstas <linas@austin.ibm.com>
Mark Brown <broonie@sirena.org.uk>
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Takashi YOSHII <takashi.yoshii.zj@renesas.com>
+Yusuke Goda <goda.yusuke@renesas.com>
The Linux DRM layer contains code intended to support the needs
of complex graphics devices, usually containing programmable
pipelines well suited to 3D graphics acceleration. Graphics
- drivers in the kernel can make use of DRM functions to make
+ drivers in the kernel may make use of DRM functions to make
tasks like memory management, interrupt handling and DMA easier,
and provide a uniform interface to applications.
</para>
existing drivers.
</para>
<para>
- First, we'll go over some typical driver initialization
+ First, we go over some typical driver initialization
requirements, like setting up command buffers, creating an
initial output configuration, and initializing core services.
- Subsequent sections will cover core internals in more detail,
+ Subsequent sections cover core internals in more detail,
providing implementation notes and examples.
</para>
<para>
</para>
<para>
The core of every DRM driver is struct drm_driver. Drivers
- will typically statically initialize a drm_driver structure,
+ typically statically initialize a drm_driver structure,
then pass it to drm_init() at load time.
</para>
</para>
<programlisting>
static struct drm_driver driver = {
- /* don't use mtrr's here, the Xserver or user space app should
- * deal with them for intel hardware.
+ /* Don't use MTRRs here; the Xserver or userspace app should
+ * deal with them for Intel hardware.
*/
.driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
</programlisting>
<para>
In the example above, taken from the i915 DRM driver, the driver
- sets several flags indicating what core features it supports.
- We'll go over the individual callbacks in later sections. Since
+ sets several flags indicating what core features it supports;
+ we go over the individual callbacks in later sections. Since
flags indicate which features your driver supports to the DRM
core, you need to set most of them prior to calling drm_init(). Some,
like DRIVER_MODESET can be set later based on user supplied parameters,
<term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term>
<listitem>
<para>
- DRIVER_HAVE_IRQ indicates whether the driver has a IRQ
- handler, DRIVER_IRQ_SHARED indicates whether the device &
+ DRIVER_HAVE_IRQ indicates whether the driver has an IRQ
+ handler. DRIVER_IRQ_SHARED indicates whether the device &
handler support shared IRQs (note that this is required of
PCI drivers).
</para>
<term>DRIVER_DMA_QUEUE</term>
<listitem>
<para>
- If the driver queues DMA requests and completes them
- asynchronously, this flag should be set. Deprecated.
+ Should be set if the driver queues DMA requests and completes them
+ asynchronously. Deprecated.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
In this specific case, the driver requires AGP and supports
- IRQs. DMA, as we'll see, is handled by device specific ioctls
+ IRQs. DMA, as discussed later, is handled by device-specific ioctls
in this case. It also supports the kernel mode setting APIs, though
unlike in the actual i915 driver source, this example unconditionally
exports KMS capability.
initial output configuration.
</para>
<para>
- Note that the tasks performed at driver load time must not
- conflict with DRM client requirements. For instance, if user
+ If compatibility is a concern (e.g. with drivers converted over
+ to the new interfaces from the old ones), care must be taken to
+ prevent device initialization and control that is incompatible with
+ currently active userspace drivers. For instance, if user
level mode setting drivers are in use, it would be problematic
to perform output discovery & configuration at load time.
- Likewise, if pre-memory management aware user level drivers are
+ Likewise, if user-level drivers unaware of memory management are
in use, memory management and command buffer setup may need to
- be omitted. These requirements are driver specific, and care
+ be omitted. These requirements are driver-specific, and care
needs to be taken to keep both old and new applications and
libraries working. The i915 driver supports the "modeset"
module parameter to control whether advanced features are
- enabled at load time or in legacy fashion. If compatibility is
- a concern (e.g. with drivers converted over to the new interfaces
- from the old ones), care must be taken to prevent incompatible
- device initialization and control with the currently active
- userspace drivers.
+ enabled at load time or in legacy fashion.
</para>
<sect2>
<title>Driver private & performance counters</title>
<para>
The driver private hangs off the main drm_device structure and
- can be used for tracking various device specific bits of
+ can be used for tracking various device-specific bits of
information, like register offsets, command buffer status,
register state for suspend/resume, etc. At load time, a
- driver can simply allocate one and set drm_device.dev_priv
- appropriately; at unload the driver can free it and set
- drm_device.dev_priv to NULL.
+ driver may simply allocate one and set drm_device.dev_priv
+ appropriately; it should be freed and drm_device.dev_priv set
+ to NULL when the driver is unloaded.
</para>
<para>
- The DRM supports several counters which can be used for rough
+ The DRM supports several counters which may be used for rough
performance characterization. Note that the DRM stat counter
system is not often used by applications, and supporting
additional counters is completely optional.
These interfaces are deprecated and should not be used. If performance
monitoring is desired, the developer should investigate and
potentially enhance the kernel perf and tracing infrastructure to export
- GPU related performance information to performance monitoring
- tools and applications.
+ GPU related performance information for consumption by performance
+ monitoring tools and applications.
</para>
</sect2>
<sect2>
<title>Configuring the device</title>
<para>
- Obviously, device configuration will be device specific.
+ Obviously, device configuration is device-specific.
However, there are several common operations: finding a
device's PCI resources, mapping them, and potentially setting
up an IRQ handler.
<para>
Finding & mapping resources is fairly straightforward. The
DRM wrapper functions, drm_get_resource_start() and
- drm_get_resource_len() can be used to find BARs on the given
+ drm_get_resource_len(), may be used to find BARs on the given
drm_device struct. Once those values have been retrieved, the
driver load function can call drm_addmap() to create a new
- mapping for the BAR in question. Note you'll probably want a
+ mapping for the BAR in question. Note that you probably want a
drm_local_map_t in your driver private structure to track any
mappings you create.
<!-- !Fdrivers/gpu/drm/drm_bufs.c drm_get_resource_* -->
<para>
if compatibility with other operating systems isn't a concern
(DRM drivers can run under various BSD variants and OpenSolaris),
- native Linux calls can be used for the above, e.g. pci_resource_*
+ native Linux calls may be used for the above, e.g. pci_resource_*
and iomap*/iounmap. See the Linux device driver book for more
info.
</para>
<para>
- Once you have a register map, you can use the DRM_READn() and
+ Once you have a register map, you may use the DRM_READn() and
DRM_WRITEn() macros to access the registers on your device, or
- use driver specific versions to offset into your MMIO space
- relative to a driver specific base pointer (see I915_READ for
- example).
+ use driver-specific versions to offset into your MMIO space
+ relative to a driver-specific base pointer (see I915_READ for
+ an example).
</para>
<para>
If your device supports interrupt generation, you may want to
- setup an interrupt handler at driver load time as well. This
+ set up an interrupt handler when the driver is loaded. This
is done using the drm_irq_install() function. If your device
supports vertical blank interrupts, it should call
drm_vblank_init() to initialize the core vblank handling code before
</para>
<!--!Fdrivers/char/drm/drm_irq.c drm_irq_install-->
<para>
- Once your interrupt handler is registered (it'll use your
+ Once your interrupt handler is registered (it uses your
drm_driver.irq_handler as the actual interrupt handling
function), you can safely enable interrupts on your device,
assuming any other state your interrupt handler uses is also
using the pci_map_rom() call, a convenience function that
takes care of mapping the actual ROM, whether it has been
shadowed into memory (typically at address 0xc0000) or exists
- on the PCI device in the ROM BAR. Note that once you've
- mapped the ROM and extracted any necessary information, be
- sure to unmap it; on many devices the ROM address decoder is
- shared with other BARs, so leaving it mapped can cause
+ on the PCI device in the ROM BAR. Note that after the ROM
+ has been mapped and any necessary information has been extracted,
+ it should be unmapped; on many devices, the ROM address decoder is
+ shared with other BARs, so leaving it mapped could cause
undesired behavior like hangs or memory corruption.
<!--!Fdrivers/pci/rom.c pci_map_rom-->
</para>
should support a memory manager.
</para>
<para>
- If your driver supports memory management (it should!), you'll
+ If your driver supports memory management (it should!), you
need to set that up at load time as well. How you initialize
- it depends on which memory manager you're using, TTM or GEM.
+ it depends on which memory manager you're using: TTM or GEM.
</para>
<sect3>
<title>TTM initialization</title>
and devices with dedicated video RAM (VRAM), i.e. most discrete
graphics devices. If your device has dedicated RAM, supporting
TTM is desirable. TTM also integrates tightly with your
- driver specific buffer execution function. See the radeon
+ driver-specific buffer execution function. See the radeon
driver for examples.
</para>
<para>
created by the memory manager at runtime. Your global TTM should
have a type of TTM_GLOBAL_TTM_MEM. The size field for the global
object should be sizeof(struct ttm_mem_global), and the init and
- release hooks should point at your driver specific init and
- release routines, which will probably eventually call
- ttm_mem_global_init and ttm_mem_global_release respectively.
+ release hooks should point at your driver-specific init and
+ release routines, which probably eventually call
+ ttm_mem_global_init and ttm_mem_global_release, respectively.
</para>
<para>
Once your global TTM accounting structure is set up and initialized
- (done by calling ttm_global_item_ref on the global object you
- just created), you'll need to create a buffer object TTM to
+ by calling ttm_global_item_ref() on it,
+ you need to create a buffer object TTM to
provide a pool for buffer object allocation by clients and the
kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO,
and its size should be sizeof(struct ttm_bo_global). Again,
- driver specific init and release functions can be provided,
- likely eventually calling ttm_bo_global_init and
- ttm_bo_global_release, respectively. Also like the previous
- object, ttm_global_item_ref is used to create an initial reference
+ driver-specific init and release functions may be provided,
+ likely eventually calling ttm_bo_global_init() and
+ ttm_bo_global_release(), respectively. Also, like the previous
+ object, ttm_global_item_ref() is used to create an initial reference
count for the TTM, which will call your initialization function.
</para>
</sect3>
GEM is an alternative to TTM, designed specifically for UMA
devices. It has simpler initialization and execution requirements
than TTM, but has no VRAM management capability. Core GEM
- initialization is comprised of a basic drm_mm_init call to create
+ is initialized by calling drm_mm_init() to create
a GTT DRM MM object, which provides an address space pool for
- object allocation. In a KMS configuration, the driver will
- need to allocate and initialize a command ring buffer following
- basic GEM initialization. Most UMA devices have a so-called
+ object allocation. In a KMS configuration, the driver
+ needs to allocate and initialize a command ring buffer following
+ core GEM initialization. A UMA device usually has what is called a
"stolen" memory region, which provides space for the initial
framebuffer and large, contiguous memory regions required by the
- device. This space is not typically managed by GEM, and must
+ device. This space is not typically managed by GEM, and it must
be initialized separately into its own DRM MM object.
</para>
<para>
- Initialization will be driver specific, and will depend on
- the architecture of the device. In the case of Intel
+ Initialization is driver-specific. In the case of Intel
integrated graphics chips like 965GM, GEM initialization can
be done by calling the internal GEM init function,
i915_gem_do_init(). Since the 965GM is a UMA device
- (i.e. it doesn't have dedicated VRAM), GEM will manage
+ (i.e. it doesn't have dedicated VRAM), GEM manages
making regular RAM available for GPU operations. Memory set
aside by the BIOS (called "stolen" memory by the i915
- driver) will be managed by the DRM memrange allocator; the
- rest of the aperture will be managed by GEM.
+ driver) is managed by the DRM memrange allocator; the
+ rest of the aperture is managed by GEM.
<programlisting>
/* Basic memrange allocator for stolen space (aka vram) */
drm_memrange_init(&dev_priv->vram, 0, prealloc_size);
<!--!Edrivers/char/drm/drm_memrange.c-->
</para>
<para>
- Once the memory manager has been set up, we can allocate the
+ Once the memory manager has been set up, we may allocate the
command buffer. In the i915 case, this is also done with a
GEM function, i915_gem_init_ringbuffer().
</para>
<sect2>
<title>Output configuration</title>
<para>
- The final initialization task is output configuration. This involves
- finding and initializing the CRTCs, encoders and connectors
- for your device, creating an initial configuration and
- registering a framebuffer console driver.
+ The final initialization task is output configuration. This involves:
+ <itemizedlist>
+ <listitem>
+ Finding and initializing the CRTCs, encoders, and connectors
+ for the device.
+ </listitem>
+ <listitem>
+ Creating an initial configuration.
+ </listitem>
+ <listitem>
+ Registering a framebuffer console driver.
+ </listitem>
+ </itemizedlist>
</para>
<sect3>
<title>Output discovery and initialization</title>
<para>
- Several core functions exist to create CRTCs, encoders and
- connectors, namely drm_crtc_init(), drm_connector_init() and
+ Several core functions exist to create CRTCs, encoders, and
+ connectors, namely: drm_crtc_init(), drm_connector_init(), and
drm_encoder_init(), along with several "helper" functions to
perform common tasks.
</para>
</programlisting>
<para>
In the example above (again, taken from the i915 driver), a
- CRT connector and encoder combination is created. A device
- specific i2c bus is also created, for fetching EDID data and
+ CRT connector and encoder combination is created. A device-specific
+ i2c bus is also created for fetching EDID data and
performing monitor detection. Once the process is complete,
- the new connector is registered with sysfs, to make its
+ the new connector is registered with sysfs to make its
properties available to applications.
</para>
<sect4>
Since many PC-class graphics devices have similar display output
designs, the DRM provides a set of helper functions to make
output management easier. The core helper routines handle
- encoder re-routing and disabling of unused functions following
- mode set. Using the helpers is optional, but recommended for
+ encoder re-routing and the disabling of unused functions following
+ mode setting. Using the helpers is optional, but recommended for
devices with PC-style architectures (i.e. a set of display planes
for feeding pixels to encoders which are in turn routed to
connectors). Devices with more complex requirements needing
- finer grained management can opt to use the core callbacks
+ finer grained management may opt to use the core callbacks
directly.
</para>
<para>
</para>
</sect4>
<para>
- For each encoder, CRTC and connector, several functions must
- be provided, depending on the object type. Encoder objects
- need to provide a DPMS (basically on/off) function, mode fixup
- (for converting requested modes into native hardware timings),
- and prepare, set and commit functions for use by the core DRM
- helper functions. Connector helpers need to provide mode fetch and
- validity functions as well as an encoder matching function for
- returning an ideal encoder for a given connector. The core
- connector functions include a DPMS callback, (deprecated)
- save/restore routines, detection, mode probing, property handling,
- and cleanup functions.
+ Each encoder object needs to provide:
+ <itemizedlist>
+ <listitem>
+ A DPMS (basically on/off) function.
+ </listitem>
+ <listitem>
+ A mode-fixup function (for converting requested modes into
+ native hardware timings).
+ </listitem>
+ <listitem>
+ Functions (prepare, set, and commit) for use by the core DRM
+ helper functions.
+ </listitem>
+ </itemizedlist>
+ Connector helpers need to provide functions (mode-fetch, validity,
+ and encoder-matching) for returning an ideal encoder for a given
+ connector. The core connector functions include a DPMS callback,
+ save/restore routines (deprecated), detection, mode probing,
+ property handling, and cleanup functions.
</para>
<!--!Edrivers/char/drm/drm_crtc.h-->
<!--!Edrivers/char/drm/drm_crtc.c-->
<title>VBlank event handling</title>
<para>
The DRM core exposes two vertical blank related ioctls:
- DRM_IOCTL_WAIT_VBLANK and DRM_IOCTL_MODESET_CTL.
+ <variablelist>
+ <varlistentry>
+ <term>DRM_IOCTL_WAIT_VBLANK</term>
+ <listitem>
+ <para>
+ This takes a struct drm_wait_vblank structure as its argument,
+ and it is used to block or request a signal when a specified
+ vblank event occurs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_IOCTL_MODESET_CTL</term>
+ <listitem>
+ <para>
+ This should be called by application level drivers before and
+ after mode setting, since on many devices the vertical blank
+ counter is reset at that time. Internally, the DRM snapshots
+ the last vblank count when the ioctl is called with the
+ _DRM_PRE_MODESET command, so that the counter won't go backwards
+ (which is dealt with when _DRM_POST_MODESET is used).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
<!--!Edrivers/char/drm/drm_irq.c-->
</para>
<para>
- DRM_IOCTL_WAIT_VBLANK takes a struct drm_wait_vblank structure
- as its argument, and is used to block or request a signal when a
- specified vblank event occurs.
- </para>
- <para>
- DRM_IOCTL_MODESET_CTL should be called by application level
- drivers before and after mode setting, since on many devices the
- vertical blank counter will be reset at that time. Internally,
- the DRM snapshots the last vblank count when the ioctl is called
- with the _DRM_PRE_MODESET command so that the counter won't go
- backwards (which is dealt with when _DRM_POST_MODESET is used).
- </para>
- <para>
To support the functions above, the DRM core provides several
helper functions for tracking vertical blank counters, and
requires drivers to provide several callbacks:
register. The enable and disable vblank callbacks should enable
and disable vertical blank interrupts, respectively. In the
absence of DRM clients waiting on vblank events, the core DRM
- code will use the disable_vblank() function to disable
- interrupts, which saves power. They'll be re-enabled again when
+ code uses the disable_vblank() function to disable
+ interrupts, which saves power. They are re-enabled again when
a client calls the vblank wait ioctl above.
</para>
<para>
- Devices that don't provide a count register can simply use an
+ A device that doesn't provide a count register may simply use an
internal atomic counter incremented on every vertical blank
- interrupt, and can make their enable and disable vblank
- functions into no-ops.
+ interrupt (and then treat the enable_vblank() and disable_vblank()
+ callbacks as no-ops).
</para>
</sect1>
<sect1>
<title>Memory management</title>
<para>
- The memory manager lies at the heart of many DRM operations, and
- is also required to support advanced client features like OpenGL
- pbuffers. The DRM currently contains two memory managers, TTM
+ The memory manager lies at the heart of many DRM operations; it
+ is required to support advanced client features like OpenGL
+ pbuffers. The DRM currently contains two memory managers: TTM
and GEM.
</para>
<para>
GEM-enabled drivers must provide gem_init_object() and
gem_free_object() callbacks to support the core memory
- allocation routines. They should also provide several driver
- specific ioctls to support command execution, pinning, buffer
+ allocation routines. They should also provide several driver-specific
+ ioctls to support command execution, pinning, buffer
read & write, mapping, and domain ownership transfers.
</para>
<para>
- On a fundamental level, GEM involves several operations: memory
- allocation and freeing, command execution, and aperture management
- at command execution time. Buffer object allocation is relatively
+ On a fundamental level, GEM involves several operations:
+ <itemizedlist>
+ <listitem>Memory allocation and freeing</listitem>
+ <listitem>Command execution</listitem>
+ <listitem>Aperture management at command execution time</listitem>
+ </itemizedlist>
+ Buffer object allocation is relatively
straightforward and largely provided by Linux's shmem layer, which
provides memory to back each object. When mapped into the GTT
or used in a command buffer, the backing pages for an object are
flushed to memory and marked write combined so as to be coherent
- with the GPU. Likewise, when the GPU finishes rendering to an object,
- if the CPU accesses it, it must be made coherent with the CPU's view
+ with the GPU. Likewise, if the CPU accesses an object after the GPU
+ has finished rendering to the object, then the object must be made
+ coherent with the CPU's view
of memory, usually involving GPU cache flushing of various kinds.
- This core CPU<->GPU coherency management is provided by the GEM
- set domain function, which evaluates an object's current domain and
+ This core CPU<->GPU coherency management is provided by a
+ device-specific ioctl, which evaluates an object's current domain and
performs any necessary flushing or synchronization to put the object
into the desired coherency domain (note that the object may be busy,
- i.e. an active render target; in that case the set domain function
- will block the client and wait for rendering to complete before
+ i.e. an active render target; in that case, setting the domain
+ blocks the client and waits for rendering to complete before
performing any necessary flushing operations).
</para>
<para>
Perhaps the most important GEM function is providing a command
execution interface to clients. Client programs construct command
- buffers containing references to previously allocated memory objects
- and submit them to GEM. At that point, GEM will take care to bind
+ buffers containing references to previously allocated memory objects,
+ and then submit them to GEM. At that point, GEM takes care to bind
all the objects into the GTT, execute the buffer, and provide
necessary synchronization between clients accessing the same buffers.
This often involves evicting some objects from the GTT and re-binding
others (a fairly expensive operation), and providing relocation
support which hides fixed GTT offsets from clients. Clients must
take care not to submit command buffers that reference more objects
- than can fit in the GTT or GEM will reject them and no rendering
+ than can fit in the GTT; otherwise, GEM will reject them and no rendering
will occur. Similarly, if several objects in the buffer require
fence registers to be allocated for correct rendering (e.g. 2D blits
on pre-965 chips), care must be taken not to require more fence
<title>Output management</title>
<para>
At the core of the DRM output management code is a set of
- structures representing CRTCs, encoders and connectors.
+ structures representing CRTCs, encoders, and connectors.
</para>
<para>
A CRTC is an abstraction representing a part of the chip that
<sect1>
<title>Framebuffer management</title>
<para>
- In order to set a mode on a given CRTC, encoder and connector
- configuration, clients need to provide a framebuffer object which
- will provide a source of pixels for the CRTC to deliver to the encoder(s)
- and ultimately the connector(s) in the configuration. A framebuffer
- is fundamentally a driver specific memory object, made into an opaque
- handle by the DRM addfb function. Once an fb has been created this
- way it can be passed to the KMS mode setting routines for use in
- a configuration.
+ Clients need to provide a framebuffer object which provides a source
+ of pixels for a CRTC to deliver to the encoder(s) and ultimately the
+ connector(s). A framebuffer is fundamentally a driver-specific memory
+ object, made into an opaque handle by the DRM's addfb() function.
+ Once a framebuffer has been created this way, it may be passed to the
+ KMS mode setting routines for use in a completed configuration.
</para>
</sect1>
<sect1>
<title>Command submission & fencing</title>
<para>
- This should cover a few device specific command submission
+ This should cover a few device-specific command submission
implementations.
</para>
</sect1>
<para>
The DRM core provides some suspend/resume code, but drivers
wanting full suspend/resume support should provide save() and
- restore() functions. These will be called at suspend,
+ restore() functions. These are called at suspend,
hibernate, or resume time, and should perform any state save or
restore required by your device across suspend or hibernate
states.
<para>
The DRM core exports several interfaces to applications,
generally intended to be used through corresponding libdrm
- wrapper functions. In addition, drivers export device specific
- interfaces for use by userspace drivers & device aware
+ wrapper functions. In addition, drivers export device-specific
+ interfaces for use by userspace drivers & device-aware
applications through ioctls and sysfs files.
</para>
<para>
management, memory management, and output management.
</para>
<para>
- Cover generic ioctls and sysfs layout here. Only need high
- level info, since man pages will cover the rest.
+ Cover generic ioctls and sysfs layout here. We only need high-level
+ info, since man pages should cover the rest.
</para>
</chapter>
From a second, unrelated bash shell:
$ kill -SIGSTOP 16690
- $ kill -SIGCONT 16990
+ $ kill -SIGCONT 16690
- <at this point 16990 exits and causes 16644 to exit too>
+ <at this point 16690 exits and causes 16644 to exit too>
This happens because bash can observe both signals and choose how it
responds to them.
targets += missing-syscalls
quiet_cmd_syscalls = CALL $<
- cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags)
+ cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) $(missing_syscalls_flags)
missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE
$(call cmd,syscalls)
ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
M: Kamil Debski <k.debski@samsung.com>
+M: Jeongtae Park <jtp.park@samsung.com>
L: linux-arm-kernel@lists.infradead.org
L: linux-media@vger.kernel.org
S: Maintained
M: Paul Menage <paul@paulmenage.org>
M: Li Zefan <lizf@cn.fujitsu.com>
L: containers@lists.linux-foundation.org
+L: cgroups@vger.kernel.org
S: Maintained
F: include/linux/cgroup*
F: kernel/cgroup*
F: drivers/gpu/drm/i915
F: include/drm/i915*
+DRM DRIVERS FOR EXYNOS
+M: Inki Dae <inki.dae@samsung.com>
+L: dri-devel@lists.freedesktop.org
+S: Supported
+F: drivers/gpu/drm/exynos
+F: include/drm/exynos*
+
DSCC4 DRIVER
M: Francois Romieu <romieu@fr.zoreil.com>
L: netdev@vger.kernel.org
M: Balbir Singh <bsingharora@gmail.com>
M: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+L: cgroups@vger.kernel.org
L: linux-mm@kvack.org
S: Maintained
F: mm/memcontrol.c
M: Ralf Baechle <ralf@linux-mips.org>
L: linux-mips@linux-mips.org
W: http://www.linux-mips.org/
-T: git git://git.linux-mips.org/pub/scm/linux.git
+T: git git://git.linux-mips.org/pub/scm/ralf/linux.git
Q: http://patchwork.linux-mips.org/project/linux-mips/list/
S: Supported
F: Documentation/mips/
VERSION = 3
PATCHLEVEL = 2
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
sdhci@c8000400 {
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
- power-gpios = <&gpio 155 0>; /* gpio PT3 */
+ power-gpios = <&gpio 70 0>; /* gpio PI6 */
};
sdhci@c8000600 {
- power-gpios = <&gpio 70 0>; /* gpio PI6 */
support-8bit;
};
};
* USB HS Device (Gadget)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
static struct resource usba_udc_resources[] = {
[0] = {
#if defined(CONFIG_SERIAL_ATMEL)
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
#if defined(CONFIG_SERIAL_ATMEL)
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
#if defined(CONFIG_SERIAL_ATMEL)
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
#if defined(CONFIG_SERIAL_ATMEL)
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
* USB HS Device (Gadget)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
static struct resource usba_udc_resources[] = {
[0] = {
.start = AT91SAM9G45_UDPHS_FIFO,
#if defined(CONFIG_SERIAL_ATMEL)
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0,
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
* USB HS Device (Gadget)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
static struct resource usba_udc_resources[] = {
[0] = {
#if defined(CONFIG_SERIAL_ATMEL)
static struct resource dbgu_resources[] = {
[0] = {
- .start = AT91_VA_BASE_SYS + AT91_DBGU,
- .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .start = AT91_BASE_SYS + AT91_DBGU,
+ .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
- .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
#include <video/s1d13xxxfb.h>
-static void __init yl9200_init_video(void)
+static void yl9200_init_video(void)
{
/* NWAIT Signal */
at91_set_A_periph(AT91_PIN_PC6, 0);
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
+#include <mach/hardware.h>
+
#define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK)
#endif
-zreladdr-$(CONFIG_ARCH_MX1) += 0x08008000
-params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
-initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
+zreladdr-$(CONFIG_SOC_IMX1) += 0x08008000
+params_phys-$(CONFIG_SOC_IMX1) := 0x08000100
+initrd_phys-$(CONFIG_SOC_IMX1) := 0x08800000
-zreladdr-$(CONFIG_MACH_MX21) += 0xC0008000
-params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
-initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
+zreladdr-$(CONFIG_SOC_IMX21) += 0xC0008000
+params_phys-$(CONFIG_SOC_IMX21) := 0xC0000100
+initrd_phys-$(CONFIG_SOC_IMX21) := 0xC0800000
-zreladdr-$(CONFIG_ARCH_MX25) += 0x80008000
-params_phys-$(CONFIG_ARCH_MX25) := 0x80000100
-initrd_phys-$(CONFIG_ARCH_MX25) := 0x80800000
+zreladdr-$(CONFIG_SOC_IMX25) += 0x80008000
+params_phys-$(CONFIG_SOC_IMX25) := 0x80000100
+initrd_phys-$(CONFIG_SOC_IMX25) := 0x80800000
-zreladdr-$(CONFIG_MACH_MX27) += 0xA0008000
-params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
-initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
+zreladdr-$(CONFIG_SOC_IMX27) += 0xA0008000
+params_phys-$(CONFIG_SOC_IMX27) := 0xA0000100
+initrd_phys-$(CONFIG_SOC_IMX27) := 0xA0800000
-zreladdr-$(CONFIG_ARCH_MX3) += 0x80008000
-params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
-initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
+zreladdr-$(CONFIG_SOC_IMX31) += 0x80008000
+params_phys-$(CONFIG_SOC_IMX31) := 0x80000100
+initrd_phys-$(CONFIG_SOC_IMX31) := 0x80800000
+
+zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000
+params_phys-$(CONFIG_SOC_IMX35) := 0x80000100
+initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000
zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
return -EINVAL;
max_div = ((d->bm_pred >> d->bp_pred) + 1) *
- ((d->bm_pred >> d->bp_pred) + 1);
+ ((d->bm_podf >> d->bp_podf) + 1);
div = parent_rate / rate;
if (div == 0)
clk_set_rate(&asrc_serial_clk, 1500000);
clk_set_rate(&enfc_clk, 11000000);
+ /*
+ * Before pinctrl API is available, we have to rely on the pad
+ * configuration set up by bootloader. For usdhc example here,
+ * u-boot sets up the pads for 49.5 MHz case, and we have to lower
+ * the usdhc clock from 198 to 49.5 MHz to match the pad configuration.
+ *
+ * FIXME: This is should be removed after pinctrl API is available.
+ * At that time, usdhc driver can call pinctrl API to change pad
+ * configuration dynamically per different usdhc clock settings.
+ */
+ clk_set_rate(&usdhc1_clk, 49500000);
+ clk_set_rate(&usdhc2_clk, 49500000);
+ clk_set_rate(&usdhc3_clk, 49500000);
+ clk_set_rate(&usdhc4_clk, 49500000);
+
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
base = of_iomap(np, 0);
WARN_ON(!base);
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
extern struct sys_timer msm_timer;
-static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag,
- char **cmdline, struct meminfo *mi)
+static void __init msm7x30_fixup(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) {
#include "devices.h"
-static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag,
- char **cmdline, struct meminfo *mi)
+static void __init msm8960_fixup(struct tag *tag, char **cmdline,
+ struct meminfo *mi)
{
for (; tag->hdr.size; tag = tag_next(tag))
if (tag->hdr.tag == ATAG_MEM &&
#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)
+static void __init msm8x60_fixup(struct tag *tag, char **cmdline,
+ struct meminfo *mi)
{
for (; tag->hdr.size; tag = tag_next(tag))
if (tag->hdr.tag == ATAG_MEM &&
__asmeq("%1", "r0")
__asmeq("%2", "r1")
__asmeq("%3", "r2")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
"smc #0 @ switch to secure world\n"
: "=r" (r0)
: "r" (r0), "r" (r1), "r" (r2)
NULL, NULL, &ipg_clk, &gpt_ipg_clk);
DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
+ NULL, NULL, &ipg_perclk, NULL);
DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
+ NULL, NULL, &ipg_perclk, NULL);
/* I2C */
DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
return 0;
}
+#ifdef CONFIG_OF
static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
unsigned long *ckih1, unsigned long *ckih2)
{
clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
return mx53_clocks_init(ckil, osc, ckih1, ckih2);
}
+#endif
"mmc0-slot-power");
if (ret)
pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
- mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+ else
+ mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW,
"mmc1-slot-power");
else
mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
- mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
mx28_add_rtc_stmp3xxx();
gpio_led_register_device(0, &mx28evk_led_data);
#define UART_SHIFT 2
- .macro addruart, rp, rv
+ .macro addruart, rp, rv, tmp
ldr \rv, =PHYS_TO_IO(PICOXCELL_UART1_BASE)
ldr \rp, =PICOXCELL_UART1_BASE
.endm
#
# Common objects
-obj-y := timer.o console.o clock.o pm_runtime.o
+obj-y := timer.o console.o clock.o
# CPU objects
obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
/* enable MMCIF */
gpio_request(GPIO_FN_MMCCLK0, NULL);
gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_0, NULL);
- gpio_request(GPIO_FN_MMCD0_1, NULL);
- gpio_request(GPIO_FN_MMCD0_2, NULL);
- gpio_request(GPIO_FN_MMCD0_3, NULL);
- gpio_request(GPIO_FN_MMCD0_4, NULL);
- gpio_request(GPIO_FN_MMCD0_5, NULL);
- gpio_request(GPIO_FN_MMCD0_6, NULL);
- gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
gpio_request(GPIO_PORT208, NULL); /* Reset */
gpio_direction_output(GPIO_PORT208, 1);
static struct resource nor_flash_resources[] = {
[0] = {
.start = 0x20000000, /* CS0 shadow instead of regular CS0 */
- .end = 0x28000000 - 1, /* needed by USB MASK ROM boot */
+ .end = 0x28000000 - 1, /* needed by USB MASK ROM boot */
.flags = IORESOURCE_MEM,
}
};
#include <asm/hardware/cache-l2x0.h>
#include <asm/traps.h>
+/* SMSC 9220 */
static struct resource smsc9220_resources[] = {
[0] = {
.start = 0x14000000, /* CS5A */
.num_resources = ARRAY_SIZE(smsc9220_resources),
};
+/* KEYSC */
static struct sh_keysc_info keysc_platdata = {
.mode = SH_KEYSC_MODE_6,
.scan_timing = 3,
},
};
+/* GPIO KEY */
#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
static struct gpio_keys_button gpio_buttons[] = {
},
};
+/* GPIO LED */
#define GPIO_LED(n, g) { .name = n, .gpio = g }
static struct gpio_led gpio_leds[] = {
},
};
+/* MMCIF */
static struct resource mmcif_resources[] = {
[0] = {
.name = "MMCIF",
.resource = mmcif_resources,
};
+/* SDHI0 */
static struct sh_mobile_sdhi_info sdhi0_info = {
.tmio_caps = MMC_CAP_SD_HIGHSPEED,
.tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
},
};
+/* SDHI1 */
static struct sh_mobile_sdhi_info sdhi1_info = {
.tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
.tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
.disable = fsidiv_disable,
};
-static struct clk_mapping sh7372_fsidiva_clk_mapping = {
+static struct clk_mapping fsidiva_clk_mapping = {
.phys = FSIDIVA,
.len = 8,
};
struct clk sh7372_fsidiva_clk = {
.ops = &fsidiv_clk_ops,
.parent = &div6_reparent_clks[DIV6_FSIA], /* late install */
- .mapping = &sh7372_fsidiva_clk_mapping,
+ .mapping = &fsidiva_clk_mapping,
};
-static struct clk_mapping sh7372_fsidivb_clk_mapping = {
+static struct clk_mapping fsidivb_clk_mapping = {
.phys = FSIDIVB,
.len = 8,
};
struct clk sh7372_fsidivb_clk = {
.ops = &fsidiv_clk_ops,
.parent = &div6_reparent_clks[DIV6_FSIB], /* late install */
- .mapping = &sh7372_fsidivb_clk_mapping,
+ .mapping = &fsidivb_clk_mapping,
};
static struct clk *late_main_clks[] = {
};
static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
- struct cpuidle_state *state)
+ struct cpuidle_driver *drv,
+ int index)
{
ktime_t before, after;
- int requested_state = state - &dev->states[0];
- dev->last_state = &dev->states[requested_state];
before = ktime_get();
local_irq_disable();
local_fiq_disable();
- shmobile_cpuidle_modes[requested_state]();
+ shmobile_cpuidle_modes[index]();
local_irq_enable();
local_fiq_enable();
after = ktime_get();
- return ktime_to_ns(ktime_sub(after, before)) >> 10;
+ dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10;
+
+ return index;
}
static struct cpuidle_device shmobile_cpuidle_dev;
static struct cpuidle_driver shmobile_cpuidle_driver = {
.name = "shmobile_cpuidle",
.owner = THIS_MODULE,
+ .states[0] = {
+ .name = "C1",
+ .desc = "WFI",
+ .exit_latency = 1,
+ .target_residency = 1 * 2,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ },
+ .safe_state_index = 0, /* C1 */
+ .state_count = 1,
};
-void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
static int shmobile_cpuidle_init(void)
{
struct cpuidle_device *dev = &shmobile_cpuidle_dev;
- struct cpuidle_state *state;
+ struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
int i;
- cpuidle_register_driver(&shmobile_cpuidle_driver);
-
- for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
- dev->states[i].name[0] = '\0';
- dev->states[i].desc[0] = '\0';
- dev->states[i].enter = shmobile_cpuidle_enter;
- }
-
- i = CPUIDLE_DRIVER_STATE_START;
-
- state = &dev->states[i++];
- snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
- strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
- state->exit_latency = 1;
- state->target_residency = 1 * 2;
- state->power_usage = 3;
- state->flags = 0;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
-
- dev->safe_state = state;
- dev->state_count = i;
+ for (i = 0; i < CPUIDLE_STATE_MAX; i++)
+ drv->states[i].enter = shmobile_cpuidle_enter;
if (shmobile_cpuidle_setup)
- shmobile_cpuidle_setup(dev);
+ shmobile_cpuidle_setup(drv);
+
+ cpuidle_register_driver(drv);
+ dev->state_count = drv->state_count;
cpuidle_register_device(dev);
return 0;
extern void shmobile_handle_irq_intc(struct pt_regs *);
extern void shmobile_handle_irq_gic(struct pt_regs *);
extern struct platform_suspend_ops shmobile_suspend_ops;
-struct cpuidle_device;
+struct cpuidle_driver;
extern void (*shmobile_cpuidle_modes[])(void);
-extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
extern void sh7367_init_irq(void);
extern void sh7367_add_early_devices(void);
GPIO_FN_SDHICMD2_PU,
GPIO_FN_MMCCMD0_PU,
GPIO_FN_MMCCMD1_PU,
+ GPIO_FN_MMCD0_0_PU,
+ GPIO_FN_MMCD0_1_PU,
+ GPIO_FN_MMCD0_2_PU,
+ GPIO_FN_MMCD0_3_PU,
+ GPIO_FN_MMCD0_4_PU,
+ GPIO_FN_MMCD0_5_PU,
+ GPIO_FN_MMCD0_6_PU,
+ GPIO_FN_MMCD0_7_PU,
GPIO_FN_FSIACK_PU,
GPIO_FN_FSIAILR_PU,
GPIO_FN_FSIAIBT_PU,
#include <linux/gpio.h>
#include <mach/sh7367.h>
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx) \
- _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
- _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
- _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
- _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
- _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _90(fn, pfx, sfx) \
- _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
- _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
- _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
- _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx), \
- _10(fn, pfx##9, sfx)
-
-#define _273(fn, pfx, sfx) \
- _10(fn, pfx, sfx), _90(fn, pfx, sfx), \
- _10(fn, pfx##10, sfx), _90(fn, pfx##1, sfx), \
- _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
- _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
- _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
- _10(fn, pfx##26, sfx), _1(fn, pfx##270, sfx), \
- _1(fn, pfx##271, sfx), _1(fn, pfx##272, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_273(str) _273(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \
+ PORT_10(fn, pfx##10, sfx), PORT_90(fn, pfx##1, sfx), \
+ PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx), \
+ PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx), \
+ PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx), \
+ PORT_10(fn, pfx##26, sfx), PORT_1(fn, pfx##270, sfx), \
+ PORT_1(fn, pfx##271, sfx), PORT_1(fn, pfx##272, sfx)
enum {
PINMUX_RESERVED = 0,
PINMUX_DATA_BEGIN,
- PORT_273(DATA), /* PORT0_DATA -> PORT272_DATA */
+ PORT_ALL(DATA), /* PORT0_DATA -> PORT272_DATA */
PINMUX_DATA_END,
PINMUX_INPUT_BEGIN,
- PORT_273(IN), /* PORT0_IN -> PORT272_IN */
+ PORT_ALL(IN), /* PORT0_IN -> PORT272_IN */
PINMUX_INPUT_END,
PINMUX_INPUT_PULLUP_BEGIN,
- PORT_273(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
+ PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
PINMUX_INPUT_PULLUP_END,
PINMUX_INPUT_PULLDOWN_BEGIN,
- PORT_273(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
+ PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
PINMUX_INPUT_PULLDOWN_END,
PINMUX_OUTPUT_BEGIN,
- PORT_273(OUT), /* PORT0_OUT -> PORT272_OUT */
+ PORT_ALL(OUT), /* PORT0_OUT -> PORT272_OUT */
PINMUX_OUTPUT_END,
PINMUX_FUNCTION_BEGIN,
- PORT_273(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
- PORT_273(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
- PORT_273(FN0), /* PORT0_FN0 -> PORT272_FN0 */
- PORT_273(FN1), /* PORT0_FN1 -> PORT272_FN1 */
- PORT_273(FN2), /* PORT0_FN2 -> PORT272_FN2 */
- PORT_273(FN3), /* PORT0_FN3 -> PORT272_FN3 */
- PORT_273(FN4), /* PORT0_FN4 -> PORT272_FN4 */
- PORT_273(FN5), /* PORT0_FN5 -> PORT272_FN5 */
- PORT_273(FN6), /* PORT0_FN6 -> PORT272_FN6 */
- PORT_273(FN7), /* PORT0_FN7 -> PORT272_FN7 */
+ PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
+ PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
+ PORT_ALL(FN0), /* PORT0_FN0 -> PORT272_FN0 */
+ PORT_ALL(FN1), /* PORT0_FN1 -> PORT272_FN1 */
+ PORT_ALL(FN2), /* PORT0_FN2 -> PORT272_FN2 */
+ PORT_ALL(FN3), /* PORT0_FN3 -> PORT272_FN3 */
+ PORT_ALL(FN4), /* PORT0_FN4 -> PORT272_FN4 */
+ PORT_ALL(FN5), /* PORT0_FN5 -> PORT272_FN5 */
+ PORT_ALL(FN6), /* PORT0_FN6 -> PORT272_FN6 */
+ PORT_ALL(FN7), /* PORT0_FN7 -> PORT272_FN7 */
MSELBCR_MSEL2_1, MSELBCR_MSEL2_0,
PINMUX_FUNCTION_END,
PINMUX_MARK_END,
};
-#define PORT_DATA_I(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
-
-#define PORT_DATA_I_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_I_PU(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_I_PU_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-#define PORT_DATA_O(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
-
-#define PORT_DATA_IO(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN)
-
-#define PORT_DATA_IO_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_IO_PU(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_IO_PU_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-
static pinmux_enum_t pinmux_data[] = {
/* specify valid pin states for each pin in GPIO mode */
PINMUX_DATA(DIVLOCK_MARK, PORT272_FN1),
};
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_273() _273(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
static struct pinmux_gpio pinmux_gpios[] = {
/* 49-1 -> 49-6 (GPIO) */
- GPIO_PORT_273(),
+ GPIO_PORT_ALL(),
/* Special Pull-up / Pull-down Functions */
GPIO_FN(PORT48_KEYIN0_PU), GPIO_FN(PORT49_KEYIN1_PU),
GPIO_FN(DIVLOCK),
};
-/* helper for top 4 bits in PORTnCR */
-#define PCRH(in, in_pd, in_pu, out) \
- 0, (out), (in), 0, \
- 0, 0, 0, 0, \
- 0, 0, (in_pd), 0, \
- 0, 0, (in_pu), 0
-
-#define PORTCR(nr, reg) \
- { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
- PORT##nr##_IN_PU, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
- PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
-
static struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
#include <linux/gpio.h>
#include <mach/sh7372.h>
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx) \
- _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
- _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
- _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
- _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
- _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _80(fn, pfx, sfx) \
- _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
- _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
- _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
- _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx)
-
-#define _190(fn, pfx, sfx) \
- _10(fn, pfx, sfx), _80(fn, pfx, sfx), _10(fn, pfx##9, sfx), \
- _10(fn, pfx##10, sfx), _80(fn, pfx##1, sfx), _1(fn, pfx##190, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_ALL(str) _190(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \
+ PORT_10(fn, pfx##10, sfx), PORT_10(fn, pfx##11, sfx), \
+ PORT_10(fn, pfx##12, sfx), PORT_10(fn, pfx##13, sfx), \
+ PORT_10(fn, pfx##14, sfx), PORT_10(fn, pfx##15, sfx), \
+ PORT_10(fn, pfx##16, sfx), PORT_10(fn, pfx##17, sfx), \
+ PORT_10(fn, pfx##18, sfx), PORT_1(fn, pfx##190, sfx)
enum {
PINMUX_RESERVED = 0,
PINMUX_MARK_END,
};
-/* PORT_DATA_I_PD(nr) */
-#define _I___D(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD)
-
-/* PORT_DATA_I_PU(nr) */
-#define _I__U_(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PU)
-
-/* PORT_DATA_I_PU_PD(nr) */
-#define _I__UD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-/* PORT_DATA_O(nr) */
-#define __O___(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
-
-/* PORT_DATA_IO(nr) */
-#define _IO___(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN)
-
-/* PORT_DATA_IO_PD(nr) */
-#define _IO__D(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN, PORT##nr##_IN_PD)
-
-/* PORT_DATA_IO_PU(nr) */
-#define _IO_U_(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN, PORT##nr##_IN_PU)
-
-/* PORT_DATA_IO_PU_PD(nr) */
-#define _IO_UD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
- PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-
static pinmux_enum_t pinmux_data[] = {
/* specify valid pin states for each pin in GPIO mode */
-
- _IO__D(0), _IO__D(1), __O___(2), _I___D(3), _I___D(4),
- _I___D(5), _IO_UD(6), _I___D(7), _IO__D(8), __O___(9),
-
- __O___(10), __O___(11), _IO_UD(12), _IO__D(13), _IO__D(14),
- __O___(15), _IO__D(16), _IO__D(17), _I___D(18), _IO___(19),
-
- _IO___(20), _IO___(21), _IO___(22), _IO___(23), _IO___(24),
- _IO___(25), _IO___(26), _IO___(27), _IO___(28), _IO___(29),
-
- _IO___(30), _IO___(31), _IO___(32), _IO___(33), _IO___(34),
- _IO___(35), _IO___(36), _IO___(37), _IO___(38), _IO___(39),
-
- _IO___(40), _IO___(41), _IO___(42), _IO___(43), _IO___(44),
- _IO___(45), _IO_U_(46), _IO_U_(47), _IO_U_(48), _IO_U_(49),
-
- _IO_U_(50), _IO_U_(51), _IO_U_(52), _IO_U_(53), _IO_U_(54),
- _IO_U_(55), _IO_U_(56), _IO_U_(57), _IO_U_(58), _IO_U_(59),
-
- _IO_U_(60), _IO_U_(61), _IO___(62), __O___(63), __O___(64),
- _IO_U_(65), __O___(66), _IO_U_(67), __O___(68), _IO___(69), /*66?*/
-
- _IO___(70), _IO___(71), __O___(72), _I__U_(73), _I__UD(74),
- _IO_UD(75), _IO_UD(76), _IO_UD(77), _IO_UD(78), _IO_UD(79),
-
- _IO_UD(80), _IO_UD(81), _IO_UD(82), _IO_UD(83), _IO_UD(84),
- _IO_UD(85), _IO_UD(86), _IO_UD(87), _IO_UD(88), _IO_UD(89),
-
- _IO_UD(90), _IO_UD(91), _IO_UD(92), _IO_UD(93), _IO_UD(94),
- _IO_UD(95), _IO_U_(96), _IO_UD(97), _IO_UD(98), __O___(99), /*99?*/
-
- _IO__D(100), _IO__D(101), _IO__D(102), _IO__D(103), _IO__D(104),
- _IO__D(105), _IO_U_(106), _IO_U_(107), _IO_U_(108), _IO_U_(109),
-
- _IO_U_(110), _IO_U_(111), _IO__D(112), _IO__D(113), _IO_U_(114),
- _IO_U_(115), _IO_U_(116), _IO_U_(117), _IO_U_(118), _IO_U_(119),
-
- _IO_U_(120), _IO__D(121), _IO__D(122), _IO__D(123), _IO__D(124),
- _IO__D(125), _IO__D(126), _IO__D(127), _IO__D(128), _IO_UD(129),
-
- _IO_UD(130), _IO_UD(131), _IO_UD(132), _IO_UD(133), _IO_UD(134),
- _IO_UD(135), _IO__D(136), _IO__D(137), _IO__D(138), _IO__D(139),
-
- _IO__D(140), _IO__D(141), _IO__D(142), _IO_UD(143), _IO__D(144),
- _IO__D(145), _IO__D(146), _IO__D(147), _IO__D(148), _IO__D(149),
-
- _IO__D(150), _IO__D(151), _IO_UD(152), _I___D(153), _IO_UD(154),
- _I___D(155), _IO__D(156), _IO__D(157), _I___D(158), _IO__D(159),
-
- __O___(160), _IO__D(161), _IO__D(162), _IO__D(163), _I___D(164),
- _IO__D(165), _I___D(166), _I___D(167), _I___D(168), _I___D(169),
-
- _I___D(170), __O___(171), _IO_UD(172), _IO_UD(173), _IO_UD(174),
- _IO_UD(175), _IO_UD(176), _IO_UD(177), _IO_UD(178), __O___(179),
-
- _IO_UD(180), _IO_UD(181), _IO_UD(182), _IO_UD(183), _IO_UD(184),
- __O___(185), _IO_UD(186), _IO_UD(187), _IO_UD(188), _IO_UD(189),
-
- _IO_UD(190),
+ PORT_DATA_IO_PD(0), PORT_DATA_IO_PD(1),
+ PORT_DATA_O(2), PORT_DATA_I_PD(3),
+ PORT_DATA_I_PD(4), PORT_DATA_I_PD(5),
+ PORT_DATA_IO_PU_PD(6), PORT_DATA_I_PD(7),
+ PORT_DATA_IO_PD(8), PORT_DATA_O(9),
+
+ PORT_DATA_O(10), PORT_DATA_O(11),
+ PORT_DATA_IO_PU_PD(12), PORT_DATA_IO_PD(13),
+ PORT_DATA_IO_PD(14), PORT_DATA_O(15),
+ PORT_DATA_IO_PD(16), PORT_DATA_IO_PD(17),
+ PORT_DATA_I_PD(18), PORT_DATA_IO(19),
+
+ PORT_DATA_IO(20), PORT_DATA_IO(21),
+ PORT_DATA_IO(22), PORT_DATA_IO(23),
+ PORT_DATA_IO(24), PORT_DATA_IO(25),
+ PORT_DATA_IO(26), PORT_DATA_IO(27),
+ PORT_DATA_IO(28), PORT_DATA_IO(29),
+
+ PORT_DATA_IO(30), PORT_DATA_IO(31),
+ PORT_DATA_IO(32), PORT_DATA_IO(33),
+ PORT_DATA_IO(34), PORT_DATA_IO(35),
+ PORT_DATA_IO(36), PORT_DATA_IO(37),
+ PORT_DATA_IO(38), PORT_DATA_IO(39),
+
+ PORT_DATA_IO(40), PORT_DATA_IO(41),
+ PORT_DATA_IO(42), PORT_DATA_IO(43),
+ PORT_DATA_IO(44), PORT_DATA_IO(45),
+ PORT_DATA_IO_PU(46), PORT_DATA_IO_PU(47),
+ PORT_DATA_IO_PU(48), PORT_DATA_IO_PU(49),
+
+ PORT_DATA_IO_PU(50), PORT_DATA_IO_PU(51),
+ PORT_DATA_IO_PU(52), PORT_DATA_IO_PU(53),
+ PORT_DATA_IO_PU(54), PORT_DATA_IO_PU(55),
+ PORT_DATA_IO_PU(56), PORT_DATA_IO_PU(57),
+ PORT_DATA_IO_PU(58), PORT_DATA_IO_PU(59),
+
+ PORT_DATA_IO_PU(60), PORT_DATA_IO_PU(61),
+ PORT_DATA_IO(62), PORT_DATA_O(63),
+ PORT_DATA_O(64), PORT_DATA_IO_PU(65),
+ PORT_DATA_O(66), PORT_DATA_IO_PU(67), /*66?*/
+ PORT_DATA_O(68), PORT_DATA_IO(69),
+
+ PORT_DATA_IO(70), PORT_DATA_IO(71),
+ PORT_DATA_O(72), PORT_DATA_I_PU(73),
+ PORT_DATA_I_PU_PD(74), PORT_DATA_IO_PU_PD(75),
+ PORT_DATA_IO_PU_PD(76), PORT_DATA_IO_PU_PD(77),
+ PORT_DATA_IO_PU_PD(78), PORT_DATA_IO_PU_PD(79),
+
+ PORT_DATA_IO_PU_PD(80), PORT_DATA_IO_PU_PD(81),
+ PORT_DATA_IO_PU_PD(82), PORT_DATA_IO_PU_PD(83),
+ PORT_DATA_IO_PU_PD(84), PORT_DATA_IO_PU_PD(85),
+ PORT_DATA_IO_PU_PD(86), PORT_DATA_IO_PU_PD(87),
+ PORT_DATA_IO_PU_PD(88), PORT_DATA_IO_PU_PD(89),
+
+ PORT_DATA_IO_PU_PD(90), PORT_DATA_IO_PU_PD(91),
+ PORT_DATA_IO_PU_PD(92), PORT_DATA_IO_PU_PD(93),
+ PORT_DATA_IO_PU_PD(94), PORT_DATA_IO_PU_PD(95),
+ PORT_DATA_IO_PU(96), PORT_DATA_IO_PU_PD(97),
+ PORT_DATA_IO_PU_PD(98), PORT_DATA_O(99), /*99?*/
+
+ PORT_DATA_IO_PD(100), PORT_DATA_IO_PD(101),
+ PORT_DATA_IO_PD(102), PORT_DATA_IO_PD(103),
+ PORT_DATA_IO_PD(104), PORT_DATA_IO_PD(105),
+ PORT_DATA_IO_PU(106), PORT_DATA_IO_PU(107),
+ PORT_DATA_IO_PU(108), PORT_DATA_IO_PU(109),
+
+ PORT_DATA_IO_PU(110), PORT_DATA_IO_PU(111),
+ PORT_DATA_IO_PD(112), PORT_DATA_IO_PD(113),
+ PORT_DATA_IO_PU(114), PORT_DATA_IO_PU(115),
+ PORT_DATA_IO_PU(116), PORT_DATA_IO_PU(117),
+ PORT_DATA_IO_PU(118), PORT_DATA_IO_PU(119),
+
+ PORT_DATA_IO_PU(120), PORT_DATA_IO_PD(121),
+ PORT_DATA_IO_PD(122), PORT_DATA_IO_PD(123),
+ PORT_DATA_IO_PD(124), PORT_DATA_IO_PD(125),
+ PORT_DATA_IO_PD(126), PORT_DATA_IO_PD(127),
+ PORT_DATA_IO_PD(128), PORT_DATA_IO_PU_PD(129),
+
+ PORT_DATA_IO_PU_PD(130), PORT_DATA_IO_PU_PD(131),
+ PORT_DATA_IO_PU_PD(132), PORT_DATA_IO_PU_PD(133),
+ PORT_DATA_IO_PU_PD(134), PORT_DATA_IO_PU_PD(135),
+ PORT_DATA_IO_PD(136), PORT_DATA_IO_PD(137),
+ PORT_DATA_IO_PD(138), PORT_DATA_IO_PD(139),
+
+ PORT_DATA_IO_PD(140), PORT_DATA_IO_PD(141),
+ PORT_DATA_IO_PD(142), PORT_DATA_IO_PU_PD(143),
+ PORT_DATA_IO_PD(144), PORT_DATA_IO_PD(145),
+ PORT_DATA_IO_PD(146), PORT_DATA_IO_PD(147),
+ PORT_DATA_IO_PD(148), PORT_DATA_IO_PD(149),
+
+ PORT_DATA_IO_PD(150), PORT_DATA_IO_PD(151),
+ PORT_DATA_IO_PU_PD(152), PORT_DATA_I_PD(153),
+ PORT_DATA_IO_PU_PD(154), PORT_DATA_I_PD(155),
+ PORT_DATA_IO_PD(156), PORT_DATA_IO_PD(157),
+ PORT_DATA_I_PD(158), PORT_DATA_IO_PD(159),
+
+ PORT_DATA_O(160), PORT_DATA_IO_PD(161),
+ PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163),
+ PORT_DATA_I_PD(164), PORT_DATA_IO_PD(165),
+ PORT_DATA_I_PD(166), PORT_DATA_I_PD(167),
+ PORT_DATA_I_PD(168), PORT_DATA_I_PD(169),
+
+ PORT_DATA_I_PD(170), PORT_DATA_O(171),
+ PORT_DATA_IO_PU_PD(172), PORT_DATA_IO_PU_PD(173),
+ PORT_DATA_IO_PU_PD(174), PORT_DATA_IO_PU_PD(175),
+ PORT_DATA_IO_PU_PD(176), PORT_DATA_IO_PU_PD(177),
+ PORT_DATA_IO_PU_PD(178), PORT_DATA_O(179),
+
+ PORT_DATA_IO_PU_PD(180), PORT_DATA_IO_PU_PD(181),
+ PORT_DATA_IO_PU_PD(182), PORT_DATA_IO_PU_PD(183),
+ PORT_DATA_IO_PU_PD(184), PORT_DATA_O(185),
+ PORT_DATA_IO_PU_PD(186), PORT_DATA_IO_PU_PD(187),
+ PORT_DATA_IO_PU_PD(188), PORT_DATA_IO_PU_PD(189),
+
+ PORT_DATA_IO_PU_PD(190),
/* IRQ */
PINMUX_DATA(IRQ0_6_MARK, PORT6_FN0, MSEL1CR_0_0),
PINMUX_DATA(MFIv4_MARK, MSEL4CR_6_1),
};
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_ALL() _190(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
static struct pinmux_gpio pinmux_gpios[] = {
/* PORT */
GPIO_FN(SDENC_DV_CLKI),
};
-/* helper for top 4 bits in PORTnCR */
-#define PCRH(in, in_pd, in_pu, out) \
- 0, (out), (in), 0, \
- 0, 0, 0, 0, \
- 0, 0, (in_pd), 0, \
- 0, 0, (in_pu), 0
-
-#define PORTCR(nr, reg) \
- { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
- PORT##nr##_IN_PU, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
- PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
-
static struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xE6051000), /* PORT0CR */
PORTCR(1, 0xE6051001), /* PORT1CR */
#include <linux/gpio.h>
#include <mach/sh7377.h>
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx) \
- _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
- _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
- _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
- _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
- _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _90(fn, pfx, sfx) \
- _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
- _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
- _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
- _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx), \
- _10(fn, pfx##9, sfx)
-
-#define _265(fn, pfx, sfx) \
- _10(fn, pfx, sfx), _90(fn, pfx, sfx), \
- _10(fn, pfx##10, sfx), \
- _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx), \
- _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx), \
- _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx), \
- _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx), \
- _1(fn, pfx##118, sfx), \
- _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx), \
- _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx), \
- _10(fn, pfx##15, sfx), \
- _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx), \
- _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx), \
- _1(fn, pfx##164, sfx), \
- _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx), \
- _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx), \
- _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx), \
- _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx), \
- _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
- _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
- _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
- _1(fn, pfx##260, sfx), _1(fn, pfx##261, sfx), \
- _1(fn, pfx##262, sfx), _1(fn, pfx##263, sfx), \
- _1(fn, pfx##264, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_265(str) _265(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \
+ PORT_10(fn, pfx##10, sfx), \
+ PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx), \
+ PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx), \
+ PORT_1(fn, pfx##114, sfx), PORT_1(fn, pfx##115, sfx), \
+ PORT_1(fn, pfx##116, sfx), PORT_1(fn, pfx##117, sfx), \
+ PORT_1(fn, pfx##118, sfx), \
+ PORT_1(fn, pfx##128, sfx), PORT_1(fn, pfx##129, sfx), \
+ PORT_10(fn, pfx##13, sfx), PORT_10(fn, pfx##14, sfx), \
+ PORT_10(fn, pfx##15, sfx), \
+ PORT_1(fn, pfx##160, sfx), PORT_1(fn, pfx##161, sfx), \
+ PORT_1(fn, pfx##162, sfx), PORT_1(fn, pfx##163, sfx), \
+ PORT_1(fn, pfx##164, sfx), \
+ PORT_1(fn, pfx##192, sfx), PORT_1(fn, pfx##193, sfx), \
+ PORT_1(fn, pfx##194, sfx), PORT_1(fn, pfx##195, sfx), \
+ PORT_1(fn, pfx##196, sfx), PORT_1(fn, pfx##197, sfx), \
+ PORT_1(fn, pfx##198, sfx), PORT_1(fn, pfx##199, sfx), \
+ PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx), \
+ PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx), \
+ PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx), \
+ PORT_1(fn, pfx##260, sfx), PORT_1(fn, pfx##261, sfx), \
+ PORT_1(fn, pfx##262, sfx), PORT_1(fn, pfx##263, sfx), \
+ PORT_1(fn, pfx##264, sfx)
enum {
PINMUX_RESERVED = 0,
PINMUX_DATA_BEGIN,
- PORT_265(DATA), /* PORT0_DATA -> PORT264_DATA */
+ PORT_ALL(DATA), /* PORT0_DATA -> PORT264_DATA */
PINMUX_DATA_END,
PINMUX_INPUT_BEGIN,
- PORT_265(IN), /* PORT0_IN -> PORT264_IN */
+ PORT_ALL(IN), /* PORT0_IN -> PORT264_IN */
PINMUX_INPUT_END,
PINMUX_INPUT_PULLUP_BEGIN,
- PORT_265(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
+ PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
PINMUX_INPUT_PULLUP_END,
PINMUX_INPUT_PULLDOWN_BEGIN,
- PORT_265(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
+ PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
PINMUX_INPUT_PULLDOWN_END,
PINMUX_OUTPUT_BEGIN,
- PORT_265(OUT), /* PORT0_OUT -> PORT264_OUT */
+ PORT_ALL(OUT), /* PORT0_OUT -> PORT264_OUT */
PINMUX_OUTPUT_END,
PINMUX_FUNCTION_BEGIN,
- PORT_265(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
- PORT_265(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
- PORT_265(FN0), /* PORT0_FN0 -> PORT264_FN0 */
- PORT_265(FN1), /* PORT0_FN1 -> PORT264_FN1 */
- PORT_265(FN2), /* PORT0_FN2 -> PORT264_FN2 */
- PORT_265(FN3), /* PORT0_FN3 -> PORT264_FN3 */
- PORT_265(FN4), /* PORT0_FN4 -> PORT264_FN4 */
- PORT_265(FN5), /* PORT0_FN5 -> PORT264_FN5 */
- PORT_265(FN6), /* PORT0_FN6 -> PORT264_FN6 */
- PORT_265(FN7), /* PORT0_FN7 -> PORT264_FN7 */
+ PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
+ PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
+ PORT_ALL(FN0), /* PORT0_FN0 -> PORT264_FN0 */
+ PORT_ALL(FN1), /* PORT0_FN1 -> PORT264_FN1 */
+ PORT_ALL(FN2), /* PORT0_FN2 -> PORT264_FN2 */
+ PORT_ALL(FN3), /* PORT0_FN3 -> PORT264_FN3 */
+ PORT_ALL(FN4), /* PORT0_FN4 -> PORT264_FN4 */
+ PORT_ALL(FN5), /* PORT0_FN5 -> PORT264_FN5 */
+ PORT_ALL(FN6), /* PORT0_FN6 -> PORT264_FN6 */
+ PORT_ALL(FN7), /* PORT0_FN7 -> PORT264_FN7 */
MSELBCR_MSEL17_1, MSELBCR_MSEL17_0,
MSELBCR_MSEL16_1, MSELBCR_MSEL16_0,
PINMUX_MARK_END,
};
-#define PORT_DATA_I(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
-
-#define PORT_DATA_I_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_I_PU(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_I_PU_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD, \
- PORT##nr##_IN_PU)
-
-#define PORT_DATA_O(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT)
-
-#define PORT_DATA_IO(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN)
-
-#define PORT_DATA_IO_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN, \
- PORT##nr##_IN_PD)
-
-#define PORT_DATA_IO_PU(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN, \
- PORT##nr##_IN_PU)
-
-#define PORT_DATA_IO_PU_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN, \
- PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
static pinmux_enum_t pinmux_data[] = {
/* specify valid pin states for each pin in GPIO mode */
/* 55-1 (GPIO) */
PINMUX_DATA(RESETOUTS_MARK, PORT264_FN1),
};
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_265() _265(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
static struct pinmux_gpio pinmux_gpios[] = {
/* 55-1 -> 55-5 (GPIO) */
- GPIO_PORT_265(),
+ GPIO_PORT_ALL(),
/* Special Pull-up / Pull-down Functions */
GPIO_FN(PORT66_KEYIN0_PU), GPIO_FN(PORT67_KEYIN1_PU),
GPIO_FN(RESETOUTS),
};
-/* helper for top 4 bits in PORTnCR */
-#define PCRH(in, in_pd, in_pu, out) \
- 0, (out), (in), 0, \
- 0, 0, 0, 0, \
- 0, 0, (in_pd), 0, \
- 0, 0, (in_pu), 0
-
-#define PORTCR(nr, reg) \
- { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
- PORT##nr##_IN_PU, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, \
- PORT##nr##_FN2, PORT##nr##_FN3, \
- PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
-
static struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
#include <mach/sh73a0.h>
#include <mach/irqs.h>
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx) \
- _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
- _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
- _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
- _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
- _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _310(fn, pfx, sfx) \
- _10(fn, pfx, sfx), _10(fn, pfx##1, sfx), \
- _10(fn, pfx##2, sfx), _10(fn, pfx##3, sfx), \
- _10(fn, pfx##4, sfx), _10(fn, pfx##5, sfx), \
- _10(fn, pfx##6, sfx), _10(fn, pfx##7, sfx), \
- _10(fn, pfx##8, sfx), _10(fn, pfx##9, sfx), \
- _10(fn, pfx##10, sfx), \
- _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx), \
- _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx), \
- _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx), \
- _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx), \
- _1(fn, pfx##118, sfx), \
- _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx), \
- _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx), \
- _10(fn, pfx##15, sfx), \
- _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx), \
- _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx), \
- _1(fn, pfx##164, sfx), \
- _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx), \
- _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx), \
- _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx), \
- _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx), \
- _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
- _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
- _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
- _10(fn, pfx##26, sfx), _10(fn, pfx##27, sfx), \
- _1(fn, pfx##280, sfx), _1(fn, pfx##281, sfx), \
- _1(fn, pfx##282, sfx), \
- _1(fn, pfx##288, sfx), _1(fn, pfx##289, sfx), \
- _10(fn, pfx##29, sfx), _10(fn, pfx##30, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_310(str) _310(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \
+ PORT_10(fn, pfx##2, sfx), PORT_10(fn, pfx##3, sfx), \
+ PORT_10(fn, pfx##4, sfx), PORT_10(fn, pfx##5, sfx), \
+ PORT_10(fn, pfx##6, sfx), PORT_10(fn, pfx##7, sfx), \
+ PORT_10(fn, pfx##8, sfx), PORT_10(fn, pfx##9, sfx), \
+ PORT_10(fn, pfx##10, sfx), \
+ PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx), \
+ PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx), \
+ PORT_1(fn, pfx##114, sfx), PORT_1(fn, pfx##115, sfx), \
+ PORT_1(fn, pfx##116, sfx), PORT_1(fn, pfx##117, sfx), \
+ PORT_1(fn, pfx##118, sfx), \
+ PORT_1(fn, pfx##128, sfx), PORT_1(fn, pfx##129, sfx), \
+ PORT_10(fn, pfx##13, sfx), PORT_10(fn, pfx##14, sfx), \
+ PORT_10(fn, pfx##15, sfx), \
+ PORT_1(fn, pfx##160, sfx), PORT_1(fn, pfx##161, sfx), \
+ PORT_1(fn, pfx##162, sfx), PORT_1(fn, pfx##163, sfx), \
+ PORT_1(fn, pfx##164, sfx), \
+ PORT_1(fn, pfx##192, sfx), PORT_1(fn, pfx##193, sfx), \
+ PORT_1(fn, pfx##194, sfx), PORT_1(fn, pfx##195, sfx), \
+ PORT_1(fn, pfx##196, sfx), PORT_1(fn, pfx##197, sfx), \
+ PORT_1(fn, pfx##198, sfx), PORT_1(fn, pfx##199, sfx), \
+ PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx), \
+ PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx), \
+ PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx), \
+ PORT_10(fn, pfx##26, sfx), PORT_10(fn, pfx##27, sfx), \
+ PORT_1(fn, pfx##280, sfx), PORT_1(fn, pfx##281, sfx), \
+ PORT_1(fn, pfx##282, sfx), \
+ PORT_1(fn, pfx##288, sfx), PORT_1(fn, pfx##289, sfx), \
+ PORT_10(fn, pfx##29, sfx), PORT_10(fn, pfx##30, sfx)
enum {
PINMUX_RESERVED = 0,
PINMUX_DATA_BEGIN,
- PORT_310(DATA), /* PORT0_DATA -> PORT309_DATA */
+ PORT_ALL(DATA), /* PORT0_DATA -> PORT309_DATA */
PINMUX_DATA_END,
PINMUX_INPUT_BEGIN,
- PORT_310(IN), /* PORT0_IN -> PORT309_IN */
+ PORT_ALL(IN), /* PORT0_IN -> PORT309_IN */
PINMUX_INPUT_END,
PINMUX_INPUT_PULLUP_BEGIN,
- PORT_310(IN_PU), /* PORT0_IN_PU -> PORT309_IN_PU */
+ PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT309_IN_PU */
PINMUX_INPUT_PULLUP_END,
PINMUX_INPUT_PULLDOWN_BEGIN,
- PORT_310(IN_PD), /* PORT0_IN_PD -> PORT309_IN_PD */
+ PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT309_IN_PD */
PINMUX_INPUT_PULLDOWN_END,
PINMUX_OUTPUT_BEGIN,
- PORT_310(OUT), /* PORT0_OUT -> PORT309_OUT */
+ PORT_ALL(OUT), /* PORT0_OUT -> PORT309_OUT */
PINMUX_OUTPUT_END,
PINMUX_FUNCTION_BEGIN,
- PORT_310(FN_IN), /* PORT0_FN_IN -> PORT309_FN_IN */
- PORT_310(FN_OUT), /* PORT0_FN_OUT -> PORT309_FN_OUT */
- PORT_310(FN0), /* PORT0_FN0 -> PORT309_FN0 */
- PORT_310(FN1), /* PORT0_FN1 -> PORT309_FN1 */
- PORT_310(FN2), /* PORT0_FN2 -> PORT309_FN2 */
- PORT_310(FN3), /* PORT0_FN3 -> PORT309_FN3 */
- PORT_310(FN4), /* PORT0_FN4 -> PORT309_FN4 */
- PORT_310(FN5), /* PORT0_FN5 -> PORT309_FN5 */
- PORT_310(FN6), /* PORT0_FN6 -> PORT309_FN6 */
- PORT_310(FN7), /* PORT0_FN7 -> PORT309_FN7 */
+ PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT309_FN_IN */
+ PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT309_FN_OUT */
+ PORT_ALL(FN0), /* PORT0_FN0 -> PORT309_FN0 */
+ PORT_ALL(FN1), /* PORT0_FN1 -> PORT309_FN1 */
+ PORT_ALL(FN2), /* PORT0_FN2 -> PORT309_FN2 */
+ PORT_ALL(FN3), /* PORT0_FN3 -> PORT309_FN3 */
+ PORT_ALL(FN4), /* PORT0_FN4 -> PORT309_FN4 */
+ PORT_ALL(FN5), /* PORT0_FN5 -> PORT309_FN5 */
+ PORT_ALL(FN6), /* PORT0_FN6 -> PORT309_FN6 */
+ PORT_ALL(FN7), /* PORT0_FN7 -> PORT309_FN7 */
MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1,
MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1,
SDHICMD2_PU_MARK,
MMCCMD0_PU_MARK,
MMCCMD1_PU_MARK,
+ MMCD0_0_PU_MARK,
+ MMCD0_1_PU_MARK,
+ MMCD0_2_PU_MARK,
+ MMCD0_3_PU_MARK,
+ MMCD0_4_PU_MARK,
+ MMCD0_5_PU_MARK,
+ MMCD0_6_PU_MARK,
+ MMCD0_7_PU_MARK,
FSIBISLD_PU_MARK,
FSIACK_PU_MARK,
FSIAILR_PU_MARK,
PINMUX_MARK_END,
};
-#define PORT_DATA_I(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
-
-#define PORT_DATA_I_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_I_PU(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_I_PU_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_IN, PORT##nr##_IN_PD, \
- PORT##nr##_IN_PU)
-
-#define PORT_DATA_O(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT)
-
-#define PORT_DATA_IO(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN)
-
-#define PORT_DATA_IO_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN, \
- PORT##nr##_IN_PD)
-
-#define PORT_DATA_IO_PU(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN, \
- PORT##nr##_IN_PU)
-
-#define PORT_DATA_IO_PU_PD(nr) \
- PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
- PORT##nr##_OUT, PORT##nr##_IN, \
- PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
static pinmux_enum_t pinmux_data[] = {
/* specify valid pin states for each pin in GPIO mode */
MSEL4CR_MSEL15_0),
PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU,
MSEL4CR_MSEL15_1),
+
+ PINMUX_DATA(MMCD0_0_PU_MARK,
+ PORT271_FN1, PORT271_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_1_PU_MARK,
+ PORT272_FN1, PORT272_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_2_PU_MARK,
+ PORT273_FN1, PORT273_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_3_PU_MARK,
+ PORT274_FN1, PORT274_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_4_PU_MARK,
+ PORT275_FN1, PORT275_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_5_PU_MARK,
+ PORT276_FN1, PORT276_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_6_PU_MARK,
+ PORT277_FN1, PORT277_IN_PU, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_7_PU_MARK,
+ PORT278_FN1, PORT278_IN_PU, MSEL4CR_MSEL15_0),
+
PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU),
PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU),
};
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_310() _310(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
static struct pinmux_gpio pinmux_gpios[] = {
- GPIO_PORT_310(),
+ GPIO_PORT_ALL(),
/* Table 25-1 (Functions 0-7) */
GPIO_FN(VBUS_0),
GPIO_FN(SDHICMD2_PU),
GPIO_FN(MMCCMD0_PU),
GPIO_FN(MMCCMD1_PU),
+ GPIO_FN(MMCD0_0_PU),
+ GPIO_FN(MMCD0_1_PU),
+ GPIO_FN(MMCD0_2_PU),
+ GPIO_FN(MMCD0_3_PU),
+ GPIO_FN(MMCD0_4_PU),
+ GPIO_FN(MMCD0_5_PU),
+ GPIO_FN(MMCD0_6_PU),
+ GPIO_FN(MMCD0_7_PU),
GPIO_FN(FSIACK_PU),
GPIO_FN(FSIAILR_PU),
GPIO_FN(FSIAIBT_PU),
GPIO_FN(FSIAISLD_PU),
};
-#define PORTCR(nr, reg) \
- { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- 0, \
- /*0001*/ PORT##nr##_OUT , \
- /*0010*/ PORT##nr##_IN , 0, 0, 0, 0, 0, 0, 0, \
- /*1010*/ PORT##nr##_IN_PD, 0, 0, 0, \
- /*1110*/ PORT##nr##_IN_PU, 0, \
- PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
- PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7, 0, 0, 0, 0, 0, 0, 0, 0 } \
- }
-
static struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
#ifdef CONFIG_CPU_IDLE
-static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
+static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
{
- struct cpuidle_state *state;
- int i = dev->state_count;
+ struct cpuidle_state *state = &drv->states[drv->state_count];
- state = &dev->states[i];
snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
state->exit_latency = 10;
state->target_residency = 20 + 10;
- state->power_usage = 1; /* perhaps not */
- state->flags = 0;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
- shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
+ state->flags = CPUIDLE_FLAG_TIME_VALID;
+ shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby;
- dev->state_count = i + 1;
+ drv->state_count++;
}
static void sh7372_cpuidle_init(void)
tegra_clk_init_from_table(tegra_dt_clk_init_table);
+ /*
+ * Finished with the static registrations now; fill in the missing
+ * devices
+ */
+ of_platform_populate(NULL, tegra_dt_match_table,
+ tegra20_auxdata_lookup, NULL);
+
for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) {
if (of_machine_is_compatible(pinmux_configs[i].machine)) {
pinmux_configs[i].init();
WARN(i == ARRAY_SIZE(pinmux_configs),
"Unknown platform! Pinmuxing not initialized\n");
-
- /*
- * Finished with the static registrations now; fill in the missing
- * devices
- */
- of_platform_populate(NULL, tegra_dt_match_table, tegra20_auxdata_lookup, NULL);
}
static const char * tegra_dt_board_compat[] = {
#include <linux/kernel.h>
#include <linux/gpio.h>
+#include <linux/of.h>
+
#include <mach/pinmux.h>
#include "gpio-names.h"
void harmony_pinmux_init(void)
{
- platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+ if (!of_machine_is_compatible("nvidia,tegra20"))
+ platform_add_devices(pinmux_devices,
+ ARRAY_SIZE(pinmux_devices));
tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
#include <linux/kernel.h>
#include <linux/gpio.h>
+#include <linux/of.h>
+
#include <mach/pinmux.h>
#include "gpio-names.h"
void paz00_pinmux_init(void)
{
- platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+ if (!of_machine_is_compatible("nvidia,tegra20"))
+ platform_add_devices(pinmux_devices,
+ ARRAY_SIZE(pinmux_devices));
tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
+#include <linux/of.h>
#include <mach/pinmux.h>
#include <mach/pinmux-t2.h>
{ .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
{ .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true },
{ .gpio = TEGRA_GPIO_POWERKEY, .enable = true },
+ { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
{ .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
{ .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
{ .gpio = TEGRA_GPIO_USB1, .enable = true },
void __init seaboard_common_pinmux_init(void)
{
- platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+ if (!of_machine_is_compatible("nvidia,tegra20"))
+ platform_add_devices(pinmux_devices,
+ ARRAY_SIZE(pinmux_devices));
tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/of.h>
#include <mach/pinmux.h>
void __init trimslice_pinmux_init(void)
{
- platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+ if (!of_machine_is_compatible("nvidia,tegra20"))
+ platform_add_devices(pinmux_devices,
+ ARRAY_SIZE(pinmux_devices));
tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
}
config ARCH_IMX_V4_V5
bool "i.MX1, i.MX21, i.MX25, i.MX27"
- select AUTO_ZRELADDR
+ select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
help
This enables support for systems based on the Freescale i.MX ARMv4
config ARCH_MX5
bool "i.MX50, i.MX51, i.MX53"
- select AUTO_ZRELADDR
+ select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
help
This enables support for machines using Freescale's i.MX50 and i.MX53
#include <linux/io.h>
#include <mach/common.h>
#include <asm/mach/irq.h>
+#include <asm/exception.h>
#include <mach/hardware.h>
#include "irq-common.h"
if (irqnr == 1023)
break;
- if (irqnr > 29 && irqnr < 1021)
+ if (irqnr > 15 && irqnr < 1021)
handle_IRQ(irqnr, regs);
#ifdef CONFIG_SMP
- else if (irqnr < 16) {
+ else {
writel_relaxed(irqstat, gic_cpu_base_addr +
GIC_CPU_EOI);
handle_IPI(irqnr, regs);
}
#endif
-#ifdef CONFIG_LOCAL_TIMERS
- else if (irqnr == 29) {
- writel_relaxed(irqstat, gic_cpu_base_addr +
- GIC_CPU_EOI);
- handle_local_timer(regs);
- }
-#endif
} while (1);
}
.macro test_for_ipi, irqnr, irqstat, base, tmp
.endm
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- .endm
#include <linux/io.h>
#include <asm/mach/irq.h>
+#include <asm/exception.h>
#include <mach/hardware.h>
#include <mach/common.h>
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int tx_irq;
+ int rx_irq;
int status_irq;
#ifndef BFIN_UART_BF54X_STYLE
unsigned int lsr;
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
*/
#include <linux/device.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
#include <linux/gpio_keys.h>
-#include <linux/export.h>
static struct gpio_keys_button bfin_gpio_keys_table[] = {
{BTN_0, GPIO_PF14, 1, "gpio-keys: BTN0"},
*/
#include <linux/device.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
#include <linux/gpio_keys.h>
-#include <linux/export.h>
static struct gpio_keys_button bfin_gpio_keys_table[] = {
{BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"},
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX + 1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX + 1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX + 1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX + 1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX + 1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX + 1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
*/
#include <linux/device.h>
+#include <linux/export.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
#include <linux/bfin_mac.h>
-#include <linux/export.h>
static const unsigned short bfin_mac_peripherals[] = P_MII0;
static struct bfin_phydev_platform_data bfin_phydev_data[] = {
#include <linux/device.h>
#include <linux/etherdevice.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
#include <linux/bfin_mac.h>
-#include <linux/export.h>
static const unsigned short bfin_mac_peripherals[] = P_MII0;
static struct bfin_phydev_platform_data bfin_phydev_data[] = {
*/
#include <linux/device.h>
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
#include <linux/bfin_mac.h>
-#include <linux/export.h>
static const unsigned short bfin_mac_peripherals[] = P_RMII0;
static struct bfin_phydev_platform_data bfin_phydev_data[] = {
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#include <linux/device.h>
#include <linux/etherdevice.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
*/
#include <linux/device.h>
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
#include <linux/i2c/adp8860.h>
-#include <linux/export.h>
static struct led_info adp8860_leds[] = {
{
.name = "adp8860-led7",
#include <linux/device.h>
#include <linux/etherdevice.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
#include <linux/bfin_mac.h>
-#include <linux/export.h>
static const unsigned short bfin_mac_peripherals[] = P_MII0;
static struct bfin_phydev_platform_data bfin_phydev_data[] = {
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART2_TX,
+ .end = IRQ_UART2_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART2_RX,
- .end = IRQ_UART2_RX+1,
+ .end = IRQ_UART2_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART2_TX,
+ .end = IRQ_UART2_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART2_RX,
- .end = IRQ_UART2_RX+1,
+ .end = IRQ_UART2_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART3_TX,
+ .end = IRQ_UART3_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART3_RX,
- .end = IRQ_UART3_RX+1,
+ .end = IRQ_UART3_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART0_TX,
+ .end = IRQ_UART0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART0_RX,
- .end = IRQ_UART0_RX+1,
+ .end = IRQ_UART0_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART1_TX,
+ .end = IRQ_UART1_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART1_RX,
- .end = IRQ_UART1_RX+1,
+ .end = IRQ_UART1_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART2_TX,
+ .end = IRQ_UART2_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART2_RX,
- .end = IRQ_UART2_RX+1,
+ .end = IRQ_UART2_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART3_TX,
+ .end = IRQ_UART3_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART3_RX,
- .end = IRQ_UART3_RX+1,
+ .end = IRQ_UART3_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART_TX,
+ .end = IRQ_UART_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART_RX,
- .end = IRQ_UART_RX + 1,
+ .end = IRQ_UART_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART_TX,
+ .end = IRQ_UART_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART_RX,
- .end = IRQ_UART_RX+1,
+ .end = IRQ_UART_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART_TX,
+ .end = IRQ_UART_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART_RX,
- .end = IRQ_UART_RX+1,
+ .end = IRQ_UART_RX,
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_MEM,
},
{
+ .start = IRQ_UART_TX,
+ .end = IRQ_UART_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
.start = IRQ_UART_RX,
- .end = IRQ_UART_RX+1,
+ .end = IRQ_UART_RX,
.flags = IORESOURCE_IRQ,
},
{
select HAVE_IDE
select HAVE_AOUT if MMU
select GENERIC_ATOMIC64 if MMU
- select HAVE_GENERIC_HARDIRQS if !MMU
- select GENERIC_IRQ_SHOW if !MMU
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
config RWSEM_GENERIC_SPINLOCK
comment "Bus Support"
+config DIO
+ bool "DIO bus support"
+ depends on HP300
+ default y
+ help
+ Say Y here to enable support for the "DIO" expansion bus used in
+ HP300 machines. If you are using such a system you almost certainly
+ want this.
+
config NUBUS
bool
depends on MAC
including the model, CPU, MMU, clock speed, BogoMIPS rating,
and memory size.
+config NATFEAT
+ bool "ARAnyM emulator support"
+ depends on ATARI
+ help
+ This option enables support for ARAnyM native features, such as
+ access to a disk image as /dev/hda.
+
+config NFBLOCK
+ tristate "NatFeat block device support"
+ depends on BLOCK && NATFEAT
+ help
+ Say Y to include support for the ARAnyM NatFeat block device
+ which allows direct access to the hard drives without using
+ the hardware emulation.
+
+config NFCON
+ tristate "NatFeat console driver"
+ depends on NATFEAT
+ help
+ Say Y to include support for the ARAnyM NatFeat console driver
+ which allows the console output to be redirected to the stderr
+ output of ARAnyM.
+
+config NFETH
+ tristate "NatFeat Ethernet support"
+ depends on ETHERNET && NATFEAT
+ help
+ Say Y to include support for the ARAnyM NatFeat network device
+ which will emulate a regular ethernet device while presenting an
+ ethertap device to the host system.
+
endmenu
menu "Character devices"
/*
- * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code
+ * Amiga Linux interrupt handling code
*
* 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.
- *
- * 11/07/96: rewritten interrupt handling, irq lists are exists now only for
- * this sources where it makes sense (VERTB/PORTS/EXTER) and you must
- * be careful that dev_id for this sources is unique since this the
- * only possibility to distinguish between different handlers for
- * free_irq. irq lists also have different irq flags:
- * - IRQ_FLG_FAST: handler is inserted at top of list (after other
- * fast handlers)
- * - IRQ_FLG_SLOW: handler is inserted at bottom of list and before
- * they're executed irq level is set to the previous
- * one, but handlers don't need to be reentrant, if
- * reentrance occurred, slow handlers will be just
- * called again.
- * The whole interrupt handling for CIAs is moved to cia.c
- * /Roman Zippel
- *
- * 07/08/99: rewamp of the interrupt handling - we now have two types of
- * interrupts, normal and fast handlers, fast handlers being
- * marked with IRQF_DISABLED and runs with all other interrupts
- * disabled. Normal interrupts disable their own source but
- * run with all other interrupt sources enabled.
- * PORTS and EXTER interrupts are always shared even if the
- * drivers do not explicitly mark this when calling
- * request_irq which they really should do.
- * This is similar to the way interrupts are handled on all
- * other architectures and makes a ton of sense besides
- * having the advantage of making it easier to share
- * drivers.
- * /Jes
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
+#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/amigaints.h>
#include <asm/amipcmcia.h>
-static void amiga_enable_irq(unsigned int irq);
-static void amiga_disable_irq(unsigned int irq);
-static irqreturn_t ami_int1(int irq, void *dev_id);
-static irqreturn_t ami_int3(int irq, void *dev_id);
-static irqreturn_t ami_int4(int irq, void *dev_id);
-static irqreturn_t ami_int5(int irq, void *dev_id);
-
-static struct irq_controller amiga_irq_controller = {
- .name = "amiga",
- .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock),
- .enable = amiga_enable_irq,
- .disable = amiga_disable_irq,
-};
-
-/*
- * void amiga_init_IRQ(void)
- *
- * Parameters: None
- *
- * Returns: Nothing
- *
- * This function should be called during kernel startup to initialize
- * the amiga IRQ handling routines.
- */
-
-void __init amiga_init_IRQ(void)
-{
- if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL))
- pr_err("Couldn't register int%d\n", 1);
- if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL))
- pr_err("Couldn't register int%d\n", 3);
- if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL))
- pr_err("Couldn't register int%d\n", 4);
- if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL))
- pr_err("Couldn't register int%d\n", 5);
-
- m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS);
-
- /* turn off PCMCIA interrupts */
- if (AMIGAHW_PRESENT(PCMCIA))
- gayle.inten = GAYLE_IRQ_IDE;
-
- /* turn off all interrupts and enable the master interrupt bit */
- amiga_custom.intena = 0x7fff;
- amiga_custom.intreq = 0x7fff;
- amiga_custom.intena = IF_SETCLR | IF_INTEN;
-
- cia_init_IRQ(&ciaa_base);
- cia_init_IRQ(&ciab_base);
-}
/*
* Enable/disable a particular machine specific interrupt source.
* internal data, that may not be changed by the interrupt at the same time.
*/
-static void amiga_enable_irq(unsigned int irq)
+static void amiga_irq_enable(struct irq_data *data)
{
- amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER));
+ amiga_custom.intena = IF_SETCLR | (1 << (data->irq - IRQ_USER));
}
-static void amiga_disable_irq(unsigned int irq)
+static void amiga_irq_disable(struct irq_data *data)
{
- amiga_custom.intena = 1 << (irq - IRQ_USER);
+ amiga_custom.intena = 1 << (data->irq - IRQ_USER);
}
+static struct irq_chip amiga_irq_chip = {
+ .name = "amiga",
+ .irq_enable = amiga_irq_enable,
+ .irq_disable = amiga_irq_disable,
+};
+
+
/*
* The builtin Amiga hardware interrupt handlers.
*/
-static irqreturn_t ami_int1(int irq, void *dev_id)
+static void ami_int1(unsigned int irq, struct irq_desc *desc)
{
unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
/* if serial transmit buffer empty, interrupt */
if (ints & IF_TBE) {
amiga_custom.intreq = IF_TBE;
- m68k_handle_int(IRQ_AMIGA_TBE);
+ generic_handle_irq(IRQ_AMIGA_TBE);
}
/* if floppy disk transfer complete, interrupt */
if (ints & IF_DSKBLK) {
amiga_custom.intreq = IF_DSKBLK;
- m68k_handle_int(IRQ_AMIGA_DSKBLK);
+ generic_handle_irq(IRQ_AMIGA_DSKBLK);
}
/* if software interrupt set, interrupt */
if (ints & IF_SOFT) {
amiga_custom.intreq = IF_SOFT;
- m68k_handle_int(IRQ_AMIGA_SOFT);
+ generic_handle_irq(IRQ_AMIGA_SOFT);
}
- return IRQ_HANDLED;
}
-static irqreturn_t ami_int3(int irq, void *dev_id)
+static void ami_int3(unsigned int irq, struct irq_desc *desc)
{
unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
/* if a blitter interrupt */
if (ints & IF_BLIT) {
amiga_custom.intreq = IF_BLIT;
- m68k_handle_int(IRQ_AMIGA_BLIT);
+ generic_handle_irq(IRQ_AMIGA_BLIT);
}
/* if a copper interrupt */
if (ints & IF_COPER) {
amiga_custom.intreq = IF_COPER;
- m68k_handle_int(IRQ_AMIGA_COPPER);
+ generic_handle_irq(IRQ_AMIGA_COPPER);
}
/* if a vertical blank interrupt */
if (ints & IF_VERTB) {
amiga_custom.intreq = IF_VERTB;
- m68k_handle_int(IRQ_AMIGA_VERTB);
+ generic_handle_irq(IRQ_AMIGA_VERTB);
}
- return IRQ_HANDLED;
}
-static irqreturn_t ami_int4(int irq, void *dev_id)
+static void ami_int4(unsigned int irq, struct irq_desc *desc)
{
unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
/* if audio 0 interrupt */
if (ints & IF_AUD0) {
amiga_custom.intreq = IF_AUD0;
- m68k_handle_int(IRQ_AMIGA_AUD0);
+ generic_handle_irq(IRQ_AMIGA_AUD0);
}
/* if audio 1 interrupt */
if (ints & IF_AUD1) {
amiga_custom.intreq = IF_AUD1;
- m68k_handle_int(IRQ_AMIGA_AUD1);
+ generic_handle_irq(IRQ_AMIGA_AUD1);
}
/* if audio 2 interrupt */
if (ints & IF_AUD2) {
amiga_custom.intreq = IF_AUD2;
- m68k_handle_int(IRQ_AMIGA_AUD2);
+ generic_handle_irq(IRQ_AMIGA_AUD2);
}
/* if audio 3 interrupt */
if (ints & IF_AUD3) {
amiga_custom.intreq = IF_AUD3;
- m68k_handle_int(IRQ_AMIGA_AUD3);
+ generic_handle_irq(IRQ_AMIGA_AUD3);
}
- return IRQ_HANDLED;
}
-static irqreturn_t ami_int5(int irq, void *dev_id)
+static void ami_int5(unsigned int irq, struct irq_desc *desc)
{
unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
/* if serial receive buffer full interrupt */
if (ints & IF_RBF) {
/* acknowledge of IF_RBF must be done by the serial interrupt */
- m68k_handle_int(IRQ_AMIGA_RBF);
+ generic_handle_irq(IRQ_AMIGA_RBF);
}
/* if a disk sync interrupt */
if (ints & IF_DSKSYN) {
amiga_custom.intreq = IF_DSKSYN;
- m68k_handle_int(IRQ_AMIGA_DSKSYN);
+ generic_handle_irq(IRQ_AMIGA_DSKSYN);
}
- return IRQ_HANDLED;
+}
+
+
+/*
+ * void amiga_init_IRQ(void)
+ *
+ * Parameters: None
+ *
+ * Returns: Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void __init amiga_init_IRQ(void)
+{
+ m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER,
+ AMI_STD_IRQS);
+
+ irq_set_chained_handler(IRQ_AUTO_1, ami_int1);
+ irq_set_chained_handler(IRQ_AUTO_3, ami_int3);
+ irq_set_chained_handler(IRQ_AUTO_4, ami_int4);
+ irq_set_chained_handler(IRQ_AUTO_5, ami_int5);
+
+ /* turn off PCMCIA interrupts */
+ if (AMIGAHW_PRESENT(PCMCIA))
+ gayle.inten = GAYLE_IRQ_IDE;
+
+ /* turn off all interrupts and enable the master interrupt bit */
+ amiga_custom.intena = 0x7fff;
+ amiga_custom.intreq = 0x7fff;
+ amiga_custom.intena = IF_SETCLR | IF_INTEN;
+
+ cia_init_IRQ(&ciaa_base);
+ cia_init_IRQ(&ciab_base);
}
amiga_custom.intreq = base->int_mask;
for (; ints; mach_irq++, ints >>= 1) {
if (ints & 1)
- m68k_handle_int(mach_irq);
+ generic_handle_irq(mach_irq);
}
return IRQ_HANDLED;
}
-static void cia_enable_irq(unsigned int irq)
+static void cia_irq_enable(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned char mask;
if (irq >= IRQ_AMIGA_CIAB) {
}
}
-static void cia_disable_irq(unsigned int irq)
+static void cia_irq_disable(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
if (irq >= IRQ_AMIGA_CIAB)
cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
else
cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
}
-static struct irq_controller cia_irq_controller = {
+static struct irq_chip cia_irq_chip = {
.name = "cia",
- .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock),
- .enable = cia_enable_irq,
- .disable = cia_disable_irq,
+ .irq_enable = cia_irq_enable,
+ .irq_disable = cia_irq_disable,
};
/*
* into this chain.
*/
-static void auto_enable_irq(unsigned int irq)
+static void auto_irq_enable(struct irq_data *data)
{
- switch (irq) {
+ switch (data->irq) {
case IRQ_AUTO_2:
amiga_custom.intena = IF_SETCLR | IF_PORTS;
break;
}
}
-static void auto_disable_irq(unsigned int irq)
+static void auto_irq_disable(struct irq_data *data)
{
- switch (irq) {
+ switch (data->irq) {
case IRQ_AUTO_2:
amiga_custom.intena = IF_PORTS;
break;
}
}
-static struct irq_controller auto_irq_controller = {
+static struct irq_chip auto_irq_chip = {
.name = "auto",
- .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
- .enable = auto_enable_irq,
- .disable = auto_disable_irq,
+ .irq_enable = auto_irq_enable,
+ .irq_disable = auto_irq_disable,
};
void __init cia_init_IRQ(struct ciabase *base)
{
- m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS);
+ m68k_setup_irq_controller(&cia_irq_chip, handle_simple_irq,
+ base->cia_irq, CIA_IRQS);
/* clear any pending interrupt and turn off all interrupts */
cia_set_irq(base, CIA_ICR_ALL);
cia_able_irq(base, CIA_ICR_ALL);
/* override auto int and install CIA handler */
- m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1);
- m68k_irq_startup(base->handler_irq);
+ m68k_setup_irq_controller(&auto_irq_chip, handle_simple_irq,
+ base->handler_irq, 1);
+ m68k_irq_startup_irq(base->handler_irq);
if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED,
base->name, base))
pr_err("Couldn't register %s interrupt\n", base->name);
#include <linux/interrupt.h>
+#include <linux/irq.h>
-#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/apollohw.h>
-void dn_process_int(unsigned int irq, struct pt_regs *fp)
+unsigned int apollo_irq_startup(struct irq_data *data)
{
- __m68k_handle_int(irq, fp);
+ unsigned int irq = data->irq;
- *(volatile unsigned char *)(pica)=0x20;
- *(volatile unsigned char *)(picb)=0x20;
-}
-
-int apollo_irq_startup(unsigned int irq)
-{
if (irq < 8)
*(volatile unsigned char *)(pica+1) &= ~(1 << irq);
else
return 0;
}
-void apollo_irq_shutdown(unsigned int irq)
+void apollo_irq_shutdown(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
if (irq < 8)
*(volatile unsigned char *)(pica+1) |= (1 << irq);
else
*(volatile unsigned char *)(picb+1) |= (1 << (irq - 8));
}
-static struct irq_controller apollo_irq_controller = {
+void apollo_irq_eoi(struct irq_data *data)
+{
+ *(volatile unsigned char *)(pica) = 0x20;
+ *(volatile unsigned char *)(picb) = 0x20;
+}
+
+static struct irq_chip apollo_irq_chip = {
.name = "apollo",
- .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock),
- .startup = apollo_irq_startup,
- .shutdown = apollo_irq_shutdown,
+ .irq_startup = apollo_irq_startup,
+ .irq_shutdown = apollo_irq_shutdown,
+ .irq_eoi = apollo_irq_eoi,
};
void __init dn_init_IRQ(void)
{
- m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int);
- m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16);
+ m68k_setup_user_interrupt(VEC_USER + 96, 16);
+ m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq,
+ IRQ_APOLLO, 16);
}
* <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
* TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
* be allocated by atari_register_vme_int().
- *
- * Each interrupt can be of three types:
- *
- * - SLOW: The handler runs with all interrupts enabled, except the one it
- * was called by (to avoid reentering). This should be the usual method.
- * But it is currently possible only for MFP ints, since only the MFP
- * offers an easy way to mask interrupts.
- *
- * - FAST: The handler runs with all interrupts disabled. This should be used
- * only for really fast handlers, that just do actions immediately
- * necessary, and let the rest do a bottom half or task queue.
- *
- * - PRIORITIZED: The handler can be interrupted by higher-level ints
- * (greater IPL, no MFP priorities!). This is the method of choice for ints
- * which should be slow, but are not from a MFP.
- *
- * The feature of more than one handler for one int source is still there, but
- * only applicable if all handers are of the same type. To not slow down
- * processing of ints with only one handler by the chaining feature, the list
- * calling function atari_call_irq_list() is only plugged in at the time the
- * second handler is registered.
- *
- * Implementation notes: For fast-as-possible int handling, there are separate
- * entry points for each type (slow/fast/prio). The assembler handler calls
- * the irq directly in the usual case, no C wrapper is involved. In case of
- * multiple handlers, atari_call_irq_list() is registered as handler and calls
- * in turn the real irq's. To ease access from assembler level to the irq
- * function pointer and accompanying data, these two are stored in a separate
- * array, irq_handler[]. The rest of data (type, name) are put into a second
- * array, irq_param, that is accessed from C only. For each slow interrupt (32
- * in all) there are separate handler functions, which makes it possible to
- * hard-code the MFP register address and value, are necessary to mask the
- * int. If there'd be only one generic function, lots of calculations would be
- * needed to determine MFP register and int mask from the vector number :-(
- *
- * Furthermore, slow ints may not lower the IPL below its previous value
- * (before the int happened). This is needed so that an int of class PRIO, on
- * that this int may be stacked, cannot be reentered. This feature is
- * implemented as follows: If the stack frame format is 1 (throwaway), the int
- * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level
- * 2, which still blocks the HSYNC, but no interrupts of interest. If the
- * frame format is 0, the int is nested, and the old IPL value can be found in
- * the sr copy in the frame.
- */
-
-#if 0
-
-#define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES)
-
-typedef void (*asm_irq_handler)(void);
-
-struct irqhandler {
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
- void *dev_id;
-};
-
-struct irqparam {
- unsigned long flags;
- const char *devname;
-};
-
-/*
- * Array with irq's and their parameter data. This array is accessed from low
- * level assembler code, so an element size of 8 allows usage of index scaling
- * addressing mode.
*/
-static struct irqhandler irq_handler[NUM_INT_SOURCES];
-
-/*
- * This array hold the rest of parameters of int handlers: type
- * (slow,fast,prio) and the name of the handler. These values are only
- * accessed from C
- */
-static struct irqparam irq_param[NUM_INT_SOURCES];
-
-/* check for valid int number (complex, sigh...) */
-#define IS_VALID_INTNO(n) \
- ((n) > 0 && \
- /* autovec and ST-MFP ok anyway */ \
- (((n) < TTMFP_SOURCE_BASE) || \
- /* TT-MFP ok if present */ \
- ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE && \
- ATARIHW_PRESENT(TT_MFP)) || \
- /* SCC ok if present and number even */ \
- ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE && \
- !((n) & 1) && ATARIHW_PRESENT(SCC)) || \
- /* greater numbers ok if they are registered VME vectors */ \
- ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \
- free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE)))))
-
-
-/*
- * Here start the assembler entry points for interrupts
- */
-
-#define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void)
-
-#define BUILD_SLOW_IRQ(n) \
-asmlinkage void IRQ_NAME(n); \
-/* Dummy function to allow asm with operands. */ \
-void atari_slow_irq_##n##_dummy (void) { \
-__asm__ (__ALIGN_STR "\n" \
-"atari_slow_irq_" #n "_handler:\t" \
-" addl %6,%5\n" /* preempt_count() += HARDIRQ_OFFSET */ \
- SAVE_ALL_INT "\n" \
- GET_CURRENT(%%d0) "\n" \
-" andb #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */ \
- /* get old IPL from stack frame */ \
-" bfextu %%sp@(%c2){#5,#3},%%d0\n" \
-" movew %%sr,%%d1\n" \
-" bfins %%d0,%%d1{#21,#3}\n" \
-" movew %%d1,%%sr\n" /* set IPL = previous value */ \
-" addql #1,%a0\n" \
-" lea %a1,%%a0\n" \
-" pea %%sp@\n" /* push addr of frame */ \
-" movel %%a0@(4),%%sp@-\n" /* push handler data */ \
-" pea (%c3+8)\n" /* push int number */ \
-" movel %%a0@,%%a0\n" \
-" jbsr %%a0@\n" /* call the handler */ \
-" addql #8,%%sp\n" \
-" addql #4,%%sp\n" \
-" orw #0x0600,%%sr\n" \
-" andw #0xfeff,%%sr\n" /* set IPL = 6 again */ \
-" orb #(1<<(%c3&7)),%a4:w\n" /* now unmask the int again */ \
-" jbra ret_from_interrupt\n" \
- : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \
- "n" (PT_OFF_SR), "n" (n), \
- "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \
- : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \
- "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \
-); \
- for (;;); /* fake noreturn */ \
-}
-
-BUILD_SLOW_IRQ(0);
-BUILD_SLOW_IRQ(1);
-BUILD_SLOW_IRQ(2);
-BUILD_SLOW_IRQ(3);
-BUILD_SLOW_IRQ(4);
-BUILD_SLOW_IRQ(5);
-BUILD_SLOW_IRQ(6);
-BUILD_SLOW_IRQ(7);
-BUILD_SLOW_IRQ(8);
-BUILD_SLOW_IRQ(9);
-BUILD_SLOW_IRQ(10);
-BUILD_SLOW_IRQ(11);
-BUILD_SLOW_IRQ(12);
-BUILD_SLOW_IRQ(13);
-BUILD_SLOW_IRQ(14);
-BUILD_SLOW_IRQ(15);
-BUILD_SLOW_IRQ(16);
-BUILD_SLOW_IRQ(17);
-BUILD_SLOW_IRQ(18);
-BUILD_SLOW_IRQ(19);
-BUILD_SLOW_IRQ(20);
-BUILD_SLOW_IRQ(21);
-BUILD_SLOW_IRQ(22);
-BUILD_SLOW_IRQ(23);
-BUILD_SLOW_IRQ(24);
-BUILD_SLOW_IRQ(25);
-BUILD_SLOW_IRQ(26);
-BUILD_SLOW_IRQ(27);
-BUILD_SLOW_IRQ(28);
-BUILD_SLOW_IRQ(29);
-BUILD_SLOW_IRQ(30);
-BUILD_SLOW_IRQ(31);
-
-asm_irq_handler slow_handlers[32] = {
- [0] = atari_slow_irq_0_handler,
- [1] = atari_slow_irq_1_handler,
- [2] = atari_slow_irq_2_handler,
- [3] = atari_slow_irq_3_handler,
- [4] = atari_slow_irq_4_handler,
- [5] = atari_slow_irq_5_handler,
- [6] = atari_slow_irq_6_handler,
- [7] = atari_slow_irq_7_handler,
- [8] = atari_slow_irq_8_handler,
- [9] = atari_slow_irq_9_handler,
- [10] = atari_slow_irq_10_handler,
- [11] = atari_slow_irq_11_handler,
- [12] = atari_slow_irq_12_handler,
- [13] = atari_slow_irq_13_handler,
- [14] = atari_slow_irq_14_handler,
- [15] = atari_slow_irq_15_handler,
- [16] = atari_slow_irq_16_handler,
- [17] = atari_slow_irq_17_handler,
- [18] = atari_slow_irq_18_handler,
- [19] = atari_slow_irq_19_handler,
- [20] = atari_slow_irq_20_handler,
- [21] = atari_slow_irq_21_handler,
- [22] = atari_slow_irq_22_handler,
- [23] = atari_slow_irq_23_handler,
- [24] = atari_slow_irq_24_handler,
- [25] = atari_slow_irq_25_handler,
- [26] = atari_slow_irq_26_handler,
- [27] = atari_slow_irq_27_handler,
- [28] = atari_slow_irq_28_handler,
- [29] = atari_slow_irq_29_handler,
- [30] = atari_slow_irq_30_handler,
- [31] = atari_slow_irq_31_handler
-};
-
-asmlinkage void atari_fast_irq_handler( void );
-asmlinkage void atari_prio_irq_handler( void );
-
-/* Dummy function to allow asm with operands. */
-void atari_fast_prio_irq_dummy (void) {
-__asm__ (__ALIGN_STR "\n"
-"atari_fast_irq_handler:\n\t"
- "orw #0x700,%%sr\n" /* disable all interrupts */
-"atari_prio_irq_handler:\n\t"
- "addl %3,%2\n\t" /* preempt_count() += HARDIRQ_OFFSET */
- SAVE_ALL_INT "\n\t"
- GET_CURRENT(%%d0) "\n\t"
- /* get vector number from stack frame and convert to source */
- "bfextu %%sp@(%c1){#4,#10},%%d0\n\t"
- "subw #(0x40-8),%%d0\n\t"
- "jpl 1f\n\t"
- "addw #(0x40-8-0x18),%%d0\n"
- "1:\tlea %a0,%%a0\n\t"
- "addql #1,%%a0@(%%d0:l:4)\n\t"
- "lea irq_handler,%%a0\n\t"
- "lea %%a0@(%%d0:l:8),%%a0\n\t"
- "pea %%sp@\n\t" /* push frame address */
- "movel %%a0@(4),%%sp@-\n\t" /* push handler data */
- "movel %%d0,%%sp@-\n\t" /* push int number */
- "movel %%a0@,%%a0\n\t"
- "jsr %%a0@\n\t" /* and call the handler */
- "addql #8,%%sp\n\t"
- "addql #4,%%sp\n\t"
- "jbra ret_from_interrupt"
- : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC),
- "m" (preempt_count()), "di" (HARDIRQ_OFFSET)
-);
- for (;;);
-}
-#endif
/*
* Bitmap for free interrupt vector numbers
extern int atari_SCC_reset_done;
-static int atari_startup_irq(unsigned int irq)
+static unsigned int atari_irq_startup(struct irq_data *data)
{
- m68k_irq_startup(irq);
+ unsigned int irq = data->irq;
+
+ m68k_irq_startup(data);
atari_turnon_irq(irq);
atari_enable_irq(irq);
return 0;
}
-static void atari_shutdown_irq(unsigned int irq)
+static void atari_irq_shutdown(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
atari_disable_irq(irq);
atari_turnoff_irq(irq);
- m68k_irq_shutdown(irq);
+ m68k_irq_shutdown(data);
if (irq == IRQ_AUTO_4)
vectors[VEC_INT4] = falcon_hblhandler;
}
-static struct irq_controller atari_irq_controller = {
+static void atari_irq_enable(struct irq_data *data)
+{
+ atari_enable_irq(data->irq);
+}
+
+static void atari_irq_disable(struct irq_data *data)
+{
+ atari_disable_irq(data->irq);
+}
+
+static struct irq_chip atari_irq_chip = {
.name = "atari",
- .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock),
- .startup = atari_startup_irq,
- .shutdown = atari_shutdown_irq,
- .enable = atari_enable_irq,
- .disable = atari_disable_irq,
+ .irq_startup = atari_irq_startup,
+ .irq_shutdown = atari_irq_shutdown,
+ .irq_enable = atari_irq_enable,
+ .irq_disable = atari_irq_disable,
};
/*
void __init atari_init_IRQ(void)
{
- m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL);
- m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
+ m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER);
+ m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1,
+ NUM_ATARI_SOURCES - 1);
/* Initialize the MFP(s) */
*/
static void __init bvme6000_init_IRQ(void)
{
- m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+ m68k_setup_user_interrupt(VEC_USER, 192);
}
void __init config_bvme6000(void)
asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
- if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector))
+ if (request_irq(IRQ_AUTO_6, hp300_tick, 0, "timer tick", vector))
pr_err("Couldn't register timer interrupt\n");
out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */
#ifdef CONFIG_MMU
+static inline void ack_bad_irq(unsigned int irq)
+{
+ pr_crit("unexpected IRQ trap at vector %02x\n", irq);
+}
+
/* entry.S is sensitive to the offsets of these fields */
typedef struct {
unsigned int __softirq_pending;
#ifdef CONFIG_MMU
-#include <linux/linkage.h>
-#include <linux/hardirq.h>
-#include <linux/irqreturn.h>
-#include <linux/spinlock_types.h>
-
/*
* Interrupt source definitions
* General interrupt sources are the level 1-7.
#define IRQ_USER 8
-extern unsigned int irq_canonicalize(unsigned int irq);
-
-struct pt_regs;
-
/*
* various flags for request_irq() - the Amiga now uses the standard
* mechanism like all other architectures - IRQF_DISABLED and
#define IRQ_FLG_STD (0x8000) /* internally used */
#endif
-/*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
- irqreturn_t (*handler)(int, void *);
- void *dev_id;
- struct irq_node *next;
- unsigned long flags;
- const char *devname;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-struct irq_handler {
- int (*handler)(int, void *);
- unsigned long flags;
- void *dev_id;
- const char *devname;
-};
-
-struct irq_controller {
- const char *name;
- spinlock_t lock;
- int (*startup)(unsigned int irq);
- void (*shutdown)(unsigned int irq);
- void (*enable)(unsigned int irq);
- void (*disable)(unsigned int irq);
-};
-
-extern int m68k_irq_startup(unsigned int);
-extern void m68k_irq_shutdown(unsigned int);
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
+struct irq_data;
+struct irq_chip;
+struct irq_desc;
+extern unsigned int m68k_irq_startup(struct irq_data *data);
+extern unsigned int m68k_irq_startup_irq(unsigned int irq);
+extern void m68k_irq_shutdown(struct irq_data *data);
+extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int,
+ struct pt_regs *));
+extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt);
+extern void m68k_setup_irq_controller(struct irq_chip *,
+ void (*handle)(unsigned int irq,
+ struct irq_desc *desc),
+ unsigned int irq, unsigned int cnt);
-extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
- void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
-
-asmlinkage void m68k_handle_int(unsigned int);
-asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
+extern unsigned int irq_canonicalize(unsigned int irq);
#else
#define irq_canonicalize(irq) (irq)
#endif /* CONFIG_MMU */
asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+extern atomic_t irq_err_count;
#endif /* _M68K_IRQ_H_ */
extern void mac_poweroff(void);
extern void mac_init_IRQ(void);
extern int mac_irq_pending(unsigned int);
+extern void mac_irq_enable(struct irq_data *data);
+extern void mac_irq_disable(struct irq_data *data);
/*
* Floppy driver magic hook - probably shouldn't be here
#define Q40_IRQ10_MASK (1<<5)
#define Q40_IRQ14_MASK (1<<6)
#define Q40_IRQ15_MASK (1<<7)
-
-extern unsigned long q40_probe_irq_on (void);
-extern int q40_probe_irq_off (unsigned long irqs);
extra-$(CONFIG_SUN3) := sun3-head.o
extra-y += vmlinux.lds
-obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \
- sys_m68k.o syscalltable.o time.o traps.o
+obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o setup.o \
+ signal.o sys_m68k.o syscalltable.o time.o traps.o
-obj-$(CONFIG_MMU) += ints.o devres.o vectors.o
-devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o
+obj-$(CONFIG_MMU) += ints.o vectors.o
ifndef CONFIG_MMU_SUN3
obj-y += dma.o
endif
ifndef CONFIG_MMU
-obj-y += init_task.o irq.o
+obj-y += init_task.o
endif
.globl sys_fork, sys_clone, sys_vfork
.globl ret_from_interrupt, bad_interrupt
.globl auto_irqhandler_fixup
-.globl user_irqvec_fixup, user_irqhandler_fixup
+.globl user_irqvec_fixup
.text
ENTRY(buserr)
movel %sp,%sp@-
movel %d0,%sp@- | put vector # on stack
auto_irqhandler_fixup = . + 2
- jsr __m68k_handle_int | process the IRQ
+ jsr do_IRQ | process the IRQ
addql #8,%sp | pop parameters off stack
ret_from_interrupt:
movel %sp,%sp@-
movel %d0,%sp@- | put vector # on stack
-user_irqhandler_fixup = . + 2
- jsr __m68k_handle_int | process the IRQ
+ jsr do_IRQ | process the IRQ
addql #8,%sp | pop parameters off stack
subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
* 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.
- *
- * 07/03/96: Timer initialization, and thus mach_sched_init(),
- * removed from request_irq() and moved to init_time().
- * We should therefore consider renaming our add_isr() and
- * remove_isr() to request_irq() and free_irq()
- * respectively, so they are compliant with the other
- * architectures. /Jes
- * 11/07/96: Changed all add_/remove_isr() to request_/free_irq() calls.
- * Removed irq list support, if any machine needs an irq server
- * it must implement this itself (as it's already done), instead
- * only default handler are used with mach_default_handler.
- * request_irq got some flags different from other architectures:
- * - IRQ_FLG_REPLACE : Replace an existing handler (the default one
- * can be replaced without this flag)
- * - IRQ_FLG_LOCK : handler can't be replaced
- * There are other machine depending flags, see there
- * If you want to replace a default handler you should know what
- * you're doing, since it might handle different other irq sources
- * which must be served /Roman Zippel
*/
#include <linux/module.h>
#endif
extern u32 auto_irqhandler_fixup[];
-extern u32 user_irqhandler_fixup[];
extern u16 user_irqvec_fixup[];
-/* table for system interrupt handlers */
-static struct irq_node *irq_list[NR_IRQS];
-static struct irq_controller *irq_controller[NR_IRQS];
-static int irq_depth[NR_IRQS];
-
static int m68k_first_user_vec;
-static struct irq_controller auto_irq_controller = {
+static struct irq_chip auto_irq_chip = {
.name = "auto",
- .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
- .startup = m68k_irq_startup,
- .shutdown = m68k_irq_shutdown,
+ .irq_startup = m68k_irq_startup,
+ .irq_shutdown = m68k_irq_shutdown,
};
-static struct irq_controller user_irq_controller = {
+static struct irq_chip user_irq_chip = {
.name = "user",
- .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock),
- .startup = m68k_irq_startup,
- .shutdown = m68k_irq_shutdown,
+ .irq_startup = m68k_irq_startup,
+ .irq_shutdown = m68k_irq_shutdown,
};
-#define NUM_IRQ_NODES 100
-static irq_node_t nodes[NUM_IRQ_NODES];
-
/*
* void init_IRQ(void)
*
}
for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++)
- irq_controller[i] = &auto_irq_controller;
+ irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq);
mach_init_IRQ();
}
* @handler: called from auto vector interrupts
*
* setup the handler to be called from auto vector interrupts instead of the
- * standard __m68k_handle_int(), it will be called with irq numbers in the range
+ * standard do_IRQ(), it will be called with irq numbers in the range
* from IRQ_AUTO_1 - IRQ_AUTO_7.
*/
void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *))
* m68k_setup_user_interrupt
* @vec: first user vector interrupt to handle
* @cnt: number of active user vector interrupts
- * @handler: called from user vector interrupts
*
* setup user vector interrupts, this includes activating the specified range
* of interrupts, only then these interrupts can be requested (note: this is
- * different from auto vector interrupts). An optional handler can be installed
- * to be called instead of the default __m68k_handle_int(), it will be called
- * with irq numbers starting from IRQ_USER.
+ * different from auto vector interrupts).
*/
-void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
- void (*handler)(unsigned int, struct pt_regs *))
+void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt)
{
int i;
BUG_ON(IRQ_USER + cnt > NR_IRQS);
m68k_first_user_vec = vec;
for (i = 0; i < cnt; i++)
- irq_controller[IRQ_USER + i] = &user_irq_controller;
+ irq_set_chip(IRQ_USER + i, &user_irq_chip);
*user_irqvec_fixup = vec - IRQ_USER;
- if (handler)
- *user_irqhandler_fixup = (u32)handler;
flush_icache();
}
/**
* m68k_setup_irq_controller
- * @contr: irq controller which controls specified irq
+ * @chip: irq chip which controls specified irq
+ * @handle: flow handler which handles specified irq
* @irq: first irq to be managed by the controller
+ * @cnt: number of irqs to be managed by the controller
*
* Change the controller for the specified range of irq, which will be used to
* manage these irq. auto/user irq already have a default controller, which can
* be changed as well, but the controller probably should use m68k_irq_startup/
* m68k_irq_shutdown.
*/
-void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq,
+void m68k_setup_irq_controller(struct irq_chip *chip,
+ irq_flow_handler_t handle, unsigned int irq,
unsigned int cnt)
{
int i;
- for (i = 0; i < cnt; i++)
- irq_controller[irq + i] = contr;
-}
-
-irq_node_t *new_irq_node(void)
-{
- irq_node_t *node;
- short i;
-
- for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) {
- if (!node->handler) {
- memset(node, 0, sizeof(*node));
- return node;
- }
+ for (i = 0; i < cnt; i++) {
+ irq_set_chip(irq + i, chip);
+ if (handle)
+ irq_set_handler(irq + i, handle);
}
-
- printk ("new_irq_node: out of nodes\n");
- return NULL;
}
-int setup_irq(unsigned int irq, struct irq_node *node)
-{
- struct irq_controller *contr;
- struct irq_node **prev;
- unsigned long flags;
-
- if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
- printk("%s: Incorrect IRQ %d from %s\n",
- __func__, irq, node->devname);
- return -ENXIO;
- }
-
- spin_lock_irqsave(&contr->lock, flags);
-
- prev = irq_list + irq;
- if (*prev) {
- /* Can't share interrupts unless both agree to */
- if (!((*prev)->flags & node->flags & IRQF_SHARED)) {
- spin_unlock_irqrestore(&contr->lock, flags);
- return -EBUSY;
- }
- while (*prev)
- prev = &(*prev)->next;
- }
-
- if (!irq_list[irq]) {
- if (contr->startup)
- contr->startup(irq);
- else
- contr->enable(irq);
- }
- node->next = NULL;
- *prev = node;
-
- spin_unlock_irqrestore(&contr->lock, flags);
-
- return 0;
-}
-
-int request_irq(unsigned int irq,
- irq_handler_t handler,
- unsigned long flags, const char *devname, void *dev_id)
-{
- struct irq_node *node;
- int res;
-
- node = new_irq_node();
- if (!node)
- return -ENOMEM;
-
- node->handler = handler;
- node->flags = flags;
- node->dev_id = dev_id;
- node->devname = devname;
-
- res = setup_irq(irq, node);
- if (res)
- node->handler = NULL;
-
- return res;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
-{
- struct irq_controller *contr;
- struct irq_node **p, *node;
- unsigned long flags;
-
- if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
- printk("%s: Incorrect IRQ %d\n", __func__, irq);
- return;
- }
-
- spin_lock_irqsave(&contr->lock, flags);
-
- p = irq_list + irq;
- while ((node = *p)) {
- if (node->dev_id == dev_id)
- break;
- p = &node->next;
- }
-
- if (node) {
- *p = node->next;
- node->handler = NULL;
- } else
- printk("%s: Removing probably wrong IRQ %d\n",
- __func__, irq);
-
- if (!irq_list[irq]) {
- if (contr->shutdown)
- contr->shutdown(irq);
- else
- contr->disable(irq);
- }
-
- spin_unlock_irqrestore(&contr->lock, flags);
-}
-
-EXPORT_SYMBOL(free_irq);
-
-void enable_irq(unsigned int irq)
-{
- struct irq_controller *contr;
- unsigned long flags;
-
- if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
- printk("%s: Incorrect IRQ %d\n",
- __func__, irq);
- return;
- }
-
- spin_lock_irqsave(&contr->lock, flags);
- if (irq_depth[irq]) {
- if (!--irq_depth[irq]) {
- if (contr->enable)
- contr->enable(irq);
- }
- } else
- WARN_ON(1);
- spin_unlock_irqrestore(&contr->lock, flags);
-}
-
-EXPORT_SYMBOL(enable_irq);
-
-void disable_irq(unsigned int irq)
-{
- struct irq_controller *contr;
- unsigned long flags;
-
- if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
- printk("%s: Incorrect IRQ %d\n",
- __func__, irq);
- return;
- }
-
- spin_lock_irqsave(&contr->lock, flags);
- if (!irq_depth[irq]++) {
- if (contr->disable)
- contr->disable(irq);
- }
- spin_unlock_irqrestore(&contr->lock, flags);
-}
-
-EXPORT_SYMBOL(disable_irq);
-
-void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
-
-EXPORT_SYMBOL(disable_irq_nosync);
-
-int m68k_irq_startup(unsigned int irq)
+unsigned int m68k_irq_startup_irq(unsigned int irq)
{
if (irq <= IRQ_AUTO_7)
vectors[VEC_SPUR + irq] = auto_inthandler;
return 0;
}
-void m68k_irq_shutdown(unsigned int irq)
+unsigned int m68k_irq_startup(struct irq_data *data)
{
- if (irq <= IRQ_AUTO_7)
- vectors[VEC_SPUR + irq] = bad_inthandler;
- else
- vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler;
+ return m68k_irq_startup_irq(data->irq);
}
-
-/*
- * Do we need these probe functions on the m68k?
- *
- * ... may be useful with ISA devices
- */
-unsigned long probe_irq_on (void)
+void m68k_irq_shutdown(struct irq_data *data)
{
-#ifdef CONFIG_Q40
- if (MACH_IS_Q40)
- return q40_probe_irq_on();
-#endif
- return 0;
-}
+ unsigned int irq = data->irq;
-EXPORT_SYMBOL(probe_irq_on);
-
-int probe_irq_off (unsigned long irqs)
-{
-#ifdef CONFIG_Q40
- if (MACH_IS_Q40)
- return q40_probe_irq_off(irqs);
-#endif
- return 0;
+ if (irq <= IRQ_AUTO_7)
+ vectors[VEC_SPUR + irq] = bad_inthandler;
+ else
+ vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler;
}
-EXPORT_SYMBOL(probe_irq_off);
unsigned int irq_canonicalize(unsigned int irq)
{
EXPORT_SYMBOL(irq_canonicalize);
-asmlinkage void m68k_handle_int(unsigned int irq)
-{
- struct irq_node *node;
- kstat_cpu(0).irqs[irq]++;
- node = irq_list[irq];
- do {
- node->handler(irq, node->dev_id);
- node = node->next;
- } while (node);
-}
-
-asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
- old_regs = set_irq_regs(regs);
- m68k_handle_int(irq);
- set_irq_regs(old_regs);
-}
asmlinkage void handle_badint(struct pt_regs *regs)
{
- kstat_cpu(0).irqs[0]++;
- printk("unexpected interrupt from %u\n", regs->vector);
-}
-
-int show_interrupts(struct seq_file *p, void *v)
-{
- struct irq_controller *contr;
- struct irq_node *node;
- int i = *(loff_t *) v;
-
- /* autovector interrupts */
- if (irq_list[i]) {
- contr = irq_controller[i];
- node = irq_list[i];
- seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname);
- while ((node = node->next))
- seq_printf(p, ", %s", node->devname);
- seq_puts(p, "\n");
- }
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-void init_irq_proc(void)
-{
- /* Insert /proc/irq driver here */
+ atomic_inc(&irq_err_count);
+ pr_warn("unexpected interrupt from %u\n", regs->vector);
}
-#endif
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <asm/traps.h>
#include <asm/bootinfo.h>
/* #define DEBUG_IRQS */
-extern void mac_enable_irq(unsigned int);
-extern void mac_disable_irq(unsigned int);
-
int baboon_present;
static volatile struct baboon *baboon;
static unsigned char baboon_disabled;
* Baboon interrupt handler. This works a lot like a VIA.
*/
-static irqreturn_t baboon_irq(int irq, void *dev_id)
+static void baboon_irq(unsigned int irq, struct irq_desc *desc)
{
int irq_bit, irq_num;
unsigned char events;
(uint) baboon->mb_status);
#endif
- if (!(events = baboon->mb_ifr & 0x07))
- return IRQ_NONE;
+ events = baboon->mb_ifr & 0x07;
+ if (!events)
+ return;
irq_num = IRQ_BABOON_0;
irq_bit = 1;
do {
if (events & irq_bit) {
baboon->mb_ifr &= ~irq_bit;
- m68k_handle_int(irq_num);
+ generic_handle_irq(irq_num);
}
irq_bit <<= 1;
irq_num++;
/* for now we need to smash all interrupts */
baboon->mb_ifr &= ~events;
#endif
- return IRQ_HANDLED;
}
/*
void __init baboon_register_interrupts(void)
{
baboon_disabled = 0;
- if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon))
- pr_err("Couldn't register baboon interrupt\n");
+ irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq);
}
/*
baboon_disabled &= ~(1 << irq_idx);
if (!baboon_disabled)
- mac_enable_irq(IRQ_NUBUS_C);
+ mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C));
}
void baboon_irq_disable(int irq)
baboon_disabled |= 1 << irq_idx;
if (baboon_disabled)
- mac_disable_irq(IRQ_NUBUS_C);
+ mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
}
void baboon_irq_clear(int irq)
{
if (iop_ism_present) {
if (oss_present) {
- if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
- IRQ_FLG_LOCK, "ISM IOP",
- (void *) IOP_NUM_ISM))
+ if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, 0,
+ "ISM IOP", (void *)IOP_NUM_ISM))
pr_err("Couldn't register ISM IOP interrupt\n");
oss_irq_enable(IRQ_MAC_ADB);
} else {
- if (request_irq(IRQ_VIA2_0, iop_ism_irq,
- IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP",
- (void *) IOP_NUM_ISM))
+ if (request_irq(IRQ_VIA2_0, iop_ism_irq, 0, "ISM IOP",
+ (void *)IOP_NUM_ISM))
pr_err("Couldn't register ISM IOP interrupt\n");
}
if (!iop_alive(iop_base[IOP_NUM_ISM])) {
/* #define DEBUG_MACINTS */
-void mac_enable_irq(unsigned int irq);
-void mac_disable_irq(unsigned int irq);
-
-static struct irq_controller mac_irq_controller = {
+static struct irq_chip mac_irq_chip = {
.name = "mac",
- .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock),
- .enable = mac_enable_irq,
- .disable = mac_disable_irq,
+ .irq_enable = mac_irq_enable,
+ .irq_disable = mac_irq_disable,
};
void __init mac_init_IRQ(void)
#ifdef DEBUG_MACINTS
printk("mac_init_IRQ(): Setting things up...\n");
#endif
- m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER,
+ m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER,
NUM_MAC_SOURCES - IRQ_USER);
/* Make sure the SONIC interrupt is cleared or things get ugly */
#ifdef SHUTUP_SONIC
}
/*
- * mac_enable_irq - enable an interrupt source
- * mac_disable_irq - disable an interrupt source
+ * mac_irq_enable - enable an interrupt source
+ * mac_irq_disable - disable an interrupt source
* mac_clear_irq - clears a pending interrupt
- * mac_pending_irq - Returns the pending status of an IRQ (nonzero = pending)
+ * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending)
*
* These routines are just dispatchers to the VIA/OSS/PSC routines.
*/
-void mac_enable_irq(unsigned int irq)
+void mac_irq_enable(struct irq_data *data)
{
+ int irq = data->irq;
int irq_src = IRQ_SRC(irq);
switch(irq_src) {
}
}
-void mac_disable_irq(unsigned int irq)
+void mac_irq_disable(struct irq_data *data)
{
+ int irq = data->irq;
int irq_src = IRQ_SRC(irq);
switch(irq_src) {
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <asm/bootinfo.h>
#include <asm/macintosh.h>
int oss_present;
volatile struct mac_oss *oss;
-static irqreturn_t oss_irq(int, void *);
-static irqreturn_t oss_nubus_irq(int, void *);
-
-extern irqreturn_t via1_irq(int, void *);
+extern void via1_irq(unsigned int irq, struct irq_desc *desc);
/*
* Initialize the OSS
}
/*
- * Register the OSS and NuBus interrupt dispatchers.
- */
-
-void __init oss_register_interrupts(void)
-{
- if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
- "scsi", (void *) oss))
- pr_err("Couldn't register %s interrupt\n", "scsi");
- if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
- "nubus", (void *) oss))
- pr_err("Couldn't register %s interrupt\n", "nubus");
- if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
- "sound", (void *) oss))
- pr_err("Couldn't register %s interrupt\n", "sound");
- if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
- "via1", (void *) via1))
- pr_err("Couldn't register %s interrupt\n", "via1");
-}
-
-/*
* Initialize OSS for Nubus access
*/
* and SCSI; everything else is routed to its own autovector IRQ.
*/
-static irqreturn_t oss_irq(int irq, void *dev_id)
+static void oss_irq(unsigned int irq, struct irq_desc *desc)
{
int events;
events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI);
if (!events)
- return IRQ_NONE;
+ return;
#ifdef DEBUG_IRQS
if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) {
- printk("oss_irq: irq %d events = 0x%04X\n", irq,
+ printk("oss_irq: irq %u events = 0x%04X\n", irq,
(int) oss->irq_pending);
}
#endif
/* FIXME: call sound handler */
} else if (events & OSS_IP_SCSI) {
oss->irq_pending &= ~OSS_IP_SCSI;
- m68k_handle_int(IRQ_MAC_SCSI);
+ generic_handle_irq(IRQ_MAC_SCSI);
} else {
/* FIXME: error check here? */
}
- return IRQ_HANDLED;
}
/*
* Unlike the VIA/RBV this is on its own autovector interrupt level.
*/
-static irqreturn_t oss_nubus_irq(int irq, void *dev_id)
+static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc)
{
int events, irq_bit, i;
events = oss->irq_pending & OSS_IP_NUBUS;
if (!events)
- return IRQ_NONE;
+ return;
#ifdef DEBUG_NUBUS_INT
if (console_loglevel > 7) {
irq_bit >>= 1;
if (events & irq_bit) {
oss->irq_pending &= ~irq_bit;
- m68k_handle_int(NUBUS_SOURCE_BASE + i);
+ generic_handle_irq(NUBUS_SOURCE_BASE + i);
}
} while(events & (irq_bit - 1));
- return IRQ_HANDLED;
+}
+
+/*
+ * Register the OSS and NuBus interrupt dispatchers.
+ */
+
+void __init oss_register_interrupts(void)
+{
+ irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq);
+ irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq);
+ irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq);
+ irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq);
}
/*
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <asm/traps.h>
#include <asm/bootinfo.h>
int psc_present;
volatile __u8 *psc;
-irqreturn_t psc_irq(int, void *);
-
/*
* Debugging dump, used in various places to see what's going on.
*/
}
/*
- * Register the PSC interrupt dispatchers for autovector interrupts 3-6.
- */
-
-void __init psc_register_interrupts(void)
-{
- if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30))
- pr_err("Couldn't register psc%d interrupt\n", 3);
- if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40))
- pr_err("Couldn't register psc%d interrupt\n", 4);
- if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50))
- pr_err("Couldn't register psc%d interrupt\n", 5);
- if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60))
- pr_err("Couldn't register psc%d interrupt\n", 6);
-}
-
-/*
* PSC interrupt handler. It's a lot like the VIA interrupt handler.
*/
-irqreturn_t psc_irq(int irq, void *dev_id)
+static void psc_irq(unsigned int irq, struct irq_desc *desc)
{
- int pIFR = pIFRbase + ((int) dev_id);
- int pIER = pIERbase + ((int) dev_id);
+ unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc);
+ int pIFR = pIFRbase + offset;
+ int pIER = pIERbase + offset;
int irq_num;
unsigned char irq_bit, events;
#ifdef DEBUG_IRQS
- printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n",
+ printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n",
irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER));
#endif
events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF;
if (!events)
- return IRQ_NONE;
+ return;
irq_num = irq << 3;
irq_bit = 1;
do {
if (events & irq_bit) {
psc_write_byte(pIFR, irq_bit);
- m68k_handle_int(irq_num);
+ generic_handle_irq(irq_num);
}
irq_num++;
irq_bit <<= 1;
} while (events >= irq_bit);
- return IRQ_HANDLED;
+}
+
+/*
+ * Register the PSC interrupt dispatchers for autovector interrupts 3-6.
+ */
+
+void __init psc_register_interrupts(void)
+{
+ irq_set_chained_handler(IRQ_AUTO_3, psc_irq);
+ irq_set_handler_data(IRQ_AUTO_3, (void *)0x30);
+ irq_set_chained_handler(IRQ_AUTO_4, psc_irq);
+ irq_set_handler_data(IRQ_AUTO_4, (void *)0x40);
+ irq_set_chained_handler(IRQ_AUTO_5, psc_irq);
+ irq_set_handler_data(IRQ_AUTO_5, (void *)0x50);
+ irq_set_chained_handler(IRQ_AUTO_6, psc_irq);
+ irq_set_handler_data(IRQ_AUTO_6, (void *)0x60);
}
void psc_irq_enable(int irq) {
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/irq.h>
#include <asm/bootinfo.h>
#include <asm/macintosh.h>
static u8 nubus_disabled;
void via_debug_dump(void);
-irqreturn_t via1_irq(int, void *);
-irqreturn_t via2_irq(int, void *);
-irqreturn_t via_nubus_irq(int, void *);
void via_irq_enable(int irq);
void via_irq_disable(int irq);
void via_irq_clear(int irq);
via1[vT1CL] = MAC_CLOCK_LOW;
via1[vT1CH] = MAC_CLOCK_HIGH;
- if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func))
+ if (request_irq(IRQ_MAC_TIMER_1, func, 0, "timer", func))
pr_err("Couldn't register %s interrupt\n", "timer");
}
/*
- * Register the interrupt dispatchers for VIA or RBV machines only.
- */
-
-void __init via_register_interrupts(void)
-{
- if (via_alt_mapping) {
- if (request_irq(IRQ_AUTO_1, via1_irq,
- IRQ_FLG_LOCK|IRQ_FLG_FAST, "software",
- (void *) via1))
- pr_err("Couldn't register %s interrupt\n", "software");
- if (request_irq(IRQ_AUTO_6, via1_irq,
- IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
- (void *) via1))
- pr_err("Couldn't register %s interrupt\n", "via1");
- } else {
- if (request_irq(IRQ_AUTO_1, via1_irq,
- IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
- (void *) via1))
- pr_err("Couldn't register %s interrupt\n", "via1");
- }
- if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
- "via2", (void *) via2))
- pr_err("Couldn't register %s interrupt\n", "via2");
- if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq,
- IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2))
- pr_err("Couldn't register %s interrupt\n", "nubus");
-}
-
-/*
* Debugging dump, used in various places to see what's going on.
*/
* via6522.c :-), disable/pending masks added.
*/
-irqreturn_t via1_irq(int irq, void *dev_id)
+void via1_irq(unsigned int irq, struct irq_desc *desc)
{
int irq_num;
unsigned char irq_bit, events;
events = via1[vIFR] & via1[vIER] & 0x7F;
if (!events)
- return IRQ_NONE;
+ return;
irq_num = VIA1_SOURCE_BASE;
irq_bit = 1;
do {
if (events & irq_bit) {
via1[vIFR] = irq_bit;
- m68k_handle_int(irq_num);
+ generic_handle_irq(irq_num);
}
++irq_num;
irq_bit <<= 1;
} while (events >= irq_bit);
- return IRQ_HANDLED;
}
-irqreturn_t via2_irq(int irq, void *dev_id)
+static void via2_irq(unsigned int irq, struct irq_desc *desc)
{
int irq_num;
unsigned char irq_bit, events;
events = via2[gIFR] & via2[gIER] & 0x7F;
if (!events)
- return IRQ_NONE;
+ return;
irq_num = VIA2_SOURCE_BASE;
irq_bit = 1;
do {
if (events & irq_bit) {
via2[gIFR] = irq_bit | rbv_clear;
- m68k_handle_int(irq_num);
+ generic_handle_irq(irq_num);
}
++irq_num;
irq_bit <<= 1;
} while (events >= irq_bit);
- return IRQ_HANDLED;
}
/*
* VIA2 dispatcher as a fast interrupt handler.
*/
-irqreturn_t via_nubus_irq(int irq, void *dev_id)
+void via_nubus_irq(unsigned int irq, struct irq_desc *desc)
{
int slot_irq;
unsigned char slot_bit, events;
else
events &= ~via2[vDirA];
if (!events)
- return IRQ_NONE;
+ return;
do {
slot_irq = IRQ_NUBUS_F;
do {
if (events & slot_bit) {
events &= ~slot_bit;
- m68k_handle_int(slot_irq);
+ generic_handle_irq(slot_irq);
}
--slot_irq;
slot_bit >>= 1;
else
events &= ~via2[vDirA];
} while (events);
- return IRQ_HANDLED;
+}
+
+/*
+ * Register the interrupt dispatchers for VIA or RBV machines only.
+ */
+
+void __init via_register_interrupts(void)
+{
+ if (via_alt_mapping) {
+ /* software interrupt */
+ irq_set_chained_handler(IRQ_AUTO_1, via1_irq);
+ /* via1 interrupt */
+ irq_set_chained_handler(IRQ_AUTO_6, via1_irq);
+ } else {
+ irq_set_chained_handler(IRQ_AUTO_1, via1_irq);
+ }
+ irq_set_chained_handler(IRQ_AUTO_2, via2_irq);
+ irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq);
}
void via_irq_enable(int irq) {
void __init mvme147_init_IRQ(void)
{
- m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+ m68k_setup_user_interrupt(VEC_USER, 192);
}
void __init config_mvme147(void)
void mvme147_sched_init (irq_handler_t timer_routine)
{
tick_handler = timer_routine;
- if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE,
- "timer 1", NULL))
+ if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL))
pr_err("Couldn't register timer interrupt\n");
/* Init the clock with a value */
static void __init mvme16x_init_IRQ (void)
{
- m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+ m68k_setup_user_interrupt(VEC_USER, 192);
}
#define pcc2chip ((volatile u_char *)0xfff42000)
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/ptrace.h>
#include <asm/system.h>
-#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/q40_master.h>
*/
static void q40_irq_handler(unsigned int, struct pt_regs *fp);
-static void q40_enable_irq(unsigned int);
-static void q40_disable_irq(unsigned int);
+static void q40_irq_enable(struct irq_data *data);
+static void q40_irq_disable(struct irq_data *data);
unsigned short q40_ablecount[35];
unsigned short q40_state[35];
-static int q40_irq_startup(unsigned int irq)
+static unsigned int q40_irq_startup(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
/* test for ISA ints not implemented by HW */
switch (irq) {
case 1: case 2: case 8: case 9:
case 11: case 12: case 13:
printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq);
- return -ENXIO;
+ /* FIXME return -ENXIO; */
}
return 0;
}
-static void q40_irq_shutdown(unsigned int irq)
+static void q40_irq_shutdown(struct irq_data *data)
{
}
-static struct irq_controller q40_irq_controller = {
+static struct irq_chip q40_irq_chip = {
.name = "q40",
- .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock),
- .startup = q40_irq_startup,
- .shutdown = q40_irq_shutdown,
- .enable = q40_enable_irq,
- .disable = q40_disable_irq,
+ .irq_startup = q40_irq_startup,
+ .irq_shutdown = q40_irq_shutdown,
+ .irq_enable = q40_irq_enable,
+ .irq_disable = q40_irq_disable,
};
/*
void __init q40_init_IRQ(void)
{
- m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX);
+ m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1,
+ Q40_IRQ_MAX);
/* setup handler for ISA ints */
m68k_setup_auto_interrupt(q40_irq_handler);
- m68k_irq_startup(IRQ_AUTO_2);
- m68k_irq_startup(IRQ_AUTO_4);
+ m68k_irq_startup_irq(IRQ_AUTO_2);
+ m68k_irq_startup_irq(IRQ_AUTO_4);
/* now enable some ints.. */
master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */
switch (irq) {
case 4:
case 6:
- __m68k_handle_int(Q40_IRQ_SAMPLE, fp);
+ do_IRQ(Q40_IRQ_SAMPLE, fp);
return;
}
if (mir & Q40_IRQ_FRAME_MASK) {
- __m68k_handle_int(Q40_IRQ_FRAME, fp);
+ do_IRQ(Q40_IRQ_FRAME, fp);
master_outb(-1, FRAME_CLEAR_REG);
}
if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) {
goto iirq;
}
q40_state[irq] |= IRQ_INPROGRESS;
- __m68k_handle_int(irq, fp);
+ do_IRQ(irq, fp);
q40_state[irq] &= ~IRQ_INPROGRESS;
/* naively enable everything, if that fails than */
mir = master_inb(IIRQ_REG);
/* should test whether keyboard irq is really enabled, doing it in defhand */
if (mir & Q40_IRQ_KEYB_MASK)
- __m68k_handle_int(Q40_IRQ_KEYBOARD, fp);
+ do_IRQ(Q40_IRQ_KEYBOARD, fp);
return;
}
-void q40_enable_irq(unsigned int irq)
+void q40_irq_enable(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
if (irq >= 5 && irq <= 15) {
mext_disabled--;
if (mext_disabled > 0)
- printk("q40_enable_irq : nested disable/enable\n");
+ printk("q40_irq_enable : nested disable/enable\n");
if (mext_disabled == 0)
master_outb(1, EXT_ENABLE_REG);
}
}
-void q40_disable_irq(unsigned int irq)
+void q40_irq_disable(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
/* disable ISA iqs : only do something if the driver has been
* verified to be Q40 "compatible" - right now IDE, NE2K
* Any driver should not attempt to sleep across disable_irq !!
printk("disable_irq nesting count %d\n",mext_disabled);
}
}
-
-unsigned long q40_probe_irq_on(void)
-{
- printk("irq probing not working - reconfigure the driver to avoid this\n");
- return -1;
-}
-int q40_probe_irq_off(unsigned long irqs)
-{
- return -1;
-}
static irqreturn_t sun3_int7(int irq, void *dev_id)
{
- *sun3_intreg |= (1 << irq);
- if (!(kstat_cpu(0).irqs[irq] % 2000))
- sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 16000) / 2000]);
+ unsigned int cnt;
+
+ cnt = kstat_irqs_cpu(irq, 0);
+ if (!(cnt % 2000))
+ sun3_leds(led_pattern[cnt % 16000 / 2000]);
return IRQ_HANDLED;
}
static irqreturn_t sun3_int5(int irq, void *dev_id)
{
+ unsigned int cnt;
+
#ifdef CONFIG_SUN3
intersil_clear();
#endif
- *sun3_intreg |= (1 << irq);
#ifdef CONFIG_SUN3
intersil_clear();
#endif
xtime_update(1);
update_process_times(user_mode(get_irq_regs()));
- if (!(kstat_cpu(0).irqs[irq] % 20))
- sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]);
+ cnt = kstat_irqs_cpu(irq, 0);
+ if (!(cnt % 20))
+ sun3_leds(led_pattern[cnt % 160 / 20]);
return IRQ_HANDLED;
}
return IRQ_HANDLED;
}
-static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
+static void sun3_irq_enable(struct irq_data *data)
{
- *sun3_intreg &= ~(1 << irq);
+ sun3_enable_irq(data->irq);
+};
- __m68k_handle_int(irq, fp);
-}
+static void sun3_irq_disable(struct irq_data *data)
+{
+ sun3_disable_irq(data->irq);
+};
-static struct irq_controller sun3_irq_controller = {
+static struct irq_chip sun3_irq_chip = {
.name = "sun3",
- .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock),
- .startup = m68k_irq_startup,
- .shutdown = m68k_irq_shutdown,
- .enable = sun3_enable_irq,
- .disable = sun3_disable_irq,
+ .irq_startup = m68k_irq_startup,
+ .irq_shutdown = m68k_irq_shutdown,
+ .irq_enable = sun3_irq_enable,
+ .irq_disable = sun3_irq_disable,
+ .irq_mask = sun3_irq_disable,
+ .irq_unmask = sun3_irq_enable,
};
void __init sun3_init_IRQ(void)
{
*sun3_intreg = 1;
- m68k_setup_auto_interrupt(sun3_inthandle);
- m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7);
- m68k_setup_user_interrupt(VEC_USER, 128, NULL);
+ m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1,
+ 7);
+ m68k_setup_user_interrupt(VEC_USER, 128);
if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL))
pr_err("Couldn't register %s interrupt\n", "int5");
archprepare:
ifdef CONFIG_MIPS32_N32
@echo ' Checking missing-syscalls for N32'
- $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=n32"
+ $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=n32"
endif
ifdef CONFIG_MIPS32_O32
@echo ' Checking missing-syscalls for O32'
- $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=32"
+ $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=32"
endif
install:
static struct map_info flash_map;
static struct mtd_info *mymtd;
-static int nr_parts;
-static struct mtd_partition *parts;
static const char *part_probe_types[] = {
"cmdlinepart",
#ifdef CONFIG_MTD_REDBOOT_PARTS
mymtd = do_map_probe("cfi_probe", &flash_map);
if (mymtd) {
mymtd->owner = THIS_MODULE;
-
- nr_parts = parse_mtd_partitions(mymtd,
- part_probe_types,
- &parts, 0);
- mtd_device_register(mymtd, parts, nr_parts);
+ mtd_device_parse_register(mymtd, part_probe_types,
+ 0, NULL, 0);
} else {
pr_err("Failed to register MTD device for flash\n");
}
* the other bits alone.
*/
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
- if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
- "SMP-IPI", mailbox_interrupt)) {
+ if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt,
+ IRQF_PERCPU | IRQF_NO_THREAD, "SMP-IPI",
+ mailbox_interrupt)) {
panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
}
}
/* arg[0] is "g", the rest is boot parameters */
for (i = 1; i < argc; i++) {
- if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+ if (strlen(arcs_cmdline) + strlen(arg[i]) + 1
>= sizeof(arcs_cmdline))
break;
strcat(arcs_cmdline, arg[i]);
return -EINVAL;
}
+#define gpio_get_value_cansleep gpio_get_value
+
static inline void gpio_set_value(unsigned gpio, int value)
{
switch (bcm47xx_bus_type) {
}
}
+#define gpio_set_value_cansleep gpio_set_value
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ return 0;
+}
+
+static inline int gpio_is_valid(unsigned gpio)
+{
+ return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
+}
+
+
static inline int gpio_direction_input(unsigned gpio)
{
switch (bcm47xx_bus_type) {
}
-/* cansleep wrappers */
-#include <asm-generic/gpio.h>
-
#endif /* __BCM47XX_GPIO_H */
#define __NR_syncfs (__NR_Linux + 342)
#define __NR_sendmmsg (__NR_Linux + 343)
#define __NR_setns (__NR_Linux + 344)
+#define __NR_process_vm_readv (__NR_Linux + 345)
+#define __NR_process_vm_writev (__NR_Linux + 346)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 344
+#define __NR_Linux_syscalls 346
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 344
+#define __NR_O32_Linux_syscalls 346
#if _MIPS_SIM == _MIPS_SIM_ABI64
#define __NR_syncfs (__NR_Linux + 301)
#define __NR_sendmmsg (__NR_Linux + 302)
#define __NR_setns (__NR_Linux + 303)
+#define __NR_process_vm_readv (__NR_Linux + 304)
+#define __NR_process_vm_writev (__NR_Linux + 305)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 303
+#define __NR_Linux_syscalls 305
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 303
+#define __NR_64_Linux_syscalls 305
#if _MIPS_SIM == _MIPS_SIM_NABI32
#define __NR_syncfs (__NR_Linux + 306)
#define __NR_sendmmsg (__NR_Linux + 307)
#define __NR_setns (__NR_Linux + 308)
+#define __NR_process_vm_readv (__NR_Linux + 309)
+#define __NR_process_vm_writev (__NR_Linux + 310)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 308
+#define __NR_Linux_syscalls 310
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 308
+#define __NR_N32_Linux_syscalls 310
#ifdef __KERNEL__
/*
* Compare interrupt can be routed and latched outside the core,
- * so a single execution hazard barrier may not be enough to give
- * it time to clear as seen in the Cause register. 4 time the
- * pipeline depth seems reasonably conservative, and empirically
- * works better in configurations with high CPU/bus clock ratios.
+ * so wait up to worst case number of cycle counter ticks for timer interrupt
+ * changes to propagate to the cause register.
*/
-
-#define compare_change_hazard() \
- do { \
- irq_disable_hazard(); \
- irq_disable_hazard(); \
- irq_disable_hazard(); \
- irq_disable_hazard(); \
- } while (0)
+#define COMPARE_INT_SEEN_TICKS 50
int c0_compare_int_usable(void)
{
* IP7 already pending? Try to clear it by acking the timer.
*/
if (c0_compare_int_pending()) {
- write_c0_compare(read_c0_count());
- compare_change_hazard();
+ cnt = read_c0_count();
+ write_c0_compare(cnt);
+ back_to_back_c0_hazard();
+ while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+ if (!c0_compare_int_pending())
+ break;
if (c0_compare_int_pending())
return 0;
}
cnt = read_c0_count();
cnt += delta;
write_c0_compare(cnt);
- compare_change_hazard();
+ back_to_back_c0_hazard();
if ((int)(read_c0_count() - cnt) < 0)
break;
/* increase delta if the timer was already expired */
while ((int)(read_c0_count() - cnt) <= 0)
; /* Wait for expiry */
- compare_change_hazard();
+ while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+ if (c0_compare_int_pending())
+ break;
if (!c0_compare_int_pending())
return 0;
-
- write_c0_compare(read_c0_count());
- compare_change_hazard();
+ cnt = read_c0_count();
+ write_c0_compare(cnt);
+ back_to_back_c0_hazard();
+ while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+ if (!c0_compare_int_pending())
+ break;
if (c0_compare_int_pending())
return 0;
* for more details.
*/
+#include <linux/module.h>
#include <linux/cpufreq.h>
#include <linux/platform_device.h>
sys sys_syncfs 1
sys sys_sendmmsg 4
sys sys_setns 2
+ sys sys_process_vm_readv 6 /* 4345 */
+ sys sys_process_vm_writev 6
.endm
/* We pre-compute the number of _instruction_ bytes needed to
PTR sys_syncfs
PTR sys_sendmmsg
PTR sys_setns
+ PTR sys_process_vm_readv
+ PTR sys_process_vm_writev /* 5305 */
.size sys_call_table,.-sys_call_table
PTR sys_syncfs
PTR compat_sys_sendmmsg
PTR sys_setns
+ PTR compat_sys_process_vm_readv
+ PTR compat_sys_process_vm_writev /* 6310 */
.size sysn32_call_table,.-sysn32_call_table
PTR sys_syncfs
PTR compat_sys_sendmmsg
PTR sys_setns
+ PTR compat_sys_process_vm_readv /* 4345 */
+ PTR compat_sys_process_vm_writev
.size sys_call_table,.-sys_call_table
}
#endif /* CONFIG_MIPS_MT_SMTC */
- cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+ if (!cpu_data[cpu].asid_cache)
+ cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
*/
#include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/clk.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
*/
#include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <asm/bootinfo.h>
*/
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/init.h>
#include <linux/clk.h>
*/
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/init.h>
#include <linux/clk.h>
*/
#include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
+#include <linux/export.h>
#include <lantiq_soc.h>
#include <xway_dma.h>
*/
#include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/ioport.h>
*/
#include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/clk.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/clk.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/pm.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <asm/reboot.h>
#include <lantiq_soc.h>
+++ /dev/null
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *
- * Author: source@mvista.com
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <pci.h>
-#include <glb.h>
-#include <nand.h>
-
-static struct resource pci_io_resource = {
- .start = PNX8550_PCIIO + 0x1000, /* reserve regacy I/O space */
- .end = PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
- .name = "pci IO space",
- .flags = IORESOURCE_IO
-};
-
-static struct resource pci_mem_resource = {
- .start = PNX8550_PCIMEM,
- .end = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
- .name = "pci memory space",
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops pnx8550_pci_ops;
-
-static struct pci_controller pnx8550_controller = {
- .pci_ops = &pnx8550_pci_ops,
- .io_map_base = PNX8550_PORT_BASE,
- .io_resource = &pci_io_resource,
- .mem_resource = &pci_mem_resource,
-};
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-static inline unsigned long get_system_mem_size(void)
-{
- /* Read IP2031_RANK0_ADDR_LO */
- unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
- /* Read IP2031_RANK1_ADDR_HI */
- unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
- return dram_r1_hi - dram_r0_lo + 1;
-}
-
-static int __init pnx8550_pci_setup(void)
-{
- int pci_mem_code;
- int mem_size = get_system_mem_size() >> 20;
-
- /* Clear the Global 2 Register, PCI Inta Output Enable Registers
- Bit 1:Enable DAC Powerdown
- -> 0:DACs are enabled and are working normally
- 1:DACs are powerdown
- Bit 0:Enable of PCI inta output
- -> 0 = Disable PCI inta output
- 1 = Enable PCI inta output
- */
- PNX8550_GLB2_ENAB_INTA_O = 0;
-
- /* Calc the PCI mem size code */
- if (mem_size >= 128)
- pci_mem_code = SIZE_128M;
- else if (mem_size >= 64)
- pci_mem_code = SIZE_64M;
- else if (mem_size >= 32)
- pci_mem_code = SIZE_32M;
- else
- pci_mem_code = SIZE_16M;
-
- /* Set PCI_XIO registers */
- outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
- outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
- outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
- outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
-
- /* Send memory transaction via PCI_BASE2 */
- outl(0x00000001, PCI_BASE | PCI_IO);
-
- /* Unlock the setup register */
- outl(0xca, PCI_BASE | PCI_UNLOCKREG);
-
- /*
- * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
- * to work, and in order for bus_to_baddr to work without any
- * hacks.
- */
- outl(0x00000000, PCI_BASE | PCI_BASE10);
-
- /*
- *These two bars are set by default or the boot code.
- * However, it's safer to set them here so we're not boot
- * code dependent.
- */
- outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */
- outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */
-
- outl(PCI_EN_TA |
- PCI_EN_PCI2MMI |
- PCI_EN_XIO |
- PCI_SETUP_BASE18_SIZE(SIZE_32M) |
- PCI_SETUP_BASE18_EN |
- PCI_SETUP_BASE14_EN |
- PCI_SETUP_BASE10_PREF |
- PCI_SETUP_BASE10_SIZE(pci_mem_code) |
- PCI_SETUP_CFGMANAGE_EN |
- PCI_SETUP_PCIARB_EN,
- PCI_BASE |
- PCI_SETUP); /* PCI_SETUP */
- outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */
-
- register_pci_controller(&pnx8550_controller);
-
- return 0;
-}
-
-arch_initcall(pnx8550_pci_setup);
+++ /dev/null
-/*
- *
- * 2.6 port, Embedded Alley Solutions, Inc
- *
- * Based on Per Hallsmark, per.hallsmark@mvista.com
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/serial_pnx8xxx.h>
-#include <linux/pm.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/reboot.h>
-#include <asm/pgtable.h>
-#include <asm/time.h>
-
-#include <glb.h>
-#include <int.h>
-#include <pci.h>
-#include <uart.h>
-#include <nand.h>
-
-extern void __init board_setup(void);
-extern void pnx8550_machine_restart(char *);
-extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
-extern struct resource ioport_resource;
-extern struct resource iomem_resource;
-extern char *prom_getcmdline(void);
-
-struct resource standard_io_resources[] = {
- {
- .start = 0x00,
- .end = 0x1f,
- .name = "dma1",
- .flags = IORESOURCE_BUSY
- }, {
- .start = 0x40,
- .end = 0x5f,
- .name = "timer",
- .flags = IORESOURCE_BUSY
- }, {
- .start = 0x80,
- .end = 0x8f,
- .name = "dma page reg",
- .flags = IORESOURCE_BUSY
- }, {
- .start = 0xc0,
- .end = 0xdf,
- .name = "dma2",
- .flags = IORESOURCE_BUSY
- },
-};
-
-#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
-
-extern struct resource pci_io_resource;
-extern struct resource pci_mem_resource;
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-unsigned long get_system_mem_size(void)
-{
- /* Read IP2031_RANK0_ADDR_LO */
- unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
- /* Read IP2031_RANK1_ADDR_HI */
- unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
- return dram_r1_hi - dram_r0_lo + 1;
-}
-
-int pnx8550_console_port = -1;
-
-void __init plat_mem_setup(void)
-{
- int i;
- char* argptr;
-
- board_setup(); /* board specific setup */
-
- _machine_restart = pnx8550_machine_restart;
- _machine_halt = pnx8550_machine_halt;
- pm_power_off = pnx8550_machine_power_off;
-
- /* Clear the Global 2 Register, PCI Inta Output Enable Registers
- Bit 1:Enable DAC Powerdown
- -> 0:DACs are enabled and are working normally
- 1:DACs are powerdown
- Bit 0:Enable of PCI inta output
- -> 0 = Disable PCI inta output
- 1 = Enable PCI inta output
- */
- PNX8550_GLB2_ENAB_INTA_O = 0;
-
- /* IO/MEM resources. */
- set_io_port_base(PNX8550_PORT_BASE);
- ioport_resource.start = 0;
- ioport_resource.end = ~0;
- iomem_resource.start = 0;
- iomem_resource.end = ~0;
-
- /* Request I/O space for devices on this board */
- for (i = 0; i < STANDARD_IO_RESOURCES; i++)
- request_resource(&ioport_resource, standard_io_resources + i);
-
- /* Place the Mode Control bit for GPIO pin 16 in primary function */
- /* Pin 16 is used by UART1, UA1_TX */
- outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
- (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
- PNX8550_GPIO_MC1);
-
- argptr = prom_getcmdline();
- if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
- argptr += strlen("console=ttyS");
- pnx8550_console_port = *argptr == '0' ? 0 : 1;
-
- /* We must initialize the UART (console) before early printk */
- /* Set LCR to 8-bit and BAUD to 38400 (no 5) */
- ip3106_lcr(UART_BASE, pnx8550_console_port) =
- PNX8XXX_UART_LCR_8BIT;
- ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
- }
-}
* Support for all devices (greater than 16) added by David Gathright.
*/
+#include <linux/export.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
+#include <linux/export.h>
#include <linux/platform_device.h>
#include <asm/pci.h>
/* Get the boot parameters */
for (i = 1; i < argc; i++) {
- if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >=
+ if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >=
sizeof(arcs_cmdline))
break;
--- /dev/null
+/*
+ * charon board Device Tree Source
+ *
+ * Copyright (C) 2007 Semihalf
+ * Marian Balakowicz <m8@semihalf.com>
+ *
+ * Copyright (C) 2010 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "anon,charon";
+ compatible = "anon,charon";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>; // 128MB
+ };
+
+ soc5200@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ reg = <0xf0000000 0x00000100>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ timer@600 { // General Purpose Timer
+ compatible = "fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ fsl,has-wdt;
+ };
+
+ can@900 {
+ compatible = "fsl,mpc5200-mscan";
+ interrupts = <2 17 0>;
+ reg = <0x900 0x80>;
+ };
+
+ can@980 {
+ compatible = "fsl,mpc5200-mscan";
+ interrupts = <2 18 0>;
+ reg = <0x980 0x80>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ usb@1000 {
+ compatible = "fsl,mpc5200-ohci","ohci-be";
+ reg = <0x1000 0xff>;
+ interrupts = <2 6 0>;
+ };
+
+ dma-controller@1200 {
+ device_type = "dma-controller";
+ compatible = "fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ serial@2000 { // PSC1
+ compatible = "fsl,mpc5200-psc-uart";
+ reg = <0x2000 0x100>;
+ interrupts = <2 1 0>;
+ };
+
+ serial@2400 { // PSC3
+ compatible = "fsl,mpc5200-psc-uart";
+ reg = <0x2400 0x100>;
+ interrupts = <2 3 0>;
+ };
+
+ ethernet@3000 {
+ compatible = "fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ fixed-link = <1 1 100 0 0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d00 0x40>;
+ interrupts = <2 15 0>;
+ };
+
+
+ i2c@3d40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d40 0x40>;
+ interrupts = <2 16 0>;
+
+ dtt@28 {
+ compatible = "national,lm80";
+ reg = <0x28>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ localbus {
+ compatible = "fsl,mpc5200-lpb","simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = < 0 0 0xfc000000 0x02000000
+ 1 0 0xe0000000 0x04000000 // CS1 range, SM501
+ 3 0 0xe8000000 0x00080000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+ };
+
+ display@1,0 {
+ compatible = "smi,sm501";
+ reg = <1 0x00000000 0x00800000
+ 1 0x03e00000 0x00200000>;
+ mode = "640x480-32@60";
+ interrupts = <1 1 3>;
+ little-endian;
+ };
+
+ mram0@3,0 {
+ compatible = "mtd-ram";
+ reg = <3 0x00000 0x80000>;
+ bank-width = <1>;
+ };
+ };
+
+ pci@f0000d00 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ compatible = "fsl,mpc5200-pci";
+ reg = <0xf0000d00 0x100>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3
+ 0xc000 0 0 2 &mpc5200_pic 0 0 3
+ 0xc000 0 0 3 &mpc5200_pic 0 0 3
+ 0xc000 0 0 4 &mpc5200_pic 0 0 3>;
+ clock-frequency = <0>; // From boot loader
+ interrupts = <2 8 0 2 9 0 2 10 0>;
+ bus-range = <0 0>;
+ ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
+ 0x02000000 0 0x90000000 0x90000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
+ };
+};
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
+CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
# CONFIG_EPOLL is not set
CONFIG_PPC_MPC5200_BUGFIX=y
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_BESTCOMM=y
-CONFIG_SPARSE_IRQ=y
CONFIG_PM=y
# CONFIG_PCI is not set
CONFIG_NET=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_ROM=y
CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_MISC_DEVICES is not set
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_ATA=y
CONFIG_PATA_PLATFORM=y
CONFIG_NETDEVICES=y
CONFIG_LXT_PHY=y
+CONFIG_FIXED_PHY=y
CONFIG_NET_ETHERNET=y
CONFIG_FEC_MPC52xx=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MPC=y
+CONFIG_SENSORS_LM80=y
CONFIG_WATCHDOG=y
+CONFIG_MFD_SM501=y
+CONFIG_FB=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_SM501=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_STORAGE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_BOOK3S_64=m
+CONFIG_KVM_BOOK3S_64_HV=y
+CONFIG_VHOST_NET=m
CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_BOOK3S_64=m
+CONFIG_KVM_BOOK3S_64_HV=y
+CONFIG_VHOST_NET=m
{
if (can_use_virtual_dma)
return request_irq(FLOPPY_IRQ, floppy_hardint,
- IRQF_DISABLED, "floppy", NULL);
+ 0, "floppy", NULL);
else
return request_irq(FLOPPY_IRQ, floppy_interrupt,
- IRQF_DISABLED, "floppy", NULL);
+ 0, "floppy", NULL);
}
static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
LV1_CALL(gpu_context_iomap, 5, 0, 221 )
LV1_CALL(gpu_context_attribute, 6, 0, 225 )
LV1_CALL(gpu_context_intr, 1, 1, 227 )
-LV1_CALL(gpu_attribute, 5, 0, 228 )
+LV1_CALL(gpu_attribute, 3, 0, 228 )
LV1_CALL(get_rtc, 0, 2, 232 )
LV1_CALL(set_ppe_periodic_tracer_frequency, 1, 0, 240 )
LV1_CALL(start_ppe_periodic_tracer, 5, 0, 241 )
#define DEFAULT_PRIORITY 5
/*
- * Mark IPIs as higher priority so we can take them inside interrupts that
- * arent marked IRQF_DISABLED
+ * Mark IPIs as higher priority so we can take them inside interrupts
+ * FIXME: still true now?
*/
#define IPI_PRIORITY 4
#ifdef CONFIG_CBE_RAS
STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
- KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
+ KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
#endif /* CONFIG_CBE_RAS */
STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
#ifdef CONFIG_CBE_RAS
STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
- KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
+ KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
#endif /* CONFIG_CBE_RAS */
STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
#ifdef CONFIG_CBE_RAS
STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
- KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
+ KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
#endif /* CONFIG_CBE_RAS */
. = 0x3000
return 1;
}
#endif
- err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU,
+ err = request_irq(virq, smp_ipi_action[msg], IRQF_PERCPU,
smp_ipi_name[msg], 0);
WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
virq, smp_ipi_name[msg], err);
addi r6,r5,VCORE_NAPPING_THREADS
31: lwarx r4,0,r6
or r4,r4,r0
- popcntw r7,r4
+ PPC_POPCNTW(r7,r4)
cmpw r7,r8
bge 2f
stwcx. r4,0,r6
#include <linux/suspend.h>
#include <linux/memblock.h>
#include <linux/hugetlb.h>
+#include <linux/slab.h>
#include <asm/pgalloc.h>
#include <asm/prom.h>
book3e_hugetlb_preload(vma->vm_mm, address, *ptep);
#endif
}
+
+/*
+ * System memory should not be in /proc/iomem but various tools expect it
+ * (eg kdump).
+ */
+static int add_system_ram_resources(void)
+{
+ struct memblock_region *reg;
+
+ for_each_memblock(memory, reg) {
+ struct resource *res;
+ unsigned long base = reg->base;
+ unsigned long size = reg->size;
+
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ WARN_ON(!res);
+
+ if (res) {
+ res->name = "System RAM";
+ res->start = base;
+ res->end = base + size - 1;
+ res->flags = IORESOURCE_MEM;
+ WARN_ON(request_resource(&iomem_resource, res) < 0);
+ }
+ }
+
+ return 0;
+}
+subsys_initcall(add_system_ram_resources);
struct device_node *root;
const char *vec5;
- root = of_find_node_by_path("/rtas");
+ if (firmware_has_feature(FW_FEATURE_OPAL))
+ root = of_find_node_by_path("/ibm,opal");
+ else
+ root = of_find_node_by_path("/rtas");
if (!root)
root = of_find_node_by_path("/");
#define VEC5_AFFINITY_BYTE 5
#define VEC5_AFFINITY 0x80
- chosen = of_find_node_by_path("/chosen");
- if (chosen) {
- vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
- if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
- dbg("Using form 1 affinity\n");
- form1_affinity = 1;
+
+ if (firmware_has_feature(FW_FEATURE_OPAL))
+ form1_affinity = 1;
+ else {
+ chosen = of_find_node_by_path("/chosen");
+ if (chosen) {
+ vec5 = of_get_property(chosen,
+ "ibm,architecture-vec-5", NULL);
+ if (vec5 && (vec5[VEC5_AFFINITY_BYTE] &
+ VEC5_AFFINITY)) {
+ dbg("Using form 1 affinity\n");
+ form1_affinity = 1;
+ }
}
}
/* list of the supported boards */
static const char *board[] __initdata = {
+ "anon,charon",
"intercontrol,digsy-mtc",
"manroland,mucmc52",
"manroland,uc101",
}
ev->virq = virq;
- rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+ rc = request_irq(virq, ev->handler, 0,
ev->typecode, NULL);
if (rc != 0) {
printk(KERN_ERR "Beat: failed to request virtual IRQ"
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
if (request_irq(virq, pciex_handle_internal_irq,
- IRQF_DISABLED, "pciex", (void *)phb)) {
+ 0, "pciex", (void *)phb)) {
pr_err("PCIEXC:Failed to request irq\n");
goto error;
}
IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT));
BUG_ON(virq == NO_IRQ);
- ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED,
- iommu->name, iommu);
+ ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu);
BUG_ON(ret);
/* set the IOC segment table origin register (and turn on the iommu) */
}
rc = request_irq(irq, cbe_pm_irq,
- IRQF_DISABLED, "cbe-pmu-0", NULL);
+ 0, "cbe-pmu-0", NULL);
if (rc) {
printk("ERROR: Request for irq on node %d failed\n",
node);
snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0",
spu->number);
ret = request_irq(spu->irqs[0], spu_irq_class_0,
- IRQF_DISABLED,
- spu->irq_c0, spu);
+ 0, spu->irq_c0, spu);
if (ret)
goto bail0;
}
snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1",
spu->number);
ret = request_irq(spu->irqs[1], spu_irq_class_1,
- IRQF_DISABLED,
- spu->irq_c1, spu);
+ 0, spu->irq_c1, spu);
if (ret)
goto bail1;
}
snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2",
spu->number);
ret = request_irq(spu->irqs[2], spu_irq_class_2,
- IRQF_DISABLED,
- spu->irq_c2, spu);
+ 0, spu->irq_c2, spu);
if (ret)
goto bail2;
}
static struct irqaction gatwick_cascade_action = {
.handler = gatwick_action,
- .flags = IRQF_DISABLED,
.name = "cascade",
};
if (psurge_secondary_virq)
rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
- IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+ IRQF_PERCPU, "IPI", NULL);
if (rc)
pr_err("Failed to setup secondary cpu IPI\n");
static struct irqaction psurge_irqaction = {
.handler = psurge_ipi_intr,
- .flags = IRQF_DISABLED|IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "primary IPI",
};
spin_lock_init(&dev.lock);
- res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
+ res = request_irq(irq, ps3_notification_interrupt, 0,
"ps3_notification", &dev);
if (res) {
pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
enum ps3_bus_type *bus_type)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
unsigned int *num_dev)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
unsigned int dev_index, enum ps3_dev_type *dev_type)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
{
int result;
- u64 v1;
- u64 v2;
+ u64 v1 = 0;
+ u64 v2 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
enum ps3_reg_type *reg_type)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
unsigned int dev_index, unsigned int *num_regions)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
unsigned int *region_id)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_CURRENT,
make_first_field("bi", 0),
int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_CURRENT,
make_first_field("bi", 0),
enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
{
int result;
- u64 v1;
- u64 v2;
+ u64 v1 = 0;
+ u64 v2 = 0;
result = read_node(PS3_LPAR_ID_CURRENT,
make_first_field("bi", 0),
int ps3_repository_read_boot_dat_size(unsigned int *size)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_CURRENT,
make_first_field("bi", 0),
int ps3_repository_read_vuart_av_port(unsigned int *port)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_CURRENT,
make_first_field("bi", 0),
int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_CURRENT,
make_first_field("bi", 0),
int ps3_repository_read_num_be(unsigned int *num_be)
{
int result;
- u64 v1;
+ u64 v1 = 0;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("ben", 0),
*/
#include <linux/init.h>
-#include <linux/export.h>
+#include <linux/module.h>
#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
* IPIs are marked IRQ_PER_CPU. This has the side effect of
* preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
* applying to them. We EOI them late to avoid re-entering.
- * We mark IPI's with IRQF_DISABLED as they must run with
- * irqs disabled.
*/
mpic_eoi(mpic);
}
}
/* Install error handler */
- if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) {
+ if (request_irq(irq, l2c_error_handler, 0, "L2C", 0) < 0) {
printk(KERN_ERR "Cannot install L2C error handler"
", cache is not enabled\n");
of_node_put(np);
BUG_ON(ipi == NO_IRQ);
/*
- * IPIs are marked IRQF_DISABLED as they must run with irqs
- * disabled, and PERCPU. The handler was set in map.
+ * IPIs are marked IRQF_PERCPU. The handler was set in map.
*/
BUG_ON(request_irq(ipi, icp_ops->ipi_action,
- IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL));
+ IRQF_PERCPU, "IPI", NULL));
}
int __init xics_smp_probe(void)
config CRASH_DUMP
bool "kernel crash dumps"
depends on 64BIT
+ select KEXEC
help
Generate crash dump after being started by kexec.
Crash dump kernels are loaded in the main kernel with kexec-tools
if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
return 0;
- if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76))
+
+ if (facility_mask & CRYPT_S390_MSA3 &&
+ (!test_facility(2) || !test_facility(76)))
return 0;
- if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77))
+ if (facility_mask & CRYPT_S390_MSA4 &&
+ (!test_facility(2) || !test_facility(77)))
return 0;
switch (func & CRYPT_S390_OP_MASK) {
unsigned long address, bits;
unsigned char skey;
+ if (!pte_present(*ptep))
+ return pgste;
address = pte_val(*ptep) & PAGE_MASK;
skey = page_get_storage_key(address);
bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
#ifdef CONFIG_PGSTE
int young;
+ if (!pte_present(*ptep))
+ return pgste;
young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
/* Transfer page referenced bit to pte software bit (host view) */
if (young || (pgste_val(pgste) & RCP_HR_BIT))
}
-static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste)
+static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste, pte_t entry)
{
#ifdef CONFIG_PGSTE
unsigned long address;
unsigned long okey, nkey;
- address = pte_val(*ptep) & PAGE_MASK;
+ if (!pte_present(entry))
+ return;
+ address = pte_val(entry) & PAGE_MASK;
okey = nkey = page_get_storage_key(address);
nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
/* Set page access key and fetch protection bit from pgste */
if (mm_has_pgste(mm)) {
pgste = pgste_get_lock(ptep);
- pgste_set_pte(ptep, pgste);
+ pgste_set_pte(ptep, pgste, entry);
*ptep = entry;
pgste_set_unlock(ptep, pgste);
} else
#define MACHINE_FLAG_LPAR (1UL << 12)
#define MACHINE_FLAG_SPP (1UL << 13)
#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
+#define MACHINE_FLAG_STCKF (1UL << 15)
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
#define MACHINE_HAS_PFMF (0)
#define MACHINE_HAS_SPP (0)
#define MACHINE_HAS_TOPOLOGY (0)
+#define MACHINE_HAS_STCKF (0)
#else /* __s390x__ */
#define MACHINE_HAS_IEEE (1)
#define MACHINE_HAS_CSP (1)
#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
+#define MACHINE_HAS_STCKF (S390_lowcore.machine_flags & MACHINE_FLAG_STCKF)
#endif /* __s390x__ */
#define ZFCPDUMP_HSA_SIZE (32UL<<20)
{
unsigned long long clk;
- if (test_facility(25))
+ if (MACHINE_HAS_STCKF)
asm volatile(".insn s,0xb27c0000,%0" : "=Q" (clk) : : "cc");
else
clk = get_clock();
#define __NR_clock_adjtime 337
#define __NR_syncfs 338
#define __NR_setns 339
-#define NR_syscalls 340
+#define __NR_process_vm_readv 340
+#define __NR_process_vm_writev 341
+#define NR_syscalls 342
/*
* There are some system calls that are not present on 64 bit, some
lgfr %r2,%r2 # int
lgfr %r3,%r3 # int
jg sys_setns
+
+ENTRY(compat_sys_process_vm_readv_wrapper)
+ lgfr %r2,%r2 # compat_pid_t
+ llgtr %r3,%r3 # struct compat_iovec __user *
+ llgfr %r4,%r4 # unsigned long
+ llgtr %r5,%r5 # struct compat_iovec __user *
+ llgfr %r6,%r6 # unsigned long
+ llgf %r0,164(%r15) # unsigned long
+ stg %r0,160(%r15)
+ jg sys_process_vm_readv
+
+ENTRY(compat_sys_process_vm_writev_wrapper)
+ lgfr %r2,%r2 # compat_pid_t
+ llgtr %r3,%r3 # struct compat_iovec __user *
+ llgfr %r4,%r4 # unsigned long
+ llgtr %r5,%r5 # struct compat_iovec __user *
+ llgfr %r6,%r6 # unsigned long
+ llgf %r0,164(%r15) # unsigned long
+ stg %r0,160(%r15)
+ jg sys_process_vm_writev
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
if (test_facility(40))
S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
+ if (test_facility(25))
+ S390_lowcore.machine_flags |= MACHINE_FLAG_STCKF;
#endif
}
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
return;
+ if (OLDMEM_BASE)
+ return;
if (console_devno != -1)
sprintf(str, " cio_ignore=all,!0.0.%04x,!0.0.%04x",
ipl_info.data.fcp.dev_id.devno, console_devno);
#ifdef CONFIG_ZFCPDUMP
- if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
+ if (ipl_info.type == IPL_TYPE_FCP_DUMP && !OLDMEM_BASE) {
memory_end = ZFCPDUMP_HSA_SIZE;
memory_end_set = 1;
}
SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper)
SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper)
SYSCALL(sys_setns,sys_setns,sys_setns_wrapper)
+SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */
+SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper)
return mask;
}
-static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
- struct mask_info *book, struct mask_info *core)
+static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
+ struct mask_info *book,
+ struct mask_info *core,
+ int z10)
{
unsigned int cpu;
cpu_book_id[lcpu] = book->id;
#endif
cpumask_set_cpu(lcpu, &core->mask);
- cpu_core_id[lcpu] = core->id;
+ if (z10) {
+ cpu_core_id[lcpu] = rcpu;
+ core = core->next;
+ } else {
+ cpu_core_id[lcpu] = core->id;
+ }
smp_cpu_polarization[lcpu] = tl_cpu->pp;
}
}
+ return core;
}
static void clear_masks(void)
{
#ifdef CONFIG_SCHED_BOOK
struct mask_info *book = &book_info;
+ struct cpuid cpu_id;
#else
struct mask_info *book = NULL;
#endif
struct mask_info *core = &core_info;
union topology_entry *tle, *end;
+ int z10 = 0;
-
+#ifdef CONFIG_SCHED_BOOK
+ get_cpu_id(&cpu_id);
+ z10 = cpu_id.machine == 0x2097 || cpu_id.machine == 0x2098;
+#endif
spin_lock_irq(&topology_lock);
clear_masks();
tle = info->tle;
end = (union topology_entry *)((unsigned long)info + info->length);
while (tle < end) {
+#ifdef CONFIG_SCHED_BOOK
+ if (z10) {
+ switch (tle->nl) {
+ case 1:
+ book = book->next;
+ book->id = tle->container.id;
+ break;
+ case 0:
+ core = add_cpus_to_mask(&tle->cpu, book, core, z10);
+ break;
+ default:
+ clear_masks();
+ goto out;
+ }
+ tle = next_tle(tle);
+ continue;
+ }
+#endif
switch (tle->nl) {
#ifdef CONFIG_SCHED_BOOK
case 2:
core->id = tle->container.id;
break;
case 0:
- add_cpus_to_mask(&tle->cpu, book, core);
+ add_cpus_to_mask(&tle->cpu, book, core, z10);
break;
default:
clear_masks();
for (i = 0; i < TOPOLOGY_NR_MAG; i++)
printk(" %d", info->mag[i]);
printk(" / %d\n", info->mnest);
- alloc_masks(info, &core_info, 2);
+ alloc_masks(info, &core_info, 1);
#ifdef CONFIG_SCHED_BOOK
- alloc_masks(info, &book_info, 3);
+ alloc_masks(info, &book_info, 2);
#endif
}
NOTES :text :note
+ .dummy : { *(.dummy) } :data
+
RODATA
#ifdef CONFIG_SHARED_KERNEL
} else {
/* Completion interrupt was faster than initial
* interrupt. Set pfault_wait to -1 so the initial
- * interrupt doesn't put the task to sleep. */
- tsk->thread.pfault_wait = -1;
+ * interrupt doesn't put the task to sleep.
+ * If the task is not running, ignore the completion
+ * interrupt since it must be a leftover of a PFAULT
+ * CANCEL operation which didn't remove all pending
+ * completion interrupts. */
+ if (tsk->state == TASK_RUNNING)
+ tsk->thread.pfault_wait = -1;
}
put_task_struct(tsk);
} else {
#endif /* !__ASSEMBLY__ */
#ifdef CONFIG_UNCACHED_MAPPING
+#if defined(CONFIG_29BIT)
+#define UNCAC_ADDR(addr) P2SEGADDR(addr)
+#define CAC_ADDR(addr) P1SEGADDR(addr)
+#else
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start)
#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET)
+#endif
#else
#define UNCAC_ADDR(addr) ((addr))
#define CAC_ADDR(addr) ((addr))
#define __NR_syncfs 362
#define __NR_sendmmsg 363
#define __NR_setns 364
+#define __NR_process_vm_readv 365
+#define __NR_process_vm_writev 366
-#define NR_syscalls 365
+#define NR_syscalls 367
#ifdef __KERNEL__
#define __NR_syncfs 373
#define __NR_sendmmsg 374
#define __NR_setns 375
+#define __NR_process_vm_readv 376
+#define __NR_process_vm_writev 377
#ifdef __KERNEL__
-#define NR_syscalls 376
+#define NR_syscalls 378
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xfffe8000,
.flags = UPF_BOOT_AUTOCONF,
- .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+ .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+ SCSCR_REIE,
.scbrr_algo_id = SCBRR_ALGO_2,
.type = PORT_SCIF,
.irqs = { 192, 192, 192, 192 },
+ .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
static struct platform_device scif0_device = {
static struct plat_sci_port scif1_platform_data = {
.mapbase = 0xfffe8800,
.flags = UPF_BOOT_AUTOCONF,
- .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+ .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+ SCSCR_REIE,
.scbrr_algo_id = SCBRR_ALGO_2,
.type = PORT_SCIF,
.irqs = { 196, 196, 196, 196 },
+ .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
static struct platform_device scif1_device = {
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xfffe9000,
.flags = UPF_BOOT_AUTOCONF,
- .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+ .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+ SCSCR_REIE,
.scbrr_algo_id = SCBRR_ALGO_2,
.type = PORT_SCIF,
.irqs = { 200, 200, 200, 200 },
+ .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
static struct platform_device scif2_device = {
static struct plat_sci_port scif3_platform_data = {
.mapbase = 0xfffe9800,
.flags = UPF_BOOT_AUTOCONF,
- .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+ .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+ SCSCR_REIE,
.scbrr_algo_id = SCBRR_ALGO_2,
.type = PORT_SCIF,
.irqs = { 204, 204, 204, 204 },
+ .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
static struct platform_device scif3_device = {
.long sys_syncfs
.long sys_sendmmsg
.long sys_setns
+ .long sys_process_vm_readv /* 365 */
+ .long sys_process_vm_writev
.long sys_syncfs
.long sys_sendmmsg
.long sys_setns /* 375 */
+ .long sys_process_vm_readv
+ .long sys_process_vm_writev
#define __NR_syncfs 335
#define __NR_sendmmsg 336
#define __NR_setns 337
+#define __NR_process_vm_readv 338
+#define __NR_process_vm_writev 339
-#define NR_syscalls 338
+#define NR_syscalls 340
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns
+/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
- .word sys_syncfs, compat_sys_sendmmsg, sys_setns
+ .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
#endif /* CONFIG_COMPAT */
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
- .word sys_syncfs, sys_sendmmsg, sys_setns
+ .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
}
#else
-static inline void sdv_serial_fixup(void);
+static inline void sdv_serial_fixup(void) {};
#endif
static void __init sdv_arch_setup(void)
}
static const struct devs_id __initconst device_ids[] = {
+ {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data},
{"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data},
{"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data},
{"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data},
spin_unlock_irqrestore(&rtc_lock, flags);
- /* vRTC YEAR reg contains the offset to 1960 */
- year += 1960;
+ /* vRTC YEAR reg contains the offset to 1972 */
+ year += 1972;
printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d "
"mon: %d year: %d\n", sec, min, hour, mday, mon, year);
return 0;
}
+#ifdef CONFIG_NET
static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_blkcipher rblkcipher;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
return 0;
}
+#ifdef CONFIG_NET
static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_blkcipher rblkcipher;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
return 0;
}
+#ifdef CONFIG_NET
static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_aead raead;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
return 0;
}
+#ifdef CONFIG_NET
static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_aead raead;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
return sizeof(struct crypto_shash *);
}
+#ifdef CONFIG_NET
static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_hash rhash;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
return crypto_init_blkcipher_ops_async(tfm);
}
+#ifdef CONFIG_NET
static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_blkcipher rblkcipher;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
down_read(&crypto_alg_sem);
- if (list_empty(&crypto_alg_list))
- return NULL;
-
list_for_each_entry(q, &crypto_alg_list, cra_list) {
int match = 0;
return 0;
}
+#ifdef CONFIG_NET
static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_comp rpcomp;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
return 0;
}
+#ifdef CONFIG_NET
static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_rng rrng;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
return alg->cra_ctxsize;
}
+#ifdef CONFIG_NET
static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
{
struct crypto_report_hash rhash;
nla_put_failure:
return -EMSGSIZE;
}
+#else
+static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ return -ENOSYS;
+}
+#endif
static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
/*
* Suspend / resume control
*/
-static int acpi_idle_suspend;
static u32 saved_bm_rld;
static void acpi_idle_bm_rld_save(void)
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
{
- if (acpi_idle_suspend == 1)
- return 0;
-
acpi_idle_bm_rld_save();
- acpi_idle_suspend = 1;
return 0;
}
int acpi_processor_resume(struct acpi_device * device)
{
- if (acpi_idle_suspend == 0)
- return 0;
-
acpi_idle_bm_rld_restore();
- acpi_idle_suspend = 0;
return 0;
}
local_irq_disable();
- /* Do not access any ACPI IO ports in suspend path */
- if (acpi_idle_suspend) {
- local_irq_enable();
- cpu_relax();
- return -EINVAL;
- }
-
lapic_timer_state_broadcast(pr, cx, 1);
kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
local_irq_disable();
- if (acpi_idle_suspend) {
- local_irq_enable();
- cpu_relax();
- return -EINVAL;
- }
-
-
if (cx->entry_method != ACPI_CSTATE_FFH) {
current_thread_info()->status &= ~TS_POLLING;
/*
if (unlikely(!pr))
return -EINVAL;
-
- if (acpi_idle_suspend) {
- cpu_relax();
- return -EINVAL;
- }
-
if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
if (drv->safe_state_index >= 0) {
return drv->states[drv->safe_state_index].enter(dev,
/* Promise */
{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */
+ /* Asmedia */
+ { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1061 */
+
/* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
static int __init ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev->platform_data;
+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
const struct platform_device_id *id = platform_get_device_id(pdev);
struct ata_port_info pi = ahci_port_info[id->driver_data];
const struct ata_port_info *ppi[] = { &pi, NULL };
static int __devexit ahci_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev->platform_data;
+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
sata_scr_read(link, SCR_STATUS, &sstatus))
rc = -ERESTART;
- if (rc == -ERESTART || try >= max_tries) {
+ if (try >= max_tries) {
/*
* Thaw host port even if reset failed, so that the port
* can be retried on the next phy event. This risks
ata_eh_acquire(ap);
}
+ /*
+ * While disks spinup behind PMP, some controllers fail sending SRST.
+ * They need to be reset - as well as the PMP - before retrying.
+ */
+ if (rc == -ERESTART) {
+ if (ata_is_host_link(link))
+ ata_eh_thaw_port(ap);
+ goto out;
+ }
+
if (try == max_tries - 1) {
sata_down_spd_limit(link, 0);
if (slave)
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;
- /* Class code report is unreliable and SRST
- * times out under certain configurations.
- */
+ /* Class code report is unreliable. */
if (link->pmp < 5)
- link->flags |= ATA_LFLAG_NO_SRST |
- ATA_LFLAG_ASSUME_ATA;
+ link->flags |= ATA_LFLAG_ASSUME_ATA;
/* port 5 is for SEMB device and it doesn't like SRST */
if (link->pmp == 5)
/**
* __ata_change_queue_depth - helper for ata_scsi_change_queue_depth
+ * @ap: ATA port to which the device change the queue depth
+ * @sdev: SCSI device to configure queue depth for
+ * @queue_depth: new queue depth
+ * @reason: calling context
*
* libsas and libata have different approaches for associating a sdev to
* its ata_port.
}
ret = of_irq_to_resource(dn, 0, &irq_res);
- if (ret == NO_IRQ)
+ if (!ret)
irq_res.start = irq_res.end = 0;
else
irq_res.flags = 0;
};
MODULE_AUTHOR("Uwe Koziolek");
-MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
+MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
MODULE_VERSION(DRV_VERSION);
struct device_opp *dev_opp = find_device_opp(dev);
if (IS_ERR(dev_opp))
- return ERR_PTR(PTR_ERR(dev_opp)); /* matching type */
+ return ERR_CAST(dev_opp); /* matching type */
return &dev_opp->head;
}
/* Certain Gen5 chipsets require require idling the GPU before
* unmapping anything from the GTT when VT-d is enabled.
*/
-extern int intel_iommu_gfx_mapped;
static inline int needs_idle_maps(void)
{
+#ifdef CONFIG_INTEL_IOMMU
const unsigned short gpu_devid = intel_private.pcidev->device;
+ extern int intel_iommu_gfx_mapped;
/* Query intel_iommu to see if we need the workaround. Presumably that
* was loaded first.
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
intel_iommu_gfx_mapped)
return 1;
-
+#endif
return 0;
}
intel_private.gtt_bus_addr = reg_addr + gtt_offset;
}
- if (needs_idle_maps());
+ if (needs_idle_maps())
intel_private.base.do_idle_maps = 1;
intel_i9xx_setup_flush();
if (!arch_get_random_long(&v))
break;
- memcpy(buf, &v, chunk);
+ memcpy(p, &v, chunk);
p += chunk;
nbytes -= chunk;
}
static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
{
- int res;
+ int i, res;
BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
freq_table[3].frequency = 1000000;
}
pr_info("db8500-cpufreq : Available frequencies:\n");
- while (freq_table[i].frequency != CPUFREQ_TABLE_END)
- pr_info(" %d Mhz\n", freq_table[i++].frequency/1000);
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+ pr_info(" %d Mhz\n", freq_table[i].frequency/1000);
/* get policy fields based on the table */
res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
}
/**
- * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ * dmi_name_in_vendors - Check if string is in the DMI system or board vendor name
* @str: Case sensitive Name
*/
int dmi_name_in_vendors(const char *str)
{
- static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
- DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
- DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+ static int fields[] = { DMI_SYS_VENDOR, DMI_BOARD_VENDOR, DMI_NONE };
int i;
for (i = 0; fields[i] != DMI_NONE; i++) {
int f = fields[i];
return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
}
-#define MOD_REG_BIT(reg, bit_mask, set) \
-do { \
- int l = __raw_readl(base + reg); \
- if (set) l |= bit_mask; \
- else l &= ~bit_mask; \
- __raw_writel(l, base + reg); \
-} while(0)
+static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
+{
+ int l = __raw_readl(base + reg);
+
+ if (set)
+ l |= mask;
+ else
+ l &= ~mask;
+
+ __raw_writel(l, base + reg);
+}
/**
* _set_gpio_debounce - low level gpio debounce time
u32 gpio_bit = 1 << gpio;
if (cpu_is_omap44xx()) {
- MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
- trigger & IRQ_TYPE_LEVEL_LOW);
- MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
- trigger & IRQ_TYPE_LEVEL_HIGH);
- MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
- trigger & IRQ_TYPE_EDGE_RISING);
- MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
- trigger & IRQ_TYPE_EDGE_FALLING);
+ _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit,
+ trigger & IRQ_TYPE_LEVEL_LOW);
+ _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit,
+ trigger & IRQ_TYPE_LEVEL_HIGH);
+ _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit,
+ trigger & IRQ_TYPE_EDGE_RISING);
+ _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit,
+ trigger & IRQ_TYPE_EDGE_FALLING);
} else {
- MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
- trigger & IRQ_TYPE_LEVEL_LOW);
- MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
- trigger & IRQ_TYPE_LEVEL_HIGH);
- MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
- trigger & IRQ_TYPE_EDGE_RISING);
- MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
- trigger & IRQ_TYPE_EDGE_FALLING);
+ _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
+ trigger & IRQ_TYPE_LEVEL_LOW);
+ _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
+ trigger & IRQ_TYPE_LEVEL_HIGH);
+ _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
+ trigger & IRQ_TYPE_EDGE_RISING);
+ _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
+ trigger & IRQ_TYPE_EDGE_FALLING);
}
if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
if (cpu_is_omap44xx()) {
- MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit,
- trigger != 0);
+ _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit,
+ trigger != 0);
} else {
/*
* GPIO wakeup request can only be generated on edge
gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,
handle_simple_irq);
+ if (!gc) {
+ dev_err(bank->dev, "Memory alloc failed for gc\n");
+ return;
+ }
+
ct = gc->chip_types;
/* NOTE: No ack required, reading IRQ status clears it. */
/* set platform specific polarity inversion */
ret = pca953x_write_reg(chip, PCA953X_INVERT, invert);
- if (ret)
- goto out;
- return 0;
out:
return ret;
}
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
int irq_base=0, invert=0;
- int ret = 0;
+ int ret;
chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
if (chip == NULL)
pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
if (chip->chip_type == PCA953X_TYPE)
- device_pca953x_init(chip, invert);
- else if (chip->chip_type == PCA957X_TYPE)
- device_pca957x_init(chip, invert);
+ ret = device_pca953x_init(chip, invert);
else
+ ret = device_pca957x_init(chip, invert);
+ if (ret)
goto out_failed;
ret = pca953x_irq_setup(chip, id, irq_base);
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
select I2C
select I2C_ALGOBIT
- select SLOW_WORK
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
select FB_CFB_IMAGEBLIT
# i915 depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
+ select BACKLIGHT_LCD_SUPPORT if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select VIDEO_OUTPUT_CONTROL if ACPI
select INPUT if ACPI
property->num_values = num_values;
INIT_LIST_HEAD(&property->enum_blob_list);
- if (name)
+ if (name) {
strncpy(property->name, name, DRM_PROP_NAME_LEN);
+ property->name[DRM_PROP_NAME_LEN-1] = '\0';
+ }
list_add_tail(&property->head, &dev->mode_config.property_list);
return property;
struct drm_connector *save_connectors, *connector;
int count = 0, ro, fail = 0;
struct drm_crtc_helper_funcs *crtc_funcs;
+ struct drm_mode_set save_set;
int ret = 0;
int i;
save_connectors[count++] = *connector;
}
+ save_set.crtc = set->crtc;
+ save_set.mode = &set->crtc->mode;
+ save_set.x = set->crtc->x;
+ save_set.y = set->crtc->y;
+ save_set.fb = set->crtc->fb;
+
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
if (set->crtc->fb != set->fb) {
*connector = save_connectors[count++];
}
+ /* Try to restore the config */
+ if (mode_changed &&
+ !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
+ save_set.y, save_set.fb))
+ DRM_ERROR("failed to restore config after modeset failure\n");
+
kfree(save_connectors);
kfree(save_encoders);
kfree(save_crtcs);
tmp->minor = minor;
tmp->dent = ent;
tmp->info_ent = &files[i];
- list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+
+ mutex_lock(&minor->debugfs_lock);
+ list_add(&tmp->list, &minor->debugfs_list);
+ mutex_unlock(&minor->debugfs_lock);
}
return 0;
char name[64];
int ret;
- INIT_LIST_HEAD(&minor->debugfs_nodes.list);
+ INIT_LIST_HEAD(&minor->debugfs_list);
+ mutex_init(&minor->debugfs_lock);
sprintf(name, "%d", minor_id);
minor->debugfs_root = debugfs_create_dir(name, root);
if (!minor->debugfs_root) {
struct drm_info_node *tmp;
int i;
+ mutex_lock(&minor->debugfs_lock);
for (i = 0; i < count; i++) {
- list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
+ list_for_each_safe(pos, q, &minor->debugfs_list) {
tmp = list_entry(pos, struct drm_info_node, list);
if (tmp->info_ent == &files[i]) {
debugfs_remove(tmp->dent);
}
}
}
+ mutex_unlock(&minor->debugfs_lock);
return 0;
}
EXPORT_SYMBOL(drm_debugfs_remove_files);
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
/* Prevent vblank irq processing while disabling vblank irqs,
* so no updates of timestamps or count can happen after we've
* disabled. Needed to prevent races in case of delayed irq's.
- * Disable preemption, so vblank_time_lock is held as short as
- * possible, even under a kernel with PREEMPT_RT patches.
*/
- preempt_disable();
spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
dev->driver->disable_vblank(dev, crtc);
clear_vblank_timestamps(dev, crtc);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
- preempt_enable();
}
static void vblank_disable_fn(unsigned long arg)
/*
* Wake up any waiters so they don't hang.
*/
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
- for (i = 0; i < dev->num_crtcs; i++) {
- DRM_WAKEUP(&dev->vbl_queue[i]);
- dev->vblank_enabled[i] = 0;
- dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
+ if (dev->num_crtcs) {
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ for (i = 0; i < dev->num_crtcs; i++) {
+ DRM_WAKEUP(&dev->vbl_queue[i]);
+ dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] =
+ dev->driver->get_vblank_counter(dev, i);
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
if (!irq_enabled)
return -EINVAL;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
- /* Disable preemption while holding vblank_time_lock. Do
- * it explicitely to guard against PREEMPT_RT kernel.
- */
- preempt_disable();
spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
if (!dev->vblank_enabled[crtc]) {
/* Enable vblank irqs under vblank_time_lock protection.
}
}
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
- preempt_enable();
} else {
if (!dev->vblank_enabled[crtc]) {
atomic_dec(&dev->vblank_refcount[crtc]);
trace_drm_vblank_event_delivered(current->pid, pipe,
vblwait->request.sequence);
} else {
+ /* drm_handle_vblank_events will call drm_vblank_put */
list_add_tail(&e->base.link, &dev->vblank_event_list);
vblwait->reply.sequence = vblwait->request.sequence;
}
goto done;
}
- if (flags & _DRM_VBLANK_EVENT)
+ if (flags & _DRM_VBLANK_EVENT) {
+ /* must hold on to the vblank ref until the event fires
+ * drm_vblank_put will be called asynchronously
+ */
return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
+ }
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
(seq - vblwait->request.sequence) <= (1<<23)) {
node->minor = minor;
node->dent = ent;
node->info_ent = (void *) key;
- list_add(&node->list, &minor->debugfs_nodes.list);
+
+ mutex_lock(&minor->debugfs_lock);
+ list_add(&node->list, &minor->debugfs_list);
+ mutex_unlock(&minor->debugfs_lock);
return 0;
}
};
static struct drm_driver driver = {
- /* don't use mtrr's here, the Xserver or user space app should
- * deal with them for intel hardware.
+ /* Don't use MTRRs here; the Xserver or userspace app should
+ * deal with them for Intel hardware.
*/
.driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
if (obj->base.size > dev_priv->mm.gtt_mappable_end) {
ret = -E2BIG;
- goto unlock;
+ goto out;
}
if (obj->madv != I915_MADV_WILLNEED) {
nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t reg0 = nv_rd32(dev, reg + 0);
- uint32_t reg1 = nv_rd32(dev, reg + 4);
struct nouveau_pll_vals pll;
struct pll_lims pll_limits;
+ u32 ctrl, mask, coef;
int ret;
ret = get_pll_limits(dev, reg, &pll_limits);
if (!clk)
return -ERANGE;
- reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16);
- reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1;
-
- if (dev_priv->vbios.execute) {
- still_alive();
- nv_wr32(dev, reg + 4, reg1);
- nv_wr32(dev, reg + 0, reg0);
+ coef = pll.N1 << 8 | pll.M1;
+ ctrl = pll.log2P << 16;
+ mask = 0x00070000;
+ if (reg == 0x004008) {
+ mask |= 0x01f80000;
+ ctrl |= (pll_limits.log2p_bias << 19);
+ ctrl |= (pll.log2P << 22);
}
+ if (!dev_priv->vbios.execute)
+ return 0;
+
+ nv_mask(dev, reg + 0, mask, ctrl);
+ nv_wr32(dev, reg + 4, coef);
return 0;
}
if (dev_priv->card_type == NV_10 &&
nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
- nvbo->bo.mem.num_pages < vram_pages / 2) {
+ nvbo->bo.mem.num_pages < vram_pages / 4) {
/*
* Make sure that the color and depth buffers are handled
* by independent memory controller units. Up to a 9x
INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
INIT_LIST_HEAD(&chan->nvsw.flip);
INIT_LIST_HEAD(&chan->fence.pending);
+ spin_lock_init(&chan->fence.lock);
/* setup channel's memory and vm */
ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle);
case OUTPUT_DP:
max_clock = nv_encoder->dp.link_nr;
max_clock *= nv_encoder->dp.link_bw;
- clock = clock * nouveau_connector_bpp(connector) / 8;
+ clock = clock * nouveau_connector_bpp(connector) / 10;
break;
default:
BUG_ON(1);
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_fbdev *nfbdev;
+ int preferred_bpp;
int ret;
nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
}
drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
- drm_fb_helper_initial_config(&nfbdev->helper, 32);
+
+ if (dev_priv->vram_size <= 32 * 1024 * 1024)
+ preferred_bpp = 8;
+ else if (dev_priv->vram_size <= 64 * 1024 * 1024)
+ preferred_bpp = 16;
+ else
+ preferred_bpp = 32;
+
+ drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp);
return 0;
}
return ret;
}
- INIT_LIST_HEAD(&chan->fence.pending);
- spin_lock_init(&chan->fence.lock);
atomic_set(&chan->fence.last_sequence_irq, 0);
return 0;
}
NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
- for (i = 0; info[i].addr; i++) {
+ for (i = 0; i2c && info[i].addr; i++) {
if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
(!match || match(i2c, &info[i]))) {
NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
if(version == 0x15) {
memtimings->timing =
kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL);
- if(!memtimings) {
+ if (!memtimings->timing) {
NV_WARN(dev,"Could not allocate memtiming table\n");
return;
}
if (ret)
goto out_display_early;
+ /* workaround an odd issue on nvc1 by disabling the device's
+ * nosnoop capability. hopefully won't cause issues until a
+ * better fix is found - assuming there is one...
+ */
+ if (dev_priv->chipset == 0xc1) {
+ nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
+ }
+
nouveau_pm_init(dev);
ret = engine->vram.init(dev);
dev_priv->noaccel = !!nouveau_noaccel;
if (nouveau_noaccel == -1) {
switch (dev_priv->chipset) {
- case 0xc1: /* known broken */
- case 0xc8: /* never tested */
+#if 0
+ case 0xXX: /* known broken */
NV_INFO(dev, "acceleration disabled by default, pass "
"noaccel=0 to force enable\n");
dev_priv->noaccel = true;
break;
+#endif
default:
dev_priv->noaccel = false;
break;
int P = (ctrl & 0x00070000) >> 16;
u32 ref = 27000, clk = 0;
- if (ctrl & 0x80000000)
+ if ((ctrl & 0x80000000) && M1) {
clk = ref * N1 / M1;
-
- if (!(ctrl & 0x00000100)) {
- if (ctrl & 0x40000000)
- clk = clk * N2 / M2;
+ if ((ctrl & 0x40000100) == 0x40000000) {
+ if (M2)
+ clk = clk * N2 / M2;
+ else
+ clk = 0;
+ }
}
return clk >> P;
}
/* memory clock */
+ if (!perflvl->memory) {
+ info->mpll_ctrl = 0x00000000;
+ goto out;
+ }
+
ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory,
&N1, &M1, &N2, &M2, &log2P);
if (ret < 0)
mdelay(5);
nv_mask(dev, 0x00c040, 0x00000333, info->ctrl);
+ if (!info->mpll_ctrl)
+ goto resume;
+
/* wait for vblank start on active crtcs, disable memory access */
for (i = 0; i < 2; i++) {
if (!(crtc_mask & (1 << i)))
NV_DEBUG(dev, "\n");
/* master reset */
- nv_mask(dev, 0x000200, 0x00200100, 0x00000000);
- nv_mask(dev, 0x000200, 0x00200100, 0x00200100);
+ nv_mask(dev, 0x000200, 0x00201000, 0x00000000);
+ nv_mask(dev, 0x000200, 0x00201000, 0x00201000);
nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */
/* reset/enable traps and interrupts */
gr_def(ctx, offset + 0x1c, 0x00880000);
break;
case 0x86:
- gr_def(ctx, offset + 0x1c, 0x008c0000);
+ gr_def(ctx, offset + 0x1c, 0x018c0000);
break;
case 0x92:
case 0x96:
colbits = (r4 & 0x0000f000) >> 12;
rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
- banks = ((r4 & 0x01000000) ? 8 : 4);
+ banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
rowsize = parts * banks * (1 << colbits) * 8;
predicted = rowsize << rowbitsa;
struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
int i = 0, gpc, tp, ret;
- u32 magic;
ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM,
&grch->unk408004);
nv_wo32(grch->mmio, i++ * 4, 0x0041880c);
nv_wo32(grch->mmio, i++ * 4, 0x80000018);
- magic = 0x02180000;
- nv_wo32(grch->mmio, i++ * 4, 0x00405830);
- nv_wo32(grch->mmio, i++ * 4, magic);
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) {
- u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800);
- nv_wo32(grch->mmio, i++ * 4, reg);
- nv_wo32(grch->mmio, i++ * 4, magic);
+ if (dev_priv->chipset != 0xc1) {
+ u32 magic = 0x02180000;
+ nv_wo32(grch->mmio, i++ * 4, 0x00405830);
+ nv_wo32(grch->mmio, i++ * 4, magic);
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
+ u32 reg = TP_UNIT(gpc, tp, 0x520);
+ nv_wo32(grch->mmio, i++ * 4, reg);
+ nv_wo32(grch->mmio, i++ * 4, magic);
+ magic += 0x0324;
+ }
+ }
+ } else {
+ u32 magic = 0x02180000;
+ nv_wo32(grch->mmio, i++ * 4, 0x00405830);
+ nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218);
+ nv_wo32(grch->mmio, i++ * 4, 0x004064c4);
+ nv_wo32(grch->mmio, i++ * 4, 0x0086ffff);
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
+ u32 reg = TP_UNIT(gpc, tp, 0x520);
+ nv_wo32(grch->mmio, i++ * 4, reg);
+ nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic);
+ magic += 0x0324;
+ }
+ for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
+ u32 reg = TP_UNIT(gpc, tp, 0x544);
+ nv_wo32(grch->mmio, i++ * 4, reg);
+ nv_wo32(grch->mmio, i++ * 4, magic);
+ magic += 0x0324;
+ }
}
}
/* calculate first set of magics */
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
+ gpc = -1;
for (tp = 0; tp < priv->tp_total; tp++) {
do {
gpc = (gpc + 1) % priv->gpc_nr;
if (1) {
u32 tp_mask = 0, tp_set = 0;
- u8 tpnr[GPC_MAX];
+ u8 tpnr[GPC_MAX], a, b;
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
for (gpc = 0; gpc < priv->gpc_nr; gpc++)
tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8);
- gpc = -1;
- for (i = 0, gpc = -1; i < 32; i++) {
- int ltp = i * (priv->tp_total - 1) / 32;
-
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpnr[gpc]);
- tp = priv->tp_nr[gpc] - tpnr[gpc]--;
+ for (i = 0, gpc = -1, b = -1; i < 32; i++) {
+ a = (i * (priv->tp_total - 1)) / 32;
+ if (a != b) {
+ b = a;
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpnr[gpc]);
+ tp = priv->tp_nr[gpc] - tpnr[gpc]--;
- tp_set |= 1 << ((gpc * 8) + tp);
+ tp_set |= 1 << ((gpc * 8) + tp);
+ }
- do {
- nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
- tp_set ^= tp_mask;
- nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set);
- tp_set ^= tp_mask;
- } while (ltp == (++i * (priv->tp_total - 1) / 32));
- i--;
+ nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
+ nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask);
}
}
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
- 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
+ 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
u32 bsize = nv_rd32(dev, 0x10f20c);
u32 offset, length;
bool uniform = true;
- int ret, i;
+ int ret, part;
NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize);
/* read amount of vram attached to each memory controller */
- for (i = 0; i < parts; i++) {
- u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000));
+ part = 0;
+ while (parts) {
+ u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000));
+ if (psize == 0)
+ continue;
+ parts--;
+
if (psize != bsize) {
if (psize < bsize)
bsize = psize;
uniform = false;
}
- NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize);
-
+ NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
dev_priv->vram_size += (u64)psize << 20;
}
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
-
- /* adjust pm to upcoming mode change */
- radeon_pm_compute_clocks(rdev);
-
if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
return false;
return true;
}
}
- DRM_ERROR("aux i2c too many retries, giving up\n");
+ DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
return -EREMOTEIO;
}
return actual_temp * 1000;
}
+void sumo_pm_init_profile(struct radeon_device *rdev)
+{
+ int idx;
+
+ /* default */
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
+
+ /* low,mid sh/mh */
+ if (rdev->flags & RADEON_IS_MOBILITY)
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
+ else
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
+
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
+
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
+
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
+
+ /* high sh/mh */
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx =
+ rdev->pm.power_state[idx].num_clock_modes - 1;
+
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx =
+ rdev->pm.power_state[idx].num_clock_modes - 1;
+}
+
void evergreen_pm_misc(struct radeon_device *rdev)
{
int req_ps_idx = rdev->pm.requested_power_state_index;
WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
rdev->mc.vram_end >> 12);
}
- WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+ WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
if (rdev->flags & RADEON_IS_IGP) {
tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
pcie_lanes);
}
-static int r600_pm_get_type_index(struct radeon_device *rdev,
- enum radeon_pm_state_type ps_type,
- int instance)
-{
- int i;
- int found_instance = -1;
-
- for (i = 0; i < rdev->pm.num_power_states; i++) {
- if (rdev->pm.power_state[i].type == ps_type) {
- found_instance++;
- if (found_instance == instance)
- return i;
- }
- }
- /* return default if no match */
- return rdev->pm.default_power_state_index;
-}
-
void rs780_pm_init_profile(struct radeon_device *rdev)
{
if (rdev->pm.num_power_states == 2) {
void r600_pm_init_profile(struct radeon_device *rdev)
{
+ int idx;
+
if (rdev->family == CHIP_R600) {
/* XXX */
/* default */
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
/* low sh */
- if (rdev->flags & RADEON_IS_MOBILITY) {
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
- } else {
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
- }
+ if (rdev->flags & RADEON_IS_MOBILITY)
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
+ else
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
/* mid sh */
- if (rdev->flags & RADEON_IS_MOBILITY) {
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
- } else {
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
- }
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
/* high sh */
- rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
- rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
/* low mh */
- if (rdev->flags & RADEON_IS_MOBILITY) {
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
- } else {
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
- }
+ if (rdev->flags & RADEON_IS_MOBILITY)
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
+ else
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
/* mid mh */
- if (rdev->flags & RADEON_IS_MOBILITY) {
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
- } else {
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
- rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
- }
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
/* high mh */
- rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
- rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx =
- r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
}
struct radeon_power_state {
enum radeon_pm_state_type type;
- /* XXX: use a define for num clock modes */
- struct radeon_pm_clock_info clock_info[8];
+ struct radeon_pm_clock_info *clock_info;
/* number of valid clock modes in this power state */
int num_clock_modes;
struct radeon_pm_clock_info *default_clock_mode;
struct device *int_hwmon_dev;
};
+int radeon_pm_get_type_index(struct radeon_device *rdev,
+ enum radeon_pm_state_type ps_type,
+ int instance);
/*
* Benchmarking
u64 gpu_addr;
};
+
+/*
+ * Mutex which allows recursive locking from the same process.
+ */
+struct radeon_mutex {
+ struct mutex mutex;
+ struct task_struct *owner;
+ int level;
+};
+
+static inline void radeon_mutex_init(struct radeon_mutex *mutex)
+{
+ mutex_init(&mutex->mutex);
+ mutex->owner = NULL;
+ mutex->level = 0;
+}
+
+static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
+{
+ if (mutex_trylock(&mutex->mutex)) {
+ /* The mutex was unlocked before, so it's ours now */
+ mutex->owner = current;
+ } else if (mutex->owner != current) {
+ /* Another process locked the mutex, take it */
+ mutex_lock(&mutex->mutex);
+ mutex->owner = current;
+ }
+ /* Otherwise the mutex was already locked by this process */
+
+ mutex->level++;
+}
+
+static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
+{
+ if (--mutex->level > 0)
+ return;
+
+ mutex->owner = NULL;
+ mutex_unlock(&mutex->mutex);
+}
+
+
/*
* Core structure, functions and helpers.
*/
struct radeon_gem gem;
struct radeon_pm pm;
uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
- struct mutex cs_mutex;
+ struct radeon_mutex cs_mutex;
struct radeon_wb wb;
struct radeon_dummy_page dummy_page;
bool gpu_lockup;
.pm_misc = &evergreen_pm_misc,
.pm_prepare = &evergreen_pm_prepare,
.pm_finish = &evergreen_pm_finish,
- .pm_init_profile = &rs780_pm_init_profile,
+ .pm_init_profile = &sumo_pm_init_profile,
.pm_get_dynpm_state = &r600_pm_get_dynpm_state,
.pre_page_flip = &evergreen_pre_page_flip,
.page_flip = &evergreen_page_flip,
extern void evergreen_pm_misc(struct radeon_device *rdev);
extern void evergreen_pm_prepare(struct radeon_device *rdev);
extern void evergreen_pm_finish(struct radeon_device *rdev);
+extern void sumo_pm_init_profile(struct radeon_device *rdev);
extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
for (i = 0; i < num_indices; i++) {
gpio = &i2c_info->asGPIO_Info[i];
+ /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */
+ if ((rdev->family == CHIP_R420) ||
+ (rdev->family == CHIP_R423) ||
+ (rdev->family == CHIP_RV410)) {
+ if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) ||
+ (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) ||
+ (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) {
+ gpio->ucClkMaskShift = 0x19;
+ gpio->ucDataMaskShift = 0x18;
+ }
+ }
+
/* some evergreen boards have bad data for this entry */
if (ASIC_IS_DCE4(rdev)) {
if ((i == 7) &&
return state_index;
/* last mode is usually default, array is low to high */
for (i = 0; i < num_modes; i++) {
+ rdev->pm.power_state[state_index].clock_info =
+ kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+ if (!rdev->pm.power_state[state_index].clock_info)
+ return state_index;
+ rdev->pm.power_state[state_index].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
switch (frev) {
case 1:
- rdev->pm.power_state[state_index].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].mclk =
le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
rdev->pm.power_state[state_index].clock_info[0].sclk =
state_index++;
break;
case 2:
- rdev->pm.power_state[state_index].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].mclk =
le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
rdev->pm.power_state[state_index].clock_info[0].sclk =
state_index++;
break;
case 3:
- rdev->pm.power_state[state_index].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].mclk =
le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
rdev->pm.power_state[state_index].clock_info[0].sclk =
rdev->pm.default_power_state_index = state_index;
rdev->pm.power_state[state_index].default_clock_mode =
&rdev->pm.power_state[state_index].clock_info[mode_index - 1];
- if (ASIC_IS_DCE5(rdev)) {
+ if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
/* NI chips post without MC ucode, so default clocks are strobe mode only */
rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
(power_state->v1.ucNonClockStateIndex *
power_info->pplib.ucNonClockSize));
- for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
- clock_info = (union pplib_clock_info *)
- (mode_info->atom_context->bios + data_offset +
- le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
- (power_state->v1.ucClockStateIndices[j] *
- power_info->pplib.ucClockInfoSize));
- valid = radeon_atombios_parse_pplib_clock_info(rdev,
- state_index, mode_index,
- clock_info);
- if (valid)
- mode_index++;
+ rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
+ ((power_info->pplib.ucStateEntrySize - 1) ?
+ (power_info->pplib.ucStateEntrySize - 1) : 1),
+ GFP_KERNEL);
+ if (!rdev->pm.power_state[i].clock_info)
+ return state_index;
+ if (power_info->pplib.ucStateEntrySize - 1) {
+ for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
+ clock_info = (union pplib_clock_info *)
+ (mode_info->atom_context->bios + data_offset +
+ le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
+ (power_state->v1.ucClockStateIndices[j] *
+ power_info->pplib.ucClockInfoSize));
+ valid = radeon_atombios_parse_pplib_clock_info(rdev,
+ state_index, mode_index,
+ clock_info);
+ if (valid)
+ mode_index++;
+ }
+ } else {
+ rdev->pm.power_state[state_index].clock_info[0].mclk =
+ rdev->clock.default_mclk;
+ rdev->pm.power_state[state_index].clock_info[0].sclk =
+ rdev->clock.default_sclk;
+ mode_index++;
}
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
if (mode_index) {
non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
&non_clock_info_array->nonClockInfo[non_clock_array_index];
- for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
- clock_array_index = power_state->v2.clockInfoIndex[j];
- /* XXX this might be an inagua bug... */
- if (clock_array_index >= clock_info_array->ucNumEntries)
- continue;
- clock_info = (union pplib_clock_info *)
- &clock_info_array->clockInfo[clock_array_index];
- valid = radeon_atombios_parse_pplib_clock_info(rdev,
- state_index, mode_index,
- clock_info);
- if (valid)
- mode_index++;
+ rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
+ (power_state->v2.ucNumDPMLevels ?
+ power_state->v2.ucNumDPMLevels : 1),
+ GFP_KERNEL);
+ if (!rdev->pm.power_state[i].clock_info)
+ return state_index;
+ if (power_state->v2.ucNumDPMLevels) {
+ for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
+ clock_array_index = power_state->v2.clockInfoIndex[j];
+ /* XXX this might be an inagua bug... */
+ if (clock_array_index >= clock_info_array->ucNumEntries)
+ continue;
+ clock_info = (union pplib_clock_info *)
+ &clock_info_array->clockInfo[clock_array_index];
+ valid = radeon_atombios_parse_pplib_clock_info(rdev,
+ state_index, mode_index,
+ clock_info);
+ if (valid)
+ mode_index++;
+ }
+ } else {
+ rdev->pm.power_state[state_index].clock_info[0].mclk =
+ rdev->clock.default_mclk;
+ rdev->pm.power_state[state_index].clock_info[0].sclk =
+ rdev->clock.default_sclk;
+ mode_index++;
}
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
if (mode_index) {
} else {
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
if (rdev->pm.power_state) {
- /* add the default mode */
- rdev->pm.power_state[state_index].type =
- POWER_STATE_TYPE_DEFAULT;
- rdev->pm.power_state[state_index].num_clock_modes = 1;
- rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
- rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
- rdev->pm.power_state[state_index].default_clock_mode =
- &rdev->pm.power_state[state_index].clock_info[0];
- rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
- rdev->pm.power_state[state_index].pcie_lanes = 16;
- rdev->pm.default_power_state_index = state_index;
- rdev->pm.power_state[state_index].flags = 0;
- state_index++;
+ rdev->pm.power_state[0].clock_info =
+ kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+ if (rdev->pm.power_state[0].clock_info) {
+ /* add the default mode */
+ rdev->pm.power_state[state_index].type =
+ POWER_STATE_TYPE_DEFAULT;
+ rdev->pm.power_state[state_index].num_clock_modes = 1;
+ rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
+ rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
+ rdev->pm.power_state[state_index].default_clock_mode =
+ &rdev->pm.power_state[state_index].clock_info[0];
+ rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+ rdev->pm.power_state[state_index].pcie_lanes = 16;
+ rdev->pm.default_power_state_index = state_index;
+ rdev->pm.power_state[state_index].flags = 0;
+ state_index++;
+ }
}
}
struct radeon_bo *sobj = NULL;
uint64_t saddr, daddr;
int r, n;
- unsigned int time;
+ int time;
n = RADEON_BENCHMARK_ITERATIONS;
r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj);
/* allocate 2 power states */
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL);
- if (!rdev->pm.power_state) {
- rdev->pm.default_power_state_index = state_index;
- rdev->pm.num_power_states = 0;
-
- rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
- rdev->pm.current_clock_mode_index = 0;
- return;
- }
+ if (rdev->pm.power_state) {
+ /* allocate 1 clock mode per state */
+ rdev->pm.power_state[0].clock_info =
+ kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+ rdev->pm.power_state[1].clock_info =
+ kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+ if (!rdev->pm.power_state[0].clock_info ||
+ !rdev->pm.power_state[1].clock_info)
+ goto pm_failed;
+ } else
+ goto pm_failed;
/* check for a thermal chip */
offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
rdev->pm.current_clock_mode_index = 0;
+ return;
+
+pm_failed:
+ rdev->pm.default_power_state_index = state_index;
+ rdev->pm.num_power_states = 0;
+
+ rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
+ rdev->pm.current_clock_mode_index = 0;
}
void radeon_external_tmds_setup(struct drm_encoder *encoder)
struct radeon_cs_chunk *ib_chunk;
int r;
- mutex_lock(&rdev->cs_mutex);
+ radeon_mutex_lock(&rdev->cs_mutex);
/* initialize parser */
memset(&parser, 0, sizeof(struct radeon_cs_parser));
parser.filp = filp;
if (r) {
DRM_ERROR("Failed to initialize parser !\n");
radeon_cs_parser_fini(&parser, r);
- mutex_unlock(&rdev->cs_mutex);
+ radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_ib_get(rdev, &parser.ib);
if (r) {
DRM_ERROR("Failed to get ib !\n");
radeon_cs_parser_fini(&parser, r);
- mutex_unlock(&rdev->cs_mutex);
+ radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_cs_parser_relocs(&parser);
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r);
- mutex_unlock(&rdev->cs_mutex);
+ radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
/* Copy the packet into the IB, the parser will read from the
if (r || parser.parser_error) {
DRM_ERROR("Invalid command stream !\n");
radeon_cs_parser_fini(&parser, r);
- mutex_unlock(&rdev->cs_mutex);
+ radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_cs_finish_pages(&parser);
if (r) {
DRM_ERROR("Invalid command stream !\n");
radeon_cs_parser_fini(&parser, r);
- mutex_unlock(&rdev->cs_mutex);
+ radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_ib_schedule(rdev, parser.ib);
DRM_ERROR("Failed to schedule IB !\n");
}
radeon_cs_parser_fini(&parser, r);
- mutex_unlock(&rdev->cs_mutex);
+ radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
/* mutex initialization are all done here so we
* can recall function without having locking issues */
- mutex_init(&rdev->cs_mutex);
+ radeon_mutex_init(&rdev->cs_mutex);
mutex_init(&rdev->ib_pool.mutex);
mutex_init(&rdev->cp.mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
int r;
int resched;
+ /* Prevent CS ioctl from interfering */
+ radeon_mutex_lock(&rdev->cs_mutex);
+
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
radeon_restore_bios_scratch_regs(rdev);
drm_helper_resume_force_mode(rdev->ddev);
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
- return 0;
}
- /* bad news, how to tell it to userspace ? */
- dev_info(rdev->dev, "GPU reset failed\n");
+
+ radeon_mutex_unlock(&rdev->cs_mutex);
+
+ if (r) {
+ /* bad news, how to tell it to userspace ? */
+ dev_info(rdev->dev, "GPU reset failed\n");
+ }
+
return r;
}
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
-
- /* adjust pm to upcoming mode change */
- radeon_pm_compute_clocks(rdev);
-
if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
return false;
return true;
#define ACPI_AC_CLASS "ac_adapter"
+int radeon_pm_get_type_index(struct radeon_device *rdev,
+ enum radeon_pm_state_type ps_type,
+ int instance)
+{
+ int i;
+ int found_instance = -1;
+
+ for (i = 0; i < rdev->pm.num_power_states; i++) {
+ if (rdev->pm.power_state[i].type == ps_type) {
+ found_instance++;
+ if (found_instance == instance)
+ return i;
+ }
+ }
+ /* return default if no match */
+ return rdev->pm.default_power_state_index;
+}
+
#ifdef CONFIG_ACPI
static int radeon_acpi_event(struct notifier_block *nb,
unsigned long val,
struct vmw_dma_buffer *dmabuf = NULL;
int ret;
+ /* A lot of the code assumes this */
+ if (handle && (width != 64 || height != 64))
+ return -EINVAL;
+
if (handle) {
ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
handle, &surface);
top = clips->y1;
bottom = clips->y2;
- clips_ptr = clips;
- for (i = 1; i < num_clips; i++, clips_ptr += inc) {
+ /* skip the first clip rect */
+ for (i = 1, clips_ptr = clips + inc;
+ i < num_clips; i++, clips_ptr += inc) {
left = min_t(int, left, (int)clips_ptr->x1);
right = max_t(int, right, (int)clips_ptr->x2);
top = min_t(int, top, (int)clips_ptr->y1);
* drm_encoder_cleanup which takes the lock we deadlock.
*/
drm_mode_config_cleanup(dev_priv->dev);
- vmw_kms_close_legacy_display_system(dev_priv);
+ if (dev_priv->sou_priv)
+ vmw_kms_close_screen_object_display(dev_priv);
+ else
+ vmw_kms_close_legacy_display_system(dev_priv);
return 0;
}
while (new_bus) {
new_bridge = new_bus->self;
- if (new_bridge) {
- /* go through list of devices already registered */
- list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
- bus = same_bridge_vgadev->pdev->bus;
- bridge = bus->self;
-
- /* see if the share a bridge with this device */
- if (new_bridge == bridge) {
- /* if their direct parent bridge is the same
- as any bridge of this device then it can't be used
- for that device */
- same_bridge_vgadev->bridge_has_one_vga = false;
- }
+ /* go through list of devices already registered */
+ list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
+ bus = same_bridge_vgadev->pdev->bus;
+ bridge = bus->self;
+
+ /* see if the share a bridge with this device */
+ if (new_bridge == bridge) {
+ /* if their direct parent bridge is the same
+ as any bridge of this device then it can't be used
+ for that device */
+ same_bridge_vgadev->bridge_has_one_vga = false;
+ }
- /* now iterate the previous devices bridge hierarchy */
- /* if the new devices parent bridge is in the other devices
- hierarchy then we can't use it to control this device */
- while (bus) {
- bridge = bus->self;
- if (bridge) {
- if (bridge == vgadev->pdev->bus->self)
- vgadev->bridge_has_one_vga = false;
- }
- bus = bus->parent;
+ /* now iterate the previous devices bridge hierarchy */
+ /* if the new devices parent bridge is in the other devices
+ hierarchy then we can't use it to control this device */
+ while (bus) {
+ bridge = bus->self;
+ if (bridge) {
+ if (bridge == vgadev->pdev->bus->self)
+ vgadev->bridge_has_one_vga = false;
}
+ bus = bus->parent;
}
}
new_bus = new_bus->parent;
* General Public License for more details.
*/
+#include <linux/module.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
return -ENODEV;
io_base = ioremap(res->start, resource_size(res));
- if (!io_base) {
- ret = -ENOMEM;
- goto free_state;
- }
+ if (!io_base)
+ return -ENOMEM;
/* make sure protocol 1 is selected */
val = readl(io_base + HSEM_CTRL_REG);
/* For SCSI -> ATAPI command conversion */
#include <scsi/scsi.h>
-#include <linux/irq.h>
#include <linux/io.h>
#include <asm/byteorder.h>
#include <linux/uaccess.h>
#include <scsi/scsi_ioctl.h>
#include <asm/byteorder.h>
-#include <linux/irq.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <asm/byteorder.h>
-#include <linux/irq.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <asm/unaligned.h>
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
del_timer_sync(&led_cdev->blink_timer);
if (led_cdev->blink_set &&
- !led_cdev->blink_set(led_cdev, delay_on, delay_off)) {
- led_cdev->blink_delay_on = *delay_on;
- led_cdev->blink_delay_off = *delay_off;
+ !led_cdev->blink_set(led_cdev, delay_on, delay_off))
return;
- }
/* blink with 1 Hz as default if nothing specified */
if (!*delay_on && !*delay_off)
err = macii_init_via();
if (err) goto out;
- err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB",
+ err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB",
macii_interrupt);
if (err) goto out;
return err;
}
- if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST,
- "ADB", maciisi_interrupt)) {
+ if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB",
+ maciisi_interrupt)) {
printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
return -EAGAIN;
}
struct r5dev *pdev, *qdev;
clear_bit(STRIPE_HANDLE, &sh->state);
- if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) {
+ if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) {
/* already being handled, ensure it gets handled
* again when current action finishes */
set_bit(STRIPE_HANDLE, &sh->state);
/* check if the array has lost more than max_degraded devices and,
* if so, some requests might need to be failed.
*/
- if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written)
- handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
- if (s.failed > conf->max_degraded && s.syncing)
- handle_failed_sync(conf, sh, &s);
+ if (s.failed > conf->max_degraded) {
+ sh->check_state = 0;
+ sh->reconstruct_state = 0;
+ if (s.to_read+s.to_write+s.written)
+ handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
+ if (s.syncing)
+ handle_failed_sync(conf, sh, &s);
+ }
/*
* might be able to return some write requests if the parity blocks
return_io(s.return_bi);
- clear_bit(STRIPE_ACTIVE, &sh->state);
+ clear_bit_unlock(STRIPE_ACTIVE, &sh->state);
}
static void raid5_activate_delayed(struct r5conf *conf)
u8 i2c_r_data[24];
u8 i = 0;
u8 fifo_status = 0;
- int ret;
int status = 0;
mxl_i2c("read %d bytes", count);
i2c_w_data[4+(i*3)] = 0x00;
}
- ret = mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
+ mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
/* Check for I2C NACK status */
if (mxl111sf_i2c_check_status(state) == 1) {
goto fail;
ret = mxl111sf_write_reg(state, 0x00, 0x00);
- if (mxl_fail(ret))
- goto fail;
+ mxl_fail(ret);
fail:
return ret;
}
/* set hysteresis value reg: 0x0B<5:0> */
ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
(hysteresis_value & 0x3F));
+ mxl_fail(ret);
}
ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
+ mxl_fail(ret);
- return val;
+ return ret;
}
/*
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/media.h>
+#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
cap->bus_info[0] = 0;
cap->version = KERNEL_VERSION(1, 0, 0);
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
- | V4L2_CAP_STREAMING;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+ V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING;
return 0;
}
strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
cap->bus_info[0] = 0;
cap->version = KERNEL_VERSION(1, 0, 0);
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
- | V4L2_CAP_VIDEO_OUTPUT
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE
+ | V4L2_CAP_VIDEO_OUTPUT_MPLANE
| V4L2_CAP_STREAMING;
return 0;
}
menu_info = &mapping->menu_info[query_menu->index];
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
+ if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
+ (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
s32 bitmap;
if (!ctrl->cached) {
/* Valid menu indices are reported by the GET_RES request for
* UVC controls that support it.
*/
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
+ if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
+ (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
if (!ctrl->cached) {
ret = uvc_ctrl_populate_cache(chain, ctrl);
if (ret < 0)
fill_event(&ev, ctrl, changes);
list_for_each_entry(sev, &ctrl->ev_subs, node)
- if (sev->fh && (sev->fh != fh ||
- (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)))
+ if (sev->fh != fh ||
+ (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))
v4l2_event_queue_fh(sev->fh, &ev);
}
if (ctrl->cluster[0]->has_volatiles)
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
}
+ fh = NULL;
}
if (changed || update_inactive) {
/* If a control was changed that was not one of the controls
unsigned long flags;
unsigned i;
+ if (sub->type == V4L2_EVENT_ALL)
+ return -EINVAL;
+
if (elems < 1)
elems = 1;
if (sub->type == V4L2_EVENT_CTRL) {
{
struct v4l2_subscribed_event *sev;
unsigned long flags;
+ int i;
if (sub->type == V4L2_EVENT_ALL) {
v4l2_event_unsubscribe_all(fh);
sev = v4l2_event_subscribed(fh, sub->type, sub->id);
if (sev != NULL) {
+ /* Remove any pending events for this subscription */
+ for (i = 0; i < sev->in_use; i++) {
+ list_del(&sev->events[sev_pos(sev, i)].list);
+ fh->navailable--;
+ }
list_del(&sev->list);
- sev->fh = NULL;
}
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
continue;
for (plane = 0; plane < vb->num_planes; ++plane) {
+ vb->v4l2_planes[plane].length = q->plane_sizes[plane];
vb->v4l2_planes[plane].m.mem_offset = off;
dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n",
q->num_buffers -= buffers;
if (!q->num_buffers)
q->memory = 0;
+ INIT_LIST_HEAD(&q->queued_list);
}
/**
{
unsigned int plane;
for (plane = 0; plane < vb->num_planes; ++plane) {
+ void *mem_priv = vb->planes[plane].mem_priv;
/*
* If num_users() has not been provided, call_memop
* will return 0, apparently nobody cares about this
* case anyway. If num_users() returns more than 1,
* we are not the only user of the plane's memory.
*/
- if (call_memop(q, plane, num_users,
- vb->planes[plane].mem_priv) > 1)
+ if (mem_priv && call_memop(q, plane, num_users, mem_priv) > 1)
return true;
}
return false;
* TODO: Event handling with irq_chip. Waiting for PRCMU fw support.
*/
+#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/platform_device.h>
* Debugfs support for the AB5500 MFD driver
*/
+#include <linux/export.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/mfd/ab5500/ab5500.h>
config EEPROM_DIGSY_MTC_CFG
bool "DigsyMTC display configuration EEPROMs device"
- depends on PPC_MPC5200_GPIO && GPIOLIB && SPI_GPIO
+ depends on GPIO_MPC5200 && SPI_GPIO
help
This option enables access to display configuration EEPROMs
on digsy_mtc board. You have to additionally select Microwire
/* VENDOR SPEC register */
#define SDHCI_VENDOR_SPEC 0xC0
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
+#define SDHCI_WTMK_LVL 0x44
#define SDHCI_MIX_CTRL 0x48
/*
if (is_imx53_esdhc(imx_data))
imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
+ /*
+ * The imx6q ROM code will change the default watermark level setting
+ * to something insane. Change it back here.
+ */
+ if (is_imx6q_usdhc(imx_data))
+ writel(0x08100810, host->ioaddr + SDHCI_WTMK_LVL);
+
boarddata = &imx_data->boarddata;
if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
if (!host->mmc->parent->platform_data) {
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
# PINCTRL infrastructure and drivers
#
-menuconfig PINCTRL
- bool "PINCTRL Support"
+config PINCTRL
+ bool
depends on EXPERIMENTAL
- help
- This enables the PINCTRL subsystem for controlling pins
- on chip packages, for example multiplexing pins on primarily
- PGA and BGA packages for systems on chip.
-
- If unsure, say N.
if PINCTRL
+menu "Pin controllers"
+ depends on PINCTRL
+
config PINMUX
bool "Support pinmux controllers"
- help
- Say Y here if you want the pincontrol subsystem to handle pin
- multiplexing drivers.
config DEBUG_PINCTRL
bool "Debug PINCTRL calls"
bool "CSR SiRFprimaII pinmux driver"
depends on ARCH_PRIMA2
select PINMUX
- help
- Say Y here to enable the SiRFprimaII pinmux driver
config PINMUX_U300
bool "U300 pinmux driver"
depends on ARCH_U300
select PINMUX
- help
- Say Y here to enable the U300 pinmux driver
+
+endmenu
endif
depends on EXPERIMENTAL
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL || RFKILL = n
- depends on POWER_SUPPLY
depends on SERIO_I8042
+ select POWER_SUPPLY
+ select LEDS_CLASS
+ select NEW_LEDS
default n
---help---
This driver adds support for rfkill and backlight control to Dell
.update_status = dell_send_intensity,
};
-static void touchpad_led_on()
+static void touchpad_led_on(void)
{
int command = 0x97;
char data = 1;
i8042_command(&data, command | 1 << 12);
}
-static void touchpad_led_off()
+static void touchpad_led_off(void)
{
int command = 0x97;
char data = 2;
}
result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
- IRQF_DISABLED, "vuart", &vuart_bus_priv);
+ 0, "vuart", &vuart_bus_priv);
if (result) {
pr_debug("%s:%d: request_irq failed (%d)\n",
goto fail_close_device;
}
- error = request_irq(dev->irq, handler, IRQF_DISABLED,
+ error = request_irq(dev->irq, handler, 0,
dev->sbd.core.driver->name, dev);
if (error) {
dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n",
/*
* rtc_time's year contains the increment over 1900, but vRTC's YEAR
* register can't be programmed to value larger than 0x64, so vRTC
- * driver chose to use 1960 (1970 is UNIX time start point) as the base,
+ * driver chose to use 1972 (1970 is UNIX time start point) as the base,
* and does the translation at read/write time.
*
- * Why not just use 1970 as the offset? it's because using 1960 will
+ * Why not just use 1970 as the offset? it's because using 1972 will
* make it consistent in leap year setting for both vrtc and low-level
- * physical rtc devices.
+ * physical rtc devices. Then why not use 1960 as the offset? If we use
+ * 1960, for a device's first use, its YEAR register is 0 and the system
+ * year will be parsed as 1960 which is not a valid UNIX time and will
+ * cause many applications to fail mysteriously.
*/
static int mrst_read_time(struct device *dev, struct rtc_time *time)
{
time->tm_year = vrtc_cmos_read(RTC_YEAR);
spin_unlock_irqrestore(&rtc_lock, flags);
- /* Adjust for the 1960/1900 */
- time->tm_year += 60;
+ /* Adjust for the 1972/1900 */
+ time->tm_year += 72;
time->tm_mon--;
- return RTC_24H;
+ return rtc_valid_tm(time);
}
static int mrst_set_time(struct device *dev, struct rtc_time *time)
min = time->tm_min;
sec = time->tm_sec;
- if (yrs < 70 || yrs > 138)
+ if (yrs < 72 || yrs > 138)
return -EINVAL;
- yrs -= 60;
+ yrs -= 72;
spin_lock_irqsave(&rtc_lock, flags);
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
return -ENODATA;
+ if (OLDMEM_BASE)
+ return -ENODATA;
zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));
debug_register_view(zcore_dbf, &debug_sprintf_view);
}
/**
- * ap_schedule_poll_timer(): Schedule poll timer.
+ * __ap_schedule_poll_timer(): Schedule poll timer.
*
* Set up the timer to run the poll tasklet
*/
-static inline void ap_schedule_poll_timer(void)
+static inline void __ap_schedule_poll_timer(void)
{
ktime_t hr_time;
spin_lock_bh(&ap_poll_timer_lock);
- if (ap_using_interrupts() || ap_suspend_flag)
- goto out;
- if (hrtimer_is_queued(&ap_poll_timer))
+ if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
goto out;
if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
hr_time = ktime_set(0, poll_timeout);
}
/**
+ * ap_schedule_poll_timer(): Schedule poll timer.
+ *
+ * Set up the timer to run the poll tasklet
+ */
+static inline void ap_schedule_poll_timer(void)
+{
+ if (ap_using_interrupts())
+ return;
+ __ap_schedule_poll_timer();
+}
+
+/**
* ap_poll_read(): Receive pending reply messages from an AP device.
* @ap_dev: pointer to the AP device
* @flags: pointer to control flags, bit 2^0 is set if another poll is
*flags |= 1;
*flags |= 2;
break;
- case AP_RESPONSE_Q_FULL:
case AP_RESPONSE_RESET_IN_PROGRESS:
+ __ap_schedule_poll_timer();
+ case AP_RESPONSE_Q_FULL:
*flags |= 2;
break;
case AP_RESPONSE_MESSAGE_TOO_BIG:
obj-$(CONFIG_MAPLE) += maple/
obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_GENERIC_GPIO) += pfc.o
+
+#
+# For the moment we only use this framework for ARM-based SH/R-Mobile
+# platforms and generic SH. SH-based SH-Mobile platforms are still using
+# an older framework that is pending up-porting, at which point this
+# special casing can go away.
+#
+obj-$(CONFIG_SUPERH)$(CONFIG_ARCH_SHMOBILE) += pm_runtime.o
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/debugfs.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/sh_clk.h>
return clk_rate_round_helper(&div_range_round);
}
+static long clk_rate_mult_range_iter(unsigned int pos,
+ struct clk_rate_round_data *rounder)
+{
+ return clk_get_rate(rounder->arg) * pos;
+}
+
+long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
+ unsigned int mult_max, unsigned long rate)
+{
+ struct clk_rate_round_data mult_range_round = {
+ .min = mult_min,
+ .max = mult_max,
+ .func = clk_rate_mult_range_iter,
+ .arg = clk_get_parent(clk),
+ .rate = rate,
+ };
+
+ return clk_rate_round_helper(&mult_range_round);
+}
+
int clk_rate_table_find(struct clk *clk,
struct cpufreq_frequency_table *freq_table,
unsigned long rate)
list_add(&child->sibling, &parent->children);
child->parent = parent;
- /* now do the debugfs renaming to reattach the child
- to the proper parent */
-
return 0;
}
subsys_initcall(clk_syscore_init);
#endif
-/*
- * debugfs support to trace clock tree hierarchy and attributes
- */
-static struct dentry *clk_debugfs_root;
-
-static int clk_debugfs_register_one(struct clk *c)
-{
- int err;
- struct dentry *d;
- struct clk *pa = c->parent;
- char s[255];
- char *p = s;
-
- p += sprintf(p, "%p", c);
- d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root);
- if (!d)
- return -ENOMEM;
- c->dentry = d;
-
- d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount);
- if (!d) {
- err = -ENOMEM;
- goto err_out;
- }
- d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate);
- if (!d) {
- err = -ENOMEM;
- goto err_out;
- }
- d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags);
- if (!d) {
- err = -ENOMEM;
- goto err_out;
- }
- return 0;
-
-err_out:
- debugfs_remove_recursive(c->dentry);
- return err;
-}
-
-static int clk_debugfs_register(struct clk *c)
-{
- int err;
- struct clk *pa = c->parent;
-
- if (pa && !pa->dentry) {
- err = clk_debugfs_register(pa);
- if (err)
- return err;
- }
-
- if (!c->dentry) {
- err = clk_debugfs_register_one(c);
- if (err)
- return err;
- }
- return 0;
-}
-
-static int __init clk_debugfs_init(void)
-{
- struct clk *c;
- struct dentry *d;
- int err;
-
- d = debugfs_create_dir("clock", NULL);
- if (!d)
- return -ENOMEM;
- clk_debugfs_root = d;
-
- list_for_each_entry(c, &clock_list, node) {
- err = clk_debugfs_register(c);
- if (err)
- goto err_out;
- }
- return 0;
-err_out:
- debugfs_remove_recursive(clk_debugfs_root);
- return err;
-}
-late_initcall(clk_debugfs_init);
-
static int __init clk_late_init(void)
{
unsigned long flags;
/*
- * arch/arm/mach-shmobile/pm_runtime.c
- *
- * Runtime PM support code for SuperH Mobile ARM
+ * Runtime PM support code
*
* Copyright (C) 2009-2010 Magnus Damm
*
/*-------------------------------------------------------------------------*/
-static int __init atmel_spi_probe(struct platform_device *pdev)
+static int __devinit atmel_spi_probe(struct platform_device *pdev)
{
struct resource *regs;
int irq;
return ret;
}
-static int __exit atmel_spi_remove(struct platform_device *pdev)
+static int __devexit atmel_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct atmel_spi *as = spi_master_get_devdata(master);
},
.suspend = atmel_spi_suspend,
.resume = atmel_spi_resume,
+ .probe = atmel_spi_probe,
.remove = __exit_p(atmel_spi_remove),
};
module_platform_driver(atmel_spi_driver);
#include "as102_fw.h"
#include "dvbdev.h"
-int debug;
-module_param_named(debug, debug, int, 0644);
+int as102_debug;
+module_param_named(debug, as102_debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
int dual_tuner;
#define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
#define DRIVER_NAME "as10x_usb"
-extern int debug;
+extern int as102_debug;
+#define debug as102_debug
#define dprintk(debug, args...) \
do { if (debug) { \
CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i;
- hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page) + fs->page_offset));
+ hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page.p) + fs->page_offset));
hw_buffer.s.size = fs->size;
CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
}
static int debug;
module_param(debug, int, 0600);
-#define T1 (HZ/10)
-#define T2 (HZ/3)
-#define N2 3
+/* Defaults: these are from the specification */
+
+#define T1 10 /* 100mS */
+#define T2 34 /* 333mS */
+#define N2 3 /* Retry 3 times */
/* Use long timers for testing at low speed with debug on */
#ifdef DEBUG_TIMING
-#define T1 HZ
-#define T2 (2 * HZ)
+#define T1 100
+#define T2 200
#endif
/*
},
/*
+ * Common SH-2(A) SCIF definitions for ports with FIFO data
+ * count registers.
+ */
+ [SCIx_SH2_SCIF_FIFODATA_REGTYPE] = {
+ [SCSMR] = { 0x00, 16 },
+ [SCBRR] = { 0x04, 8 },
+ [SCSCR] = { 0x08, 16 },
+ [SCxTDR] = { 0x0c, 8 },
+ [SCxSR] = { 0x10, 16 },
+ [SCxRDR] = { 0x14, 8 },
+ [SCFCR] = { 0x18, 16 },
+ [SCFDR] = { 0x1c, 16 },
+ [SCTFDR] = sci_reg_invalid,
+ [SCRFDR] = sci_reg_invalid,
+ [SCSPTR] = { 0x20, 16 },
+ [SCLSR] = { 0x24, 16 },
+ },
+
+ /*
* Common SH-3 SCIF definitions.
*/
[SCIx_SH3_SCIF_REGTYPE] = {
static void virtio_pci_release_dev(struct device *_d)
{
- struct virtio_device *dev = container_of(_d, struct virtio_device,
- dev);
- struct virtio_pci_device *vp_dev = to_vp_device(dev);
-
- kfree(vp_dev);
+ /*
+ * No need for a release method as we allocate/free
+ * all devices together with the pci devices.
+ * Provide an empty one to avoid getting a warning from core.
+ */
}
/* the PCI probing function */
pci_iounmap(pci_dev, vp_dev->ioaddr);
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
+ kfree(vp_dev);
}
#ifdef CONFIG_PM
* the btrfs file release call will add this inode to the
* ordered operations list so that we make sure to flush out any
* new data the application may have written before commit.
- *
- * yes, its silly to have a single bitflag, but we might grow more
- * of these.
*/
unsigned ordered_data_close:1;
unsigned orphan_meta_reserved:1;
unsigned dummy_inode:1;
unsigned in_defrag:1;
+ unsigned delalloc_meta_reserved:1;
/*
* always compress this one file
static int btrfs_delayed_inode_reserve_metadata(
struct btrfs_trans_handle *trans,
struct btrfs_root *root,
+ struct inode *inode,
struct btrfs_delayed_node *node)
{
struct btrfs_block_rsv *src_rsv;
struct btrfs_block_rsv *dst_rsv;
u64 num_bytes;
int ret;
+ int release = false;
src_rsv = trans->block_rsv;
dst_rsv = &root->fs_info->delayed_block_rsv;
if (!ret)
node->bytes_reserved = num_bytes;
return ret;
+ } else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
+ spin_lock(&BTRFS_I(inode)->lock);
+ if (BTRFS_I(inode)->delalloc_meta_reserved) {
+ BTRFS_I(inode)->delalloc_meta_reserved = 0;
+ spin_unlock(&BTRFS_I(inode)->lock);
+ release = true;
+ goto migrate;
+ }
+ spin_unlock(&BTRFS_I(inode)->lock);
+
+ /* Ok we didn't have space pre-reserved. This shouldn't happen
+ * too often but it can happen if we do delalloc to an existing
+ * inode which gets dirtied because of the time update, and then
+ * isn't touched again until after the transaction commits and
+ * then we try to write out the data. First try to be nice and
+ * reserve something strictly for us. If not be a pain and try
+ * to steal from the delalloc block rsv.
+ */
+ ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes);
+ if (!ret)
+ goto out;
+
+ ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
+ if (!ret)
+ goto out;
+
+ /*
+ * Ok this is a problem, let's just steal from the global rsv
+ * since this really shouldn't happen that often.
+ */
+ WARN_ON(1);
+ ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv,
+ dst_rsv, num_bytes);
+ goto out;
}
+migrate:
ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
+
+out:
+ /*
+ * Migrate only takes a reservation, it doesn't touch the size of the
+ * block_rsv. This is to simplify people who don't normally have things
+ * migrated from their block rsv. If they go to release their
+ * reservation, that will decrease the size as well, so if migrate
+ * reduced size we'd end up with a negative size. But for the
+ * delalloc_meta_reserved stuff we will only know to drop 1 reservation,
+ * but we could in fact do this reserve/migrate dance several times
+ * between the time we did the original reservation and we'd clean it
+ * up. So to take care of this, release the space for the meta
+ * reservation here. I think it may be time for a documentation page on
+ * how block rsvs. work.
+ */
if (!ret)
node->bytes_reserved = num_bytes;
+ if (release)
+ btrfs_block_rsv_release(root, src_rsv, num_bytes);
+
return ret;
}
goto release_node;
}
- ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node);
+ ret = btrfs_delayed_inode_reserve_metadata(trans, root, inode,
+ delayed_node);
if (ret)
goto release_node;
u64 features;
struct btrfs_key location;
struct buffer_head *bh;
- struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root),
- GFP_NOFS);
- struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
- GFP_NOFS);
+ struct btrfs_super_block *disk_super;
struct btrfs_root *tree_root = btrfs_sb(sb);
- struct btrfs_fs_info *fs_info = NULL;
- struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
- GFP_NOFS);
- struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
- GFP_NOFS);
+ struct btrfs_fs_info *fs_info = tree_root->fs_info;
+ struct btrfs_root *extent_root;
+ struct btrfs_root *csum_root;
+ struct btrfs_root *chunk_root;
+ struct btrfs_root *dev_root;
struct btrfs_root *log_tree_root;
-
int ret;
int err = -EINVAL;
int num_backups_tried = 0;
int backup_index = 0;
- struct btrfs_super_block *disk_super;
+ extent_root = fs_info->extent_root =
+ kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+ csum_root = fs_info->csum_root =
+ kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+ chunk_root = fs_info->chunk_root =
+ kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+ dev_root = fs_info->dev_root =
+ kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
- if (!extent_root || !tree_root || !tree_root->fs_info ||
- !chunk_root || !dev_root || !csum_root) {
+ if (!extent_root || !csum_root || !chunk_root || !dev_root) {
err = -ENOMEM;
goto fail;
}
- fs_info = tree_root->fs_info;
ret = init_srcu_struct(&fs_info->subvol_srcu);
if (ret) {
mutex_init(&fs_info->reloc_mutex);
init_completion(&fs_info->kobj_unregister);
- fs_info->tree_root = tree_root;
- fs_info->extent_root = extent_root;
- fs_info->csum_root = csum_root;
- fs_info->chunk_root = chunk_root;
- fs_info->dev_root = dev_root;
- fs_info->fs_devices = fs_devices;
INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
INIT_LIST_HEAD(&fs_info->space_info);
btrfs_mapping_init(&fs_info->mapping_tree);
btrfs_stop_workers(&fs_info->caching_workers);
fail_alloc:
fail_iput:
+ btrfs_mapping_tree_free(&fs_info->mapping_tree);
+
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
iput(fs_info->btree_inode);
-
- btrfs_close_devices(fs_info->fs_devices);
- btrfs_mapping_tree_free(&fs_info->mapping_tree);
fail_bdi:
bdi_destroy(&fs_info->bdi);
fail_srcu:
cleanup_srcu_struct(&fs_info->subvol_srcu);
fail:
+ btrfs_close_devices(fs_info->fs_devices);
free_fs_info(fs_info);
return ERR_PTR(err);
recovery_tree_root:
-
if (!btrfs_test_opt(tree_root, RECOVERY))
goto fail_tree_roots;
kfree(rsv);
}
-int btrfs_block_rsv_add(struct btrfs_root *root,
- struct btrfs_block_rsv *block_rsv,
- u64 num_bytes)
+static inline int __block_rsv_add(struct btrfs_root *root,
+ struct btrfs_block_rsv *block_rsv,
+ u64 num_bytes, int flush)
{
int ret;
if (num_bytes == 0)
return 0;
- ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
+ ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
if (!ret) {
block_rsv_add_bytes(block_rsv, num_bytes, 1);
return 0;
return ret;
}
+int btrfs_block_rsv_add(struct btrfs_root *root,
+ struct btrfs_block_rsv *block_rsv,
+ u64 num_bytes)
+{
+ return __block_rsv_add(root, block_rsv, num_bytes, 1);
+}
+
int btrfs_block_rsv_add_noflush(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv,
u64 num_bytes)
{
- int ret;
-
- if (num_bytes == 0)
- return 0;
-
- ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 0);
- if (!ret) {
- block_rsv_add_bytes(block_rsv, num_bytes, 1);
- return 0;
- }
-
- return ret;
+ return __block_rsv_add(root, block_rsv, num_bytes, 0);
}
int btrfs_block_rsv_check(struct btrfs_root *root,
*/
static unsigned drop_outstanding_extent(struct inode *inode)
{
+ unsigned drop_inode_space = 0;
unsigned dropped_extents = 0;
BUG_ON(!BTRFS_I(inode)->outstanding_extents);
BTRFS_I(inode)->outstanding_extents--;
+ if (BTRFS_I(inode)->outstanding_extents == 0 &&
+ BTRFS_I(inode)->delalloc_meta_reserved) {
+ drop_inode_space = 1;
+ BTRFS_I(inode)->delalloc_meta_reserved = 0;
+ }
+
/*
* If we have more or the same amount of outsanding extents than we have
* reserved then we need to leave the reserved extents count alone.
*/
if (BTRFS_I(inode)->outstanding_extents >=
BTRFS_I(inode)->reserved_extents)
- return 0;
+ return drop_inode_space;
dropped_extents = BTRFS_I(inode)->reserved_extents -
BTRFS_I(inode)->outstanding_extents;
BTRFS_I(inode)->reserved_extents -= dropped_extents;
- return dropped_extents;
+ return dropped_extents + drop_inode_space;
}
/**
nr_extents = BTRFS_I(inode)->outstanding_extents -
BTRFS_I(inode)->reserved_extents;
BTRFS_I(inode)->reserved_extents += nr_extents;
+ }
- to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
+ /*
+ * Add an item to reserve for updating the inode when we complete the
+ * delalloc io.
+ */
+ if (!BTRFS_I(inode)->delalloc_meta_reserved) {
+ nr_extents++;
+ BTRFS_I(inode)->delalloc_meta_reserved = 1;
}
+
+ to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
spin_unlock(&BTRFS_I(inode)->lock);
struct btrfs_free_space *entry, u8 *type)
{
struct btrfs_free_space_entry *e;
+ int ret;
+
+ if (!io_ctl->cur) {
+ ret = io_ctl_check_crc(io_ctl, io_ctl->index);
+ if (ret)
+ return ret;
+ }
e = io_ctl->cur;
entry->offset = le64_to_cpu(e->offset);
io_ctl_unmap_page(io_ctl);
- if (io_ctl->index >= io_ctl->num_pages)
- return 0;
-
- return io_ctl_check_crc(io_ctl, io_ctl->index);
+ return 0;
}
static int io_ctl_read_bitmap(struct io_ctl *io_ctl,
{
int ret;
- if (io_ctl->cur && io_ctl->cur != io_ctl->orig)
- io_ctl_unmap_page(io_ctl);
-
ret = io_ctl_check_crc(io_ctl, io_ctl->index);
if (ret)
return ret;
num_entries--;
}
+ io_ctl_unmap_page(&io_ctl);
+
/*
* We add the bitmaps at the end of the entries in order that
* the bitmap entries are added to the cache.
struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
struct btrfs_path *path;
struct inode *inode;
+ struct btrfs_block_rsv *rsv;
+ u64 num_bytes;
u64 alloc_hint = 0;
int ret;
int prealloc;
if (!path)
return -ENOMEM;
+ rsv = trans->block_rsv;
+ trans->block_rsv = &root->fs_info->trans_block_rsv;
+
+ num_bytes = trans->bytes_reserved;
+ /*
+ * 1 item for inode item insertion if need
+ * 3 items for inode item update (in the worst case)
+ * 1 item for free space object
+ * 3 items for pre-allocation
+ */
+ trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8);
+ ret = btrfs_block_rsv_add_noflush(root, trans->block_rsv,
+ trans->bytes_reserved);
+ if (ret)
+ goto out;
again:
inode = lookup_free_ino_inode(root, path);
if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
ret = PTR_ERR(inode);
- goto out;
+ goto out_release;
}
if (IS_ERR(inode)) {
ret = create_free_ino_inode(root, trans, path);
if (ret)
- goto out;
+ goto out_release;
goto again;
}
}
btrfs_free_reserved_data_space(inode, prealloc);
+ ret = btrfs_write_out_ino_cache(root, trans, path);
out_put:
iput(inode);
+out_release:
+ btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
out:
- if (ret == 0)
- ret = btrfs_write_out_ino_cache(root, trans, path);
+ trans->block_rsv = rsv;
+ trans->bytes_reserved = num_bytes;
btrfs_free_path(path);
return ret;
struct page *locked_page,
u64 start, u64 end, int *page_started,
unsigned long *nr_written, int unlock);
+static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode);
static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
struct inode *inode, struct inode *dir,
trans = btrfs_join_transaction(root);
BUG_ON(IS_ERR(trans));
trans->block_rsv = &root->fs_info->delalloc_block_rsv;
- ret = btrfs_update_inode(trans, root, inode);
+ ret = btrfs_update_inode_fallback(trans, root, inode);
BUG_ON(ret);
}
goto out;
ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
- ret = btrfs_update_inode(trans, root, inode);
+ ret = btrfs_update_inode_fallback(trans, root, inode);
BUG_ON(ret);
}
ret = 0;
if (ret)
goto out;
}
+ /* release the path since we're done with it */
+ btrfs_release_path(path);
+
root->orphan_cleanup_state = ORPHAN_CLEANUP_DONE;
if (root->orphan_block_rsv)
/*
* copy everything in the in-memory inode into the btree.
*/
-noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
+static noinline int btrfs_update_inode_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct inode *inode)
{
struct btrfs_inode_item *inode_item;
struct extent_buffer *leaf;
int ret;
- /*
- * If the inode is a free space inode, we can deadlock during commit
- * if we put it into the delayed code.
- *
- * The data relocation inode should also be directly updated
- * without delay
- */
- if (!btrfs_is_free_space_inode(root, inode)
- && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
- ret = btrfs_delayed_update_inode(trans, root, inode);
- if (!ret)
- btrfs_set_inode_last_trans(trans, inode);
- return ret;
- }
-
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
}
/*
+ * copy everything in the in-memory inode into the btree.
+ */
+noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode)
+{
+ int ret;
+
+ /*
+ * If the inode is a free space inode, we can deadlock during commit
+ * if we put it into the delayed code.
+ *
+ * The data relocation inode should also be directly updated
+ * without delay
+ */
+ if (!btrfs_is_free_space_inode(root, inode)
+ && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
+ ret = btrfs_delayed_update_inode(trans, root, inode);
+ if (!ret)
+ btrfs_set_inode_last_trans(trans, inode);
+ return ret;
+ }
+
+ return btrfs_update_inode_item(trans, root, inode);
+}
+
+static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode)
+{
+ int ret;
+
+ ret = btrfs_update_inode(trans, root, inode);
+ if (ret == -ENOSPC)
+ return btrfs_update_inode_item(trans, root, inode);
+ return ret;
+}
+
+/*
* unlink helper that gets used here in inode.c and in the tree logging
* recovery code. It remove a link in a directory with a given name, and
* also drops the back refs in the inode to the directory
if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) {
ret = btrfs_ordered_update_i_size(inode, 0, ordered);
if (!ret)
- err = btrfs_update_inode(trans, root, inode);
+ err = btrfs_update_inode_fallback(trans, root, inode);
goto out;
}
add_pending_csums(trans, inode, ordered->file_offset, &ordered->list);
ret = btrfs_ordered_update_i_size(inode, 0, ordered);
if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags))
- btrfs_update_inode(trans, root, inode);
+ btrfs_update_inode_fallback(trans, root, inode);
ret = 0;
out_unlock:
unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset,
ret = btrfs_orphan_del(NULL, inode);
}
- trans->block_rsv = &root->fs_info->trans_block_rsv;
- ret = btrfs_update_inode(trans, root, inode);
- if (ret && !err)
- err = ret;
+ if (trans) {
+ trans->block_rsv = &root->fs_info->trans_block_rsv;
+ ret = btrfs_update_inode(trans, root, inode);
+ if (ret && !err)
+ err = ret;
- nr = trans->blocks_used;
- ret = btrfs_end_transaction_throttle(trans, root);
- btrfs_btree_balance_dirty(root, nr);
+ nr = trans->blocks_used;
+ ret = btrfs_end_transaction_throttle(trans, root);
+ btrfs_btree_balance_dirty(root, nr);
+ }
out:
btrfs_free_block_rsv(root, rsv);
ei->orphan_meta_reserved = 0;
ei->dummy_inode = 0;
ei->in_defrag = 0;
+ ei->delalloc_meta_reserved = 0;
ei->force_compress = BTRFS_COMPRESS_NONE;
ei->delayed_node = NULL;
list_add_tail(&new_edge->list[UPPER],
&new_node->lower);
}
+ } else {
+ list_add_tail(&new_node->lower, &cache->leaves);
}
rb_node = tree_insert(&cache->rb_root, new_node->bytenr,
static int scrub_submit(struct scrub_dev *sdev)
{
struct scrub_bio *sbio;
- struct bio *bio;
- int i;
if (sdev->curr == -1)
return 0;
sbio = sdev->bios[sdev->curr];
-
- bio = bio_alloc(GFP_NOFS, sbio->count);
- if (!bio)
- goto nomem;
-
- bio->bi_private = sbio;
- bio->bi_end_io = scrub_bio_end_io;
- bio->bi_bdev = sdev->dev->bdev;
- bio->bi_sector = sbio->physical >> 9;
-
- for (i = 0; i < sbio->count; ++i) {
- struct page *page;
- int ret;
-
- page = alloc_page(GFP_NOFS);
- if (!page)
- goto nomem;
-
- ret = bio_add_page(bio, page, PAGE_SIZE, 0);
- if (!ret) {
- __free_page(page);
- goto nomem;
- }
- }
-
sbio->err = 0;
sdev->curr = -1;
atomic_inc(&sdev->in_flight);
- submit_bio(READ, bio);
+ submit_bio(READ, sbio->bio);
return 0;
-
-nomem:
- scrub_free_bio(bio);
-
- return -ENOMEM;
}
static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len,
u8 *csum, int force)
{
struct scrub_bio *sbio;
+ struct page *page;
+ int ret;
again:
/*
}
sbio = sdev->bios[sdev->curr];
if (sbio->count == 0) {
+ struct bio *bio;
+
sbio->physical = physical;
sbio->logical = logical;
+ bio = bio_alloc(GFP_NOFS, SCRUB_PAGES_PER_BIO);
+ if (!bio)
+ return -ENOMEM;
+
+ bio->bi_private = sbio;
+ bio->bi_end_io = scrub_bio_end_io;
+ bio->bi_bdev = sdev->dev->bdev;
+ bio->bi_sector = sbio->physical >> 9;
+ sbio->err = 0;
+ sbio->bio = bio;
} else if (sbio->physical + sbio->count * PAGE_SIZE != physical ||
sbio->logical + sbio->count * PAGE_SIZE != logical) {
- int ret;
-
ret = scrub_submit(sdev);
if (ret)
return ret;
sbio->spag[sbio->count].generation = gen;
sbio->spag[sbio->count].have_csum = 0;
sbio->spag[sbio->count].mirror_num = mirror_num;
+
+ page = alloc_page(GFP_NOFS);
+ if (!page)
+ return -ENOMEM;
+
+ ret = bio_add_page(sbio->bio, page, PAGE_SIZE, 0);
+ if (!ret) {
+ __free_page(page);
+ ret = scrub_submit(sdev);
+ if (ret)
+ return ret;
+ goto again;
+ }
+
if (csum) {
sbio->spag[sbio->count].have_csum = 1;
memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size);
{Opt_subvolrootid, "subvolrootid=%d"},
{Opt_defrag, "autodefrag"},
{Opt_inode_cache, "inode_cache"},
- {Opt_no_space_cache, "no_space_cache"},
+ {Opt_no_space_cache, "nospace_cache"},
{Opt_recovery, "recovery"},
{Opt_err, NULL},
};
token = match_token(p, tokens, args);
switch (token) {
case Opt_subvol:
+ kfree(*subvol_name);
*subvol_name = match_strdup(&args[0]);
break;
case Opt_subvolid:
if (btrfs_test_opt(root, SPACE_CACHE))
seq_puts(seq, ",space_cache");
else
- seq_puts(seq, ",no_space_cache");
+ seq_puts(seq, ",nospace_cache");
if (btrfs_test_opt(root, CLEAR_CACHE))
seq_puts(seq, ",clear_cache");
if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
struct super_block *s;
struct dentry *root;
struct btrfs_fs_devices *fs_devices = NULL;
- struct btrfs_root *tree_root = NULL;
struct btrfs_fs_info *fs_info = NULL;
fmode_t mode = FMODE_READ;
char *subvol_name = NULL;
error = btrfs_parse_early_options(data, mode, fs_type,
&subvol_name, &subvol_objectid,
&subvol_rootid, &fs_devices);
- if (error)
+ if (error) {
+ kfree(subvol_name);
return ERR_PTR(error);
+ }
if (subvol_name) {
root = mount_subvol(subvol_name, flags, device_name, data);
if (error)
return ERR_PTR(error);
- error = btrfs_open_devices(fs_devices, mode, fs_type);
- if (error)
- return ERR_PTR(error);
-
- if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
- error = -EACCES;
- goto error_close_devices;
- }
-
/*
* Setup a dummy root and fs_info for test/set super. This is because
* we don't actually fill this stuff out until open_ctree, but we need
* then open_ctree will properly initialize everything later.
*/
fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
- tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
- if (!fs_info || !tree_root) {
+ if (!fs_info)
+ return ERR_PTR(-ENOMEM);
+
+ fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+ if (!fs_info->tree_root) {
error = -ENOMEM;
- goto error_close_devices;
+ goto error_fs_info;
}
- fs_info->tree_root = tree_root;
+ fs_info->tree_root->fs_info = fs_info;
fs_info->fs_devices = fs_devices;
- tree_root->fs_info = fs_info;
fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
if (!fs_info->super_copy || !fs_info->super_for_commit) {
error = -ENOMEM;
+ goto error_fs_info;
+ }
+
+ error = btrfs_open_devices(fs_devices, mode, fs_type);
+ if (error)
+ goto error_fs_info;
+
+ if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
+ error = -EACCES;
goto error_close_devices;
}
bdev = fs_devices->latest_bdev;
- s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root);
+ s = sget(fs_type, btrfs_test_super, btrfs_set_super,
+ fs_info->tree_root);
if (IS_ERR(s)) {
error = PTR_ERR(s);
goto error_close_devices;
if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) {
deactivate_locked_super(s);
- return ERR_PTR(-EBUSY);
+ error = -EBUSY;
+ goto error_close_devices;
}
btrfs_close_devices(fs_devices);
free_fs_info(fs_info);
- kfree(tree_root);
} else {
char b[BDEVNAME_SIZE];
error_close_devices:
btrfs_close_devices(fs_devices);
+error_fs_info:
free_fs_info(fs_info);
- kfree(tree_root);
return ERR_PTR(error);
}
btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
if (to_reserve > 0) {
- ret = btrfs_block_rsv_add(root, &pending->block_rsv,
- to_reserve);
+ ret = btrfs_block_rsv_add_noflush(root, &pending->block_rsv,
+ to_reserve);
if (ret) {
pending->error = ret;
goto fail;
key.objectid = device->devid;
key.offset = start;
key.type = BTRFS_DEV_EXTENT_KEY;
-
+again:
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret > 0) {
ret = btrfs_previous_item(root, path, key.objectid,
struct btrfs_dev_extent);
BUG_ON(found_key.offset > start || found_key.offset +
btrfs_dev_extent_length(leaf, extent) < start);
+ key = found_key;
+ btrfs_release_path(path);
+ goto again;
} else if (ret == 0) {
leaf = path->nodes[0];
extent = btrfs_item_ptr(leaf, path->slots[0],
src = in->name;
srclen = in->len;
+ if (srclen > HFS_NAMELEN)
+ srclen = HFS_NAMELEN;
dst = out;
dstlen = HFS_MAX_NAMELEN;
if (nls_io) {
return error;
}
-static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry,
- struct kstat *stat)
-{
- struct inode *inode = dentry->d_inode;
- struct task_struct *task = get_proc_task(inode);
- int rc;
-
- if (task == NULL)
- return -ESRCH;
-
- rc = -EACCES;
- if (lock_trace(task))
- goto out_task;
-
- generic_fillattr(inode, stat);
- unlock_trace(task);
- rc = 0;
-out_task:
- put_task_struct(task);
- return rc;
-}
-
static const struct inode_operations proc_pid_link_inode_operations = {
.readlink = proc_pid_readlink,
.follow_link = proc_pid_follow_link,
.setattr = proc_setattr,
};
-static const struct inode_operations proc_fdinfo_link_inode_operations = {
- .setattr = proc_setattr,
- .getattr = proc_pid_fd_link_getattr,
-};
-
-static const struct inode_operations proc_fd_link_inode_operations = {
- .readlink = proc_pid_readlink,
- .follow_link = proc_pid_follow_link,
- .setattr = proc_setattr,
- .getattr = proc_pid_fd_link_getattr,
-};
-
/* building an inode */
static int proc_fd_info(struct inode *inode, struct path *path, char *info)
{
- struct task_struct *task;
- struct files_struct *files;
+ struct task_struct *task = get_proc_task(inode);
+ struct files_struct *files = NULL;
struct file *file;
int fd = proc_fd(inode);
- int rc;
-
- task = get_proc_task(inode);
- if (!task)
- return -ENOENT;
-
- rc = -EACCES;
- if (lock_trace(task))
- goto out_task;
-
- rc = -ENOENT;
- files = get_files_struct(task);
- if (files == NULL)
- goto out_unlock;
- /*
- * We are not taking a ref to the file structure, so we must
- * hold ->file_lock.
- */
- spin_lock(&files->file_lock);
- file = fcheck_files(files, fd);
- if (file) {
- unsigned int f_flags;
- struct fdtable *fdt;
-
- fdt = files_fdtable(files);
- f_flags = file->f_flags & ~O_CLOEXEC;
- if (FD_ISSET(fd, fdt->close_on_exec))
- f_flags |= O_CLOEXEC;
-
- if (path) {
- *path = file->f_path;
- path_get(&file->f_path);
+ if (task) {
+ files = get_files_struct(task);
+ put_task_struct(task);
+ }
+ if (files) {
+ /*
+ * We are not taking a ref to the file structure, so we must
+ * hold ->file_lock.
+ */
+ spin_lock(&files->file_lock);
+ file = fcheck_files(files, fd);
+ if (file) {
+ unsigned int f_flags;
+ struct fdtable *fdt;
+
+ fdt = files_fdtable(files);
+ f_flags = file->f_flags & ~O_CLOEXEC;
+ if (FD_ISSET(fd, fdt->close_on_exec))
+ f_flags |= O_CLOEXEC;
+
+ if (path) {
+ *path = file->f_path;
+ path_get(&file->f_path);
+ }
+ if (info)
+ snprintf(info, PROC_FDINFO_MAX,
+ "pos:\t%lli\n"
+ "flags:\t0%o\n",
+ (long long) file->f_pos,
+ f_flags);
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ return 0;
}
- if (info)
- snprintf(info, PROC_FDINFO_MAX,
- "pos:\t%lli\n"
- "flags:\t0%o\n",
- (long long) file->f_pos,
- f_flags);
- rc = 0;
- } else
- rc = -ENOENT;
- spin_unlock(&files->file_lock);
- put_files_struct(files);
-
-out_unlock:
- unlock_trace(task);
-out_task:
- put_task_struct(task);
- return rc;
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ }
+ return -ENOENT;
}
static int proc_fd_link(struct inode *inode, struct path *path)
spin_unlock(&files->file_lock);
put_files_struct(files);
- inode->i_op = &proc_fd_link_inode_operations;
+ inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
ei->op.proc_get_link = proc_fd_link;
d_set_d_op(dentry, &tid_fd_dentry_operations);
if (fd == ~0U)
goto out;
- result = ERR_PTR(-EACCES);
- if (lock_trace(task))
- goto out;
-
result = instantiate(dir, dentry, task, &fd);
- unlock_trace(task);
out:
put_task_struct(task);
out_no_task:
retval = -ENOENT;
if (!p)
goto out_no_task;
-
- retval = -EACCES;
- if (lock_trace(p))
- goto out;
-
retval = 0;
fd = filp->f_pos;
switch (fd) {
case 0:
if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
- goto out_unlock;
+ goto out;
filp->f_pos++;
case 1:
ino = parent_ino(dentry);
if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
- goto out_unlock;
+ goto out;
filp->f_pos++;
default:
files = get_files_struct(p);
if (!files)
- goto out_unlock;
+ goto out;
rcu_read_lock();
for (fd = filp->f_pos-2;
fd < files_fdtable(files)->max_fds;
rcu_read_unlock();
put_files_struct(files);
}
-
-out_unlock:
- unlock_trace(p);
out:
put_task_struct(p);
out_no_task:
ei->fd = fd;
inode->i_mode = S_IFREG | S_IRUSR;
inode->i_fop = &proc_fdinfo_file_operations;
- inode->i_op = &proc_fdinfo_link_inode_operations;
d_set_d_op(dentry, &tid_fd_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
int error = 0;
if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
- error = -EIO;
+ ioend->io_error = -EIO;
goto done;
}
if (ioend->io_error)
/*
* This is the ops vector shared by all buf log items.
*/
-static struct xfs_item_ops xfs_buf_item_ops = {
+static const struct xfs_item_ops xfs_buf_item_ops = {
.iop_size = xfs_buf_item_size,
.iop_format = xfs_buf_item_format,
.iop_pin = xfs_buf_item_pin,
/*
* This is the ops vector for dquots
*/
-static struct xfs_item_ops xfs_dquot_item_ops = {
+static const struct xfs_item_ops xfs_dquot_item_ops = {
.iop_size = xfs_qm_dquot_logitem_size,
.iop_format = xfs_qm_dquot_logitem_format,
.iop_pin = xfs_qm_dquot_logitem_pin,
{
}
-static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
+static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
.iop_size = xfs_qm_qoff_logitem_size,
.iop_format = xfs_qm_qoff_logitem_format,
.iop_pin = xfs_qm_qoff_logitem_pin,
/*
* This is the ops vector shared by all quotaoff-start log items.
*/
-static struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
+static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
.iop_size = xfs_qm_qoff_logitem_size,
.iop_format = xfs_qm_qoff_logitem_format,
.iop_pin = xfs_qm_qoff_logitem_pin,
/*
* This is the ops vector shared by all efi log items.
*/
-static struct xfs_item_ops xfs_efi_item_ops = {
+static const struct xfs_item_ops xfs_efi_item_ops = {
.iop_size = xfs_efi_item_size,
.iop_format = xfs_efi_item_format,
.iop_pin = xfs_efi_item_pin,
/*
* This is the ops vector shared by all efd log items.
*/
-static struct xfs_item_ops xfs_efd_item_ops = {
+static const struct xfs_item_ops xfs_efd_item_ops = {
.iop_size = xfs_efd_item_size,
.iop_format = xfs_efd_item_format,
.iop_pin = xfs_efd_item_pin,
/*
* This is the ops vector shared by all buf log items.
*/
-static struct xfs_item_ops xfs_inode_item_ops = {
+static const struct xfs_item_ops xfs_inode_item_ops = {
.iop_size = xfs_inode_item_size,
.iop_format = xfs_inode_item_format,
.iop_pin = xfs_inode_item_pin,
struct xfs_mount *mp,
struct xfs_log_item *item,
int type,
- struct xfs_item_ops *ops)
+ const struct xfs_item_ops *ops)
{
item->li_mountp = mp;
item->li_ailp = mp->m_ail;
void xfs_log_item_init(struct xfs_mount *mp,
struct xfs_log_item *item,
int type,
- struct xfs_item_ops *ops);
+ const struct xfs_item_ops *ops);
xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
struct xlog_ticket *ticket,
struct xfs_log_item *);
/* buffer item iodone */
/* callback func */
- struct xfs_item_ops *li_ops; /* function list */
+ const struct xfs_item_ops *li_ops; /* function list */
/* delayed logging */
struct list_head li_cil; /* CIL pointers */
{ XFS_LI_IN_AIL, "IN_AIL" }, \
{ XFS_LI_ABORTED, "ABORTED" }
-typedef struct xfs_item_ops {
+struct xfs_item_ops {
uint (*iop_size)(xfs_log_item_t *);
void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
void (*iop_pin)(xfs_log_item_t *);
void (*iop_push)(xfs_log_item_t *);
bool (*iop_pushbuf)(xfs_log_item_t *);
void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
-} xfs_item_ops_t;
+};
#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip)
#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp)
char *link)
{
xfs_mount_t *mp = ip->i_mount;
- int pathlen;
+ xfs_fsize_t pathlen;
int error = 0;
trace_xfs_readlink(ip);
xfs_ilock(ip, XFS_ILOCK_SHARED);
- ASSERT(S_ISLNK(ip->i_d.di_mode));
- ASSERT(ip->i_d.di_size <= MAXPATHLEN);
-
pathlen = ip->i_d.di_size;
if (!pathlen)
goto out;
+ if (pathlen < 0 || pathlen > MAXPATHLEN) {
+ xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
+ __func__, (unsigned long long) ip->i_ino,
+ (long long) pathlen);
+ ASSERT(0);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+
if (ip->i_df.if_flags & XFS_IFINLINE) {
memcpy(link, ip->i_df.if_u1.if_data, pathlen);
link[pathlen] = '\0';
struct proc_dir_entry *proc_root; /**< proc directory entry */
struct drm_info_node proc_nodes;
struct dentry *debugfs_root;
- struct drm_info_node debugfs_nodes;
+
+ struct list_head debugfs_list;
+ struct mutex debugfs_lock; /* Protects debugfs_list. */
struct drm_master *master; /* currently active master for this node */
struct list_head master_list;
*/
#define radeon_PCI_IDS \
{0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x3151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C6E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
{0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
* - this size value would be page-aligned internally.
* @flags: user request for setting memory type or cache attributes.
* @handle: returned handle for the object.
+ * @pad: just padding to be 64-bit aligned.
*/
struct drm_exynos_gem_create {
unsigned int size;
unsigned int flags;
unsigned int handle;
+ unsigned int pad;
};
/**
unsigned long total_time;
unsigned long busy_time;
unsigned long current_frequency;
- void *private_date;
+ void *private_data;
};
/**
static inline
void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
{
- return 0;
}
static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
#define PCI_VENDOR_ID_AZWAVE 0x1a3b
+#define PCI_VENDOR_ID_ASMEDIA 0x1b21
+
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
#else
+struct pinctrl_dev;
/* Sufficiently stupid default function when pinctrl is not in use */
static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
SCIx_IRDA_REGTYPE,
SCIx_SCIFA_REGTYPE,
SCIx_SCIFB_REGTYPE,
+ SCIx_SH2_SCIF_FIFODATA_REGTYPE,
SCIx_SH3_SCIF_REGTYPE,
SCIx_SH4_SCIF_REGTYPE,
SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
unsigned long arch_flags;
void *priv;
- struct dentry *dentry;
struct clk_mapping *mapping;
struct cpufreq_frequency_table *freq_table;
unsigned int nr_freqs;
long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
unsigned int div_max, unsigned long rate);
+long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
+ unsigned int mult_max, unsigned long rate);
+
long clk_round_parent(struct clk *clk, unsigned long target,
unsigned long *best_freq, unsigned long *parent_freq,
unsigned int div_min, unsigned int div_max);
int register_pinmux(struct pinmux_info *pip);
int unregister_pinmux(struct pinmux_info *pip);
+/* helper macro for port */
+#define PORT_1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define PORT_10(fn, pfx, sfx) \
+ PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx), \
+ PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx), \
+ PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx), \
+ PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx), \
+ PORT_1(fn, pfx##8, sfx), PORT_1(fn, pfx##9, sfx)
+
+#define PORT_90(fn, pfx, sfx) \
+ PORT_10(fn, pfx##1, sfx), PORT_10(fn, pfx##2, sfx), \
+ PORT_10(fn, pfx##3, sfx), PORT_10(fn, pfx##4, sfx), \
+ PORT_10(fn, pfx##5, sfx), PORT_10(fn, pfx##6, sfx), \
+ PORT_10(fn, pfx##7, sfx), PORT_10(fn, pfx##8, sfx), \
+ PORT_10(fn, pfx##9, sfx)
+
+#define _PORT_ALL(pfx, sfx) pfx##_##sfx
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define PORT_ALL(str) CPU_ALL_PORT(_PORT_ALL, PORT, str)
+#define GPIO_PORT_ALL() CPU_ALL_PORT(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+/* helper macro for pinmux_enum_t */
+#define PORT_DATA_I(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+/* helper macro for top 4 bits in PORTnCR */
+#define _PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { \
+ PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ _PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, \
+ PORT##nr##_FN2, PORT##nr##_FN3, \
+ PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
#endif /* __SH_PFC_H */
struct irq_desc *desc;
int i, ok = 0;
- if (atomic_inc_return(&irq_poll_active) == 1)
+ if (atomic_inc_return(&irq_poll_active) != 1)
goto out;
irq_poll_cpu = smp_processor_id();
};
static struct pm_qos_object cpu_dma_pm_qos = {
.constraints = &cpu_dma_constraints,
+ .name = "cpu_dma_latency",
};
static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
* anon_vma prepared.
*/
if (unlikely(anon_vma_prepare(vma))) {
+ page_cache_release(new_page);
+ page_cache_release(old_page);
/* Caller expects lock to be held */
spin_lock(&mm->page_table_lock);
return VM_FAULT_OOM;
if (!p)
return 0;
+ if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) {
+ task_unlock(p);
+ return 0;
+ }
+
/*
* The memory controller may have a limit of 0 bytes, so avoid a divide
* by zero, if necessary.
key->expiry = 0;
}
- kfree_rcu(zap, rcu);
+ if (zap)
+ kfree_rcu(zap, rcu);
error:
return ret;
(0x0fUL << 12) |
(PS3_AUDIO_IOID);
- ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0);
+ ret = lv1_gpu_attribute(0x100, 0x007, val);
if (ret)
pr_info("%s: gpu_attribute failed %d\n", __func__,
ret);
$default{"BISECT_SKIP"} = 1;
$default{"SUCCESS_LINE"} = "login:";
$default{"DETECT_TRIPLE_FAULT"} = 1;
+$default{"NO_INSTALL"} = 0;
$default{"BOOTED_TIMEOUT"} = 1;
$default{"DIE_ON_FAILURE"} = 1;
$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
my $target;
my $make;
my $post_install;
+my $no_install;
my $noclean;
my $minconfig;
my $start_minconfig;
my $booted_timeout;
my $detect_triplefault;
my $console;
+my $reboot_success_line;
my $success_line;
my $stop_after_success;
my $stop_after_failure;
my %variable;
my %force_config;
+# do not force reboots on config problems
+my $no_reboot = 1;
+
+# default variables that can be used
+chomp ($variable{"PWD"} = `pwd`);
+
$config_help{"MACHINE"} = << "EOF"
The machine hostname that you will test.
EOF
sub get_ktest_config {
my ($config) = @_;
+ my $ans;
return if (defined($opt{$config}));
if (defined($default{$config})) {
print "\[$default{$config}\] ";
}
- $entered_configs{$config} = <STDIN>;
- $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
- if ($entered_configs{$config} =~ /^\s*$/) {
+ $ans = <STDIN>;
+ $ans =~ s/^\s*(.*\S)\s*$/$1/;
+ if ($ans =~ /^\s*$/) {
if ($default{$config}) {
- $entered_configs{$config} = $default{$config};
+ $ans = $default{$config};
} else {
print "Your answer can not be blank\n";
next;
}
}
+ $entered_configs{$config} = process_variables($ans);
last;
}
}
}
sub process_variables {
- my ($value) = @_;
+ my ($value, $remove_undef) = @_;
my $retval = "";
# We want to check for '\', and it is just easier
$retval = "$retval$begin";
if (defined($variable{$var})) {
$retval = "$retval$variable{$var}";
+ } elsif (defined($remove_undef) && $remove_undef) {
+ # for if statements, any variable that is not defined,
+ # we simple convert to 0
+ $retval = "${retval}0";
} else {
# put back the origin piece.
$retval = "$retval\$\{$var\}";
}
sub set_value {
- my ($lvalue, $rvalue) = @_;
+ my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
if (defined($opt{$lvalue})) {
- die "Error: Option $lvalue defined more than once!\n";
+ if (!$override || defined(${$overrides}{$lvalue})) {
+ my $extra = "";
+ if ($override) {
+ $extra = "In the same override section!\n";
+ }
+ die "$name: $.: Option $lvalue defined more than once!\n$extra";
+ }
+ ${$overrides}{$lvalue} = $rvalue;
}
if ($rvalue =~ /^\s*$/) {
delete $opt{$lvalue};
}
}
-sub read_config {
- my ($config) = @_;
+sub process_compare {
+ my ($lval, $cmp, $rval) = @_;
+
+ # remove whitespace
+
+ $lval =~ s/^\s*//;
+ $lval =~ s/\s*$//;
+
+ $rval =~ s/^\s*//;
+ $rval =~ s/\s*$//;
+
+ if ($cmp eq "==") {
+ return $lval eq $rval;
+ } elsif ($cmp eq "!=") {
+ return $lval ne $rval;
+ }
+
+ my $statement = "$lval $cmp $rval";
+ my $ret = eval $statement;
+
+ # $@ stores error of eval
+ if ($@) {
+ return -1;
+ }
+
+ return $ret;
+}
+
+sub value_defined {
+ my ($val) = @_;
+
+ return defined($variable{$2}) ||
+ defined($opt{$2});
+}
+
+my $d = 0;
+sub process_expression {
+ my ($name, $val) = @_;
+
+ my $c = $d++;
+
+ while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
+ my $express = $1;
+
+ if (process_expression($name, $express)) {
+ $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
+ } else {
+ $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
+ }
+ }
+
+ $d--;
+ my $OR = "\\|\\|";
+ my $AND = "\\&\\&";
+
+ while ($val =~ s/^(.*?)($OR|$AND)//) {
+ my $express = $1;
+ my $op = $2;
+
+ if (process_expression($name, $express)) {
+ if ($op eq "||") {
+ return 1;
+ }
+ } else {
+ if ($op eq "&&") {
+ return 0;
+ }
+ }
+ }
+
+ if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
+ my $ret = process_compare($1, $2, $3);
+ if ($ret < 0) {
+ die "$name: $.: Unable to process comparison\n";
+ }
+ return $ret;
+ }
+
+ if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
+ if (defined $1) {
+ return !value_defined($2);
+ } else {
+ return value_defined($2);
+ }
+ }
+
+ if ($val =~ /^\s*0\s*$/) {
+ return 0;
+ } elsif ($val =~ /^\s*\d+\s*$/) {
+ return 1;
+ }
+
+ die ("$name: $.: Undefined content $val in if statement\n");
+}
+
+sub process_if {
+ my ($name, $value) = @_;
+
+ # Convert variables and replace undefined ones with 0
+ my $val = process_variables($value, 1);
+ my $ret = process_expression $name, $val;
+
+ return $ret;
+}
- open(IN, $config) || die "can't read file $config";
+sub __read_config {
+ my ($config, $current_test_num) = @_;
+
+ my $in;
+ open($in, $config) || die "can't read file $config";
my $name = $config;
$name =~ s,.*/(.*),$1,;
- my $test_num = 0;
+ my $test_num = $$current_test_num;
my $default = 1;
my $repeat = 1;
my $num_tests_set = 0;
my $skip = 0;
my $rest;
+ my $line;
my $test_case = 0;
+ my $if = 0;
+ my $if_set = 0;
+ my $override = 0;
- while (<IN>) {
+ my %overrides;
+
+ while (<$in>) {
# ignore blank lines and comments
next if (/^\s*$/ || /\s*\#/);
- if (/^\s*TEST_START(.*)/) {
+ if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
- $rest = $1;
+ my $type = $1;
+ $rest = $2;
+ $line = $2;
- if ($num_tests_set) {
- die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
- }
+ my $old_test_num;
+ my $old_repeat;
+ $override = 0;
+
+ if ($type eq "TEST_START") {
+
+ if ($num_tests_set) {
+ die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
+ }
- my $old_test_num = $test_num;
- my $old_repeat = $repeat;
+ $old_test_num = $test_num;
+ $old_repeat = $repeat;
- $test_num += $repeat;
- $default = 0;
- $repeat = 1;
+ $test_num += $repeat;
+ $default = 0;
+ $repeat = 1;
+ } else {
+ $default = 1;
+ }
- if ($rest =~ /\s+SKIP(.*)/) {
- $rest = $1;
+ # If SKIP is anywhere in the line, the command will be skipped
+ if ($rest =~ s/\s+SKIP\b//) {
$skip = 1;
} else {
$test_case = 1;
$skip = 0;
}
- if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
- $repeat = $1;
- $rest = $2;
- $repeat_tests{"$test_num"} = $repeat;
+ if ($rest =~ s/\sELSE\b//) {
+ if (!$if) {
+ die "$name: $.: ELSE found with out matching IF section\n$_";
+ }
+ $if = 0;
+
+ if ($if_set) {
+ $skip = 1;
+ } else {
+ $skip = 0;
+ }
}
- if ($rest =~ /\s+SKIP(.*)/) {
- $rest = $1;
- $skip = 1;
+ if ($rest =~ s/\sIF\s+(.*)//) {
+ if (process_if($name, $1)) {
+ $if_set = 1;
+ } else {
+ $skip = 1;
+ }
+ $if = 1;
+ } else {
+ $if = 0;
+ $if_set = 0;
}
- if ($rest !~ /^\s*$/) {
- die "$name: $.: Gargbage found after TEST_START\n$_";
+ if (!$skip) {
+ if ($type eq "TEST_START") {
+ if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
+ $repeat = $1;
+ $repeat_tests{"$test_num"} = $repeat;
+ }
+ } elsif ($rest =~ s/\sOVERRIDE\b//) {
+ # DEFAULT only
+ $override = 1;
+ # Clear previous overrides
+ %overrides = ();
+ }
+ }
+
+ if (!$skip && $rest !~ /^\s*$/) {
+ die "$name: $.: Gargbage found after $type\n$_";
}
- if ($skip) {
+ if ($skip && $type eq "TEST_START") {
$test_num = $old_test_num;
$repeat = $old_repeat;
}
- } elsif (/^\s*DEFAULTS(.*)$/) {
- $default = 1;
-
+ } elsif (/^\s*ELSE\b(.*)$/) {
+ if (!$if) {
+ die "$name: $.: ELSE found with out matching IF section\n$_";
+ }
$rest = $1;
-
- if ($rest =~ /\s+SKIP(.*)/) {
- $rest = $1;
+ if ($if_set) {
$skip = 1;
+ $rest = "";
} else {
$skip = 0;
+
+ if ($rest =~ /\sIF\s+(.*)/) {
+ # May be a ELSE IF section.
+ if (!process_if($name, $1)) {
+ $skip = 1;
+ }
+ $rest = "";
+ } else {
+ $if = 0;
+ }
}
if ($rest !~ /^\s*$/) {
die "$name: $.: Gargbage found after DEFAULTS\n$_";
}
+ } elsif (/^\s*INCLUDE\s+(\S+)/) {
+
+ next if ($skip);
+
+ if (!$default) {
+ die "$name: $.: INCLUDE can only be done in default sections\n$_";
+ }
+
+ my $file = process_variables($1);
+
+ if ($file !~ m,^/,) {
+ # check the path of the config file first
+ if ($config =~ m,(.*)/,) {
+ if (-f "$1/$file") {
+ $file = "$1/$file";
+ }
+ }
+ }
+
+ if ( ! -r $file ) {
+ die "$name: $.: Can't read file $file\n$_";
+ }
+
+ if (__read_config($file, \$test_num)) {
+ $test_case = 1;
+ }
+
} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
next if ($skip);
}
if ($default || $lvalue =~ /\[\d+\]$/) {
- set_value($lvalue, $rvalue);
+ set_value($lvalue, $rvalue, $override, \%overrides, $name);
} else {
my $val = "$lvalue\[$test_num\]";
- set_value($val, $rvalue);
+ set_value($val, $rvalue, $override, \%overrides, $name);
if ($repeat > 1) {
$repeats{$val} = $repeat;
}
}
- close(IN);
-
if ($test_num) {
$test_num += $repeat - 1;
$opt{"NUM_TESTS"} = $test_num;
}
+ close($in);
+
+ $$current_test_num = $test_num;
+
+ return $test_case;
+}
+
+sub read_config {
+ my ($config) = @_;
+
+ my $test_case;
+ my $test_num = 0;
+
+ $test_case = __read_config $config, \$test_num;
+
# make sure we have all mandatory configs
get_ktest_configs;
}
sub run_command;
+sub start_monitor;
+sub end_monitor;
+sub wait_for_monitor;
sub reboot {
+ my ($time) = @_;
+
+ if (defined($time)) {
+ start_monitor;
+ # flush out current monitor
+ # May contain the reboot success line
+ wait_for_monitor 1;
+ }
+
# try to reboot normally
if (run_command $reboot) {
if (defined($powercycle_after_reboot)) {
# nope? power cycle it.
run_command "$power_cycle";
}
+
+ if (defined($time)) {
+ wait_for_monitor($time, $reboot_success_line);
+ end_monitor;
+ }
}
sub do_not_reboot {
my $i = $iteration;
- return $test_type eq "build" ||
+ return $test_type eq "build" || $no_reboot ||
($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
}
}
sub wait_for_monitor {
- my ($time) = @_;
+ my ($time, $stop) = @_;
+ my $full_line = "";
my $line;
+ my $booted = 0;
doprint "** Wait for monitor to settle down **\n";
# read the monitor and wait for the system to calm down
- do {
+ while (!$booted) {
$line = wait_for_input($monitor_fp, $time);
- print "$line" if (defined($line));
- } while (defined($line));
+ last if (!defined($line));
+ print "$line";
+ $full_line .= $line;
+
+ if (defined($stop) && $full_line =~ /$stop/) {
+ doprint "wait for monitor detected $stop\n";
+ $booted = 1;
+ }
+
+ if ($line =~ /\n/) {
+ $full_line = "";
+ }
+ }
print "** Monitor flushed **\n";
}
# no need to reboot for just building.
if (!do_not_reboot) {
doprint "REBOOTING\n";
- reboot;
- start_monitor;
- wait_for_monitor $sleep_time;
- end_monitor;
+ reboot $sleep_time;
}
my $name = "";
open(IN, "$ssh_grub |")
or die "unable to get menu.lst";
+ my $found = 0;
+
while (<IN>) {
if (/^\s*title\s+$grub_menu\s*$/) {
$grub_number++;
+ $found = 1;
last;
} elsif (/^\s*title\s/) {
$grub_number++;
close(IN);
die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
- if ($grub_number < 0);
+ if (!$found);
doprint "$grub_number\n";
}
sub reboot_to {
if ($reboot_type eq "grub") {
- run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
+ run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+ reboot;
return;
}
sub install {
+ return if ($no_install);
+
run_scp "$outputdir/$build_target", "$target_image" or
dodie "failed to copy image";
}
sub start_monitor_and_boot {
+ # Make sure the stable kernel has finished booting
+ start_monitor;
+ wait_for_monitor 5;
+ end_monitor;
+
get_grub_index;
get_version;
install;
unlink $buildlog;
+ # Failed builds should not reboot the target
+ my $save_no_reboot = $no_reboot;
+ $no_reboot = 1;
+
if (defined($pre_build)) {
my $ret = run_command $pre_build;
if (!$ret && defined($pre_build_die) &&
# allow for empty configs
run_command "touch $output_config";
- run_command "mv $output_config $outputdir/config_temp" or
- dodie "moving .config";
+ if (!$noclean) {
+ run_command "mv $output_config $outputdir/config_temp" or
+ dodie "moving .config";
- if (!$noclean && !run_command "$make mrproper") {
- dodie "make mrproper";
- }
+ run_command "$make mrproper" or dodie "make mrproper";
- run_command "mv $outputdir/config_temp $output_config" or
- dodie "moving config_temp";
+ run_command "mv $outputdir/config_temp $output_config" or
+ dodie "moving config_temp";
+ }
} elsif (!$noclean) {
unlink "$output_config";
if (!$build_ret) {
# bisect may need this to pass
- return 0 if ($in_bisect);
+ if ($in_bisect) {
+ $no_reboot = $save_no_reboot;
+ return 0;
+ }
fail "failed build" and return 0;
}
+ $no_reboot = $save_no_reboot;
+
return 1;
}
if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
doprint "Reboot and wait $sleep_time seconds\n";
- reboot;
- start_monitor;
- wait_for_monitor $sleep_time;
- end_monitor;
+ reboot $sleep_time;
}
}
sub bisect_reboot {
doprint "Reboot and sleep $bisect_sleep_time seconds\n";
- reboot;
- start_monitor;
- wait_for_monitor $bisect_sleep_time;
- end_monitor;
+ reboot $bisect_sleep_time;
}
# returns 1 on success, 0 on failure, -1 on skip
sub patchcheck_reboot {
doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
- reboot;
- start_monitor;
- wait_for_monitor $patchcheck_sleep_time;
- end_monitor;
+ reboot $patchcheck_sleep_time;
}
sub patchcheck {
}
my %depends;
+my %depcount;
my $iflevel = 0;
my @ifdeps;
# prevent recursion
my %read_kconfigs;
+sub add_dep {
+ # $config depends on $dep
+ my ($config, $dep) = @_;
+
+ if (defined($depends{$config})) {
+ $depends{$config} .= " " . $dep;
+ } else {
+ $depends{$config} = $dep;
+ }
+
+ # record the number of configs depending on $dep
+ if (defined $depcount{$dep}) {
+ $depcount{$dep}++;
+ } else {
+ $depcount{$dep} = 1;
+ }
+}
+
# taken from streamline_config.pl
sub read_kconfig {
my ($kconfig) = @_;
$config = $2;
for (my $i = 0; $i < $iflevel; $i++) {
- if ($i) {
- $depends{$config} .= " " . $ifdeps[$i];
- } else {
- $depends{$config} = $ifdeps[$i];
- }
- $state = "DEP";
+ add_dep $config, $ifdeps[$i];
}
# collect the depends for the config
} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
- if (defined($depends{$1})) {
- $depends{$config} .= " " . $1;
- } else {
- $depends{$config} = $1;
- }
+ add_dep $config, $1;
# Get the configs that select this config
- } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
- if (defined($depends{$1})) {
- $depends{$1} .= " " . $config;
- } else {
- $depends{$1} = $config;
- }
+ } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
+
+ # selected by depends on config
+ add_dep $1, $config;
# Check for if statements
} elsif (/^if\s+(.*\S)\s*$/) {
close OUT;
}
+sub chomp_config {
+ my ($config) = @_;
+
+ $config =~ s/CONFIG_//;
+
+ return $config;
+}
+
sub get_depends {
my ($dep) = @_;
- my $kconfig = $dep;
- $kconfig =~ s/CONFIG_//;
+ my $kconfig = chomp_config $dep;
$dep = $depends{"$kconfig"};
return undef;
}
- my $kconfig = $config;
- $kconfig =~ s/CONFIG_//;
+ my $kconfig = chomp_config $config;
# Test dependencies first
if (defined($depends{"$kconfig"})) {
my @config_keys = keys %min_configs;
+ # All configs need a depcount
+ foreach my $config (@config_keys) {
+ my $kconfig = chomp_config $config;
+ if (!defined $depcount{$kconfig}) {
+ $depcount{$kconfig} = 0;
+ }
+ }
+
# Remove anything that was set by the make allnoconfig
# we shouldn't need them as they get set for us anyway.
foreach my $config (@config_keys) {
# Now disable each config one by one and do a make oldconfig
# till we find a config that changes our list.
- # Put configs that did not modify the config at the end.
my @test_configs = keys %min_configs;
+
+ # Sort keys by who is most dependent on
+ @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
+ @test_configs ;
+
+ # Put configs that did not modify the config at the end.
my $reset = 1;
for (my $i = 0; $i < $#test_configs; $i++) {
if (!defined($nochange_config{$test_configs[0]})) {
}
doprint "Reboot and wait $sleep_time seconds\n";
- reboot;
- start_monitor;
- wait_for_monitor $sleep_time;
- end_monitor;
+ reboot $sleep_time;
}
success $i;
# First we need to do is the builds
for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
+ # Do not reboot on failing test options
+ $no_reboot = 1;
+
$iteration = $i;
my $makecmd = set_test_option("MAKE_CMD", $i);
$reboot_type = set_test_option("REBOOT_TYPE", $i);
$grub_menu = set_test_option("GRUB_MENU", $i);
$post_install = set_test_option("POST_INSTALL", $i);
+ $no_install = set_test_option("NO_INSTALL", $i);
$reboot_script = set_test_option("REBOOT_SCRIPT", $i);
$reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
$poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
$console = set_test_option("CONSOLE", $i);
$detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
$success_line = set_test_option("SUCCESS_LINE", $i);
+ $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
$stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
$stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
$stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
chdir $builddir || die "can't change directory to $builddir";
- if (!-d $tmpdir) {
- mkpath($tmpdir) or
- die "can't create $tmpdir";
+ foreach my $dir ($tmpdir, $outputdir) {
+ if (!-d $dir) {
+ mkpath($dir) or
+ die "can't create $dir";
+ }
}
$ENV{"SSH_USER"} = $ssh_user;
$run_type = "ERROR";
}
+ my $installme = "";
+ $installme = " no_install" if ($no_install);
+
doprint "\n\n";
- doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
+ doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
unlink $dmesg;
unlink $buildlog;
die "failed to checkout $checkout";
}
+ $no_reboot = 0;
+
+
if ($test_type eq "bisect") {
bisect $i;
next;
build $build_type or next;
}
+ if ($test_type eq "install") {
+ get_version;
+ install;
+ success $i;
+ next;
+ }
+
if ($test_type ne "build") {
my $failed = 0;
start_monitor_and_boot or $failed = 1;
# the same option name under the same test or as default
# ktest will fail to execute, and no tests will run.
#
+# DEFAULTS OVERRIDE
+#
+# Options defined in the DEFAULTS section can not be duplicated
+# even if they are defined in two different DEFAULT sections.
+# This is done to catch mistakes where an option is added but
+# the previous option was forgotten about and not commented.
+#
+# The OVERRIDE keyword can be added to a section to allow this
+# section to override other DEFAULT sections values that have
+# been defined previously. It will only override options that
+# have been defined before its use. Options defined later
+# in a non override section will still error. The same option
+# can not be defined in the same section even if that section
+# is marked OVERRIDE.
+#
+#
+#
+# Both TEST_START and DEFAULTS sections can also have the IF keyword
+# The value after the IF must evaluate into a 0 or non 0 positive
+# integer, and can use the config variables (explained below).
+#
+# DEFAULTS IF ${IS_X86_32}
+#
+# The above will process the DEFAULTS section if the config
+# variable IS_X86_32 evaluates to a non zero positive integer
+# otherwise if it evaluates to zero, it will act the same
+# as if the SKIP keyword was used.
+#
+# The ELSE keyword can be used directly after a section with
+# a IF statement.
+#
+# TEST_START IF ${RUN_NET_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network
+#
+# ELSE
+#
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-normal
+#
+#
+# The ELSE keyword can also contain an IF statement to allow multiple
+# if then else sections. But all the sections must be either
+# DEFAULT or TEST_START, they can not be a mixture.
+#
+# TEST_START IF ${RUN_NET_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network
+#
+# ELSE IF ${RUN_DISK_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-tests
+#
+# ELSE IF ${RUN_CPU_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-cpu
+#
+# ELSE
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network
+#
+# The if statement may also have comparisons that will and for
+# == and !=, strings may be used for both sides.
+#
+# BOX_TYPE := x86_32
+#
+# DEFAULTS IF ${BOX_TYPE} == x86_32
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-32
+# ELSE
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-64
+#
+# The DEFINED keyword can be used by the IF statements too.
+# It returns true if the given config variable or option has been defined
+# or false otherwise.
+#
+#
+# DEFAULTS IF DEFINED USE_CC
+# CC := ${USE_CC}
+# ELSE
+# CC := gcc
+#
+#
+# As well as NOT DEFINED.
+#
+# DEFAULTS IF NOT DEFINED MAKE_CMD
+# MAKE_CMD := make ARCH=x86
+#
+#
+# And/or ops (&&,||) may also be used to make complex conditionals.
+#
+# TEST_START IF (DEFINED ALL_TESTS || ${MYTEST} == boottest) && ${MACHINE} == gandalf
+#
+# Notice the use of paranthesis. Without any paranthesis the above would be
+# processed the same as:
+#
+# TEST_START IF DEFINED ALL_TESTS || (${MYTEST} == boottest && ${MACHINE} == gandalf)
+#
+#
+#
+# INCLUDE file
+#
+# The INCLUDE keyword may be used in DEFAULT sections. This will
+# read another config file and process that file as well. The included
+# file can include other files, add new test cases or default
+# statements. Config variables will be passed to these files and changes
+# to config variables will be seen by top level config files. Including
+# a file is processed just like the contents of the file was cut and pasted
+# into the top level file, except, that include files that end with
+# TEST_START sections will have that section ended at the end of
+# the include file. That is, an included file is included followed
+# by another DEFAULT keyword.
+#
+# Unlike other files referenced in this config, the file path does not need
+# to be absolute. If the file does not start with '/', then the directory
+# that the current config file was located in is used. If no config by the
+# given name is found there, then the current directory is searched.
+#
+# INCLUDE myfile
+# DEFAULT
+#
+# is the same as:
+#
+# INCLUDE myfile
+#
+# Note, if the include file does not contain a full path, the file is
+# searched first by the location of the original include file, and then
+# by the location that ktest.pl was executed in.
+#
#### Config variables ####
#
# The default test type (default test)
# The test types may be:
-# build - only build the kernel, do nothing else
-# boot - build and boot the kernel
-# test - build, boot and if TEST is set, run the test script
+# build - only build the kernel, do nothing else
+# install - build and install, but do nothing else (does not reboot)
+# boot - build, install, and boot the kernel
+# test - build, boot and if TEST is set, run the test script
# (If TEST is not set, it defaults back to boot)
# bisect - Perform a bisect on the kernel (see BISECT_TYPE below)
# patchcheck - Do a test on a series of commits in git (see PATCHCHECK below)
# or on some systems:
#POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION
+# If for some reason you just want to boot the kernel and you do not
+# want the test to install anything new. For example, you may just want
+# to boot test the same kernel over and over and do not want to go through
+# the hassle of installing anything, you can set this option to 1
+# (default 0)
+#NO_INSTALL = 1
+
# If there is a script that you require to run before the build is done
# you can specify it with PRE_BUILD.
#
# (default "login:")
#SUCCESS_LINE = login:
+# To speed up between reboots, defining a line that the
+# default kernel produces that represents that the default
+# kernel has successfully booted and can be used to pass
+# a new test kernel to it. Otherwise ktest.pl will wait till
+# SLEEP_TIME to continue.
+# (default undefined)
+#REBOOT_SUCCESS_LINE = login:
+
# In case the console constantly fills the screen, having
# a specified time to stop the test after success is recommended.
# (in seconds)
# another test. If a reboot to the reliable kernel happens,
# we wait SLEEP_TIME for the console to stop producing output
# before starting the next test.
+#
+# You can speed up reboot times even more by setting REBOOT_SUCCESS_LINE.
# (default 60)
#SLEEP_TIME = 60