10311 lines
332 KiB
Diff
10311 lines
332 KiB
Diff
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
|
|
index c279158..196b8b9 100644
|
|
--- a/Documentation/DocBook/drm.tmpl
|
|
+++ b/Documentation/DocBook/drm.tmpl
|
|
@@ -32,7 +32,7 @@
|
|
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>
|
|
@@ -57,10 +57,10 @@
|
|
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>
|
|
@@ -74,7 +74,7 @@
|
|
</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>
|
|
|
|
@@ -88,8 +88,8 @@
|
|
</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 |
|
|
@@ -154,8 +154,8 @@
|
|
</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,
|
|
@@ -203,8 +203,8 @@
|
|
<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>
|
|
@@ -214,8 +214,8 @@
|
|
<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>
|
|
@@ -238,7 +238,7 @@
|
|
</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.
|
|
@@ -269,36 +269,34 @@
|
|
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.
|
|
@@ -307,15 +305,15 @@
|
|
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.
|
|
@@ -323,10 +321,10 @@
|
|
<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_* -->
|
|
@@ -335,20 +333,20 @@
|
|
<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
|
|
@@ -357,7 +355,7 @@
|
|
</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
|
|
@@ -371,10 +369,10 @@
|
|
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>
|
|
@@ -389,9 +387,9 @@
|
|
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>
|
|
@@ -401,7 +399,7 @@
|
|
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>
|
|
@@ -429,21 +427,21 @@
|
|
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>
|
|
@@ -453,27 +451,26 @@
|
|
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);
|
|
@@ -483,7 +480,7 @@
|
|
<!--!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>
|
|
@@ -493,16 +490,25 @@
|
|
<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>
|
|
@@ -555,10 +561,10 @@ void intel_crt_init(struct drm_device *dev)
|
|
</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>
|
|
@@ -567,12 +573,12 @@ void intel_crt_init(struct drm_device *dev)
|
|
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>
|
|
@@ -580,17 +586,25 @@ void intel_crt_init(struct drm_device *dev)
|
|
</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-->
|
|
@@ -605,23 +619,34 @@ void intel_crt_init(struct drm_device *dev)
|
|
<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:
|
|
@@ -632,24 +657,24 @@ void intel_crt_init(struct drm_device *dev)
|
|
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>
|
|
|
|
@@ -679,41 +704,46 @@ void intel_crt_init(struct drm_device *dev)
|
|
<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
|
|
@@ -729,7 +759,7 @@ void intel_crt_init(struct drm_device *dev)
|
|
<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
|
|
@@ -765,21 +795,19 @@ void intel_crt_init(struct drm_device *dev)
|
|
<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>
|
|
@@ -789,7 +817,7 @@ void intel_crt_init(struct drm_device *dev)
|
|
<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.
|
|
@@ -812,8 +840,8 @@ void intel_crt_init(struct drm_device *dev)
|
|
<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>
|
|
@@ -822,8 +850,8 @@ void intel_crt_init(struct drm_device *dev)
|
|
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>
|
|
|
|
diff --git a/Documentation/cgroups/freezer-subsystem.txt b/Documentation/cgroups/freezer-subsystem.txt
|
|
index c21d777..7e62de1 100644
|
|
--- a/Documentation/cgroups/freezer-subsystem.txt
|
|
+++ b/Documentation/cgroups/freezer-subsystem.txt
|
|
@@ -33,9 +33,9 @@ demonstrate this problem using nested bash shells:
|
|
|
|
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.
|
|
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
|
|
index 4f34432..edad99a 100644
|
|
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
|
|
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
|
|
@@ -349,6 +349,7 @@ STAC92HD83*
|
|
ref Reference board
|
|
mic-ref Reference board with power management for ports
|
|
dell-s14 Dell laptop
|
|
+ dell-vostro-3500 Dell Vostro 3500 laptop
|
|
hp HP laptops with (inverted) mute-LED
|
|
hp-dv7-4000 HP dv-7 4000
|
|
auto BIOS setup (default)
|
|
diff --git a/Kbuild b/Kbuild
|
|
index 4caab4f..b8b708a 100644
|
|
--- a/Kbuild
|
|
+++ b/Kbuild
|
|
@@ -92,7 +92,7 @@ always += missing-syscalls
|
|
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)
|
|
diff --git a/MAINTAINERS b/MAINTAINERS
|
|
index 4808256..071a996 100644
|
|
--- a/MAINTAINERS
|
|
+++ b/MAINTAINERS
|
|
@@ -1106,6 +1106,7 @@ F: drivers/media/video/s5p-fimc/
|
|
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
|
|
@@ -2342,6 +2343,13 @@ S: Supported
|
|
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
|
|
@@ -6122,7 +6130,7 @@ F: sound/
|
|
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
|
|
M: Liam Girdwood <lrg@ti.com>
|
|
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
|
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
|
|
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
|
|
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
|
W: http://alsa-project.org/main/index.php/ASoC
|
|
S: Supported
|
|
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
|
|
index 9b29a62..3f9abd6 100644
|
|
--- a/arch/arm/boot/dts/tegra-ventana.dts
|
|
+++ b/arch/arm/boot/dts/tegra-ventana.dts
|
|
@@ -22,11 +22,10 @@
|
|
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;
|
|
};
|
|
};
|
|
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
|
|
index a4401d6..adad70d 100644
|
|
--- a/arch/arm/mach-at91/at91cap9_devices.c
|
|
+++ b/arch/arm/mach-at91/at91cap9_devices.c
|
|
@@ -98,7 +98,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
|
|
* 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] = {
|
|
@@ -1021,8 +1021,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
#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] = {
|
|
@@ -1035,7 +1035,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
|
|
index 01d8bbd..66591fa 100644
|
|
--- a/arch/arm/mach-at91/at91rm9200_devices.c
|
|
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
|
|
@@ -877,8 +877,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
#if defined(CONFIG_SERIAL_ATMEL)
|
|
static struct resource dbgu_resources[] = {
|
|
[0] = {
|
|
- .start = AT91_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] = {
|
|
@@ -891,7 +891,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
|
|
index 24b6f8c..25e3464 100644
|
|
--- a/arch/arm/mach-at91/at91sam9260_devices.c
|
|
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
|
|
@@ -837,8 +837,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
#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] = {
|
|
@@ -851,7 +851,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
|
|
index 3b70b38..ae78f4d 100644
|
|
--- a/arch/arm/mach-at91/at91sam9261_devices.c
|
|
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
|
|
@@ -816,8 +816,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
#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] = {
|
|
@@ -830,7 +830,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
|
|
index 3faa1fd..ad017eb 100644
|
|
--- a/arch/arm/mach-at91/at91sam9263_devices.c
|
|
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
|
|
@@ -1196,8 +1196,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
|
|
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] = {
|
|
@@ -1210,7 +1210,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
|
|
index 000b5e1..09a16d6 100644
|
|
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
|
|
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
|
|
@@ -197,7 +197,7 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
|
|
* 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,
|
|
@@ -1332,8 +1332,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
#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] = {
|
|
@@ -1346,7 +1346,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
|
|
index 305a851..628eb56 100644
|
|
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
|
|
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
|
|
@@ -75,7 +75,7 @@ void __init at91_add_device_hdmac(void) {}
|
|
* 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] = {
|
|
@@ -908,8 +908,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
|
|
#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] = {
|
|
@@ -922,7 +922,6 @@ static struct resource dbgu_resources[] = {
|
|
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);
|
|
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
|
|
index 649b052..12a3f95 100644
|
|
--- a/arch/arm/mach-at91/board-yl-9200.c
|
|
+++ b/arch/arm/mach-at91/board-yl-9200.c
|
|
@@ -384,7 +384,7 @@ static struct spi_board_info yl9200_spi_devices[] = {
|
|
#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);
|
|
diff --git a/arch/arm/mach-at91/include/mach/vmalloc.h b/arch/arm/mach-at91/include/mach/vmalloc.h
|
|
index 8eb459f..8e4a1bd 100644
|
|
--- a/arch/arm/mach-at91/include/mach/vmalloc.h
|
|
+++ b/arch/arm/mach-at91/include/mach/vmalloc.h
|
|
@@ -21,6 +21,8 @@
|
|
#ifndef __ASM_ARCH_VMALLOC_H
|
|
#define __ASM_ARCH_VMALLOC_H
|
|
|
|
+#include <mach/hardware.h>
|
|
+
|
|
#define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK)
|
|
|
|
#endif
|
|
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
|
|
index 22d8588..cfede57 100644
|
|
--- a/arch/arm/mach-imx/Makefile.boot
|
|
+++ b/arch/arm/mach-imx/Makefile.boot
|
|
@@ -1,22 +1,26 @@
|
|
-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
|
|
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
|
|
index e0b926d..613a1b9 100644
|
|
--- a/arch/arm/mach-imx/clock-imx6q.c
|
|
+++ b/arch/arm/mach-imx/clock-imx6q.c
|
|
@@ -1139,7 +1139,7 @@ static int _clk_set_rate(struct clk *clk, unsigned long rate)
|
|
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)
|
|
@@ -2002,6 +2002,21 @@ int __init mx6q_clocks_init(void)
|
|
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);
|
|
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
|
|
index 4285dfd..4ad3969 100644
|
|
--- a/arch/arm/mach-msm/Makefile
|
|
+++ b/arch/arm/mach-msm/Makefile
|
|
@@ -15,6 +15,8 @@ obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
|
|
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
|
|
|
|
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
|
|
index 71de506..db81ed5 100644
|
|
--- a/arch/arm/mach-msm/board-msm7x30.c
|
|
+++ b/arch/arm/mach-msm/board-msm7x30.c
|
|
@@ -42,8 +42,8 @@
|
|
|
|
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) {
|
|
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
|
|
index b04468e..6dc1cbd 100644
|
|
--- a/arch/arm/mach-msm/board-msm8960.c
|
|
+++ b/arch/arm/mach-msm/board-msm8960.c
|
|
@@ -32,8 +32,8 @@
|
|
|
|
#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 &&
|
|
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
|
|
index cf38e22..44bf716 100644
|
|
--- a/arch/arm/mach-msm/board-msm8x60.c
|
|
+++ b/arch/arm/mach-msm/board-msm8x60.c
|
|
@@ -28,8 +28,8 @@
|
|
#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 &&
|
|
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
|
|
index 232f97a..bafabb5 100644
|
|
--- a/arch/arm/mach-msm/scm.c
|
|
+++ b/arch/arm/mach-msm/scm.c
|
|
@@ -180,6 +180,9 @@ static u32 smc(u32 cmd_addr)
|
|
__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)
|
|
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
|
|
index 2aacf41..4cb2769 100644
|
|
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
|
|
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
|
|
@@ -1281,9 +1281,9 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
|
|
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,
|
|
@@ -1634,6 +1634,7 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_OF
|
|
static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
|
|
unsigned long *ckih1, unsigned long *ckih2)
|
|
{
|
|
@@ -1671,3 +1672,4 @@ int __init mx53_clocks_init_dt(void)
|
|
clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
|
|
return mx53_clocks_init(ckil, osc, ckih1, ckih2);
|
|
}
|
|
+#endif
|
|
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
|
|
index ac2316d..064ec5a 100644
|
|
--- a/arch/arm/mach-mxs/mach-mx28evk.c
|
|
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
|
|
@@ -471,7 +471,8 @@ static void __init mx28evk_init(void)
|
|
"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");
|
|
@@ -480,7 +481,6 @@ static void __init mx28evk_init(void)
|
|
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);
|
|
diff --git a/arch/arm/mach-picoxcell/include/mach/debug-macro.S b/arch/arm/mach-picoxcell/include/mach/debug-macro.S
|
|
index 8f2c234..58d4ee3 100644
|
|
--- a/arch/arm/mach-picoxcell/include/mach/debug-macro.S
|
|
+++ b/arch/arm/mach-picoxcell/include/mach/debug-macro.S
|
|
@@ -14,7 +14,7 @@
|
|
|
|
#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
|
|
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
|
|
index d368f8d..74743ad 100644
|
|
--- a/arch/arm/mach-tegra/board-dt.c
|
|
+++ b/arch/arm/mach-tegra/board-dt.c
|
|
@@ -101,6 +101,13 @@ static void __init tegra_dt_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();
|
|
@@ -110,12 +117,6 @@ static void __init tegra_dt_init(void)
|
|
|
|
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[] = {
|
|
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
|
|
index e99b456..7a4a26d 100644
|
|
--- a/arch/arm/mach-tegra/board-harmony-pinmux.c
|
|
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
|
|
@@ -16,6 +16,8 @@
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/gpio.h>
|
|
+#include <linux/of.h>
|
|
+
|
|
#include <mach/pinmux.h>
|
|
|
|
#include "gpio-names.h"
|
|
@@ -161,7 +163,9 @@ static struct tegra_gpio_table gpio_table[] = {
|
|
|
|
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));
|
|
|
|
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c
|
|
index fb20894..be30e21 100644
|
|
--- a/arch/arm/mach-tegra/board-paz00-pinmux.c
|
|
+++ b/arch/arm/mach-tegra/board-paz00-pinmux.c
|
|
@@ -16,6 +16,8 @@
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/gpio.h>
|
|
+#include <linux/of.h>
|
|
+
|
|
#include <mach/pinmux.h>
|
|
|
|
#include "gpio-names.h"
|
|
@@ -158,7 +160,9 @@ static struct tegra_gpio_table gpio_table[] = {
|
|
|
|
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));
|
|
|
|
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
|
|
index fbce31d..b1c2972 100644
|
|
--- a/arch/arm/mach-tegra/board-seaboard-pinmux.c
|
|
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
|
|
@@ -16,6 +16,7 @@
|
|
#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>
|
|
@@ -191,6 +192,7 @@ static struct tegra_gpio_table common_gpio_table[] = {
|
|
{ .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 },
|
|
@@ -218,7 +220,9 @@ static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size)
|
|
|
|
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));
|
|
|
|
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c
|
|
index 4969dd2..7ab719d 100644
|
|
--- a/arch/arm/mach-tegra/board-trimslice-pinmux.c
|
|
+++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c
|
|
@@ -16,6 +16,7 @@
|
|
#include <linux/gpio.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
+#include <linux/of.h>
|
|
|
|
#include <mach/pinmux.h>
|
|
|
|
@@ -157,7 +158,9 @@ static struct tegra_gpio_table gpio_table[] = {
|
|
|
|
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));
|
|
}
|
|
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
|
|
index a08a951..b3a1f2b 100644
|
|
--- a/arch/arm/plat-mxc/Kconfig
|
|
+++ b/arch/arm/plat-mxc/Kconfig
|
|
@@ -10,7 +10,7 @@ choice
|
|
|
|
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
|
|
@@ -26,7 +26,7 @@ config ARCH_IMX_V6_V7
|
|
|
|
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
|
|
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
|
|
index 8875fb4..55f1569 100644
|
|
--- a/arch/arm/plat-mxc/avic.c
|
|
+++ b/arch/arm/plat-mxc/avic.c
|
|
@@ -22,6 +22,7 @@
|
|
#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"
|
|
diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c
|
|
index b3b8eed..12f8f81 100644
|
|
--- a/arch/arm/plat-mxc/gic.c
|
|
+++ b/arch/arm/plat-mxc/gic.c
|
|
@@ -28,21 +28,14 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
|
|
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);
|
|
}
|
|
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
|
|
index 9fe0dfc..ca5cf26 100644
|
|
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
|
|
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
|
|
@@ -25,6 +25,3 @@
|
|
|
|
.macro test_for_ipi, irqnr, irqstat, base, tmp
|
|
.endm
|
|
-
|
|
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
|
|
- .endm
|
|
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
|
|
index e993a18..a3c164c 100644
|
|
--- a/arch/arm/plat-mxc/tzic.c
|
|
+++ b/arch/arm/plat-mxc/tzic.c
|
|
@@ -17,6 +17,7 @@
|
|
#include <linux/io.h>
|
|
|
|
#include <asm/mach/irq.h>
|
|
+#include <asm/exception.h>
|
|
|
|
#include <mach/hardware.h>
|
|
#include <mach/common.h>
|
|
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
|
|
index 6c28582..361d540 100644
|
|
--- a/arch/m68k/Kconfig
|
|
+++ b/arch/m68k/Kconfig
|
|
@@ -4,8 +4,8 @@ config M68K
|
|
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
|
|
diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus
|
|
index 8294f0c..3adb499 100644
|
|
--- a/arch/m68k/Kconfig.bus
|
|
+++ b/arch/m68k/Kconfig.bus
|
|
@@ -2,6 +2,15 @@ if MMU
|
|
|
|
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
|
|
diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
|
|
index d214034..6033f5d 100644
|
|
--- a/arch/m68k/Kconfig.devices
|
|
+++ b/arch/m68k/Kconfig.devices
|
|
@@ -24,6 +24,37 @@ config PROC_HARDWARE
|
|
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"
|
|
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
|
|
index c5b5212..47b5f90 100644
|
|
--- a/arch/m68k/amiga/amiints.c
|
|
+++ b/arch/m68k/amiga/amiints.c
|
|
@@ -1,43 +1,15 @@
|
|
/*
|
|
- * 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>
|
|
@@ -45,56 +17,6 @@
|
|
#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.
|
|
@@ -103,112 +25,150 @@ void __init amiga_init_IRQ(void)
|
|
* 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);
|
|
}
|
|
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
|
|
index ecd0f7c..18c0e29 100644
|
|
--- a/arch/m68k/amiga/cia.c
|
|
+++ b/arch/m68k/amiga/cia.c
|
|
@@ -93,13 +93,14 @@ static irqreturn_t cia_handler(int irq, void *dev_id)
|
|
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) {
|
|
@@ -113,19 +114,20 @@ static void cia_enable_irq(unsigned int irq)
|
|
}
|
|
}
|
|
|
|
-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,
|
|
};
|
|
|
|
/*
|
|
@@ -134,9 +136,9 @@ static struct irq_controller cia_irq_controller = {
|
|
* 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;
|
|
@@ -146,9 +148,9 @@ static void auto_enable_irq(unsigned int irq)
|
|
}
|
|
}
|
|
|
|
-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;
|
|
@@ -158,24 +160,25 @@ static void auto_disable_irq(unsigned int irq)
|
|
}
|
|
}
|
|
|
|
-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);
|
|
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
|
|
index 5d47f3a..17be1e7 100644
|
|
--- a/arch/m68k/apollo/dn_ints.c
|
|
+++ b/arch/m68k/apollo/dn_ints.c
|
|
@@ -1,19 +1,13 @@
|
|
#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
|
|
@@ -21,24 +15,33 @@ int apollo_irq_startup(unsigned int irq)
|
|
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);
|
|
}
|
|
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
|
|
index 26a804e..6d196da 100644
|
|
--- a/arch/m68k/atari/ataints.c
|
|
+++ b/arch/m68k/atari/ataints.c
|
|
@@ -60,243 +60,7 @@
|
|
* <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
|
|
@@ -320,31 +84,44 @@ extern void atari_microwire_cmd(int cmd);
|
|
|
|
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,
|
|
};
|
|
|
|
/*
|
|
@@ -360,8 +137,9 @@ static struct irq_controller atari_irq_controller = {
|
|
|
|
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) */
|
|
|
|
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
|
|
index 1edd950..8128647 100644
|
|
--- a/arch/m68k/bvme6000/config.c
|
|
+++ b/arch/m68k/bvme6000/config.c
|
|
@@ -86,7 +86,7 @@ static void bvme6000_get_model(char *model)
|
|
*/
|
|
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)
|
|
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
|
|
index f6312c7..c87fe69 100644
|
|
--- a/arch/m68k/hp300/time.c
|
|
+++ b/arch/m68k/hp300/time.c
|
|
@@ -70,7 +70,7 @@ void __init hp300_sched_init(irq_handler_t vector)
|
|
|
|
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 */
|
|
diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h
|
|
index 870e534..db30ed2 100644
|
|
--- a/arch/m68k/include/asm/hardirq.h
|
|
+++ b/arch/m68k/include/asm/hardirq.h
|
|
@@ -18,6 +18,11 @@
|
|
|
|
#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;
|
|
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
|
|
index 69ed0d74..6198df5 100644
|
|
--- a/arch/m68k/include/asm/irq.h
|
|
+++ b/arch/m68k/include/asm/irq.h
|
|
@@ -27,11 +27,6 @@
|
|
|
|
#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.
|
|
@@ -54,10 +49,6 @@
|
|
|
|
#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
|
|
@@ -71,57 +62,27 @@ struct pt_regs;
|
|
#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_ */
|
|
diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h
|
|
index c2a1c5e..12ebe43 100644
|
|
--- a/arch/m68k/include/asm/macintosh.h
|
|
+++ b/arch/m68k/include/asm/macintosh.h
|
|
@@ -12,6 +12,8 @@ extern void mac_reset(void);
|
|
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
|
|
diff --git a/arch/m68k/include/asm/q40ints.h b/arch/m68k/include/asm/q40ints.h
|
|
index 3d970af..22f12c9 100644
|
|
--- a/arch/m68k/include/asm/q40ints.h
|
|
+++ b/arch/m68k/include/asm/q40ints.h
|
|
@@ -24,6 +24,3 @@
|
|
#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);
|
|
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
|
|
index e7f0f2e..c569619 100644
|
|
--- a/arch/m68k/kernel/Makefile
|
|
+++ b/arch/m68k/kernel/Makefile
|
|
@@ -6,16 +6,15 @@ extra-$(CONFIG_MMU) := head.o
|
|
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
|
|
|
|
diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S
|
|
index bd0ec05..c713f51 100644
|
|
--- a/arch/m68k/kernel/entry_mm.S
|
|
+++ b/arch/m68k/kernel/entry_mm.S
|
|
@@ -48,7 +48,7 @@
|
|
.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)
|
|
@@ -207,7 +207,7 @@ ENTRY(auto_inthandler)
|
|
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:
|
|
@@ -240,8 +240,7 @@ user_irqvec_fixup = . + 2
|
|
|
|
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)
|
|
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
|
|
index 761ee04..74fefac 100644
|
|
--- a/arch/m68k/kernel/ints.c
|
|
+++ b/arch/m68k/kernel/ints.c
|
|
@@ -4,25 +4,6 @@
|
|
* 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>
|
|
@@ -47,33 +28,22 @@
|
|
#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)
|
|
*
|
|
@@ -96,7 +66,7 @@ void __init 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();
|
|
}
|
|
@@ -106,7 +76,7 @@ void __init init_IRQ(void)
|
|
* @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 *))
|
|
@@ -120,217 +90,49 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re
|
|
* 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;
|
|
@@ -339,41 +141,21 @@ int m68k_irq_startup(unsigned int irq)
|
|
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)
|
|
{
|
|
@@ -386,52 +168,9 @@ 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
|
|
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
|
|
index 2a96beb..b403924 100644
|
|
--- a/arch/m68k/mac/baboon.c
|
|
+++ b/arch/m68k/mac/baboon.c
|
|
@@ -11,6 +11,7 @@
|
|
#include <linux/mm.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/init.h>
|
|
+#include <linux/irq.h>
|
|
|
|
#include <asm/traps.h>
|
|
#include <asm/bootinfo.h>
|
|
@@ -20,9 +21,6 @@
|
|
|
|
/* #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;
|
|
@@ -53,7 +51,7 @@ void __init baboon_init(void)
|
|
* 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;
|
|
@@ -64,15 +62,16 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
|
|
(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++;
|
|
@@ -82,7 +81,6 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
|
|
/* for now we need to smash all interrupts */
|
|
baboon->mb_ifr &= ~events;
|
|
#endif
|
|
- return IRQ_HANDLED;
|
|
}
|
|
|
|
/*
|
|
@@ -92,8 +90,7 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
|
|
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);
|
|
}
|
|
|
|
/*
|
|
@@ -111,7 +108,7 @@ void baboon_irq_enable(int 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)
|
|
@@ -124,7 +121,7 @@ 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)
|
|
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
|
|
index 1ad4e9d..a5462cc 100644
|
|
--- a/arch/m68k/mac/iop.c
|
|
+++ b/arch/m68k/mac/iop.c
|
|
@@ -305,15 +305,13 @@ void __init iop_register_interrupts(void)
|
|
{
|
|
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])) {
|
|
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
|
|
index f92190c..ba220b7 100644
|
|
--- a/arch/m68k/mac/macints.c
|
|
+++ b/arch/m68k/mac/macints.c
|
|
@@ -190,14 +190,10 @@ irqreturn_t mac_debug_handler(int, void *);
|
|
|
|
/* #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)
|
|
@@ -205,7 +201,7 @@ 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
|
|
@@ -241,16 +237,17 @@ void __init mac_init_IRQ(void)
|
|
}
|
|
|
|
/*
|
|
- * 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) {
|
|
@@ -283,8 +280,9 @@ void mac_enable_irq(unsigned int irq)
|
|
}
|
|
}
|
|
|
|
-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) {
|
|
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
|
|
index a9c0f5a..a4c82da 100644
|
|
--- a/arch/m68k/mac/oss.c
|
|
+++ b/arch/m68k/mac/oss.c
|
|
@@ -19,6 +19,7 @@
|
|
#include <linux/mm.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/init.h>
|
|
+#include <linux/irq.h>
|
|
|
|
#include <asm/bootinfo.h>
|
|
#include <asm/macintosh.h>
|
|
@@ -29,10 +30,7 @@
|
|
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
|
|
@@ -60,26 +58,6 @@ void __init oss_init(void)
|
|
}
|
|
|
|
/*
|
|
- * 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
|
|
*/
|
|
|
|
@@ -92,17 +70,17 @@ void __init oss_nubus_init(void)
|
|
* 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
|
|
@@ -113,11 +91,10 @@ static irqreturn_t oss_irq(int irq, void *dev_id)
|
|
/* 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;
|
|
}
|
|
|
|
/*
|
|
@@ -126,13 +103,13 @@ static irqreturn_t oss_irq(int irq, void *dev_id)
|
|
* 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) {
|
|
@@ -148,10 +125,21 @@ static irqreturn_t oss_nubus_irq(int irq, void *dev_id)
|
|
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);
|
|
}
|
|
|
|
/*
|
|
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
|
|
index a4c3eb6..e6c2d20 100644
|
|
--- a/arch/m68k/mac/psc.c
|
|
+++ b/arch/m68k/mac/psc.c
|
|
@@ -18,6 +18,7 @@
|
|
#include <linux/mm.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/init.h>
|
|
+#include <linux/irq.h>
|
|
|
|
#include <asm/traps.h>
|
|
#include <asm/bootinfo.h>
|
|
@@ -30,8 +31,6 @@
|
|
int psc_present;
|
|
volatile __u8 *psc;
|
|
|
|
-irqreturn_t psc_irq(int, void *);
|
|
-
|
|
/*
|
|
* Debugging dump, used in various places to see what's going on.
|
|
*/
|
|
@@ -112,52 +111,52 @@ void __init psc_init(void)
|
|
}
|
|
|
|
/*
|
|
- * 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) {
|
|
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
|
|
index e71166d..f1600ad 100644
|
|
--- a/arch/m68k/mac/via.c
|
|
+++ b/arch/m68k/mac/via.c
|
|
@@ -28,6 +28,7 @@
|
|
#include <linux/delay.h>
|
|
#include <linux/init.h>
|
|
#include <linux/module.h>
|
|
+#include <linux/irq.h>
|
|
|
|
#include <asm/bootinfo.h>
|
|
#include <asm/macintosh.h>
|
|
@@ -77,9 +78,6 @@ static int gIER,gIFR,gBufA,gBufB;
|
|
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);
|
|
@@ -281,40 +279,11 @@ void __init via_init_clock(irq_handler_t func)
|
|
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.
|
|
*/
|
|
|
|
@@ -446,48 +415,46 @@ void __init via_nubus_init(void)
|
|
* 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;
|
|
}
|
|
|
|
/*
|
|
@@ -495,7 +462,7 @@ irqreturn_t via2_irq(int irq, void *dev_id)
|
|
* 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;
|
|
@@ -506,7 +473,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
|
|
else
|
|
events &= ~via2[vDirA];
|
|
if (!events)
|
|
- return IRQ_NONE;
|
|
+ return;
|
|
|
|
do {
|
|
slot_irq = IRQ_NUBUS_F;
|
|
@@ -514,7 +481,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
|
|
do {
|
|
if (events & slot_bit) {
|
|
events &= ~slot_bit;
|
|
- m68k_handle_int(slot_irq);
|
|
+ generic_handle_irq(slot_irq);
|
|
}
|
|
--slot_irq;
|
|
slot_bit >>= 1;
|
|
@@ -528,7 +495,24 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
|
|
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) {
|
|
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
|
|
index 6cb9c3a..5de924e 100644
|
|
--- a/arch/m68k/mvme147/config.c
|
|
+++ b/arch/m68k/mvme147/config.c
|
|
@@ -81,7 +81,7 @@ static void mvme147_get_model(char *model)
|
|
|
|
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)
|
|
@@ -114,8 +114,7 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
|
|
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 */
|
|
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
|
|
index 0b28e26..31a66d9 100644
|
|
--- a/arch/m68k/mvme16x/config.c
|
|
+++ b/arch/m68k/mvme16x/config.c
|
|
@@ -117,7 +117,7 @@ static void mvme16x_get_hardware_list(struct seq_file *m)
|
|
|
|
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)
|
|
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
|
|
index 9f0e3d5..2b88849 100644
|
|
--- a/arch/m68k/q40/q40ints.c
|
|
+++ b/arch/m68k/q40/q40ints.c
|
|
@@ -15,10 +15,10 @@
|
|
#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>
|
|
@@ -35,35 +35,36 @@
|
|
*/
|
|
|
|
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,
|
|
};
|
|
|
|
/*
|
|
@@ -81,13 +82,14 @@ static int disabled;
|
|
|
|
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 */
|
|
@@ -218,11 +220,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
|
|
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)) {
|
|
@@ -257,7 +259,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
|
|
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 */
|
|
@@ -288,25 +290,29 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
|
|
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 !!
|
|
@@ -319,13 +325,3 @@ void q40_disable_irq(unsigned int 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;
|
|
-}
|
|
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
|
|
index 6464ad3..78b60f5 100644
|
|
--- a/arch/m68k/sun3/sun3ints.c
|
|
+++ b/arch/m68k/sun3/sun3ints.c
|
|
@@ -51,25 +51,29 @@ void sun3_disable_irq(unsigned int irq)
|
|
|
|
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;
|
|
}
|
|
|
|
@@ -79,29 +83,33 @@ static irqreturn_t sun3_vec255(int irq, void *dev_id)
|
|
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");
|
|
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
|
|
index 9b4cb00..0be3186 100644
|
|
--- a/arch/mips/Makefile
|
|
+++ b/arch/mips/Makefile
|
|
@@ -286,11 +286,11 @@ CLEAN_FILES += vmlinux.32 vmlinux.64
|
|
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:
|
|
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts
|
|
new file mode 100644
|
|
index 0000000..0e00e50
|
|
--- /dev/null
|
|
+++ b/arch/powerpc/boot/dts/charon.dts
|
|
@@ -0,0 +1,236 @@
|
|
+/*
|
|
+ * 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>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig
|
|
index 959cd2c..716a37b 100644
|
|
--- a/arch/powerpc/configs/52xx/tqm5200_defconfig
|
|
+++ b/arch/powerpc/configs/52xx/tqm5200_defconfig
|
|
@@ -1,9 +1,10 @@
|
|
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
|
|
@@ -17,7 +18,6 @@ CONFIG_PPC_MPC5200_SIMPLE=y
|
|
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
|
|
@@ -38,17 +38,18 @@ CONFIG_MTD=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
|
|
@@ -56,13 +57,11 @@ CONFIG_PATA_MPC52xx=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
|
|
@@ -70,7 +69,13 @@ 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
|
|
@@ -80,10 +85,10 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
|
|
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
|
|
@@ -102,7 +107,6 @@ CONFIG_DEBUG_KERNEL=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
|
|
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
|
|
index 84a685a5..535711f 100644
|
|
--- a/arch/powerpc/configs/ppc64_defconfig
|
|
+++ b/arch/powerpc/configs/ppc64_defconfig
|
|
@@ -485,3 +485,7 @@ CONFIG_CRYPTO_TWOFISH=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
|
|
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
|
|
index 96a58b7..a72f241 100644
|
|
--- a/arch/powerpc/configs/pseries_defconfig
|
|
+++ b/arch/powerpc/configs/pseries_defconfig
|
|
@@ -362,3 +362,7 @@ CONFIG_CRYPTO_TWOFISH=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
|
|
diff --git a/arch/powerpc/include/asm/floppy.h b/arch/powerpc/include/asm/floppy.h
|
|
index 24bd34c..936a904 100644
|
|
--- a/arch/powerpc/include/asm/floppy.h
|
|
+++ b/arch/powerpc/include/asm/floppy.h
|
|
@@ -108,10 +108,10 @@ static int fd_request_irq(void)
|
|
{
|
|
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)
|
|
diff --git a/arch/powerpc/include/asm/lv1call.h b/arch/powerpc/include/asm/lv1call.h
|
|
index 9cd5fc8..f77c708 100644
|
|
--- a/arch/powerpc/include/asm/lv1call.h
|
|
+++ b/arch/powerpc/include/asm/lv1call.h
|
|
@@ -316,7 +316,7 @@ LV1_CALL(gpu_context_free, 1, 0, 218 )
|
|
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 )
|
|
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
|
|
index bd6c401..c48de98 100644
|
|
--- a/arch/powerpc/include/asm/xics.h
|
|
+++ b/arch/powerpc/include/asm/xics.h
|
|
@@ -15,8 +15,8 @@
|
|
#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
|
|
|
|
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
|
|
index a54d92f..cf9c69b 100644
|
|
--- a/arch/powerpc/kernel/exceptions-64s.S
|
|
+++ b/arch/powerpc/kernel/exceptions-64s.S
|
|
@@ -267,7 +267,7 @@ vsx_unavailable_pSeries_1:
|
|
|
|
#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)
|
|
@@ -275,7 +275,7 @@ vsx_unavailable_pSeries_1:
|
|
|
|
#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)
|
|
@@ -283,7 +283,7 @@ vsx_unavailable_pSeries_1:
|
|
|
|
#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
|
|
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
|
|
index 25ddbfc..6df7090 100644
|
|
--- a/arch/powerpc/kernel/smp.c
|
|
+++ b/arch/powerpc/kernel/smp.c
|
|
@@ -187,7 +187,7 @@ int smp_request_message_ipi(int virq, int msg)
|
|
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);
|
|
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
|
|
index f422231..44d8829 100644
|
|
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
|
|
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
|
|
@@ -1263,7 +1263,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
|
|
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
|
|
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
|
|
index 16da595..2dd6bdd 100644
|
|
--- a/arch/powerpc/mm/mem.c
|
|
+++ b/arch/powerpc/mm/mem.c
|
|
@@ -34,6 +34,7 @@
|
|
#include <linux/suspend.h>
|
|
#include <linux/memblock.h>
|
|
#include <linux/hugetlb.h>
|
|
+#include <linux/slab.h>
|
|
|
|
#include <asm/pgalloc.h>
|
|
#include <asm/prom.h>
|
|
@@ -555,3 +556,32 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
|
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);
|
|
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
|
|
index c7dd4de..b22a83a 100644
|
|
--- a/arch/powerpc/mm/numa.c
|
|
+++ b/arch/powerpc/mm/numa.c
|
|
@@ -315,7 +315,10 @@ static int __init find_min_common_depth(void)
|
|
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("/");
|
|
|
|
@@ -344,12 +347,19 @@ static int __init find_min_common_depth(void)
|
|
|
|
#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;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
|
|
index e36d6e2..846b789 100644
|
|
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
|
|
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
|
|
@@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void)
|
|
|
|
/* list of the supported boards */
|
|
static const char *board[] __initdata = {
|
|
+ "anon,charon",
|
|
"intercontrol,digsy-mtc",
|
|
"manroland,mucmc52",
|
|
"manroland,uc101",
|
|
diff --git a/arch/powerpc/platforms/cell/beat.c b/arch/powerpc/platforms/cell/beat.c
|
|
index 232fc38..852592b 100644
|
|
--- a/arch/powerpc/platforms/cell/beat.c
|
|
+++ b/arch/powerpc/platforms/cell/beat.c
|
|
@@ -230,7 +230,7 @@ static int __init beat_register_event(void)
|
|
}
|
|
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"
|
|
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
|
|
index ae790ac..14be2bd 100644
|
|
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
|
|
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
|
|
@@ -514,7 +514,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
|
|
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;
|
|
}
|
|
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
|
|
index fc46fca..592c3d5 100644
|
|
--- a/arch/powerpc/platforms/cell/iommu.c
|
|
+++ b/arch/powerpc/platforms/cell/iommu.c
|
|
@@ -412,8 +412,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
|
|
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) */
|
|
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
|
|
index 1acf360..59c1a16 100644
|
|
--- a/arch/powerpc/platforms/cell/pmu.c
|
|
+++ b/arch/powerpc/platforms/cell/pmu.c
|
|
@@ -392,7 +392,7 @@ static int __init cbe_init_pm_irq(void)
|
|
}
|
|
|
|
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);
|
|
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
|
|
index 3675da7..e94d3ec 100644
|
|
--- a/arch/powerpc/platforms/cell/spu_base.c
|
|
+++ b/arch/powerpc/platforms/cell/spu_base.c
|
|
@@ -442,8 +442,7 @@ static int spu_request_irqs(struct spu *spu)
|
|
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;
|
|
}
|
|
@@ -451,8 +450,7 @@ static int spu_request_irqs(struct spu *spu)
|
|
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;
|
|
}
|
|
@@ -460,8 +458,7 @@ static int spu_request_irqs(struct spu *spu)
|
|
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;
|
|
}
|
|
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
|
|
index cb40e92..901bfbd 100644
|
|
--- a/arch/powerpc/platforms/powermac/pic.c
|
|
+++ b/arch/powerpc/platforms/powermac/pic.c
|
|
@@ -272,7 +272,6 @@ static struct irqaction xmon_action = {
|
|
|
|
static struct irqaction gatwick_cascade_action = {
|
|
.handler = gatwick_action,
|
|
- .flags = IRQF_DISABLED,
|
|
.name = "cascade",
|
|
};
|
|
|
|
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
|
|
index 9a521dc..9b6a820 100644
|
|
--- a/arch/powerpc/platforms/powermac/smp.c
|
|
+++ b/arch/powerpc/platforms/powermac/smp.c
|
|
@@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void)
|
|
|
|
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");
|
|
@@ -408,7 +408,7 @@ static int __init smp_psurge_kick_cpu(int nr)
|
|
|
|
static struct irqaction psurge_irqaction = {
|
|
.handler = psurge_ipi_intr,
|
|
- .flags = IRQF_DISABLED|IRQF_PERCPU,
|
|
+ .flags = IRQF_PERCPU,
|
|
.name = "primary IPI",
|
|
};
|
|
|
|
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
|
|
index 6c4b583..3f175e8 100644
|
|
--- a/arch/powerpc/platforms/ps3/device-init.c
|
|
+++ b/arch/powerpc/platforms/ps3/device-init.c
|
|
@@ -825,7 +825,7 @@ static int ps3_probe_thread(void *data)
|
|
|
|
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__,
|
|
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
|
|
index 5e304c2..ca40f6a 100644
|
|
--- a/arch/powerpc/platforms/ps3/repository.c
|
|
+++ b/arch/powerpc/platforms/ps3/repository.c
|
|
@@ -184,7 +184,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index,
|
|
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),
|
|
@@ -199,7 +199,7 @@ int ps3_repository_read_bus_num_dev(unsigned int 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),
|
|
@@ -239,7 +239,7 @@ int ps3_repository_read_dev_type(unsigned int 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),
|
|
@@ -256,8 +256,8 @@ int ps3_repository_read_dev_intr(unsigned int 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),
|
|
@@ -275,7 +275,7 @@ int ps3_repository_read_dev_reg_type(unsigned int 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),
|
|
@@ -615,7 +615,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int 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),
|
|
@@ -631,7 +631,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int 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),
|
|
@@ -786,7 +786,7 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
|
|
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),
|
|
@@ -805,7 +805,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
|
|
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),
|
|
@@ -827,8 +827,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
|
|
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),
|
|
@@ -854,7 +854,7 @@ static int ps3_repository_read_boot_dat_address(u64 *address)
|
|
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),
|
|
@@ -869,7 +869,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size)
|
|
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),
|
|
@@ -884,7 +884,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port)
|
|
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),
|
|
@@ -919,7 +919,7 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
|
|
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),
|
|
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
|
|
index 0842c6f..8c7e852 100644
|
|
--- a/arch/powerpc/sysdev/mpic.c
|
|
+++ b/arch/powerpc/sysdev/mpic.c
|
|
@@ -800,8 +800,6 @@ static void mpic_end_ipi(struct irq_data *d)
|
|
* 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);
|
|
}
|
|
diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c
|
|
index d3d6ce3..0debcc3 100644
|
|
--- a/arch/powerpc/sysdev/ppc4xx_soc.c
|
|
+++ b/arch/powerpc/sysdev/ppc4xx_soc.c
|
|
@@ -115,7 +115,7 @@ static int __init ppc4xx_l2c_probe(void)
|
|
}
|
|
|
|
/* 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);
|
|
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
|
|
index 3d93a8d..63762c6 100644
|
|
--- a/arch/powerpc/sysdev/xics/xics-common.c
|
|
+++ b/arch/powerpc/sysdev/xics/xics-common.c
|
|
@@ -134,11 +134,10 @@ static void xics_request_ipi(void)
|
|
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)
|
|
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
|
|
index 6260d5d..c7cb0af 100644
|
|
--- a/arch/sparc/include/asm/unistd.h
|
|
+++ b/arch/sparc/include/asm/unistd.h
|
|
@@ -406,8 +406,10 @@
|
|
#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,
|
|
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
|
|
index 09d8ec4..63402f9 100644
|
|
--- a/arch/sparc/kernel/systbls_32.S
|
|
+++ b/arch/sparc/kernel/systbls_32.S
|
|
@@ -84,4 +84,4 @@ sys_call_table:
|
|
/*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
|
|
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
|
|
index edbec45..db86b1a 100644
|
|
--- a/arch/sparc/kernel/systbls_64.S
|
|
+++ b/arch/sparc/kernel/systbls_64.S
|
|
@@ -85,7 +85,7 @@ sys_call_table32:
|
|
/*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 */
|
|
|
|
@@ -162,4 +162,4 @@ sys_call_table:
|
|
/*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
|
|
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
|
|
index 28071bb..4c61b52 100644
|
|
--- a/arch/x86/platform/ce4100/ce4100.c
|
|
+++ b/arch/x86/platform/ce4100/ce4100.c
|
|
@@ -109,7 +109,7 @@ static __init void sdv_serial_fixup(void)
|
|
}
|
|
|
|
#else
|
|
-static inline void sdv_serial_fixup(void);
|
|
+static inline void sdv_serial_fixup(void) {};
|
|
#endif
|
|
|
|
static void __init sdv_arch_setup(void)
|
|
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
|
|
index 6ed7afd..541020d 100644
|
|
--- a/arch/x86/platform/mrst/mrst.c
|
|
+++ b/arch/x86/platform/mrst/mrst.c
|
|
@@ -608,6 +608,7 @@ static void *msic_ocd_platform_data(void *info)
|
|
}
|
|
|
|
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},
|
|
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c
|
|
index a8ac6f1..225bd0f 100644
|
|
--- a/arch/x86/platform/mrst/vrtc.c
|
|
+++ b/arch/x86/platform/mrst/vrtc.c
|
|
@@ -76,8 +76,8 @@ unsigned long vrtc_get_time(void)
|
|
|
|
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);
|
|
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
|
|
index a816f24..a0f768c 100644
|
|
--- a/crypto/ablkcipher.c
|
|
+++ b/crypto/ablkcipher.c
|
|
@@ -383,6 +383,7 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_NET
|
|
static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_blkcipher rblkcipher;
|
|
@@ -404,6 +405,12 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
@@ -457,6 +464,7 @@ static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_NET
|
|
static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_blkcipher rblkcipher;
|
|
@@ -478,6 +486,12 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
diff --git a/crypto/aead.c b/crypto/aead.c
|
|
index 701556f..04add3dc 100644
|
|
--- a/crypto/aead.c
|
|
+++ b/crypto/aead.c
|
|
@@ -111,6 +111,7 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_NET
|
|
static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_aead raead;
|
|
@@ -132,6 +133,12 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
@@ -190,6 +197,7 @@ static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_NET
|
|
static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_aead raead;
|
|
@@ -210,6 +218,12 @@ static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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)
|
|
diff --git a/crypto/ahash.c b/crypto/ahash.c
|
|
index a3e6ef9..ac93c99 100644
|
|
--- a/crypto/ahash.c
|
|
+++ b/crypto/ahash.c
|
|
@@ -399,6 +399,7 @@ static unsigned int crypto_ahash_extsize(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;
|
|
@@ -416,6 +417,12 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
|
|
index 2572d26..1e61d1a 100644
|
|
--- a/crypto/blkcipher.c
|
|
+++ b/crypto/blkcipher.c
|
|
@@ -494,6 +494,7 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
|
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;
|
|
@@ -515,6 +516,12 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
|
|
index 2abca78..0605a2b 100644
|
|
--- a/crypto/crypto_user.c
|
|
+++ b/crypto/crypto_user.c
|
|
@@ -44,9 +44,6 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
|
|
|
|
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;
|
|
|
|
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
|
|
index fefda78..2e458e5 100644
|
|
--- a/crypto/pcompress.c
|
|
+++ b/crypto/pcompress.c
|
|
@@ -48,6 +48,7 @@ static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_NET
|
|
static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_comp rpcomp;
|
|
@@ -62,6 +63,12 @@ static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
diff --git a/crypto/rng.c b/crypto/rng.c
|
|
index feb7de0..64f864f 100644
|
|
--- a/crypto/rng.c
|
|
+++ b/crypto/rng.c
|
|
@@ -60,6 +60,7 @@ static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_NET
|
|
static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_rng rrng;
|
|
@@ -76,6 +77,12 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
diff --git a/crypto/shash.c b/crypto/shash.c
|
|
index ea8a9c6..9100912 100644
|
|
--- a/crypto/shash.c
|
|
+++ b/crypto/shash.c
|
|
@@ -524,6 +524,7 @@ static unsigned int crypto_shash_extsize(struct crypto_alg *alg)
|
|
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;
|
|
@@ -541,6 +542,12 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
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));
|
|
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
|
|
index 73b2909..0e8e2de 100644
|
|
--- a/drivers/acpi/processor_idle.c
|
|
+++ b/drivers/acpi/processor_idle.c
|
|
@@ -224,7 +224,6 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
|
/*
|
|
* Suspend / resume control
|
|
*/
|
|
-static int acpi_idle_suspend;
|
|
static u32 saved_bm_rld;
|
|
|
|
static void acpi_idle_bm_rld_save(void)
|
|
@@ -243,21 +242,13 @@ static void acpi_idle_bm_rld_restore(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;
|
|
}
|
|
|
|
@@ -763,13 +754,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
|
|
|
|
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);
|
|
@@ -810,13 +794,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
|
|
|
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;
|
|
/*
|
|
@@ -895,12 +872,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
|
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,
|
|
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
|
|
index fb7b90b..cf26222 100644
|
|
--- a/drivers/ata/ahci.c
|
|
+++ b/drivers/ata/ahci.c
|
|
@@ -390,6 +390,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|
/* 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 },
|
|
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
|
|
index 004f2ce..ec55595 100644
|
|
--- a/drivers/ata/ahci_platform.c
|
|
+++ b/drivers/ata/ahci_platform.c
|
|
@@ -65,7 +65,7 @@ static struct scsi_host_template ahci_platform_sht = {
|
|
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 };
|
|
@@ -191,7 +191,7 @@ err0:
|
|
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);
|
|
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
|
|
index f22957c..a9b2820 100644
|
|
--- a/drivers/ata/libata-eh.c
|
|
+++ b/drivers/ata/libata-eh.c
|
|
@@ -2883,7 +2883,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|
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
|
|
@@ -2909,6 +2909,16 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|
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)
|
|
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
|
|
index 104462d..21b80c5 100644
|
|
--- a/drivers/ata/libata-pmp.c
|
|
+++ b/drivers/ata/libata-pmp.c
|
|
@@ -389,12 +389,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
|
|
/* 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)
|
|
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
|
|
index 72a9770..2a5412e 100644
|
|
--- a/drivers/ata/libata-scsi.c
|
|
+++ b/drivers/ata/libata-scsi.c
|
|
@@ -1217,6 +1217,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
|
|
|
|
/**
|
|
* __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.
|
|
diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c
|
|
index a72ab0d..2a472c5 100644
|
|
--- a/drivers/ata/pata_of_platform.c
|
|
+++ b/drivers/ata/pata_of_platform.c
|
|
@@ -52,7 +52,7 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev)
|
|
}
|
|
|
|
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;
|
|
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
|
|
index 447d9c0..95ec435 100644
|
|
--- a/drivers/ata/sata_sis.c
|
|
+++ b/drivers/ata/sata_sis.c
|
|
@@ -104,7 +104,7 @@ static const struct ata_port_info sis_port_info = {
|
|
};
|
|
|
|
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);
|
|
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
|
|
index 434a6c0..95706fa 100644
|
|
--- a/drivers/base/power/opp.c
|
|
+++ b/drivers/base/power/opp.c
|
|
@@ -669,7 +669,7 @@ struct srcu_notifier_head *opp_get_notifier(struct device *dev)
|
|
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;
|
|
}
|
|
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
|
|
index 66cd0b8..c92424c 100644
|
|
--- a/drivers/char/agp/intel-gtt.c
|
|
+++ b/drivers/char/agp/intel-gtt.c
|
|
@@ -1186,10 +1186,11 @@ static void gen6_cleanup(void)
|
|
/* 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.
|
|
@@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void)
|
|
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
|
|
intel_iommu_gfx_mapped)
|
|
return 1;
|
|
-
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -1236,7 +1237,7 @@ static int i9xx_setup(void)
|
|
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();
|
|
diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c
|
|
index edaa987..f500201 100644
|
|
--- a/drivers/cpufreq/db8500-cpufreq.c
|
|
+++ b/drivers/cpufreq/db8500-cpufreq.c
|
|
@@ -109,7 +109,7 @@ static unsigned int db8500_cpufreq_getspeed(unsigned int cpu)
|
|
|
|
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));
|
|
|
|
@@ -120,8 +120,8 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
|
|
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);
|
|
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
|
|
index 785127c..1368826 100644
|
|
--- a/drivers/gpu/drm/Kconfig
|
|
+++ b/drivers/gpu/drm/Kconfig
|
|
@@ -9,7 +9,6 @@ menuconfig DRM
|
|
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
|
|
@@ -96,6 +95,7 @@ config DRM_I915
|
|
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
|
|
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
|
|
index 9a2e2a1..405c63b 100644
|
|
--- a/drivers/gpu/drm/drm_crtc.c
|
|
+++ b/drivers/gpu/drm/drm_crtc.c
|
|
@@ -2118,8 +2118,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
|
|
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;
|
|
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
|
|
index 2957636..3969f75 100644
|
|
--- a/drivers/gpu/drm/drm_crtc_helper.c
|
|
+++ b/drivers/gpu/drm/drm_crtc_helper.c
|
|
@@ -484,6 +484,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
|
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;
|
|
|
|
@@ -556,6 +557,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
|
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) {
|
|
@@ -721,6 +728,12 @@ fail:
|
|
*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);
|
|
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
|
|
index d067c12..1c7a1c0 100644
|
|
--- a/drivers/gpu/drm/drm_debugfs.c
|
|
+++ b/drivers/gpu/drm/drm_debugfs.c
|
|
@@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
|
|
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;
|
|
|
|
@@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
|
|
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) {
|
|
@@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
|
|
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);
|
|
@@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
|
|
}
|
|
}
|
|
}
|
|
+ mutex_unlock(&minor->debugfs_lock);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(drm_debugfs_remove_files);
|
|
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
|
|
index fc81af9..40c187c 100644
|
|
--- a/drivers/gpu/drm/drm_drv.c
|
|
+++ b/drivers/gpu/drm/drm_drv.c
|
|
@@ -125,7 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
|
|
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),
|
|
|
|
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
|
|
index cb3794a..68b7562 100644
|
|
--- a/drivers/gpu/drm/drm_irq.c
|
|
+++ b/drivers/gpu/drm/drm_irq.c
|
|
@@ -407,13 +407,16 @@ int drm_irq_uninstall(struct drm_device *dev)
|
|
/*
|
|
* 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;
|
|
@@ -1125,6 +1128,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
|
|
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;
|
|
}
|
|
@@ -1205,8 +1209,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
|
|
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)) {
|
|
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
|
|
index d14b44e..4f40f1c 100644
|
|
--- a/drivers/gpu/drm/i915/i915_debugfs.c
|
|
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
|
|
@@ -1506,7 +1506,10 @@ drm_add_fake_info_node(struct drm_minor *minor,
|
|
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;
|
|
}
|
|
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
|
|
index cc531bb..e9c2cfe 100644
|
|
--- a/drivers/gpu/drm/i915/i915_drv.c
|
|
+++ b/drivers/gpu/drm/i915/i915_drv.c
|
|
@@ -789,8 +789,8 @@ static struct vm_operations_struct i915_gem_vm_ops = {
|
|
};
|
|
|
|
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 |*/
|
|
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
|
|
index 6651c36..d18b07a 100644
|
|
--- a/drivers/gpu/drm/i915/i915_gem.c
|
|
+++ b/drivers/gpu/drm/i915/i915_gem.c
|
|
@@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
|
|
|
|
if (obj->base.size > dev_priv->mm.gtt_mappable_end) {
|
|
ret = -E2BIG;
|
|
- goto unlock;
|
|
+ goto out;
|
|
}
|
|
|
|
if (obj->madv != I915_MADV_WILLNEED) {
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
|
|
index 032a820..5fc201b 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
|
|
@@ -640,10 +640,9 @@ static int
|
|
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);
|
|
@@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
|
|
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;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
|
|
index 7226f41..7cc37e6 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
|
|
@@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
|
|
|
|
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
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
|
|
index a319d56..bb6ec9e 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
|
|
@@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
|
|
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);
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
index e0d275e..cea6696 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
@@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
|
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);
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
|
index 14a8627..3a4cc32 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
|
@@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev)
|
|
{
|
|
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);
|
|
@@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev)
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
|
|
index 81116cf..2f6daae 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
|
|
@@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
|
|
return ret;
|
|
}
|
|
|
|
- INIT_LIST_HEAD(&chan->fence.pending);
|
|
- spin_lock_init(&chan->fence.lock);
|
|
atomic_set(&chan->fence.last_sequence_irq, 0);
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
|
|
index c6143df..d39b220 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
|
|
@@ -333,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what,
|
|
|
|
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);
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
|
|
index 9f178aa..33d03fb 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
|
|
@@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev)
|
|
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;
|
|
}
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
|
|
index 82478e0..d8831ab 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
|
|
@@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev)
|
|
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);
|
|
@@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|
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;
|
|
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c
|
|
index bbc0b9c..e676b0d 100644
|
|
--- a/drivers/gpu/drm/nouveau/nv40_pm.c
|
|
+++ b/drivers/gpu/drm/nouveau/nv40_pm.c
|
|
@@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg)
|
|
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;
|
|
@@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
|
|
}
|
|
|
|
/* 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)
|
|
@@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
|
|
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)))
|
|
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
|
|
index 8c979b3..ac601f7 100644
|
|
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
|
|
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
|
|
@@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine)
|
|
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 */
|
|
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c
|
|
index d05c2c3..4b46d69 100644
|
|
--- a/drivers/gpu/drm/nouveau/nv50_grctx.c
|
|
+++ b/drivers/gpu/drm/nouveau/nv50_grctx.c
|
|
@@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
|
|
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:
|
|
diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c
|
|
index 9da2383..2e45e57 100644
|
|
--- a/drivers/gpu/drm/nouveau/nv50_vram.c
|
|
+++ b/drivers/gpu/drm/nouveau/nv50_vram.c
|
|
@@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev)
|
|
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;
|
|
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
|
|
index bbdbc51..a74e501 100644
|
|
--- a/drivers/gpu/drm/nouveau/nvc0_graph.c
|
|
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
|
|
@@ -157,8 +157,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
|
|
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);
|
|
@@ -207,14 +207,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
|
|
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;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c
|
|
index dd0e6a7..96b0b93 100644
|
|
--- a/drivers/gpu/drm/nouveau/nvc0_grctx.c
|
|
+++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c
|
|
@@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
|
|
/* 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;
|
|
@@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c
|
|
index edbfe93..ce984d5 100644
|
|
--- a/drivers/gpu/drm/nouveau/nvc0_vram.c
|
|
+++ b/drivers/gpu/drm/nouveau/nvc0_vram.c
|
|
@@ -43,7 +43,7 @@ static const u8 types[256] = {
|
|
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
|
|
@@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev)
|
|
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;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
|
|
index 87921c8..87631fe 100644
|
|
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
|
|
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
|
|
@@ -1522,12 +1522,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
|
|
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;
|
|
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
|
|
index a0de485..6fb335a 100644
|
|
--- a/drivers/gpu/drm/radeon/atombios_dp.c
|
|
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
|
|
@@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
|
}
|
|
}
|
|
|
|
- DRM_ERROR("aux i2c too many retries, giving up\n");
|
|
+ DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
|
|
return -EREMOTEIO;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
|
|
index e4c384b..1d603a3 100644
|
|
--- a/drivers/gpu/drm/radeon/evergreen.c
|
|
+++ b/drivers/gpu/drm/radeon/evergreen.c
|
|
@@ -157,6 +157,57 @@ int sumo_get_temp(struct radeon_device *rdev)
|
|
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;
|
|
@@ -1219,7 +1270,7 @@ void evergreen_mc_program(struct radeon_device *rdev)
|
|
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;
|
|
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
|
|
index 19afc43..9cdda0b 100644
|
|
--- a/drivers/gpu/drm/radeon/r600.c
|
|
+++ b/drivers/gpu/drm/radeon/r600.c
|
|
@@ -288,24 +288,6 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev)
|
|
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) {
|
|
@@ -421,6 +403,8 @@ void rs780_pm_init_profile(struct radeon_device *rdev)
|
|
|
|
void r600_pm_init_profile(struct radeon_device *rdev)
|
|
{
|
|
+ int idx;
|
|
+
|
|
if (rdev->family == CHIP_R600) {
|
|
/* XXX */
|
|
/* default */
|
|
@@ -502,81 +486,43 @@ void r600_pm_init_profile(struct radeon_device *rdev)
|
|
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;
|
|
}
|
|
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
|
|
index b316b30..fc5a1d6 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon.h
|
|
+++ b/drivers/gpu/drm/radeon/radeon.h
|
|
@@ -784,8 +784,7 @@ struct radeon_pm_clock_info {
|
|
|
|
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;
|
|
@@ -855,6 +854,9 @@ struct radeon_pm {
|
|
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
|
|
@@ -1142,6 +1144,48 @@ struct r600_vram_scratch {
|
|
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.
|
|
*/
|
|
@@ -1197,7 +1241,7 @@ struct radeon_device {
|
|
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;
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
|
|
index e294456..a2e1eae 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_asic.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
|
|
@@ -834,7 +834,7 @@ static struct radeon_asic sumo_asic = {
|
|
.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,
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
|
|
index 85f14f0..5991484 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_asic.h
|
|
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
|
|
@@ -413,6 +413,7 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p);
|
|
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);
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
|
|
index 08d0b94..d2d1792 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
|
|
@@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
|
rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
|
|
switch (frev) {
|
|
case 1:
|
|
+ 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].mclk =
|
|
le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
|
|
@@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
|
state_index++;
|
|
break;
|
|
case 2:
|
|
+ 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].mclk =
|
|
le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
|
|
@@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
|
state_index++;
|
|
break;
|
|
case 3:
|
|
+ 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].mclk =
|
|
le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
|
|
@@ -2257,7 +2269,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
|
|
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;
|
|
@@ -2377,17 +2389,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
|
|
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) {
|
|
@@ -2456,18 +2482,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
|
|
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) {
|
|
@@ -2524,19 +2564,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
|
} 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++;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
|
|
index 5cafc90..17e1a9b 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
|
|
@@ -98,7 +98,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
|
|
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);
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
|
|
index 8bf83c4..81fc100 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_combios.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
|
|
@@ -2563,14 +2563,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
|
|
|
|
/* 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);
|
|
@@ -2735,6 +2738,14 @@ default_mode:
|
|
|
|
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)
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
|
|
index fae00c0..ccaa243 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_cs.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
|
|
@@ -222,7 +222,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
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;
|
|
@@ -233,14 +233,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *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);
|
|
@@ -248,7 +248,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
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
|
|
@@ -260,14 +260,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
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);
|
|
@@ -275,7 +275,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
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;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
|
|
index c33bc91..c4d00a1 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_device.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_device.c
|
|
@@ -716,7 +716,7 @@ int radeon_device_init(struct radeon_device *rdev,
|
|
|
|
/* 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);
|
|
@@ -955,6 +955,9 @@ int radeon_gpu_reset(struct radeon_device *rdev)
|
|
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);
|
|
@@ -967,10 +970,15 @@ int radeon_gpu_reset(struct radeon_device *rdev)
|
|
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;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
|
|
index 41a5d48..daadf21 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
|
|
@@ -991,12 +991,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
|
|
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;
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
|
|
index 6fabe89..78a665b 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_pm.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
|
|
@@ -53,6 +53,24 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev);
|
|
|
|
#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,
|
|
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
|
|
index 03daefa..880e285 100644
|
|
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
|
|
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
|
|
@@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
|
|
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);
|
|
@@ -410,8 +414,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
|
|
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);
|
|
@@ -1323,7 +1328,10 @@ int vmw_kms_close(struct vmw_private *dev_priv)
|
|
* 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;
|
|
}
|
|
|
|
diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c
|
|
index 143461a..86980fe 100644
|
|
--- a/drivers/hwspinlock/u8500_hsem.c
|
|
+++ b/drivers/hwspinlock/u8500_hsem.c
|
|
@@ -21,6 +21,7 @@
|
|
* General Public License for more details.
|
|
*/
|
|
|
|
+#include <linux/module.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/io.h>
|
|
#include <linux/pm_runtime.h>
|
|
@@ -108,10 +109,8 @@ static int __devinit u8500_hsem_probe(struct platform_device *pdev)
|
|
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);
|
|
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
|
|
index 04b0956..8126824 100644
|
|
--- a/drivers/ide/ide-cd.c
|
|
+++ b/drivers/ide/ide-cd.c
|
|
@@ -43,7 +43,6 @@
|
|
/* 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>
|
|
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
|
|
index 61fdf54..3d42043 100644
|
|
--- a/drivers/ide/ide-floppy.c
|
|
+++ b/drivers/ide/ide-floppy.c
|
|
@@ -35,7 +35,6 @@
|
|
#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>
|
|
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
|
|
index 7ecb1ad..ce8237d 100644
|
|
--- a/drivers/ide/ide-tape.c
|
|
+++ b/drivers/ide/ide-tape.c
|
|
@@ -41,7 +41,6 @@
|
|
#include <scsi/scsi.h>
|
|
|
|
#include <asm/byteorder.h>
|
|
-#include <linux/irq.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/io.h>
|
|
#include <asm/unaligned.h>
|
|
diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
|
|
index 817f37a..c9570fc 100644
|
|
--- a/drivers/macintosh/via-macii.c
|
|
+++ b/drivers/macintosh/via-macii.c
|
|
@@ -159,7 +159,7 @@ int macii_init(void)
|
|
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;
|
|
|
|
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
|
|
index 9ab5b0c..34d02a9 100644
|
|
--- a/drivers/macintosh/via-maciisi.c
|
|
+++ b/drivers/macintosh/via-maciisi.c
|
|
@@ -122,8 +122,8 @@ maciisi_init(void)
|
|
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;
|
|
}
|
|
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
|
|
index 472aedf..297e260 100644
|
|
--- a/drivers/md/raid5.c
|
|
+++ b/drivers/md/raid5.c
|
|
@@ -3110,7 +3110,7 @@ static void handle_stripe(struct stripe_head *sh)
|
|
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);
|
|
@@ -3159,10 +3159,14 @@ static void handle_stripe(struct stripe_head *sh)
|
|
/* 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
|
|
@@ -3371,7 +3375,7 @@ finish:
|
|
|
|
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)
|
|
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c
|
|
index 2e8c288..3443455 100644
|
|
--- a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c
|
|
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c
|
|
@@ -398,7 +398,6 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
|
|
u8 i2c_r_data[24];
|
|
u8 i = 0;
|
|
u8 fifo_status = 0;
|
|
- int ret;
|
|
int status = 0;
|
|
|
|
mxl_i2c("read %d bytes", count);
|
|
@@ -418,7 +417,7 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
|
|
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) {
|
|
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c
|
|
index 91dc1fc..b741b3a 100644
|
|
--- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c
|
|
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c
|
|
@@ -296,8 +296,7 @@ int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
|
|
goto fail;
|
|
|
|
ret = mxl111sf_write_reg(state, 0x00, 0x00);
|
|
- if (mxl_fail(ret))
|
|
- goto fail;
|
|
+ mxl_fail(ret);
|
|
fail:
|
|
return ret;
|
|
}
|
|
@@ -328,11 +327,13 @@ int mxl111sf_idac_config(struct mxl111sf_state *state,
|
|
/* 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;
|
|
}
|
|
|
|
/*
|
|
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c
|
|
index 2446736..0df7f2a 100644
|
|
--- a/drivers/media/video/s5k6aa.c
|
|
+++ b/drivers/media/video/s5k6aa.c
|
|
@@ -19,6 +19,7 @@
|
|
#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>
|
|
|
|
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
|
|
index 725634d..844a4d7 100644
|
|
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
|
|
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
|
|
@@ -220,8 +220,8 @@ static int vidioc_querycap(struct file *file, void *priv,
|
|
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;
|
|
}
|
|
|
|
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
|
|
index ecef127..1e8cdb7 100644
|
|
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
|
|
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
|
|
@@ -785,8 +785,8 @@ static int vidioc_querycap(struct file *file, void *priv,
|
|
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;
|
|
}
|
|
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
|
|
index 10c2364..254d326 100644
|
|
--- a/drivers/media/video/uvc/uvc_ctrl.c
|
|
+++ b/drivers/media/video/uvc/uvc_ctrl.c
|
|
@@ -1016,7 +1016,8 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
|
|
|
|
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) {
|
|
@@ -1225,7 +1226,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
|
|
/* 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)
|
|
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
|
|
index f17f92b..0f415da 100644
|
|
--- a/drivers/media/video/v4l2-ctrls.c
|
|
+++ b/drivers/media/video/v4l2-ctrls.c
|
|
@@ -821,8 +821,8 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
|
|
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);
|
|
}
|
|
|
|
@@ -947,6 +947,7 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
|
|
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
|
|
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
|
|
index 46037f22..c26ad96 100644
|
|
--- a/drivers/media/video/v4l2-event.c
|
|
+++ b/drivers/media/video/v4l2-event.c
|
|
@@ -216,6 +216,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
|
|
unsigned long flags;
|
|
unsigned i;
|
|
|
|
+ if (sub->type == V4L2_EVENT_ALL)
|
|
+ return -EINVAL;
|
|
+
|
|
if (elems < 1)
|
|
elems = 1;
|
|
if (sub->type == V4L2_EVENT_CTRL) {
|
|
@@ -283,6 +286,7 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
|
|
{
|
|
struct v4l2_subscribed_event *sev;
|
|
unsigned long flags;
|
|
+ int i;
|
|
|
|
if (sub->type == V4L2_EVENT_ALL) {
|
|
v4l2_event_unsubscribe_all(fh);
|
|
@@ -293,8 +297,12 @@ int v4l2_event_unsubscribe(struct v4l2_fh *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);
|
|
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
|
|
index 979e544..95a3f5e 100644
|
|
--- a/drivers/media/video/videobuf2-core.c
|
|
+++ b/drivers/media/video/videobuf2-core.c
|
|
@@ -131,6 +131,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)
|
|
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",
|
|
@@ -264,6 +265,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
|
|
q->num_buffers -= buffers;
|
|
if (!q->num_buffers)
|
|
q->memory = 0;
|
|
+ INIT_LIST_HEAD(&q->queued_list);
|
|
}
|
|
|
|
/**
|
|
@@ -296,14 +298,14 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
|
|
{
|
|
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;
|
|
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c
|
|
index 4175544..ec10629 100644
|
|
--- a/drivers/mfd/ab5500-core.c
|
|
+++ b/drivers/mfd/ab5500-core.c
|
|
@@ -13,6 +13,7 @@
|
|
* 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>
|
|
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c
|
|
index 6be1fe6..43c0ebb 100644
|
|
--- a/drivers/mfd/ab5500-debugfs.c
|
|
+++ b/drivers/mfd/ab5500-debugfs.c
|
|
@@ -4,6 +4,7 @@
|
|
* 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>
|
|
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
|
|
index ae57769..4b976f0 100644
|
|
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
|
|
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
|
|
@@ -32,6 +32,7 @@
|
|
/* 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
|
|
|
|
/*
|
|
@@ -476,6 +477,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
|
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) {
|
|
diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
|
|
index 608967f..736ca10 100644
|
|
--- a/drivers/mtd/maps/bcm963xx-flash.c
|
|
+++ b/drivers/mtd/maps/bcm963xx-flash.c
|
|
@@ -21,6 +21,7 @@
|
|
#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>
|
|
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
|
|
index f4e3d82..7f43cf8 100644
|
|
--- a/drivers/platform/x86/Kconfig
|
|
+++ b/drivers/platform/x86/Kconfig
|
|
@@ -83,8 +83,10 @@ config DELL_LAPTOP
|
|
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
|
|
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c
|
|
index d9fb729..fb73008 100644
|
|
--- a/drivers/ps3/ps3-vuart.c
|
|
+++ b/drivers/ps3/ps3-vuart.c
|
|
@@ -952,7 +952,7 @@ static int ps3_vuart_bus_interrupt_get(void)
|
|
}
|
|
|
|
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",
|
|
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
|
|
index cc328de..8c3f5ad 100644
|
|
--- a/drivers/ps3/ps3stor_lib.c
|
|
+++ b/drivers/ps3/ps3stor_lib.c
|
|
@@ -167,7 +167,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)
|
|
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",
|
|
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
|
|
index d335448..bb21f44 100644
|
|
--- a/drivers/rtc/rtc-mrst.c
|
|
+++ b/drivers/rtc/rtc-mrst.c
|
|
@@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void)
|
|
/*
|
|
* 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)
|
|
{
|
|
@@ -99,10 +102,10 @@ 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)
|
|
@@ -119,9 +122,9 @@ 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);
|
|
|
|
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
|
|
index 79665e2..16d6a83 100644
|
|
--- a/drivers/spi/spi-atmel.c
|
|
+++ b/drivers/spi/spi-atmel.c
|
|
@@ -907,7 +907,7 @@ static void atmel_spi_cleanup(struct spi_device *spi)
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
-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;
|
|
@@ -1003,7 +1003,7 @@ out_free:
|
|
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);
|
|
@@ -1072,6 +1072,7 @@ static struct platform_driver atmel_spi_driver = {
|
|
},
|
|
.suspend = atmel_spi_suspend,
|
|
.resume = atmel_spi_resume,
|
|
+ .probe = atmel_spi_probe,
|
|
.remove = __exit_p(atmel_spi_remove),
|
|
};
|
|
module_platform_driver(atmel_spi_driver);
|
|
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
|
|
index 4cb0d0a..fc7bbba 100644
|
|
--- a/drivers/tty/n_gsm.c
|
|
+++ b/drivers/tty/n_gsm.c
|
|
@@ -66,14 +66,16 @@
|
|
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
|
|
|
|
/*
|
|
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
|
|
index 5a5d325..634608d 100644
|
|
--- a/fs/btrfs/btrfs_inode.h
|
|
+++ b/fs/btrfs/btrfs_inode.h
|
|
@@ -147,14 +147,12 @@ struct btrfs_inode {
|
|
* 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
|
|
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
|
|
index 3a1b939..5b16357 100644
|
|
--- a/fs/btrfs/delayed-inode.c
|
|
+++ b/fs/btrfs/delayed-inode.c
|
|
@@ -617,12 +617,14 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
|
|
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;
|
|
@@ -652,12 +654,65 @@ static int btrfs_delayed_inode_reserve_metadata(
|
|
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;
|
|
}
|
|
|
|
@@ -1708,7 +1763,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
|
|
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;
|
|
|
|
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
|
index 102c176..62afe5c 100644
|
|
--- a/fs/btrfs/disk-io.c
|
|
+++ b/fs/btrfs/disk-io.c
|
|
@@ -1890,31 +1890,32 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|
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) {
|
|
@@ -1954,12 +1955,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|
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);
|
|
@@ -2465,21 +2460,20 @@ fail_sb_buffer:
|
|
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;
|
|
|
|
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
|
|
index 9879bd4..b232150 100644
|
|
--- a/fs/btrfs/extent-tree.c
|
|
+++ b/fs/btrfs/extent-tree.c
|
|
@@ -3797,16 +3797,16 @@ void btrfs_free_block_rsv(struct btrfs_root *root,
|
|
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;
|
|
@@ -3815,22 +3815,18 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
|
|
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,
|
|
@@ -4064,23 +4060,30 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans,
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
@@ -4166,9 +4169,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
|
|
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);
|
|
|
|
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
|
|
index 7a15fcf..181760f 100644
|
|
--- a/fs/btrfs/free-space-cache.c
|
|
+++ b/fs/btrfs/free-space-cache.c
|
|
@@ -537,6 +537,13 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl,
|
|
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);
|
|
@@ -550,10 +557,7 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl,
|
|
|
|
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,
|
|
@@ -561,9 +565,6 @@ 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;
|
|
@@ -699,6 +700,8 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
|
|
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.
|
|
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
|
|
index 53dcbdf..f8962a9 100644
|
|
--- a/fs/btrfs/inode-map.c
|
|
+++ b/fs/btrfs/inode-map.c
|
|
@@ -398,6 +398,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
|
|
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;
|
|
@@ -421,11 +423,26 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
|
|
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)) {
|
|
@@ -434,7 +451,7 @@ again:
|
|
|
|
ret = create_free_ino_inode(root, trans, path);
|
|
if (ret)
|
|
- goto out;
|
|
+ goto out_release;
|
|
goto again;
|
|
}
|
|
|
|
@@ -477,11 +494,14 @@ 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;
|
|
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
|
|
index 966ddcc..116ab67 100644
|
|
--- a/fs/btrfs/inode.c
|
|
+++ b/fs/btrfs/inode.c
|
|
@@ -93,6 +93,8 @@ static noinline int cow_file_range(struct inode *inode,
|
|
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,
|
|
@@ -1741,7 +1743,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|
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;
|
|
@@ -1791,7 +1793,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|
|
|
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;
|
|
@@ -2199,6 +2201,9 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
|
|
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)
|
|
@@ -2426,7 +2431,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
|
|
/*
|
|
* 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;
|
|
@@ -2434,21 +2439,6 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
|
|
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;
|
|
@@ -2477,6 +2467,43 @@ failed:
|
|
}
|
|
|
|
/*
|
|
+ * 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
|
|
@@ -5632,7 +5659,7 @@ again:
|
|
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;
|
|
}
|
|
|
|
@@ -5670,7 +5697,7 @@ again:
|
|
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,
|
|
@@ -6529,14 +6556,16 @@ end_trans:
|
|
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);
|
|
@@ -6605,6 +6634,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
|
|
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;
|
|
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
|
|
index 24d654c..dff29d5 100644
|
|
--- a/fs/btrfs/relocation.c
|
|
+++ b/fs/btrfs/relocation.c
|
|
@@ -1174,6 +1174,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
|
|
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,
|
|
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
|
|
index ed11d38..f4190f2 100644
|
|
--- a/fs/btrfs/scrub.c
|
|
+++ b/fs/btrfs/scrub.c
|
|
@@ -944,50 +944,18 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer)
|
|
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,
|
|
@@ -995,6 +963,8 @@ 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:
|
|
/*
|
|
@@ -1015,12 +985,22 @@ 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;
|
|
@@ -1030,6 +1010,20 @@ again:
|
|
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);
|
|
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
|
|
index 57080df..8bd9d6d 100644
|
|
--- a/fs/btrfs/super.c
|
|
+++ b/fs/btrfs/super.c
|
|
@@ -197,7 +197,7 @@ static match_table_t tokens = {
|
|
{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},
|
|
};
|
|
@@ -448,6 +448,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
|
|
token = match_token(p, tokens, args);
|
|
switch (token) {
|
|
case Opt_subvol:
|
|
+ kfree(*subvol_name);
|
|
*subvol_name = match_strdup(&args[0]);
|
|
break;
|
|
case Opt_subvolid:
|
|
@@ -710,7 +711,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
|
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))
|
|
@@ -890,7 +891,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|
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;
|
|
@@ -904,8 +904,10 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|
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);
|
|
@@ -917,15 +919,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|
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
|
|
@@ -933,24 +926,36 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|
* 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;
|
|
@@ -959,12 +964,12 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|
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];
|
|
|
|
@@ -991,8 +996,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|
|
|
error_close_devices:
|
|
btrfs_close_devices(fs_devices);
|
|
+error_fs_info:
|
|
free_fs_info(fs_info);
|
|
- kfree(tree_root);
|
|
return ERR_PTR(error);
|
|
}
|
|
|
|
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
|
|
index 960835e..6a0574e 100644
|
|
--- a/fs/btrfs/transaction.c
|
|
+++ b/fs/btrfs/transaction.c
|
|
@@ -882,8 +882,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
|
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;
|
|
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
|
|
index f8e29431..c37433d 100644
|
|
--- a/fs/btrfs/volumes.c
|
|
+++ b/fs/btrfs/volumes.c
|
|
@@ -999,7 +999,7 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
|
|
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,
|
|
@@ -1012,6 +1012,9 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
|
|
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],
|
|
diff --git a/fs/proc/base.c b/fs/proc/base.c
|
|
index 2db1bd3..851ba3d 100644
|
|
--- a/fs/proc/base.c
|
|
+++ b/fs/proc/base.c
|
|
@@ -1652,46 +1652,12 @@ out:
|
|
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 */
|
|
|
|
@@ -1923,61 +1889,49 @@ out:
|
|
|
|
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)
|
|
@@ -2072,7 +2026,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
|
|
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);
|
|
@@ -2104,12 +2058,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
|
|
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:
|
|
@@ -2129,28 +2078,23 @@ static int proc_readfd_common(struct file * filp, void * dirent,
|
|
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;
|
|
@@ -2174,9 +2118,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,
|
|
rcu_read_unlock();
|
|
put_files_struct(files);
|
|
}
|
|
-
|
|
-out_unlock:
|
|
- unlock_trace(p);
|
|
out:
|
|
put_task_struct(p);
|
|
out_no_task:
|
|
@@ -2254,7 +2195,6 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
|
|
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 */
|
|
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
|
|
index 33b1331..574d4ee 100644
|
|
--- a/fs/xfs/xfs_aops.c
|
|
+++ b/fs/xfs/xfs_aops.c
|
|
@@ -189,7 +189,7 @@ xfs_end_io(
|
|
int error = 0;
|
|
|
|
if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
|
|
- error = -EIO;
|
|
+ ioend->io_error = -EIO;
|
|
goto done;
|
|
}
|
|
if (ioend->io_error)
|
|
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
|
|
index 1a35138..eac97ef 100644
|
|
--- a/fs/xfs/xfs_buf_item.c
|
|
+++ b/fs/xfs/xfs_buf_item.c
|
|
@@ -656,7 +656,7 @@ xfs_buf_item_committing(
|
|
/*
|
|
* 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,
|
|
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
|
|
index bb3f71d..0dee0b7 100644
|
|
--- a/fs/xfs/xfs_dquot_item.c
|
|
+++ b/fs/xfs/xfs_dquot_item.c
|
|
@@ -295,7 +295,7 @@ xfs_qm_dquot_logitem_committing(
|
|
/*
|
|
* 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,
|
|
@@ -483,7 +483,7 @@ xfs_qm_qoff_logitem_committing(
|
|
{
|
|
}
|
|
|
|
-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,
|
|
@@ -498,7 +498,7 @@ static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
|
|
/*
|
|
* 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,
|
|
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
|
|
index d22e626..35c2aff 100644
|
|
--- a/fs/xfs/xfs_extfree_item.c
|
|
+++ b/fs/xfs/xfs_extfree_item.c
|
|
@@ -217,7 +217,7 @@ xfs_efi_item_committing(
|
|
/*
|
|
* 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,
|
|
@@ -477,7 +477,7 @@ xfs_efd_item_committing(
|
|
/*
|
|
* 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,
|
|
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
|
|
index b7cf21b..abaafdb 100644
|
|
--- a/fs/xfs/xfs_inode_item.c
|
|
+++ b/fs/xfs/xfs_inode_item.c
|
|
@@ -795,7 +795,7 @@ xfs_inode_item_committing(
|
|
/*
|
|
* 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,
|
|
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
|
|
index 2758a62..a14cd89 100644
|
|
--- a/fs/xfs/xfs_log.c
|
|
+++ b/fs/xfs/xfs_log.c
|
|
@@ -626,7 +626,7 @@ 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)
|
|
{
|
|
item->li_mountp = mp;
|
|
item->li_ailp = mp->m_ail;
|
|
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
|
|
index 78c9039..3f7bf45 100644
|
|
--- a/fs/xfs/xfs_log.h
|
|
+++ b/fs/xfs/xfs_log.h
|
|
@@ -137,7 +137,7 @@ struct xfs_trans;
|
|
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,
|
|
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
|
|
index 603f3eb..3ae713c 100644
|
|
--- a/fs/xfs/xfs_trans.h
|
|
+++ b/fs/xfs/xfs_trans.h
|
|
@@ -326,7 +326,7 @@ typedef struct xfs_log_item {
|
|
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 */
|
|
@@ -341,7 +341,7 @@ typedef struct xfs_log_item {
|
|
{ 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 *);
|
|
@@ -352,7 +352,7 @@ typedef struct xfs_item_ops {
|
|
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)
|
|
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
|
|
index 4ecf2a5..ce9268a 100644
|
|
--- a/fs/xfs/xfs_vnodeops.c
|
|
+++ b/fs/xfs/xfs_vnodeops.c
|
|
@@ -112,7 +112,7 @@ xfs_readlink(
|
|
char *link)
|
|
{
|
|
xfs_mount_t *mp = ip->i_mount;
|
|
- int pathlen;
|
|
+ xfs_fsize_t pathlen;
|
|
int error = 0;
|
|
|
|
trace_xfs_readlink(ip);
|
|
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
|
|
index cf39949..1f9e951 100644
|
|
--- a/include/drm/drmP.h
|
|
+++ b/include/drm/drmP.h
|
|
@@ -990,7 +990,9 @@ struct drm_minor {
|
|
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;
|
|
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
|
|
index 874c4d2..1d161cb 100644
|
|
--- a/include/drm/exynos_drm.h
|
|
+++ b/include/drm/exynos_drm.h
|
|
@@ -36,11 +36,13 @@
|
|
* - 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;
|
|
};
|
|
|
|
/**
|
|
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
|
|
index afb9458..98ce812 100644
|
|
--- a/include/linux/devfreq.h
|
|
+++ b/include/linux/devfreq.h
|
|
@@ -41,7 +41,7 @@ struct devfreq_dev_status {
|
|
unsigned long total_time;
|
|
unsigned long busy_time;
|
|
unsigned long current_frequency;
|
|
- void *private_date;
|
|
+ void *private_data;
|
|
};
|
|
|
|
/**
|
|
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
|
|
index 08a2fee..aad6bd4 100644
|
|
--- a/include/linux/hwspinlock.h
|
|
+++ b/include/linux/hwspinlock.h
|
|
@@ -118,7 +118,6 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
|
|
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)
|
|
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
|
|
index fae2950..83a9cae 100644
|
|
--- a/include/linux/mfd/wm8994/registers.h
|
|
+++ b/include/linux/mfd/wm8994/registers.h
|
|
@@ -1963,6 +1963,21 @@
|
|
#define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
|
|
|
|
/*
|
|
+ * R210 (0xD2) - Mic Detect 3
|
|
+ */
|
|
+#define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
|
|
+#define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
|
|
+#define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
|
|
+#define WM8958_MICD_VALID 0x0002 /* MICD_VALID */
|
|
+#define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */
|
|
+#define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */
|
|
+#define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */
|
|
+#define WM8958_MICD_STS 0x0001 /* MICD_STS */
|
|
+#define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */
|
|
+#define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */
|
|
+#define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */
|
|
+
|
|
+/*
|
|
* R76 (0x4C) - Charge Pump (1)
|
|
*/
|
|
#define WM8994_CP_ENA 0x8000 /* CP_ENA */
|
|
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
|
|
index 3fdf251..172ba70 100644
|
|
--- a/include/linux/pci_ids.h
|
|
+++ b/include/linux/pci_ids.h
|
|
@@ -2405,6 +2405,8 @@
|
|
|
|
#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
|
|
|
|
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
|
|
index 56db751..995e3bd 100644
|
|
--- a/kernel/power/qos.c
|
|
+++ b/kernel/power/qos.c
|
|
@@ -70,6 +70,7 @@ static struct pm_qos_constraints cpu_dma_constraints = {
|
|
};
|
|
static struct pm_qos_object cpu_dma_pm_qos = {
|
|
.constraints = &cpu_dma_constraints,
|
|
+ .name = "cpu_dma_latency",
|
|
};
|
|
|
|
static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
|
|
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
|
|
index 5dbab38..130cfe6 100644
|
|
--- a/sound/core/vmaster.c
|
|
+++ b/sound/core/vmaster.c
|
|
@@ -52,6 +52,7 @@ struct link_slave {
|
|
struct link_ctl_info info;
|
|
int vals[2]; /* current values */
|
|
unsigned int flags;
|
|
+ struct snd_kcontrol *kctl; /* original kcontrol pointer */
|
|
struct snd_kcontrol slave; /* the copy of original control entry */
|
|
};
|
|
|
|
@@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave,
|
|
slave->count * sizeof(*slave->vd), GFP_KERNEL);
|
|
if (!srec)
|
|
return -ENOMEM;
|
|
+ srec->kctl = slave;
|
|
srec->slave = *slave;
|
|
memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd));
|
|
srec->master = master_link;
|
|
@@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol,
|
|
static void master_free(struct snd_kcontrol *kcontrol)
|
|
{
|
|
struct link_master *master = snd_kcontrol_chip(kcontrol);
|
|
- struct link_slave *slave;
|
|
-
|
|
- list_for_each_entry(slave, &master->slaves, list)
|
|
- slave->master = NULL;
|
|
+ struct link_slave *slave, *n;
|
|
+
|
|
+ /* free all slave links and retore the original slave kctls */
|
|
+ list_for_each_entry_safe(slave, n, &master->slaves, list) {
|
|
+ struct snd_kcontrol *sctl = slave->kctl;
|
|
+ struct list_head olist = sctl->list;
|
|
+ memcpy(sctl, &slave->slave, sizeof(*sctl));
|
|
+ memcpy(sctl->vd, slave->slave.vd,
|
|
+ sctl->count * sizeof(*sctl->vd));
|
|
+ sctl->list = olist; /* keep the current linked-list */
|
|
+ kfree(slave);
|
|
+ }
|
|
kfree(master);
|
|
}
|
|
|
|
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
|
|
index 916a186..e44b107 100644
|
|
--- a/sound/pci/hda/hda_codec.c
|
|
+++ b/sound/pci/hda/hda_codec.c
|
|
@@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec)
|
|
return 0;
|
|
}
|
|
|
|
+typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
|
|
+
|
|
+/* apply the function to all matching slave ctls in the mixer list */
|
|
+static int map_slaves(struct hda_codec *codec, const char * const *slaves,
|
|
+ map_slave_func_t func, void *data)
|
|
+{
|
|
+ struct hda_nid_item *items;
|
|
+ const char * const *s;
|
|
+ int i, err;
|
|
+
|
|
+ items = codec->mixers.list;
|
|
+ for (i = 0; i < codec->mixers.used; i++) {
|
|
+ struct snd_kcontrol *sctl = items[i].kctl;
|
|
+ if (!sctl || !sctl->id.name ||
|
|
+ sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
|
|
+ continue;
|
|
+ for (s = slaves; *s; s++) {
|
|
+ if (!strcmp(sctl->id.name, *s)) {
|
|
+ err = func(data, sctl);
|
|
+ if (err)
|
|
+ return err;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int check_slave_present(void *data, struct snd_kcontrol *sctl)
|
|
+{
|
|
+ return 1;
|
|
+}
|
|
+
|
|
/**
|
|
* snd_hda_add_vmaster - create a virtual master control and add slaves
|
|
* @codec: HD-audio codec
|
|
@@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
|
unsigned int *tlv, const char * const *slaves)
|
|
{
|
|
struct snd_kcontrol *kctl;
|
|
- const char * const *s;
|
|
int err;
|
|
|
|
- for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
|
|
- ;
|
|
- if (!*s) {
|
|
+ err = map_slaves(codec, slaves, check_slave_present, NULL);
|
|
+ if (err != 1) {
|
|
snd_printdd("No slave found for %s\n", name);
|
|
return 0;
|
|
}
|
|
@@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
|
if (err < 0)
|
|
return err;
|
|
|
|
- for (s = slaves; *s; s++) {
|
|
- struct snd_kcontrol *sctl;
|
|
- int i = 0;
|
|
- for (;;) {
|
|
- sctl = _snd_hda_find_mixer_ctl(codec, *s, i);
|
|
- if (!sctl) {
|
|
- if (!i)
|
|
- snd_printdd("Cannot find slave %s, "
|
|
- "skipped\n", *s);
|
|
- break;
|
|
- }
|
|
- err = snd_ctl_add_slave(kctl, sctl);
|
|
- if (err < 0)
|
|
- return err;
|
|
- i++;
|
|
- }
|
|
- }
|
|
+ err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave,
|
|
+ kctl);
|
|
+ if (err < 0)
|
|
+ return err;
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
|
|
@@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
|
|
memset(sequences_hp, 0, sizeof(sequences_hp));
|
|
assoc_line_out = 0;
|
|
|
|
+ codec->ignore_misc_bit = true;
|
|
end_nid = codec->start_nid + codec->num_nodes;
|
|
for (nid = codec->start_nid; nid < end_nid; nid++) {
|
|
unsigned int wid_caps = get_wcaps(codec, nid);
|
|
@@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
|
|
continue;
|
|
|
|
def_conf = snd_hda_codec_get_pincfg(codec, nid);
|
|
+ if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
|
|
+ AC_DEFCFG_MISC_NO_PRESENCE))
|
|
+ codec->ignore_misc_bit = false;
|
|
conn = get_defcfg_connect(def_conf);
|
|
if (conn == AC_JACK_PORT_NONE)
|
|
continue;
|
|
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
|
|
index 755f2b0..5644711 100644
|
|
--- a/sound/pci/hda/hda_codec.h
|
|
+++ b/sound/pci/hda/hda_codec.h
|
|
@@ -854,6 +854,7 @@ struct hda_codec {
|
|
unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
|
|
unsigned int pins_shutup:1; /* pins are shut up */
|
|
unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
|
|
+ unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
|
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
|
unsigned int power_on :1; /* current (global) power-state */
|
|
unsigned int power_transition :1; /* power-state in transition */
|
|
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
|
|
index dcbea0d..6579e0f 100644
|
|
--- a/sound/pci/hda/hda_local.h
|
|
+++ b/sound/pci/hda/hda_local.h
|
|
@@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
|
|
|
|
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
|
|
{
|
|
- return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
|
|
- /* disable MISC_NO_PRESENCE check because it may break too
|
|
- * many devices
|
|
- */
|
|
- /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) &
|
|
- AC_DEFCFG_MISC_NO_PRESENCE)) &&*/
|
|
- (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
|
|
+ if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
|
|
+ return false;
|
|
+ if (!codec->ignore_misc_bit &&
|
|
+ (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
|
|
+ AC_DEFCFG_MISC_NO_PRESENCE))
|
|
+ return false;
|
|
+ if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
|
|
+ return false;
|
|
+ return true;
|
|
}
|
|
|
|
/* flags for hda_nid_item */
|
|
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
|
|
index 5e706e4..0de2119 100644
|
|
--- a/sound/pci/hda/patch_conexant.c
|
|
+++ b/sound/pci/hda/patch_conexant.c
|
|
@@ -3062,7 +3062,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
|
|
SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
|
|
SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
|
|
SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
|
|
- SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
|
|
SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
|
|
CXT5066_LAPTOP),
|
|
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
|
|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
|
index a24e068..308bb57 100644
|
|
--- a/sound/pci/hda/patch_realtek.c
|
|
+++ b/sound/pci/hda/patch_realtek.c
|
|
@@ -284,7 +284,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
|
struct alc_spec *spec = codec->spec;
|
|
const struct hda_input_mux *imux;
|
|
unsigned int mux_idx;
|
|
- int i, type;
|
|
+ int i, type, num_conns;
|
|
hda_nid_t nid;
|
|
|
|
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
|
|
@@ -307,16 +307,17 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
|
spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
|
|
|
|
/* no selection? */
|
|
- if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
|
|
+ num_conns = snd_hda_get_conn_list(codec, nid, NULL);
|
|
+ if (num_conns <= 1)
|
|
return 1;
|
|
|
|
type = get_wcaps_type(get_wcaps(codec, nid));
|
|
if (type == AC_WID_AUD_MIX) {
|
|
/* Matrix-mixer style (e.g. ALC882) */
|
|
- for (i = 0; i < imux->num_items; i++) {
|
|
- unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
|
|
- snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
|
|
- imux->items[i].index,
|
|
+ int active = imux->items[idx].index;
|
|
+ for (i = 0; i < num_conns; i++) {
|
|
+ unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE;
|
|
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i,
|
|
HDA_AMP_MUTE, v);
|
|
}
|
|
} else {
|
|
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
|
|
index 4e715fe..edc2b7b 100644
|
|
--- a/sound/pci/hda/patch_sigmatel.c
|
|
+++ b/sound/pci/hda/patch_sigmatel.c
|
|
@@ -95,6 +95,7 @@ enum {
|
|
STAC_92HD83XXX_REF,
|
|
STAC_92HD83XXX_PWR_REF,
|
|
STAC_DELL_S14,
|
|
+ STAC_DELL_VOSTRO_3500,
|
|
STAC_92HD83XXX_HP,
|
|
STAC_92HD83XXX_HP_cNB11_INTQUAD,
|
|
STAC_HP_DV7_4000,
|
|
@@ -1659,6 +1660,12 @@ static const unsigned int dell_s14_pin_configs[10] = {
|
|
0x40f000f0, 0x40f000f0,
|
|
};
|
|
|
|
+static const unsigned int dell_vostro_3500_pin_configs[10] = {
|
|
+ 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110,
|
|
+ 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160,
|
|
+ 0x400000f4, 0x400000f5,
|
|
+};
|
|
+
|
|
static const unsigned int hp_dv7_4000_pin_configs[10] = {
|
|
0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
|
|
0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
|
|
@@ -1675,6 +1682,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
|
|
[STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
|
|
[STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
|
|
[STAC_DELL_S14] = dell_s14_pin_configs,
|
|
+ [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
|
|
[STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
|
|
[STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
|
|
};
|
|
@@ -1684,6 +1692,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
|
|
[STAC_92HD83XXX_REF] = "ref",
|
|
[STAC_92HD83XXX_PWR_REF] = "mic-ref",
|
|
[STAC_DELL_S14] = "dell-s14",
|
|
+ [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
|
|
[STAC_92HD83XXX_HP] = "hp",
|
|
[STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
|
|
[STAC_HP_DV7_4000] = "hp-dv7-4000",
|
|
@@ -1697,6 +1706,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
|
|
"DFI LanParty", STAC_92HD83XXX_REF),
|
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
|
|
"unknown Dell", STAC_DELL_S14),
|
|
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
|
|
+ "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
|
|
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
|
|
"HP", STAC_92HD83XXX_HP),
|
|
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
|
|
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
|
|
index 29e3125..11718b49 100644
|
|
--- a/sound/pci/intel8x0.c
|
|
+++ b/sound/pci/intel8x0.c
|
|
@@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
|
|
}
|
|
if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV))
|
|
continue;
|
|
+
|
|
+ /* IO read operation is very expensive inside virtual machine
|
|
+ * as it is emulated. The probability that subsequent PICB read
|
|
+ * will return different result is high enough to loop till
|
|
+ * timeout here.
|
|
+ * Same CIV is strict enough condition to be sure that PICB
|
|
+ * is valid inside VM on emulated card. */
|
|
if (chip->inside_vm)
|
|
break;
|
|
if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
|
|
@@ -2930,6 +2937,45 @@ static unsigned int sis_codec_bits[3] = {
|
|
ICH_PCR, ICH_SCR, ICH_SIS_TCR
|
|
};
|
|
|
|
+static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci)
|
|
+{
|
|
+ int result = inside_vm;
|
|
+ char *msg = NULL;
|
|
+
|
|
+ /* check module parameter first (override detection) */
|
|
+ if (result >= 0) {
|
|
+ msg = result ? "enable (forced) VM" : "disable (forced) VM";
|
|
+ goto fini;
|
|
+ }
|
|
+
|
|
+ /* detect KVM and Parallels virtual environments */
|
|
+ result = kvm_para_available();
|
|
+#ifdef X86_FEATURE_HYPERVISOR
|
|
+ result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR);
|
|
+#endif
|
|
+ if (!result)
|
|
+ goto fini;
|
|
+
|
|
+ /* check for known (emulated) devices */
|
|
+ if (pci->subsystem_vendor == 0x1af4 &&
|
|
+ pci->subsystem_device == 0x1100) {
|
|
+ /* KVM emulated sound, PCI SSID: 1af4:1100 */
|
|
+ msg = "enable KVM";
|
|
+ } else if (pci->subsystem_vendor == 0x1ab8) {
|
|
+ /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */
|
|
+ msg = "enable Parallels VM";
|
|
+ } else {
|
|
+ msg = "disable (unknown or VT-d) VM";
|
|
+ result = 0;
|
|
+ }
|
|
+
|
|
+fini:
|
|
+ if (msg != NULL)
|
|
+ printk(KERN_INFO "intel8x0: %s optimization\n", msg);
|
|
+
|
|
+ return result;
|
|
+}
|
|
+
|
|
static int __devinit snd_intel8x0_create(struct snd_card *card,
|
|
struct pci_dev *pci,
|
|
unsigned long device_type,
|
|
@@ -2997,9 +3043,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
|
|
if (xbox)
|
|
chip->xbox = 1;
|
|
|
|
- chip->inside_vm = inside_vm;
|
|
- if (inside_vm)
|
|
- printk(KERN_INFO "intel8x0: enable KVM optimization\n");
|
|
+ chip->inside_vm = snd_intel8x0_inside_vm(pci);
|
|
|
|
if (pci->vendor == PCI_VENDOR_ID_INTEL &&
|
|
pci->device == PCI_DEVICE_ID_INTEL_440MX)
|
|
@@ -3243,14 +3287,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
|
|
buggy_irq = 0;
|
|
}
|
|
|
|
- if (inside_vm < 0) {
|
|
- /* detect KVM and Parallels virtual environments */
|
|
- inside_vm = kvm_para_available();
|
|
-#if defined(__i386__) || defined(__x86_64__)
|
|
- inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR);
|
|
-#endif
|
|
- }
|
|
-
|
|
if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
|
|
&chip)) < 0) {
|
|
snd_card_free(card);
|
|
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
|
|
index a3ce1b2..1aa52ef 100644
|
|
--- a/sound/ppc/snd_ps3.c
|
|
+++ b/sound/ppc/snd_ps3.c
|
|
@@ -876,7 +876,7 @@ static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
|
|
(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);
|
|
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
|
|
index 6b73efd..9c982e4 100644
|
|
--- a/sound/soc/codecs/wm8994.c
|
|
+++ b/sound/soc/codecs/wm8994.c
|
|
@@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = {
|
|
static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
|
|
{
|
|
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
|
- struct wm8994 *control = wm8994->control_data;
|
|
+ struct wm8994 *control = codec->control_data;
|
|
|
|
switch (reg) {
|
|
case WM8994_GPIO_1:
|
|
@@ -3030,19 +3030,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
|
|
{
|
|
struct wm8994_priv *wm8994 = data;
|
|
struct snd_soc_codec *codec = wm8994->codec;
|
|
- int reg;
|
|
+ int reg, count;
|
|
|
|
- reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
|
|
- if (reg < 0) {
|
|
- dev_err(codec->dev, "Failed to read mic detect status: %d\n",
|
|
- reg);
|
|
- return IRQ_NONE;
|
|
- }
|
|
+ /* We may occasionally read a detection without an impedence
|
|
+ * range being provided - if that happens loop again.
|
|
+ */
|
|
+ count = 10;
|
|
+ do {
|
|
+ reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
|
|
+ if (reg < 0) {
|
|
+ dev_err(codec->dev,
|
|
+ "Failed to read mic detect status: %d\n",
|
|
+ reg);
|
|
+ return IRQ_NONE;
|
|
+ }
|
|
|
|
- if (!(reg & WM8958_MICD_VALID)) {
|
|
- dev_dbg(codec->dev, "Mic detect data not valid\n");
|
|
- goto out;
|
|
- }
|
|
+ if (!(reg & WM8958_MICD_VALID)) {
|
|
+ dev_dbg(codec->dev, "Mic detect data not valid\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK))
|
|
+ break;
|
|
+
|
|
+ msleep(1);
|
|
+ } while (count--);
|
|
+
|
|
+ if (count == 0)
|
|
+ dev_warn(codec->dev, "No impedence range reported for jack\n");
|
|
|
|
#ifndef CONFIG_SND_SOC_WM8994_MODULE
|
|
trace_snd_soc_jack_irq(dev_name(codec->dev));
|
|
@@ -3180,9 +3195,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
|
|
|
|
wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
|
|
wm8994_fifo_error, "FIFO error", codec);
|
|
- wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN,
|
|
+ wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN,
|
|
wm8994_temp_warn, "Thermal warning", codec);
|
|
- wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT,
|
|
+ wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT,
|
|
wm8994_temp_shut, "Thermal shutdown", codec);
|
|
|
|
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
|
|
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
|
|
index 60f65ac..ab23869 100644
|
|
--- a/sound/usb/mixer.c
|
|
+++ b/sound/usb/mixer.c
|
|
@@ -765,10 +765,61 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
|
|
* interface to ALSA control for feature/mixer units
|
|
*/
|
|
|
|
+/* volume control quirks */
|
|
+static void volume_control_quirks(struct usb_mixer_elem_info *cval,
|
|
+ struct snd_kcontrol *kctl)
|
|
+{
|
|
+ switch (cval->mixer->chip->usb_id) {
|
|
+ case USB_ID(0x0471, 0x0101):
|
|
+ case USB_ID(0x0471, 0x0104):
|
|
+ case USB_ID(0x0471, 0x0105):
|
|
+ case USB_ID(0x0672, 0x1041):
|
|
+ /* quirk for UDA1321/N101.
|
|
+ * note that detection between firmware 2.1.1.7 (N101)
|
|
+ * and later 2.1.1.21 is not very clear from datasheets.
|
|
+ * I hope that the min value is -15360 for newer firmware --jk
|
|
+ */
|
|
+ if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
|
|
+ cval->min == -15616) {
|
|
+ snd_printk(KERN_INFO
|
|
+ "set volume quirk for UDA1321/N101 chip\n");
|
|
+ cval->max = -256;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case USB_ID(0x046d, 0x09a4):
|
|
+ if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
|
|
+ snd_printk(KERN_INFO
|
|
+ "set volume quirk for QuickCam E3500\n");
|
|
+ cval->min = 6080;
|
|
+ cval->max = 8768;
|
|
+ cval->res = 192;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case USB_ID(0x046d, 0x0808):
|
|
+ case USB_ID(0x046d, 0x0809):
|
|
+ case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
|
|
+ case USB_ID(0x046d, 0x0991):
|
|
+ /* Most audio usb devices lie about volume resolution.
|
|
+ * Most Logitech webcams have res = 384.
|
|
+ * Proboly there is some logitech magic behind this number --fishor
|
|
+ */
|
|
+ if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
|
|
+ snd_printk(KERN_INFO
|
|
+ "set resolution quirk: cval->res = 384\n");
|
|
+ cval->res = 384;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ }
|
|
+}
|
|
+
|
|
/*
|
|
* retrieve the minimum and maximum values for the specified control
|
|
*/
|
|
-static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
|
+static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
|
|
+ int default_min, struct snd_kcontrol *kctl)
|
|
{
|
|
/* for failsafe */
|
|
cval->min = default_min;
|
|
@@ -844,6 +895,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
|
cval->initialized = 1;
|
|
}
|
|
|
|
+ if (kctl)
|
|
+ volume_control_quirks(cval, kctl);
|
|
+
|
|
/* USB descriptions contain the dB scale in 1/256 dB unit
|
|
* while ALSA TLV contains in 1/100 dB unit
|
|
*/
|
|
@@ -864,6 +918,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
|
return 0;
|
|
}
|
|
|
|
+#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
|
|
|
|
/* get a feature/mixer unit info */
|
|
static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
|
@@ -882,7 +937,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
|
uinfo->value.integer.max = 1;
|
|
} else {
|
|
if (!cval->initialized) {
|
|
- get_min_max(cval, 0);
|
|
+ get_min_max_with_quirks(cval, 0, kcontrol);
|
|
if (cval->initialized && cval->dBmin >= cval->dBmax) {
|
|
kcontrol->vd[0].access &=
|
|
~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
|
|
@@ -1045,9 +1100,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
|
|
cval->ch_readonly = readonly_mask;
|
|
}
|
|
|
|
- /* get min/max values */
|
|
- get_min_max(cval, 0);
|
|
-
|
|
/* if all channels in the mask are marked read-only, make the control
|
|
* read-only. set_cur_mix_value() will check the mask again and won't
|
|
* issue write commands to read-only channels. */
|
|
@@ -1069,6 +1121,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
|
|
len = snd_usb_copy_string_desc(state, nameid,
|
|
kctl->id.name, sizeof(kctl->id.name));
|
|
|
|
+ /* get min/max values */
|
|
+ get_min_max_with_quirks(cval, 0, kctl);
|
|
+
|
|
switch (control) {
|
|
case UAC_FU_MUTE:
|
|
case UAC_FU_VOLUME:
|
|
@@ -1118,51 +1173,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
|
|
break;
|
|
}
|
|
|
|
- /* volume control quirks */
|
|
- switch (state->chip->usb_id) {
|
|
- case USB_ID(0x0471, 0x0101):
|
|
- case USB_ID(0x0471, 0x0104):
|
|
- case USB_ID(0x0471, 0x0105):
|
|
- case USB_ID(0x0672, 0x1041):
|
|
- /* quirk for UDA1321/N101.
|
|
- * note that detection between firmware 2.1.1.7 (N101)
|
|
- * and later 2.1.1.21 is not very clear from datasheets.
|
|
- * I hope that the min value is -15360 for newer firmware --jk
|
|
- */
|
|
- if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
|
|
- cval->min == -15616) {
|
|
- snd_printk(KERN_INFO
|
|
- "set volume quirk for UDA1321/N101 chip\n");
|
|
- cval->max = -256;
|
|
- }
|
|
- break;
|
|
-
|
|
- case USB_ID(0x046d, 0x09a4):
|
|
- if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
|
|
- snd_printk(KERN_INFO
|
|
- "set volume quirk for QuickCam E3500\n");
|
|
- cval->min = 6080;
|
|
- cval->max = 8768;
|
|
- cval->res = 192;
|
|
- }
|
|
- break;
|
|
-
|
|
- case USB_ID(0x046d, 0x0808):
|
|
- case USB_ID(0x046d, 0x0809):
|
|
- case USB_ID(0x046d, 0x0991):
|
|
- /* Most audio usb devices lie about volume resolution.
|
|
- * Most Logitech webcams have res = 384.
|
|
- * Proboly there is some logitech magic behind this number --fishor
|
|
- */
|
|
- if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
|
|
- snd_printk(KERN_INFO
|
|
- "set resolution quirk: cval->res = 384\n");
|
|
- cval->res = 384;
|
|
- }
|
|
- break;
|
|
-
|
|
- }
|
|
-
|
|
range = (cval->max - cval->min) / cval->res;
|
|
/* Are there devices with volume range more than 255? I use a bit more
|
|
* to be sure. 384 is a resolution magic number found on Logitech
|
|
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
|
|
index 2e5bc73..a3ddac0 100644
|
|
--- a/sound/usb/quirks.c
|
|
+++ b/sound/usb/quirks.c
|
|
@@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
|
|
return -ENOMEM;
|
|
}
|
|
if (fp->nr_rates > 0) {
|
|
- rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
|
|
+ rate_table = kmemdup(fp->rate_table,
|
|
+ sizeof(int) * fp->nr_rates, GFP_KERNEL);
|
|
if (!rate_table) {
|
|
kfree(fp);
|
|
return -ENOMEM;
|
|
}
|
|
- memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
|
|
fp->rate_table = rate_table;
|
|
}
|
|
|
|
@@ -224,10 +224,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
|
|
if (altsd->bNumEndpoints != 1)
|
|
return -ENXIO;
|
|
|
|
- fp = kmalloc(sizeof(*fp), GFP_KERNEL);
|
|
+ fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL);
|
|
if (!fp)
|
|
return -ENOMEM;
|
|
- memcpy(fp, &ua_format, sizeof(*fp));
|
|
|
|
fp->iface = altsd->bInterfaceNumber;
|
|
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
|
|
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
|
|
index 8d02ccb..30e2bef 100755
|
|
--- a/tools/testing/ktest/ktest.pl
|
|
+++ b/tools/testing/ktest/ktest.pl
|
|
@@ -42,6 +42,7 @@ $default{"BISECT_MANUAL"} = 0;
|
|
$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";
|
|
@@ -84,6 +85,7 @@ my $grub_number;
|
|
my $target;
|
|
my $make;
|
|
my $post_install;
|
|
+my $no_install;
|
|
my $noclean;
|
|
my $minconfig;
|
|
my $start_minconfig;
|
|
@@ -115,6 +117,7 @@ my $timeout;
|
|
my $booted_timeout;
|
|
my $detect_triplefault;
|
|
my $console;
|
|
+my $reboot_success_line;
|
|
my $success_line;
|
|
my $stop_after_success;
|
|
my $stop_after_failure;
|
|
@@ -130,6 +133,12 @@ my %config_help;
|
|
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
|
|
@@ -241,6 +250,7 @@ sub read_yn {
|
|
|
|
sub get_ktest_config {
|
|
my ($config) = @_;
|
|
+ my $ans;
|
|
|
|
return if (defined($opt{$config}));
|
|
|
|
@@ -254,16 +264,17 @@ sub get_ktest_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;
|
|
}
|
|
}
|
|
@@ -298,7 +309,7 @@ sub get_ktest_configs {
|
|
}
|
|
|
|
sub process_variables {
|
|
- my ($value) = @_;
|
|
+ my ($value, $remove_undef) = @_;
|
|
my $retval = "";
|
|
|
|
# We want to check for '\', and it is just easier
|
|
@@ -316,6 +327,10 @@ sub process_variables {
|
|
$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\}";
|
|
@@ -331,10 +346,17 @@ sub process_variables {
|
|
}
|
|
|
|
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};
|
|
@@ -355,86 +377,274 @@ sub set_variable {
|
|
}
|
|
}
|
|
|
|
-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);
|
|
@@ -460,10 +670,10 @@ sub read_config {
|
|
}
|
|
|
|
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;
|
|
@@ -490,13 +700,26 @@ sub read_config {
|
|
}
|
|
}
|
|
|
|
- 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;
|
|
|
|
@@ -603,8 +826,20 @@ sub doprint {
|
|
}
|
|
|
|
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)) {
|
|
@@ -615,12 +850,17 @@ sub 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");
|
|
}
|
|
@@ -693,16 +933,29 @@ sub end_monitor {
|
|
}
|
|
|
|
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";
|
|
}
|
|
|
|
@@ -719,10 +972,7 @@ sub fail {
|
|
# 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 = "";
|
|
@@ -854,9 +1104,12 @@ sub get_grub_index {
|
|
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++;
|
|
@@ -865,7 +1118,7 @@ sub get_grub_index {
|
|
close(IN);
|
|
|
|
die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
|
|
- if ($grub_number < 0);
|
|
+ if (!$found);
|
|
doprint "$grub_number\n";
|
|
}
|
|
|
|
@@ -902,7 +1155,8 @@ sub wait_for_input
|
|
|
|
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;
|
|
}
|
|
|
|
@@ -1083,6 +1337,8 @@ sub do_post_install {
|
|
|
|
sub install {
|
|
|
|
+ return if ($no_install);
|
|
+
|
|
run_scp "$outputdir/$build_target", "$target_image" or
|
|
dodie "failed to copy image";
|
|
|
|
@@ -1140,6 +1396,11 @@ sub get_version {
|
|
}
|
|
|
|
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;
|
|
@@ -1250,6 +1511,10 @@ sub build {
|
|
|
|
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) &&
|
|
@@ -1272,15 +1537,15 @@ sub build {
|
|
# 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";
|
|
@@ -1318,10 +1583,15 @@ sub build {
|
|
|
|
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;
|
|
}
|
|
|
|
@@ -1356,10 +1626,7 @@ sub success {
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
@@ -1500,10 +1767,7 @@ sub run_git_bisect {
|
|
|
|
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
|
|
@@ -2066,10 +2330,7 @@ sub config_bisect {
|
|
|
|
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 {
|
|
@@ -2178,12 +2439,31 @@ 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) = @_;
|
|
@@ -2230,30 +2510,19 @@ sub read_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*$/) {
|
|
@@ -2365,11 +2634,18 @@ sub make_new_config {
|
|
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"};
|
|
|
|
@@ -2419,8 +2695,7 @@ sub test_this_config {
|
|
return undef;
|
|
}
|
|
|
|
- my $kconfig = $config;
|
|
- $kconfig =~ s/CONFIG_//;
|
|
+ my $kconfig = chomp_config $config;
|
|
|
|
# Test dependencies first
|
|
if (defined($depends{"$kconfig"})) {
|
|
@@ -2510,6 +2785,14 @@ sub make_min_config {
|
|
|
|
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) {
|
|
@@ -2548,8 +2831,13 @@ sub make_min_config {
|
|
# 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]})) {
|
|
@@ -2659,10 +2947,7 @@ sub make_min_config {
|
|
}
|
|
|
|
doprint "Reboot and wait $sleep_time seconds\n";
|
|
- reboot;
|
|
- start_monitor;
|
|
- wait_for_monitor $sleep_time;
|
|
- end_monitor;
|
|
+ reboot $sleep_time;
|
|
}
|
|
|
|
success $i;
|
|
@@ -2783,6 +3068,9 @@ sub set_test_option {
|
|
# 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);
|
|
@@ -2811,6 +3099,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $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);
|
|
@@ -2832,6 +3121,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $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);
|
|
@@ -2850,9 +3140,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $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;
|
|
@@ -2889,8 +3181,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
$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;
|
|
@@ -2911,6 +3206,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
die "failed to checkout $checkout";
|
|
}
|
|
|
|
+ $no_reboot = 0;
|
|
+
|
|
+
|
|
if ($test_type eq "bisect") {
|
|
bisect $i;
|
|
next;
|
|
@@ -2929,6 +3227,13 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
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;
|
|
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf
|
|
index b8bcd14..dbedfa1 100644
|
|
--- a/tools/testing/ktest/sample.conf
|
|
+++ b/tools/testing/ktest/sample.conf
|
|
@@ -72,6 +72,128 @@
|
|
# 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 ####
|
|
#
|
|
@@ -253,9 +375,10 @@
|
|
|
|
# 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)
|
|
@@ -293,6 +416,13 @@
|
|
# 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.
|
|
#
|
|
@@ -415,6 +545,14 @@
|
|
# (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)
|
|
@@ -480,6 +618,8 @@
|
|
# 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
|
|
|