Merge branch 'irqchip-consolidation' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into devel-stable
Conflicts: arch/arm/mach-omap2/board-4430sdp.c arch/arm/mach-omap2/board-omap4panda.c arch/arm/mach-omap2/include/mach/omap4-common.h arch/arm/plat-omap/include/plat/irqs.h The changes to omap4-common.h were moved to arch/arm/mach-omap2/common.h and the other trivial conflicts resolved. The now empty ifdef in irqs.h was also eliminated.
This commit is contained in:
		
						commit
						2d13ccaa87
					
				
							
								
								
									
										2
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								.mailmap
									
									
									
									
									
								
							| @ -68,6 +68,7 @@ Juha Yrjola <juha.yrjola@solidboot.com> | ||||
| Kay Sievers <kay.sievers@vrfy.org> | ||||
| Kenneth W Chen <kenneth.w.chen@intel.com> | ||||
| Koushik <raghavendra.koushik@neterion.com> | ||||
| Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||||
| Leonid I Ananiev <leonid.i.ananiev@intel.com> | ||||
| Linas Vepstas <linas@austin.ibm.com> | ||||
| Mark Brown <broonie@sirena.org.uk> | ||||
| @ -111,3 +112,4 @@ Uwe Kleine-König <ukl@pengutronix.de> | ||||
| Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> | ||||
| Valdis Kletnieks <Valdis.Kletnieks@vt.edu> | ||||
| Takashi YOSHII <takashi.yoshii.zj@renesas.com> | ||||
| Yusuke Goda <goda.yusuke@renesas.com> | ||||
|  | ||||
| @ -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,22 +619,33 @@ 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 | ||||
| @ -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> | ||||
| 
 | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
| @ -42,6 +42,10 @@ Optional | ||||
| - interrupts	: Interrupt source of the parent interrupt controller. Only | ||||
|   present on secondary GICs. | ||||
| 
 | ||||
| - cpu-offset	: per-cpu offset within the distributor and cpu interface | ||||
|   regions, used when the GIC doesn't have banked registers. The offset is | ||||
|   cpu-offset * cpu-nr. | ||||
| 
 | ||||
| Example: | ||||
| 
 | ||||
| 	intc: interrupt-controller@fff11000 { | ||||
|  | ||||
							
								
								
									
										29
									
								
								Documentation/devicetree/bindings/arm/vic.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Documentation/devicetree/bindings/arm/vic.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| * ARM Vectored Interrupt Controller | ||||
| 
 | ||||
| One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM | ||||
| system for interrupt routing.  For multiple controllers they can either be | ||||
| nested or have the outputs wire-OR'd together. | ||||
| 
 | ||||
| Required properties: | ||||
| 
 | ||||
| - compatible : should be one of | ||||
| 	"arm,pl190-vic" | ||||
| 	"arm,pl192-vic" | ||||
| - interrupt-controller : Identifies the node as an interrupt controller | ||||
| - #interrupt-cells : The number of cells to define the interrupts.  Must be 1 as | ||||
|   the VIC has no configuration options for interrupt sources.  The cell is a u32 | ||||
|   and defines the interrupt number. | ||||
| - reg : The register bank for the VIC. | ||||
| 
 | ||||
| Optional properties: | ||||
| 
 | ||||
| - interrupts : Interrupt source for parent controllers if the VIC is nested. | ||||
| 
 | ||||
| Example: | ||||
| 
 | ||||
| 	vic0: interrupt-controller@60000 { | ||||
| 		compatible = "arm,pl192-vic"; | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 		reg = <0x60000 0x1000>; | ||||
| 	}; | ||||
| @ -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) | ||||
|  | ||||
							
								
								
									
										2
									
								
								Kbuild
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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) | ||||
|  | ||||
							
								
								
									
										10
									
								
								MAINTAINERS
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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 | ||||
|  | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| VERSION = 3 | ||||
| PATCHLEVEL = 2 | ||||
| SUBLEVEL = 0 | ||||
| EXTRAVERSION = -rc1 | ||||
| EXTRAVERSION = -rc2 | ||||
| NAME = Saber-toothed Squirrel | ||||
| 
 | ||||
| # *DOCUMENTATION*
 | ||||
|  | ||||
| @ -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; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -1,8 +1,14 @@ | ||||
| config ARM_GIC | ||||
| 	select IRQ_DOMAIN | ||||
| 	select MULTI_IRQ_HANDLER | ||||
| 	bool | ||||
| 
 | ||||
| config GIC_NON_BANKED | ||||
| 	bool | ||||
| 
 | ||||
| config ARM_VIC | ||||
| 	select IRQ_DOMAIN | ||||
| 	select MULTI_IRQ_HANDLER | ||||
| 	bool | ||||
| 
 | ||||
| config ARM_VIC_NR | ||||
|  | ||||
| @ -40,13 +40,36 @@ | ||||
| #include <linux/slab.h> | ||||
| 
 | ||||
| #include <asm/irq.h> | ||||
| #include <asm/exception.h> | ||||
| #include <asm/mach/irq.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| 
 | ||||
| static DEFINE_RAW_SPINLOCK(irq_controller_lock); | ||||
| union gic_base { | ||||
| 	void __iomem *common_base; | ||||
| 	void __percpu __iomem **percpu_base; | ||||
| }; | ||||
| 
 | ||||
| /* Address of GIC 0 CPU interface */ | ||||
| void __iomem *gic_cpu_base_addr __read_mostly; | ||||
| struct gic_chip_data { | ||||
| 	unsigned int irq_offset; | ||||
| 	union gic_base dist_base; | ||||
| 	union gic_base cpu_base; | ||||
| #ifdef CONFIG_CPU_PM | ||||
| 	u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; | ||||
| 	u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; | ||||
| 	u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; | ||||
| 	u32 __percpu *saved_ppi_enable; | ||||
| 	u32 __percpu *saved_ppi_conf; | ||||
| #endif | ||||
| #ifdef CONFIG_IRQ_DOMAIN | ||||
| 	struct irq_domain domain; | ||||
| #endif | ||||
| 	unsigned int gic_irqs; | ||||
| #ifdef CONFIG_GIC_NON_BANKED | ||||
| 	void __iomem *(*get_base)(union gic_base *); | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| static DEFINE_RAW_SPINLOCK(irq_controller_lock); | ||||
| 
 | ||||
| /*
 | ||||
|  * Supported arch specific GIC irq extension. | ||||
| @ -67,16 +90,48 @@ struct irq_chip gic_arch_extn = { | ||||
| 
 | ||||
| static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; | ||||
| 
 | ||||
| #ifdef CONFIG_GIC_NON_BANKED | ||||
| static void __iomem *gic_get_percpu_base(union gic_base *base) | ||||
| { | ||||
| 	return *__this_cpu_ptr(base->percpu_base); | ||||
| } | ||||
| 
 | ||||
| static void __iomem *gic_get_common_base(union gic_base *base) | ||||
| { | ||||
| 	return base->common_base; | ||||
| } | ||||
| 
 | ||||
| static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data) | ||||
| { | ||||
| 	return data->get_base(&data->dist_base); | ||||
| } | ||||
| 
 | ||||
| static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data) | ||||
| { | ||||
| 	return data->get_base(&data->cpu_base); | ||||
| } | ||||
| 
 | ||||
| static inline void gic_set_base_accessor(struct gic_chip_data *data, | ||||
| 					 void __iomem *(*f)(union gic_base *)) | ||||
| { | ||||
| 	data->get_base = f; | ||||
| } | ||||
| #else | ||||
| #define gic_data_dist_base(d)	((d)->dist_base.common_base) | ||||
| #define gic_data_cpu_base(d)	((d)->cpu_base.common_base) | ||||
| #define gic_set_base_accessor(d,f) | ||||
| #endif | ||||
| 
 | ||||
| static inline void __iomem *gic_dist_base(struct irq_data *d) | ||||
| { | ||||
| 	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | ||||
| 	return gic_data->dist_base; | ||||
| 	return gic_data_dist_base(gic_data); | ||||
| } | ||||
| 
 | ||||
| static inline void __iomem *gic_cpu_base(struct irq_data *d) | ||||
| { | ||||
| 	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | ||||
| 	return gic_data->cpu_base; | ||||
| 	return gic_data_cpu_base(gic_data); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned int gic_irq(struct irq_data *d) | ||||
| @ -215,6 +270,32 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) | ||||
| #define gic_set_wake	NULL | ||||
| #endif | ||||
| 
 | ||||
| asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | ||||
| { | ||||
| 	u32 irqstat, irqnr; | ||||
| 	struct gic_chip_data *gic = &gic_data[0]; | ||||
| 	void __iomem *cpu_base = gic_data_cpu_base(gic); | ||||
| 
 | ||||
| 	do { | ||||
| 		irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); | ||||
| 		irqnr = irqstat & ~0x1c00; | ||||
| 
 | ||||
| 		if (likely(irqnr > 15 && irqnr < 1021)) { | ||||
| 			irqnr = irq_domain_to_irq(&gic->domain, irqnr); | ||||
| 			handle_IRQ(irqnr, regs); | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (irqnr < 16) { | ||||
| 			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); | ||||
| #ifdef CONFIG_SMP | ||||
| 			handle_IPI(irqnr, regs); | ||||
| #endif | ||||
| 			continue; | ||||
| 		} | ||||
| 		break; | ||||
| 	} while (1); | ||||
| } | ||||
| 
 | ||||
| static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | ||||
| { | ||||
| 	struct gic_chip_data *chip_data = irq_get_handler_data(irq); | ||||
| @ -225,7 +306,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | ||||
| 	chained_irq_enter(chip, desc); | ||||
| 
 | ||||
| 	raw_spin_lock(&irq_controller_lock); | ||||
| 	status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK); | ||||
| 	status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); | ||||
| 	raw_spin_unlock(&irq_controller_lock); | ||||
| 
 | ||||
| 	gic_irq = (status & 0x3ff); | ||||
| @ -270,7 +351,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | ||||
| 	u32 cpumask; | ||||
| 	unsigned int gic_irqs = gic->gic_irqs; | ||||
| 	struct irq_domain *domain = &gic->domain; | ||||
| 	void __iomem *base = gic->dist_base; | ||||
| 	void __iomem *base = gic_data_dist_base(gic); | ||||
| 	u32 cpu = 0; | ||||
| 
 | ||||
| #ifdef CONFIG_SMP | ||||
| @ -330,8 +411,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | ||||
| 
 | ||||
| static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | ||||
| { | ||||
| 	void __iomem *dist_base = gic->dist_base; | ||||
| 	void __iomem *base = gic->cpu_base; | ||||
| 	void __iomem *dist_base = gic_data_dist_base(gic); | ||||
| 	void __iomem *base = gic_data_cpu_base(gic); | ||||
| 	int i; | ||||
| 
 | ||||
| 	/*
 | ||||
| @ -368,7 +449,7 @@ static void gic_dist_save(unsigned int gic_nr) | ||||
| 		BUG(); | ||||
| 
 | ||||
| 	gic_irqs = gic_data[gic_nr].gic_irqs; | ||||
| 	dist_base = gic_data[gic_nr].dist_base; | ||||
| 	dist_base = gic_data_dist_base(&gic_data[gic_nr]); | ||||
| 
 | ||||
| 	if (!dist_base) | ||||
| 		return; | ||||
| @ -403,7 +484,7 @@ static void gic_dist_restore(unsigned int gic_nr) | ||||
| 		BUG(); | ||||
| 
 | ||||
| 	gic_irqs = gic_data[gic_nr].gic_irqs; | ||||
| 	dist_base = gic_data[gic_nr].dist_base; | ||||
| 	dist_base = gic_data_dist_base(&gic_data[gic_nr]); | ||||
| 
 | ||||
| 	if (!dist_base) | ||||
| 		return; | ||||
| @ -439,8 +520,8 @@ static void gic_cpu_save(unsigned int gic_nr) | ||||
| 	if (gic_nr >= MAX_GIC_NR) | ||||
| 		BUG(); | ||||
| 
 | ||||
| 	dist_base = gic_data[gic_nr].dist_base; | ||||
| 	cpu_base = gic_data[gic_nr].cpu_base; | ||||
| 	dist_base = gic_data_dist_base(&gic_data[gic_nr]); | ||||
| 	cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); | ||||
| 
 | ||||
| 	if (!dist_base || !cpu_base) | ||||
| 		return; | ||||
| @ -465,8 +546,8 @@ static void gic_cpu_restore(unsigned int gic_nr) | ||||
| 	if (gic_nr >= MAX_GIC_NR) | ||||
| 		BUG(); | ||||
| 
 | ||||
| 	dist_base = gic_data[gic_nr].dist_base; | ||||
| 	cpu_base = gic_data[gic_nr].cpu_base; | ||||
| 	dist_base = gic_data_dist_base(&gic_data[gic_nr]); | ||||
| 	cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); | ||||
| 
 | ||||
| 	if (!dist_base || !cpu_base) | ||||
| 		return; | ||||
| @ -491,6 +572,11 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd,	void *v) | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < MAX_GIC_NR; i++) { | ||||
| #ifdef CONFIG_GIC_NON_BANKED | ||||
| 		/* Skip over unused GICs */ | ||||
| 		if (!gic_data[i].get_base) | ||||
| 			continue; | ||||
| #endif | ||||
| 		switch (cmd) { | ||||
| 		case CPU_PM_ENTER: | ||||
| 			gic_cpu_save(i); | ||||
| @ -563,8 +649,9 @@ const struct irq_domain_ops gic_irq_domain_ops = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| void __init gic_init(unsigned int gic_nr, int irq_start, | ||||
| 	void __iomem *dist_base, void __iomem *cpu_base) | ||||
| void __init gic_init_bases(unsigned int gic_nr, int irq_start, | ||||
| 			   void __iomem *dist_base, void __iomem *cpu_base, | ||||
| 			   u32 percpu_offset) | ||||
| { | ||||
| 	struct gic_chip_data *gic; | ||||
| 	struct irq_domain *domain; | ||||
| @ -574,15 +661,42 @@ void __init gic_init(unsigned int gic_nr, int irq_start, | ||||
| 
 | ||||
| 	gic = &gic_data[gic_nr]; | ||||
| 	domain = &gic->domain; | ||||
| 	gic->dist_base = dist_base; | ||||
| 	gic->cpu_base = cpu_base; | ||||
| #ifdef CONFIG_GIC_NON_BANKED | ||||
| 	if (percpu_offset) { /* Frankein-GIC without banked registers... */ | ||||
| 		unsigned int cpu; | ||||
| 
 | ||||
| 		gic->dist_base.percpu_base = alloc_percpu(void __iomem *); | ||||
| 		gic->cpu_base.percpu_base = alloc_percpu(void __iomem *); | ||||
| 		if (WARN_ON(!gic->dist_base.percpu_base || | ||||
| 			    !gic->cpu_base.percpu_base)) { | ||||
| 			free_percpu(gic->dist_base.percpu_base); | ||||
| 			free_percpu(gic->cpu_base.percpu_base); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		for_each_possible_cpu(cpu) { | ||||
| 			unsigned long offset = percpu_offset * cpu_logical_map(cpu); | ||||
| 			*per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset; | ||||
| 			*per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset; | ||||
| 		} | ||||
| 
 | ||||
| 		gic_set_base_accessor(gic, gic_get_percpu_base); | ||||
| 	} else | ||||
| #endif | ||||
| 	{			/* Normal, sane GIC... */ | ||||
| 		WARN(percpu_offset, | ||||
| 		     "GIC_NON_BANKED not enabled, ignoring %08x offset!", | ||||
| 		     percpu_offset); | ||||
| 		gic->dist_base.common_base = dist_base; | ||||
| 		gic->cpu_base.common_base = cpu_base; | ||||
| 		gic_set_base_accessor(gic, gic_get_common_base); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For primary GICs, skip over SGIs. | ||||
| 	 * For secondary GICs, skip over PPIs, too. | ||||
| 	 */ | ||||
| 	if (gic_nr == 0) { | ||||
| 		gic_cpu_base_addr = cpu_base; | ||||
| 		domain->hwirq_base = 16; | ||||
| 		if (irq_start > 0) | ||||
| 			irq_start = (irq_start & ~31) + 16; | ||||
| @ -593,7 +707,7 @@ void __init gic_init(unsigned int gic_nr, int irq_start, | ||||
| 	 * Find out how many interrupts are supported. | ||||
| 	 * The GIC only supports up to 1020 interrupt sources. | ||||
| 	 */ | ||||
| 	gic_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x1f; | ||||
| 	gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f; | ||||
| 	gic_irqs = (gic_irqs + 1) * 32; | ||||
| 	if (gic_irqs > 1020) | ||||
| 		gic_irqs = 1020; | ||||
| @ -641,7 +755,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | ||||
| 	dsb(); | ||||
| 
 | ||||
| 	/* this always happens on GIC0 */ | ||||
| 	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); | ||||
| 	writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -652,6 +766,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) | ||||
| { | ||||
| 	void __iomem *cpu_base; | ||||
| 	void __iomem *dist_base; | ||||
| 	u32 percpu_offset; | ||||
| 	int irq; | ||||
| 	struct irq_domain *domain = &gic_data[gic_cnt].domain; | ||||
| 
 | ||||
| @ -664,9 +779,12 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) | ||||
| 	cpu_base = of_iomap(node, 1); | ||||
| 	WARN(!cpu_base, "unable to map gic cpu registers\n"); | ||||
| 
 | ||||
| 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) | ||||
| 		percpu_offset = 0; | ||||
| 
 | ||||
| 	domain->of_node = of_node_get(node); | ||||
| 
 | ||||
| 	gic_init(gic_cnt, -1, dist_base, cpu_base); | ||||
| 	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset); | ||||
| 
 | ||||
| 	if (parent) { | ||||
| 		irq = irq_of_parse_and_map(node, 0); | ||||
|  | ||||
| @ -19,17 +19,22 @@ | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/export.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/irqdomain.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_address.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/syscore_ops.h> | ||||
| #include <linux/device.h> | ||||
| #include <linux/amba/bus.h> | ||||
| 
 | ||||
| #include <asm/exception.h> | ||||
| #include <asm/mach/irq.h> | ||||
| #include <asm/hardware/vic.h> | ||||
| 
 | ||||
| #ifdef CONFIG_PM | ||||
| /**
 | ||||
|  * struct vic_device - VIC PM device | ||||
|  * @irq: The IRQ number for the base of the VIC. | ||||
| @ -40,6 +45,7 @@ | ||||
|  * @int_enable: Save for VIC_INT_ENABLE. | ||||
|  * @soft_int: Save for VIC_INT_SOFT. | ||||
|  * @protect: Save for VIC_PROTECT. | ||||
|  * @domain: The IRQ domain for the VIC. | ||||
|  */ | ||||
| struct vic_device { | ||||
| 	void __iomem	*base; | ||||
| @ -50,13 +56,13 @@ struct vic_device { | ||||
| 	u32		int_enable; | ||||
| 	u32		soft_int; | ||||
| 	u32		protect; | ||||
| 	struct irq_domain domain; | ||||
| }; | ||||
| 
 | ||||
| /* we cannot allocate memory when VICs are initially registered */ | ||||
| static struct vic_device vic_devices[CONFIG_ARM_VIC_NR]; | ||||
| 
 | ||||
| static int vic_id; | ||||
| #endif /* CONFIG_PM */ | ||||
| 
 | ||||
| /**
 | ||||
|  * vic_init2 - common initialisation code | ||||
| @ -156,39 +162,50 @@ static int __init vic_pm_init(void) | ||||
| 	return 0; | ||||
| } | ||||
| late_initcall(vic_pm_init); | ||||
| #endif /* CONFIG_PM */ | ||||
| 
 | ||||
| /**
 | ||||
|  * vic_pm_register - Register a VIC for later power management control | ||||
|  * vic_register() - Register a VIC. | ||||
|  * @base: The base address of the VIC. | ||||
|  * @irq: The base IRQ for the VIC. | ||||
|  * @resume_sources: bitmask of interrupts allowed for resume sources. | ||||
|  * @node: The device tree node associated with the VIC. | ||||
|  * | ||||
|  * Register the VIC with the system device tree so that it can be notified | ||||
|  * of suspend and resume requests and ensure that the correct actions are | ||||
|  * taken to re-instate the settings on resume. | ||||
|  * | ||||
|  * This also configures the IRQ domain for the VIC. | ||||
|  */ | ||||
| static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources) | ||||
| static void __init vic_register(void __iomem *base, unsigned int irq, | ||||
| 				u32 resume_sources, struct device_node *node) | ||||
| { | ||||
| 	struct vic_device *v; | ||||
| 
 | ||||
| 	if (vic_id >= ARRAY_SIZE(vic_devices)) | ||||
| 	if (vic_id >= ARRAY_SIZE(vic_devices)) { | ||||
| 		printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__); | ||||
| 	else { | ||||
| 		v = &vic_devices[vic_id]; | ||||
| 		v->base = base; | ||||
| 		v->resume_sources = resume_sources; | ||||
| 		v->irq = irq; | ||||
| 		vic_id++; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	v = &vic_devices[vic_id]; | ||||
| 	v->base = base; | ||||
| 	v->resume_sources = resume_sources; | ||||
| 	v->irq = irq; | ||||
| 	vic_id++; | ||||
| 
 | ||||
| 	v->domain.irq_base = irq; | ||||
| 	v->domain.nr_irq = 32; | ||||
| #ifdef CONFIG_OF_IRQ | ||||
| 	v->domain.of_node = of_node_get(node); | ||||
| 	v->domain.ops = &irq_domain_simple_ops; | ||||
| #endif /* CONFIG_OF */ | ||||
| 	irq_domain_add(&v->domain); | ||||
| } | ||||
| #else | ||||
| static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { } | ||||
| #endif /* CONFIG_PM */ | ||||
| 
 | ||||
| static void vic_ack_irq(struct irq_data *d) | ||||
| { | ||||
| 	void __iomem *base = irq_data_get_irq_chip_data(d); | ||||
| 	unsigned int irq = d->irq & 31; | ||||
| 	unsigned int irq = d->hwirq; | ||||
| 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); | ||||
| 	/* moreover, clear the soft-triggered, in case it was the reason */ | ||||
| 	writel(1 << irq, base + VIC_INT_SOFT_CLEAR); | ||||
| @ -197,14 +214,14 @@ static void vic_ack_irq(struct irq_data *d) | ||||
| static void vic_mask_irq(struct irq_data *d) | ||||
| { | ||||
| 	void __iomem *base = irq_data_get_irq_chip_data(d); | ||||
| 	unsigned int irq = d->irq & 31; | ||||
| 	unsigned int irq = d->hwirq; | ||||
| 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); | ||||
| } | ||||
| 
 | ||||
| static void vic_unmask_irq(struct irq_data *d) | ||||
| { | ||||
| 	void __iomem *base = irq_data_get_irq_chip_data(d); | ||||
| 	unsigned int irq = d->irq & 31; | ||||
| 	unsigned int irq = d->hwirq; | ||||
| 	writel(1 << irq, base + VIC_INT_ENABLE); | ||||
| } | ||||
| 
 | ||||
| @ -226,7 +243,7 @@ static struct vic_device *vic_from_irq(unsigned int irq) | ||||
| static int vic_set_wake(struct irq_data *d, unsigned int on) | ||||
| { | ||||
| 	struct vic_device *v = vic_from_irq(d->irq); | ||||
| 	unsigned int off = d->irq & 31; | ||||
| 	unsigned int off = d->hwirq; | ||||
| 	u32 bit = 1 << off; | ||||
| 
 | ||||
| 	if (!v) | ||||
| @ -330,15 +347,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, | ||||
| 	vic_set_irq_sources(base, irq_start, vic_sources); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * vic_init - initialise a vectored interrupt controller | ||||
|  * @base: iomem base address | ||||
|  * @irq_start: starting interrupt number, must be muliple of 32 | ||||
|  * @vic_sources: bitmask of interrupt sources to allow | ||||
|  * @resume_sources: bitmask of interrupt sources to allow for resume | ||||
|  */ | ||||
| void __init vic_init(void __iomem *base, unsigned int irq_start, | ||||
| 		     u32 vic_sources, u32 resume_sources) | ||||
| static void __init __vic_init(void __iomem *base, unsigned int irq_start, | ||||
| 			      u32 vic_sources, u32 resume_sources, | ||||
| 			      struct device_node *node) | ||||
| { | ||||
| 	unsigned int i; | ||||
| 	u32 cellid = 0; | ||||
| @ -375,5 +386,81 @@ void __init vic_init(void __iomem *base, unsigned int irq_start, | ||||
| 
 | ||||
| 	vic_set_irq_sources(base, irq_start, vic_sources); | ||||
| 
 | ||||
| 	vic_pm_register(base, irq_start, resume_sources); | ||||
| 	vic_register(base, irq_start, resume_sources, node); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * vic_init() - initialise a vectored interrupt controller | ||||
|  * @base: iomem base address | ||||
|  * @irq_start: starting interrupt number, must be muliple of 32 | ||||
|  * @vic_sources: bitmask of interrupt sources to allow | ||||
|  * @resume_sources: bitmask of interrupt sources to allow for resume | ||||
|  */ | ||||
| void __init vic_init(void __iomem *base, unsigned int irq_start, | ||||
| 		     u32 vic_sources, u32 resume_sources) | ||||
| { | ||||
| 	__vic_init(base, irq_start, vic_sources, resume_sources, NULL); | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_OF | ||||
| int __init vic_of_init(struct device_node *node, struct device_node *parent) | ||||
| { | ||||
| 	void __iomem *regs; | ||||
| 	int irq_base; | ||||
| 
 | ||||
| 	if (WARN(parent, "non-root VICs are not supported")) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	regs = of_iomap(node, 0); | ||||
| 	if (WARN_ON(!regs)) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); | ||||
| 	if (WARN_ON(irq_base < 0)) | ||||
| 		goto out_unmap; | ||||
| 
 | ||||
| 	__vic_init(regs, irq_base, ~0, ~0, node); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
|  out_unmap: | ||||
| 	iounmap(regs); | ||||
| 
 | ||||
| 	return -EIO; | ||||
| } | ||||
| #endif /* CONFIG OF */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Handle each interrupt in a single VIC.  Returns non-zero if we've | ||||
|  * handled at least one interrupt.  This does a single read of the | ||||
|  * status register and handles all interrupts in order from LSB first. | ||||
|  */ | ||||
| static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) | ||||
| { | ||||
| 	u32 stat, irq; | ||||
| 	int handled = 0; | ||||
| 
 | ||||
| 	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); | ||||
| 	while (stat) { | ||||
| 		irq = ffs(stat) - 1; | ||||
| 		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); | ||||
| 		stat &= ~(1 << irq); | ||||
| 		handled = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	return handled; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Keep iterating over all registered VIC's until there are no pending | ||||
|  * interrupts. | ||||
|  */ | ||||
| asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs) | ||||
| { | ||||
| 	int i, handled; | ||||
| 
 | ||||
| 	do { | ||||
| 		for (i = 0, handled = 0; i < vic_id; ++i) | ||||
| 			handled |= handle_one_vic(&vic_devices[i], regs); | ||||
| 	} while (handled); | ||||
| } | ||||
|  | ||||
| @ -1,57 +0,0 @@ | ||||
| /* arch/arm/include/asm/entry-macro-vic2.S | ||||
|  * | ||||
|  * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S | ||||
|  * | ||||
|  * Copyright 2008 Openmoko, Inc. | ||||
|  * Copyright 2008 Simtec Electronics | ||||
|  *	http://armlinux.simtec.co.uk/ | ||||
|  *	Ben Dooks <ben@simtec.co.uk>
 | ||||
|  * | ||||
|  * Low-level IRQ helper macros for a device with two VICs | ||||
|  * | ||||
|  * This file is licensed under  the terms of the GNU General Public | ||||
|  * License version 2. This program is licensed "as is" without any | ||||
|  * warranty of any kind, whether express or implied. | ||||
| */ | ||||
| 
 | ||||
| /* This should be included from <mach/entry-macro.S> with the necessary | ||||
|  * defines for virtual addresses and IRQ bases for the two vics. | ||||
|  * | ||||
|  * The code needs the following defined: | ||||
|  *	IRQ_VIC0_BASE	IRQ number of VIC0's first IRQ | ||||
|  *	IRQ_VIC1_BASE	IRQ number of VIC1's first IRQ | ||||
|  *	VA_VIC0		Virtual address of VIC0 | ||||
|  *	VA_VIC1		Virtual address of VIC1 | ||||
|  * | ||||
|  * Note, code assumes VIC0's virtual address is an ARM immediate constant | ||||
|  * away from VIC1. | ||||
| */ | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| 
 | ||||
| 	.macro	disable_fiq
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_preamble, base, tmp | ||||
| 	ldr	\base, =VA_VIC0 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	arch_ret_to_user, tmp1, tmp2 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 
 | ||||
| 	@ check the vic0
 | ||||
| 	mov	\irqnr, #IRQ_VIC0_BASE + 31 | ||||
| 	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ] | ||||
| 	teq	\irqstat, #0 | ||||
| 
 | ||||
| 	@ otherwise try vic1
 | ||||
| 	addeq	\tmp, \base, #(VA_VIC1 - VA_VIC0) | ||||
| 	addeq	\irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE) | ||||
| 	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ] | ||||
| 	teqeq	\irqstat, #0 | ||||
| 
 | ||||
| 	clzne	\irqstat, \irqstat | ||||
| 	subne	\irqnr, \irqnr, \irqstat | ||||
| 	.endm | ||||
| @ -1,60 +0,0 @@ | ||||
| /* | ||||
|  * arch/arm/include/asm/hardware/entry-macro-gic.S | ||||
|  * | ||||
|  * Low-level IRQ helper macros for GIC | ||||
|  * | ||||
|  * This file is licensed under  the terms of the GNU General Public | ||||
|  * License version 2. This program is licensed "as is" without any | ||||
|  * warranty of any kind, whether express or implied. | ||||
|  */ | ||||
| 
 | ||||
| #include <asm/hardware/gic.h> | ||||
| 
 | ||||
| #ifndef HAVE_GET_IRQNR_PREAMBLE | ||||
| 	.macro	get_irqnr_preamble, base, tmp | ||||
| 	ldr	\base, =gic_cpu_base_addr | ||||
| 	ldr	\base, [\base] | ||||
| 	.endm | ||||
| #endif | ||||
| 
 | ||||
| /* | ||||
|  * The interrupt numbering scheme is defined in the | ||||
|  * interrupt controller spec.  To wit: | ||||
|  * | ||||
|  * Interrupts 0-15 are IPI | ||||
|  * 16-31 are local.  We allow 30 to be used for the watchdog. | ||||
|  * 32-1020 are global | ||||
|  * 1021-1022 are reserved | ||||
|  * 1023 is "spurious" (no interrupt) | ||||
|  * | ||||
|  * A simple read from the controller will tell us the number of the highest | ||||
|  * priority enabled interrupt.  We then just need to check whether it is in the | ||||
|  * valid range for an IRQ (30-1020 inclusive). | ||||
|  */ | ||||
| 
 | ||||
| 	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 
 | ||||
| 	ldr     \irqstat, [\base, #GIC_CPU_INTACK] | ||||
| 	/* bits 12-10 = src CPU, 9-0 = int # */ | ||||
| 
 | ||||
| 	ldr	\tmp, =1021 | ||||
| 	bic     \irqnr, \irqstat, #0x1c00 | ||||
| 	cmp     \irqnr, #15 | ||||
| 	cmpcc	\irqnr, \irqnr | ||||
| 	cmpne	\irqnr, \tmp | ||||
| 	cmpcs	\irqnr, \irqnr | ||||
| 	.endm | ||||
| 
 | ||||
| /* We assume that irqstat (the raw value of the IRQ acknowledge | ||||
|  * register) is preserved from the macro above. | ||||
|  * If there is an IPI, we immediately signal end of interrupt on the | ||||
|  * controller, since this requires the original irqstat value which | ||||
|  * we won't easily be able to recreate later. | ||||
|  */ | ||||
| 
 | ||||
| 	.macro test_for_ipi, irqnr, irqstat, base, tmp | ||||
| 	bic	\irqnr, \irqstat, #0x1c00 | ||||
| 	cmp	\irqnr, #16 | ||||
| 	strcc	\irqstat, [\base, #GIC_CPU_EOI] | ||||
| 	cmpcs	\irqnr, \irqnr | ||||
| 	.endm | ||||
| @ -36,30 +36,22 @@ | ||||
| #include <linux/irqdomain.h> | ||||
| struct device_node; | ||||
| 
 | ||||
| extern void __iomem *gic_cpu_base_addr; | ||||
| extern struct irq_chip gic_arch_extn; | ||||
| 
 | ||||
| void gic_init(unsigned int, int, void __iomem *, void __iomem *); | ||||
| void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, | ||||
| 		    u32 offset); | ||||
| int gic_of_init(struct device_node *node, struct device_node *parent); | ||||
| void gic_secondary_init(unsigned int); | ||||
| void gic_handle_irq(struct pt_regs *regs); | ||||
| void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); | ||||
| void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); | ||||
| 
 | ||||
| struct gic_chip_data { | ||||
| 	void __iomem *dist_base; | ||||
| 	void __iomem *cpu_base; | ||||
| #ifdef CONFIG_CPU_PM | ||||
| 	u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; | ||||
| 	u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; | ||||
| 	u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; | ||||
| 	u32 __percpu *saved_ppi_enable; | ||||
| 	u32 __percpu *saved_ppi_conf; | ||||
| #endif | ||||
| #ifdef CONFIG_IRQ_DOMAIN | ||||
| 	struct irq_domain domain; | ||||
| #endif | ||||
| 	unsigned int gic_irqs; | ||||
| }; | ||||
| static inline void gic_init(unsigned int nr, int start, | ||||
| 			    void __iomem *dist , void __iomem *cpu) | ||||
| { | ||||
| 	gic_init_bases(nr, start, dist, cpu, 0); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -41,7 +41,15 @@ | ||||
| #define VIC_PL192_VECT_ADDR		0xF00 | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); | ||||
| #endif | ||||
| #include <linux/compiler.h> | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| struct device_node; | ||||
| struct pt_regs; | ||||
| 
 | ||||
| void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); | ||||
| int vic_of_init(struct device_node *node, struct device_node *parent); | ||||
| void vic_handle_irq(struct pt_regs *regs); | ||||
| 
 | ||||
| #endif /* __ASSEMBLY__ */ | ||||
| #endif | ||||
|  | ||||
| @ -36,12 +36,11 @@ | ||||
| #ifdef CONFIG_MULTI_IRQ_HANDLER | ||||
| 	ldr	r1, =handle_arch_irq | ||||
| 	mov	r0, sp | ||||
| 	ldr	r1, [r1] | ||||
| 	adr	lr, BSYM(9997f) | ||||
| 	teq	r1, #0 | ||||
| 	movne	pc, r1 | ||||
| #endif | ||||
| 	ldr	pc, [r1] | ||||
| #else | ||||
| 	arch_irq_handler_default | ||||
| #endif | ||||
| 9997: | ||||
| 	.endm | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -26,6 +26,7 @@ | ||||
| #include <linux/mtd/partitions.h> | ||||
| #include <asm/setup.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/mach/map.h> | ||||
| #include <asm/mach/time.h> | ||||
| @ -201,5 +202,6 @@ MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board") | ||||
| 	.map_io		= cns3420_map_io, | ||||
| 	.init_irq	= cns3xxx_init_irq, | ||||
| 	.timer		= &cns3xxx_timer, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= cns3420_init, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -8,8 +8,6 @@ | ||||
|  * published by the Free Software Foundation. | ||||
|  */ | ||||
| 
 | ||||
| #include <asm/hardware/entry-macro-gic.S> | ||||
| 
 | ||||
| 		.macro	disable_fiq
 | ||||
| 		.endm | ||||
| 
 | ||||
|  | ||||
| @ -16,6 +16,7 @@ | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| 
 | ||||
| @ -36,6 +37,7 @@ MACHINE_START(ADSSPHERE, "ADS Sphere board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= adssphere_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -39,6 +39,7 @@ | ||||
| #include <mach/ep93xx_spi.h> | ||||
| #include <mach/gpio-ep93xx.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| 
 | ||||
| @ -250,6 +251,7 @@ MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -261,6 +263,7 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -272,6 +275,7 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -283,6 +287,7 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -294,6 +299,7 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -305,6 +311,7 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -316,6 +323,7 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
| @ -327,6 +335,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= edb93xx_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -16,6 +16,7 @@ | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| 
 | ||||
| @ -36,6 +37,7 @@ MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= gesbc9312_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -9,51 +9,9 @@ | ||||
|  * the Free Software Foundation; either version 2 of the License, or (at
 | ||||
|  * your option) any later version. | ||||
|  */ | ||||
| #include <mach/ep93xx-regs.h> | ||||
| 
 | ||||
| 		.macro	disable_fiq
 | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  get_irqnr_preamble, base, tmp | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  arch_ret_to_user, tmp1, tmp2 | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 		ldr	\base, =(EP93XX_AHB_VIRT_BASE) | ||||
| 		orr	\base, \base, #0x000b0000 | ||||
| 		mov	\irqnr, #0 | ||||
| 		ldr	\irqstat, [\base]		@ lower 32 interrupts
 | ||||
| 		cmp	\irqstat, #0 | ||||
| 		bne	1001f | ||||
| 
 | ||||
| 		eor	\base, \base, #0x00070000 | ||||
| 		ldr	\irqstat, [\base]		@ upper 32 interrupts
 | ||||
| 		cmp	\irqstat, #0 | ||||
| 		beq	1002f | ||||
| 		mov	\irqnr, #0x20 | ||||
| 
 | ||||
| 1001: | ||||
| 		movs	\tmp, \irqstat, lsl #16 | ||||
| 		movne	\irqstat, \tmp | ||||
| 		addeq	\irqnr, \irqnr, #16 | ||||
| 
 | ||||
| 		movs	\tmp, \irqstat, lsl #8 | ||||
| 		movne	\irqstat, \tmp | ||||
| 		addeq	\irqnr, \irqnr, #8 | ||||
| 
 | ||||
| 		movs	\tmp, \irqstat, lsl #4 | ||||
| 		movne	\irqstat, \tmp | ||||
| 		addeq	\irqnr, \irqnr, #4 | ||||
| 
 | ||||
| 		movs	\tmp, \irqstat, lsl #2 | ||||
| 		movne	\irqstat, \tmp | ||||
| 		addeq	\irqnr, \irqnr, #2 | ||||
| 
 | ||||
| 		movs	\tmp, \irqstat, lsl #1 | ||||
| 		addeq	\irqnr, \irqnr, #1 | ||||
| 		orrs	\base, \base, #1 | ||||
| 
 | ||||
| 1002: | ||||
| 		.endm | ||||
|  | ||||
| @ -18,6 +18,7 @@ | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| 
 | ||||
| @ -80,6 +81,7 @@ MACHINE_START(MICRO9, "Contec Micro9-High") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= micro9_init_machine, | ||||
| MACHINE_END | ||||
| @ -91,6 +93,7 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= micro9_init_machine, | ||||
| MACHINE_END | ||||
| @ -102,6 +105,7 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= micro9_init_machine, | ||||
| MACHINE_END | ||||
| @ -113,6 +117,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= micro9_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -25,6 +25,7 @@ | ||||
| #include <mach/fb.h> | ||||
| #include <mach/gpio-ep93xx.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| 
 | ||||
| @ -80,6 +81,7 @@ MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= simone_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -31,6 +31,7 @@ | ||||
| #include <mach/fb.h> | ||||
| #include <mach/gpio-ep93xx.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| 
 | ||||
| @ -177,6 +178,7 @@ MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ep93xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer 		= &ep93xx_timer, | ||||
| 	.init_machine	= snappercl15_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -23,6 +23,7 @@ | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/ts72xx.h> | ||||
| 
 | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/map.h> | ||||
| #include <asm/mach/arch.h> | ||||
| @ -247,6 +248,7 @@ MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= ts72xx_map_io, | ||||
| 	.init_irq	= ep93xx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &ep93xx_timer, | ||||
| 	.init_machine	= ts72xx_init_machine, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -15,6 +15,7 @@ | ||||
| #include <asm/mach/irq.h> | ||||
| 
 | ||||
| #include <asm/proc-fns.h> | ||||
| #include <asm/exception.h> | ||||
| #include <asm/hardware/cache-l2x0.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| 
 | ||||
| @ -33,8 +34,6 @@ | ||||
| #include <mach/regs-irq.h> | ||||
| #include <mach/regs-pmu.h> | ||||
| 
 | ||||
| unsigned int gic_bank_offset __read_mostly; | ||||
| 
 | ||||
| extern int combiner_init(unsigned int combiner_nr, void __iomem *base, | ||||
| 			 unsigned int irq_start); | ||||
| extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); | ||||
| @ -207,27 +206,14 @@ void __init exynos4_init_clocks(int xtal) | ||||
| 	exynos4_setup_clocks(); | ||||
| } | ||||
| 
 | ||||
| static void exynos4_gic_irq_fix_base(struct irq_data *d) | ||||
| { | ||||
| 	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | ||||
| 
 | ||||
| 	gic_data->cpu_base = S5P_VA_GIC_CPU + | ||||
| 			    (gic_bank_offset * smp_processor_id()); | ||||
| 
 | ||||
| 	gic_data->dist_base = S5P_VA_GIC_DIST + | ||||
| 			    (gic_bank_offset * smp_processor_id()); | ||||
| } | ||||
| 
 | ||||
| void __init exynos4_init_irq(void) | ||||
| { | ||||
| 	int irq; | ||||
| 	unsigned int bank_offset; | ||||
| 
 | ||||
| 	gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; | ||||
| 
 | ||||
| 	gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); | ||||
| 	gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; | ||||
| 	gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; | ||||
| 	gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; | ||||
| 	gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset); | ||||
| 
 | ||||
| 	for (irq = 0; irq < MAX_COMBINER_NR; irq++) { | ||||
| 
 | ||||
|  | ||||
| @ -9,83 +9,8 @@ | ||||
|  * warranty of any kind, whether express or implied. | ||||
| */ | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/map.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| 
 | ||||
| 		.macro	disable_fiq
 | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  get_irqnr_preamble, base, tmp | ||||
| 		mov	\tmp, #0 | ||||
| 
 | ||||
| 		mrc	p15, 0, \base, c0, c0, 5 | ||||
| 		and	\base, \base, #3 | ||||
| 		cmp	\base, #0 | ||||
| 		beq	1f | ||||
| 
 | ||||
| 		ldr	\tmp, =gic_bank_offset | ||||
| 		ldr	\tmp, [\tmp] | ||||
| 		cmp	\base, #1 | ||||
| 		beq	1f | ||||
| 
 | ||||
| 		cmp	\base, #2 | ||||
| 		addeq	\tmp, \tmp, \tmp | ||||
| 		addne	\tmp, \tmp, \tmp, LSL #1 | ||||
| 
 | ||||
| 1:		ldr	\base, =gic_cpu_base_addr | ||||
| 		ldr	\base, [\base] | ||||
| 		add	\base, \base, \tmp | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  arch_ret_to_user, tmp1, tmp2 | ||||
| 		.endm | ||||
| 
 | ||||
| 		/* | ||||
| 		 * The interrupt numbering scheme is defined in the | ||||
| 		 * interrupt controller spec.  To wit: | ||||
| 		 * | ||||
| 		 * Interrupts 0-15 are IPI | ||||
| 		 * 16-28 are reserved | ||||
| 		 * 29-31 are local.  We allow 30 to be used for the watchdog. | ||||
| 		 * 32-1020 are global | ||||
| 		 * 1021-1022 are reserved | ||||
| 		 * 1023 is "spurious" (no interrupt) | ||||
| 		 * | ||||
| 		 * For now, we ignore all local interrupts so only return an interrupt if it's | ||||
| 		 * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs. | ||||
| 		 * | ||||
| 		 * A simple read from the controller will tell us the number of the highest | ||||
|                  * priority enabled interrupt.  We then just need to check whether it is in the | ||||
| 		 * valid range for an IRQ (30-1020 inclusive). | ||||
| 		 */ | ||||
| 
 | ||||
| 		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 
 | ||||
| 		ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ | ||||
| 
 | ||||
| 		ldr	\tmp, =1021 | ||||
| 
 | ||||
| 		bic     \irqnr, \irqstat, #0x1c00 | ||||
| 
 | ||||
| 		cmp     \irqnr, #15 | ||||
| 		cmpcc	\irqnr, \irqnr | ||||
| 		cmpne	\irqnr, \tmp | ||||
| 		cmpcs	\irqnr, \irqnr | ||||
| 		addne	\irqnr, \irqnr, #32 | ||||
| 
 | ||||
| 		.endm | ||||
| 
 | ||||
| 		/* We assume that irqstat (the raw value of the IRQ acknowledge | ||||
| 		 * register) is preserved from the macro above. | ||||
| 		 * If there is an IPI, we immediately signal end of interrupt on the | ||||
| 		 * controller, since this requires the original irqstat value which | ||||
| 		 * we won't easily be able to recreate later. | ||||
| 		 */ | ||||
| 
 | ||||
| 		.macro test_for_ipi, irqnr, irqstat, base, tmp | ||||
| 		bic	\irqnr, \irqstat, #0x1c00 | ||||
| 		cmp	\irqnr, #16 | ||||
| 		strcc	\irqstat, [\base, #GIC_CPU_EOI] | ||||
| 		cmpcs	\irqnr, \irqnr | ||||
| 		.endm | ||||
|  | ||||
| @ -16,6 +16,7 @@ | ||||
| #include <linux/smsc911x.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| 
 | ||||
| #include <plat/cpu.h> | ||||
| @ -210,6 +211,7 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= armlex4210_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= armlex4210_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -32,6 +32,7 @@ | ||||
| #include <media/v4l2-mediabus.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| 
 | ||||
| #include <plat/adc.h> | ||||
| @ -1333,6 +1334,7 @@ MACHINE_START(NURI, "NURI") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= nuri_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= nuri_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| 	.reserve        = &nuri_reserve, | ||||
|  | ||||
| @ -22,6 +22,7 @@ | ||||
| #include <linux/lcd.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| 
 | ||||
| #include <video/platform_lcd.h> | ||||
| @ -694,6 +695,7 @@ MACHINE_START(ORIGEN, "ORIGEN") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= origen_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= origen_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| 	.reserve	= &origen_reserve, | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| #include <linux/serial_core.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| 
 | ||||
| #include <plat/backlight.h> | ||||
| @ -287,6 +288,7 @@ MACHINE_START(SMDK4212, "SMDK4212") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= smdk4x12_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= smdk4x12_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| MACHINE_END | ||||
| @ -297,6 +299,7 @@ MACHINE_START(SMDK4412, "SMDK4412") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= smdk4x12_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= smdk4x12_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| #include <linux/pwm_backlight.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| 
 | ||||
| #include <video/platform_lcd.h> | ||||
| @ -375,6 +376,7 @@ MACHINE_START(SMDKV310, "SMDKV310") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= smdkv310_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= smdkv310_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| 	.reserve	= &smdkv310_reserve, | ||||
| @ -385,6 +387,7 @@ MACHINE_START(SMDKC210, "SMDKC210") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= smdkv310_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= smdkv310_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -21,9 +21,10 @@ | ||||
| #include <linux/mmc/host.h> | ||||
| #include <linux/i2c-gpio.h> | ||||
| #include <linux/i2c/mcs.h> | ||||
| #include <linux/i2c/atmel_mxt_ts.h> | ||||
|  <linux/i2c/atmel_mxt_ts.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| 
 | ||||
| #include <plat/regs-serial.h> | ||||
| @ -1058,6 +1059,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.init_irq	= exynos4_init_irq, | ||||
| 	.map_io		= universal_map_io, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= universal_machine_init, | ||||
| 	.timer		= &exynos4_timer, | ||||
| 	.reserve        = &universal_reserve, | ||||
|  | ||||
| @ -32,7 +32,6 @@ | ||||
| 
 | ||||
| #include <plat/cpu.h> | ||||
| 
 | ||||
| extern unsigned int gic_bank_offset; | ||||
| extern void exynos4_secondary_startup(void); | ||||
| 
 | ||||
| #define CPU1_BOOT_REG		(samsung_rev() == EXYNOS4210_REV_1_1 ? \ | ||||
| @ -65,31 +64,6 @@ static void __iomem *scu_base_addr(void) | ||||
| 
 | ||||
| static DEFINE_SPINLOCK(boot_lock); | ||||
| 
 | ||||
| static void __cpuinit exynos4_gic_secondary_init(void) | ||||
| { | ||||
| 	void __iomem *dist_base = S5P_VA_GIC_DIST + | ||||
| 				(gic_bank_offset * smp_processor_id()); | ||||
| 	void __iomem *cpu_base = S5P_VA_GIC_CPU + | ||||
| 				(gic_bank_offset * smp_processor_id()); | ||||
| 	int i; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Deal with the banked PPI and SGI interrupts - disable all | ||||
| 	 * PPI interrupts, ensure all SGI interrupts are enabled. | ||||
| 	 */ | ||||
| 	__raw_writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); | ||||
| 	__raw_writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Set priority on PPI and SGI interrupts | ||||
| 	 */ | ||||
| 	for (i = 0; i < 32; i += 4) | ||||
| 		__raw_writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); | ||||
| 
 | ||||
| 	__raw_writel(0xf0, cpu_base + GIC_CPU_PRIMASK); | ||||
| 	__raw_writel(1, cpu_base + GIC_CPU_CTRL); | ||||
| } | ||||
| 
 | ||||
| void __cpuinit platform_secondary_init(unsigned int cpu) | ||||
| { | ||||
| 	/*
 | ||||
| @ -97,7 +71,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) | ||||
| 	 * core (e.g. timer irq), then they will not have been enabled | ||||
| 	 * for us: do so | ||||
| 	 */ | ||||
| 	exynos4_gic_secondary_init(); | ||||
| 	gic_secondary_init(0); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * let the primary processor know we're out of the | ||||
|  | ||||
| @ -140,6 +140,7 @@ DT_MACHINE_START(HIGHBANK, "Highbank") | ||||
| 	.map_io		= highbank_map_io, | ||||
| 	.init_irq	= highbank_init_irq, | ||||
| 	.timer		= &highbank_timer, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= highbank_init, | ||||
| 	.dt_compat	= highbank_match, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -1,5 +1,3 @@ | ||||
| #include <asm/hardware/entry-macro-gic.S> | ||||
| 
 | ||||
| 	.macro	disable_fiq
 | ||||
| 	.endm | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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 && | ||||
| @ -99,6 +99,7 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR") | ||||
| 	.map_io = msm8960_map_io, | ||||
| 	.init_irq = msm8960_init_irq, | ||||
| 	.timer = &msm_timer, | ||||
| 	.handle_irq = gic_handle_irq, | ||||
| 	.init_machine = msm8960_sim_init, | ||||
| MACHINE_END | ||||
| 
 | ||||
| @ -108,6 +109,7 @@ MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3") | ||||
| 	.map_io = msm8960_map_io, | ||||
| 	.init_irq = msm8960_init_irq, | ||||
| 	.timer = &msm_timer, | ||||
| 	.handle_irq = gic_handle_irq, | ||||
| 	.init_machine = msm8960_rumi3_init, | ||||
| MACHINE_END | ||||
| 
 | ||||
|  | ||||
| @ -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 && | ||||
| @ -108,6 +108,7 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3") | ||||
| 	.reserve = msm8x60_reserve, | ||||
| 	.map_io = msm8x60_map_io, | ||||
| 	.init_irq = msm8x60_init_irq, | ||||
| 	.handle_irq = gic_handle_irq, | ||||
| 	.init_machine = msm8x60_init, | ||||
| 	.timer = &msm_timer, | ||||
| MACHINE_END | ||||
| @ -117,6 +118,7 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF") | ||||
| 	.reserve = msm8x60_reserve, | ||||
| 	.map_io = msm8x60_map_io, | ||||
| 	.init_irq = msm8x60_init_irq, | ||||
| 	.handle_irq = gic_handle_irq, | ||||
| 	.init_machine = msm8x60_init, | ||||
| 	.timer = &msm_timer, | ||||
| MACHINE_END | ||||
| @ -126,6 +128,7 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR") | ||||
| 	.reserve = msm8x60_reserve, | ||||
| 	.map_io = msm8x60_map_io, | ||||
| 	.init_irq = msm8x60_init_irq, | ||||
| 	.handle_irq = gic_handle_irq, | ||||
| 	.init_machine = msm8x60_init, | ||||
| 	.timer = &msm_timer, | ||||
| MACHINE_END | ||||
| @ -135,6 +138,7 @@ MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA") | ||||
| 	.reserve = msm8x60_reserve, | ||||
| 	.map_io = msm8x60_map_io, | ||||
| 	.init_irq = msm8x60_init_irq, | ||||
| 	.handle_irq = gic_handle_irq, | ||||
| 	.init_machine = msm8x60_init, | ||||
| 	.timer = &msm_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -1,17 +0,0 @@ | ||||
| /* | ||||
|  * Low-level IRQ helper macros | ||||
|  * | ||||
|  * Copyright (c) 2010, Code Aurora Forum. All rights reserved. | ||||
|  * | ||||
|  * This file is licensed under  the terms of the GNU General Public | ||||
|  * License version 2. This program is licensed "as is" without any | ||||
|  * warranty of any kind, whether express or implied. | ||||
|  */ | ||||
| 
 | ||||
| #include <asm/hardware/entry-macro-gic.S> | ||||
| 
 | ||||
| 	.macro	disable_fiq
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro  arch_ret_to_user, tmp1, tmp2 | ||||
| 	.endm | ||||
| @ -1,37 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2007 Google, Inc. | ||||
|  * Author: Brian Swetland <swetland@google.com>
 | ||||
|  * | ||||
|  * This software is licensed under the terms of the GNU General Public | ||||
|  * License version 2, as published by the Free Software Foundation, and | ||||
|  * may be copied, distributed, and modified under those terms. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include <mach/msm_iomap.h> | ||||
| 
 | ||||
| 	.macro	disable_fiq
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_preamble, base, tmp | ||||
| 	@ enable imprecise aborts
 | ||||
| 	cpsie	a | ||||
| 	mov	\base, #MSM_VIC_BASE | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	arch_ret_to_user, tmp1, tmp2 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 	@ 0xD0 has irq# or old irq# if the irq has been handled
 | ||||
| 	@ 0xD4 has irq# or -1 if none pending *but* if you just
 | ||||
| 	@ read 0xD4 you never get the first irq for some reason
 | ||||
| 	ldr	\irqnr, [\base, #0xD0] | ||||
| 	ldr	\irqnr, [\base, #0xD4] | ||||
| 	cmp	\irqnr, #0xffffffff | ||||
| 	.endm | ||||
| @ -16,8 +16,27 @@ | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #if defined(CONFIG_ARM_GIC) | ||||
| #include <mach/entry-macro-qgic.S> | ||||
| #else | ||||
| #include <mach/entry-macro-vic.S> | ||||
| 	.macro	disable_fiq
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	arch_ret_to_user, tmp1, tmp2 | ||||
| 	.endm | ||||
| 
 | ||||
| #if !defined(CONFIG_ARM_GIC) | ||||
| #include <mach/msm_iomap.h> | ||||
| 
 | ||||
| 	.macro	get_irqnr_preamble, base, tmp | ||||
| 	@ enable imprecise aborts
 | ||||
| 	cpsie	a | ||||
| 	mov	\base, #MSM_VIC_BASE | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 	@ 0xD0 has irq# or old irq# if the irq has been handled
 | ||||
| 	@ 0xD4 has irq# or -1 if none pending *but* if you just
 | ||||
| 	@ read 0xD4 you never get the first irq for some reason
 | ||||
| 	ldr	\irqnr, [\base, #0xD0] | ||||
| 	ldr	\irqnr, [\base, #0xD4] | ||||
| 	cmp	\irqnr, #0xffffffff | ||||
| 	.endm | ||||
| #endif | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -18,22 +18,9 @@ | ||||
|  * along with this program; if not, write to the Free Software
 | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
| #include <mach/hardware.h> | ||||
| 
 | ||||
| 		.macro  disable_fiq
 | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  get_irqnr_preamble, base, tmp | ||||
| 		ldr	\base, =io_p2v(0x001ff000) | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  arch_ret_to_user, tmp1, tmp2 | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 		ldr	\irqstat, [\base, #0] | ||||
| 		clz	\irqnr, \irqstat | ||||
| 		rsb     \irqnr, \irqnr, #31 | ||||
| 		cmp	\irqstat, #0 | ||||
| 		.endm | ||||
| 
 | ||||
|  | ||||
| @ -28,6 +28,7 @@ | ||||
| #include <mach/hardware.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <mach/netx-regs.h> | ||||
| #include <mach/eth.h> | ||||
| 
 | ||||
| @ -203,6 +204,7 @@ MACHINE_START(NXDB500, "Hilscher nxdb500") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= netx_map_io, | ||||
| 	.init_irq	= netx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &netx_timer, | ||||
| 	.init_machine	= nxdb500_init, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -28,6 +28,7 @@ | ||||
| #include <mach/hardware.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <mach/netx-regs.h> | ||||
| #include <mach/eth.h> | ||||
| 
 | ||||
| @ -96,6 +97,7 @@ MACHINE_START(NXDKN, "Hilscher nxdkn") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= netx_map_io, | ||||
| 	.init_irq	= netx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &netx_timer, | ||||
| 	.init_machine	= nxdkn_init, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -28,6 +28,7 @@ | ||||
| #include <mach/hardware.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <mach/netx-regs.h> | ||||
| #include <mach/eth.h> | ||||
| 
 | ||||
| @ -180,6 +181,7 @@ MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= netx_map_io, | ||||
| 	.init_irq	= netx_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &netx_timer, | ||||
| 	.init_machine	= nxeb500hmi_init, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| #include <linux/mtd/onenand.h> | ||||
| #include <linux/mtd/partitions.h> | ||||
| #include <linux/io.h> | ||||
| #include <asm/hardware/vic.h> | ||||
| #include <asm/sizes.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| @ -280,6 +281,7 @@ MACHINE_START(NOMADIK, "NHK8815") | ||||
| 	.atag_offset	= 0x100, | ||||
| 	.map_io		= cpu8815_map_io, | ||||
| 	.init_irq	= cpu8815_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &nomadik_timer, | ||||
| 	.init_machine	= nhk8815_platform_init, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -6,38 +6,8 @@ | ||||
|  * warranty of any kind, whether express or implied. | ||||
|  */ | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/irqs.h> | ||||
| 
 | ||||
| 	.macro	disable_fiq
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_preamble, base, tmp | ||||
| 	ldr	\base, =IO_ADDRESS(NOMADIK_IC_BASE) | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	arch_ret_to_user, tmp1, tmp2 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 
 | ||||
| 	/* This stanza gets the irq mask from one of two status registers */ | ||||
| 	mov	\irqnr, #0 | ||||
| 	ldr	\irqstat, [\base, #VIC_REG_IRQSR0]	@ get masked status
 | ||||
| 	cmp	\irqstat, #0 | ||||
| 	bne	1001f | ||||
| 	add	\irqnr, \irqnr, #32 | ||||
| 	ldr	\irqstat, [\base, #VIC_REG_IRQSR1]	@ get masked status
 | ||||
| 
 | ||||
| 1001:	tst	\irqstat, #15 | ||||
| 	bne	1002f | ||||
| 	add	\irqnr, \irqnr, #4 | ||||
| 	movs	\irqstat, \irqstat, lsr #4 | ||||
| 	bne	1001b | ||||
| 1002:	tst	\irqstat, #1 | ||||
| 	bne	1003f | ||||
| 	add	\irqnr, \irqnr, #1 | ||||
| 	movs	\irqstat, \irqstat, lsr #1 | ||||
| 	bne	1002b | ||||
| 1003:	/* EQ will be set if no irqs pending */ | ||||
| 	.endm | ||||
|  | ||||
| @ -25,6 +25,7 @@ config ARCH_OMAP2 | ||||
| 	depends on ARCH_OMAP2PLUS | ||||
| 	default y | ||||
| 	select CPU_V6 | ||||
| 	select MULTI_IRQ_HANDLER | ||||
| 
 | ||||
| config ARCH_OMAP3 | ||||
| 	bool "TI OMAP3" | ||||
| @ -36,6 +37,7 @@ config ARCH_OMAP3 | ||||
| 	select ARCH_HAS_OPP | ||||
| 	select PM_OPP if PM | ||||
| 	select ARM_CPU_SUSPEND if PM | ||||
| 	select MULTI_IRQ_HANDLER | ||||
| 
 | ||||
| config ARCH_OMAP4 | ||||
| 	bool "TI OMAP4" | ||||
|  | ||||
| @ -301,6 +301,7 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board") | ||||
| 	.map_io		= omap243x_map_io, | ||||
| 	.init_early	= omap2430_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= omap_2430sdp_init, | ||||
| 	.timer		= &omap2_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -728,6 +728,7 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap_3430sdp_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -215,6 +215,7 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3630_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap_sdp_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -27,6 +27,7 @@ | ||||
| #include <linux/leds_pwm.h> | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/mach/map.h> | ||||
| @ -983,6 +984,7 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board") | ||||
| 	.map_io		= omap4_map_io, | ||||
| 	.init_early	= omap4430_init_early, | ||||
| 	.init_irq	= gic_init_irq, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= omap_4430sdp_init, | ||||
| 	.timer		= &omap4_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -98,6 +98,7 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= am35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= am3517_crane_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -491,6 +491,7 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= am35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= am3517_evm_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -354,6 +354,7 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") | ||||
| 	.map_io		= omap242x_map_io, | ||||
| 	.init_early	= omap2420_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= omap_apollon_init, | ||||
| 	.timer		= &omap2_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -634,6 +634,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= cm_t35_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
| @ -644,6 +645,7 @@ MACHINE_START(CM_T3730, "Compulab CM-T3730") | ||||
| 	.map_io         = omap3_map_io, | ||||
| 	.init_early     = omap3630_init_early, | ||||
| 	.init_irq       = omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine   = cm_t3730_init, | ||||
| 	.timer          = &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -299,6 +299,7 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= am35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= cm_t3517_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -660,6 +660,7 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= devkit8000_init, | ||||
| 	.timer		= &omap3_secure_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -121,6 +121,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") | ||||
| 	.map_io		= omap243x_map_io, | ||||
| 	.init_early	= omap2430_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.timer		= &omap2_timer, | ||||
| 	.dt_compat	= omap243x_boards_compat, | ||||
|  | ||||
| @ -396,6 +396,7 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board") | ||||
| 	.map_io		= omap242x_map_io, | ||||
| 	.init_early	= omap2420_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= omap_h4_init, | ||||
| 	.timer		= &omap2_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -672,6 +672,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= igep_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
| @ -682,6 +683,7 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= igep_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -434,6 +434,7 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap_ldp_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -689,6 +689,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800") | ||||
| 	.map_io		= omap242x_map_io, | ||||
| 	.init_early	= omap2420_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= n8x0_init_machine, | ||||
| 	.timer		= &omap2_timer, | ||||
| MACHINE_END | ||||
| @ -699,6 +700,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810") | ||||
| 	.map_io		= omap242x_map_io, | ||||
| 	.init_early	= omap2420_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= n8x0_init_machine, | ||||
| 	.timer		= &omap2_timer, | ||||
| MACHINE_END | ||||
| @ -709,6 +711,7 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") | ||||
| 	.map_io		= omap242x_map_io, | ||||
| 	.init_early	= omap2420_init_early, | ||||
| 	.init_irq	= omap2_init_irq, | ||||
| 	.handle_irq	= omap2_intc_handle_irq, | ||||
| 	.init_machine	= n8x0_init_machine, | ||||
| 	.timer		= &omap2_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -559,6 +559,7 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap3_beagle_init, | ||||
| 	.timer		= &omap3_secure_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -681,6 +681,7 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap3_evm_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -208,6 +208,7 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap3logic_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
| @ -217,6 +218,7 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap3logic_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -606,6 +606,7 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap3pandora_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -454,6 +454,7 @@ MACHINE_START(SBC3530, "OMAP3 STALKER") | ||||
| 	.map_io			= omap3_map_io, | ||||
| 	.init_early		= omap35xx_init_early, | ||||
| 	.init_irq		= omap3_init_irq, | ||||
| 	.handle_irq		= omap3_intc_handle_irq, | ||||
| 	.init_machine		= omap3_stalker_init, | ||||
| 	.timer			= &omap3_secure_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -381,6 +381,7 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap3_touchbook_init, | ||||
| 	.timer		= &omap3_secure_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -30,6 +30,7 @@ | ||||
| #include <linux/wl12xx.h> | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| #include <asm/mach-types.h> | ||||
| #include <asm/mach/arch.h> | ||||
| #include <asm/mach/map.h> | ||||
| @ -576,6 +577,7 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board") | ||||
| 	.map_io		= omap4_map_io, | ||||
| 	.init_early	= omap4430_init_early, | ||||
| 	.init_irq	= gic_init_irq, | ||||
| 	.handle_irq	= gic_handle_irq, | ||||
| 	.init_machine	= omap4_panda_init, | ||||
| 	.timer		= &omap4_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -562,6 +562,7 @@ MACHINE_START(OVERO, "Gumstix Overo") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap35xx_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= overo_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -149,6 +149,7 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3630_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= rm680_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -127,6 +127,7 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= rx51_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -135,6 +135,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap_zoom_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
| @ -145,6 +146,7 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") | ||||
| 	.map_io		= omap3_map_io, | ||||
| 	.init_early	= omap3630_init_early, | ||||
| 	.init_irq	= omap3_init_irq, | ||||
| 	.handle_irq	= omap3_intc_handle_irq, | ||||
| 	.init_machine	= omap_zoom_init, | ||||
| 	.timer		= &omap3_timer, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -169,8 +169,6 @@ void omap3_intc_resume_idle(void); | ||||
| extern void __iomem *l2cache_base; | ||||
| #endif | ||||
| 
 | ||||
| extern void __iomem *gic_dist_base_addr; | ||||
| 
 | ||||
| extern void __init gic_init_irq(void); | ||||
| extern void omap_smc1(u32 fn, u32 arg); | ||||
| 
 | ||||
|  | ||||
| @ -10,146 +10,9 @@ | ||||
|  * License version 2. This program is licensed "as is" without any | ||||
|  * warranty of any kind, whether express or implied. | ||||
|  */ | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/io.h> | ||||
| #include <mach/irqs.h> | ||||
| #include <asm/hardware/gic.h> | ||||
| 
 | ||||
| #include <plat/omap24xx.h> | ||||
| #include <plat/omap34xx.h> | ||||
| #include <plat/omap44xx.h> | ||||
| 
 | ||||
| #include <plat/multi.h> | ||||
| 
 | ||||
| #define OMAP2_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE) | ||||
| #define OMAP3_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE) | ||||
| #define OMAP4_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE) | ||||
| #define INTCPS_SIR_IRQ_OFFSET	0x0040	/* omap2/3 active interrupt offset */ | ||||
| #define	ACTIVEIRQ_MASK		0x7f	/* omap2/3 active interrupt bits */ | ||||
| 
 | ||||
| 		.macro	disable_fiq
 | ||||
| 		.endm | ||||
| 
 | ||||
| 		.macro  arch_ret_to_user, tmp1, tmp2 | ||||
| 		.endm | ||||
| 
 | ||||
| /* | ||||
|  * Unoptimized irq functions for multi-omap2, 3 and 4 | ||||
|  */ | ||||
| 
 | ||||
| #ifdef MULTI_OMAP2 | ||||
| 		/* | ||||
| 		 * Configure the interrupt base on the first interrupt. | ||||
| 		 * See also omap_irq_base_init for setting omap_irq_base. | ||||
| 		 */ | ||||
| 		.macro  get_irqnr_preamble, base, tmp | ||||
| 		ldr	\base, =omap_irq_base	@ irq base address
 | ||||
| 		ldr	\base, [\base, #0]	@ irq base value
 | ||||
| 		.endm | ||||
| 
 | ||||
| 		/* Check the pending interrupts. Note that base already set */ | ||||
| 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 		tst	\base, #0x100		@ gic address?
 | ||||
| 		bne	4401f			@ found gic
 | ||||
| 
 | ||||
| 		/* Handle omap2 and omap3 */ | ||||
| 		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| 		bne	9998f | ||||
| 		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| 		bne	9998f | ||||
| 		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| 		bne	9998f | ||||
| 
 | ||||
| 		/* | ||||
| 		 * ti816x has additional IRQ pending register. Checking this | ||||
| 		 * register on omap2 & omap3 has no effect (read as 0). | ||||
| 		 */ | ||||
| 		ldr	\irqnr, [\base, #0xf8] /* IRQ pending reg 4 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| 9998: | ||||
| 		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET] | ||||
| 		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */ | ||||
| 		b	9999f | ||||
| 
 | ||||
| 		/* Handle omap4 */ | ||||
| 4401:		ldr     \irqstat, [\base, #GIC_CPU_INTACK] | ||||
| 		ldr     \tmp, =1021 | ||||
| 		bic     \irqnr, \irqstat, #0x1c00 | ||||
| 		cmp     \irqnr, #15 | ||||
| 		cmpcc   \irqnr, \irqnr | ||||
| 		cmpne   \irqnr, \tmp | ||||
| 		cmpcs   \irqnr, \irqnr | ||||
| 9999: | ||||
| 		.endm | ||||
| 
 | ||||
| #ifdef CONFIG_SMP | ||||
| 		/* We assume that irqstat (the raw value of the IRQ acknowledge | ||||
| 		 * register) is preserved from the macro above. | ||||
| 		 * If there is an IPI, we immediately signal end of interrupt | ||||
| 		 * on the controller, since this requires the original irqstat | ||||
| 		 * value which we won't easily be able to recreate later. | ||||
| 		 */ | ||||
| 
 | ||||
| 		.macro test_for_ipi, irqnr, irqstat, base, tmp | ||||
| 		bic	\irqnr, \irqstat, #0x1c00 | ||||
| 		cmp	\irqnr, #16 | ||||
| 		it	cc | ||||
| 		strcc	\irqstat, [\base, #GIC_CPU_EOI] | ||||
| 		it	cs | ||||
| 		cmpcs	\irqnr, \irqnr | ||||
| 		.endm | ||||
| #endif	/* CONFIG_SMP */ | ||||
| 
 | ||||
| #else	/* MULTI_OMAP2 */ | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  * Optimized irq functions for omap2, 3 and 4 | ||||
|  */ | ||||
| 
 | ||||
| #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||||
| 		.macro  get_irqnr_preamble, base, tmp | ||||
| #ifdef CONFIG_ARCH_OMAP2 | ||||
| 		ldr	\base, =OMAP2_IRQ_BASE | ||||
| #else | ||||
| 		ldr	\base, =OMAP3_IRQ_BASE | ||||
| #endif | ||||
| 		.endm | ||||
| 
 | ||||
| 		/* Check the pending interrupts. Note that base already set */ | ||||
| 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp | ||||
| 		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| 		bne	9999f | ||||
| 		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| 		bne	9999f | ||||
| 		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| #ifdef CONFIG_SOC_OMAPTI816X | ||||
| 		bne	9999f | ||||
| 		ldr	\irqnr, [\base, #0xf8] /* IRQ pending reg 4 */ | ||||
| 		cmp	\irqnr, #0x0 | ||||
| #endif | ||||
| 9999: | ||||
| 		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET] | ||||
| 		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */ | ||||
| 
 | ||||
| 		.endm | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #ifdef CONFIG_ARCH_OMAP4 | ||||
| #define HAVE_GET_IRQNR_PREAMBLE | ||||
| #include <asm/hardware/entry-macro-gic.S> | ||||
| 
 | ||||
| 		.macro  get_irqnr_preamble, base, tmp | ||||
| 		ldr     \base, =OMAP4_IRQ_BASE | ||||
| 		.endm | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #endif	/* MULTI_OMAP2 */ | ||||
|  | ||||
| @ -316,9 +316,6 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) | ||||
| 	return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); | ||||
| } | ||||
| 
 | ||||
| /* See irq.c, omap4-common.c and entry-macro.S */ | ||||
| void __iomem *omap_irq_base; | ||||
| 
 | ||||
| static void __init omap_common_init_early(void) | ||||
| { | ||||
| 	omap2_check_revision(); | ||||
|  | ||||
| @ -15,6 +15,7 @@ | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/io.h> | ||||
| #include <mach/hardware.h> | ||||
| #include <asm/exception.h> | ||||
| #include <asm/mach/irq.h> | ||||
| 
 | ||||
| 
 | ||||
| @ -35,6 +36,11 @@ | ||||
| /* Number of IRQ state bits in each MIR register */ | ||||
| #define IRQ_BITS_PER_REG	32 | ||||
| 
 | ||||
| #define OMAP2_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE) | ||||
| #define OMAP3_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE) | ||||
| #define INTCPS_SIR_IRQ_OFFSET	0x0040	/* omap2/3 active interrupt offset */ | ||||
| #define ACTIVEIRQ_MASK		0x7f	/* omap2/3 active interrupt bits */ | ||||
| 
 | ||||
| /*
 | ||||
|  * OMAP2 has a number of different interrupt controllers, each interrupt | ||||
|  * controller is identified as its own "bank". Register definitions are | ||||
| @ -143,6 +149,7 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) | ||||
| 
 | ||||
| static void __init omap_init_irq(u32 base, int nr_irqs) | ||||
| { | ||||
| 	void __iomem *omap_irq_base; | ||||
| 	unsigned long nr_of_irqs = 0; | ||||
| 	unsigned int nr_banks = 0; | ||||
| 	int i, j; | ||||
| @ -191,6 +198,44 @@ void __init ti816x_init_irq(void) | ||||
| 	omap_init_irq(OMAP34XX_IC_BASE, 128); | ||||
| } | ||||
| 
 | ||||
| static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) | ||||
| { | ||||
| 	u32 irqnr; | ||||
| 
 | ||||
| 	do { | ||||
| 		irqnr = readl_relaxed(base_addr + 0x98); | ||||
| 		if (irqnr) | ||||
| 			goto out; | ||||
| 
 | ||||
| 		irqnr = readl_relaxed(base_addr + 0xb8); | ||||
| 		if (irqnr) | ||||
| 			goto out; | ||||
| 
 | ||||
| 		irqnr = readl_relaxed(base_addr + 0xd8); | ||||
| #ifdef CONFIG_SOC_OMAPTI816X | ||||
| 		if (irqnr) | ||||
| 			goto out; | ||||
| 		irqnr = readl_relaxed(base_addr + 0xf8); | ||||
| #endif | ||||
| 
 | ||||
| out: | ||||
| 		if (!irqnr) | ||||
| 			break; | ||||
| 
 | ||||
| 		irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET); | ||||
| 		irqnr &= ACTIVEIRQ_MASK; | ||||
| 
 | ||||
| 		if (irqnr) | ||||
| 			handle_IRQ(irqnr, regs); | ||||
| 	} while (irqnr); | ||||
| } | ||||
| 
 | ||||
| asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs) | ||||
| { | ||||
| 	void __iomem *base_addr = OMAP2_IRQ_BASE; | ||||
| 	omap_intc_handle_irq(base_addr, regs); | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_ARCH_OMAP3 | ||||
| static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; | ||||
| 
 | ||||
| @ -263,4 +308,10 @@ void omap3_intc_resume_idle(void) | ||||
| 	/* Re-enable autoidle */ | ||||
| 	intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG); | ||||
| } | ||||
| 
 | ||||
| asmlinkage void __exception_irq_entry omap3_intc_handle_irq(struct pt_regs *regs) | ||||
| { | ||||
| 	void __iomem *base_addr = OMAP3_IRQ_BASE; | ||||
| 	omap_intc_handle_irq(base_addr, regs); | ||||
| } | ||||
| #endif /* CONFIG_ARCH_OMAP3 */ | ||||
|  | ||||
| @ -29,11 +29,11 @@ | ||||
| void __iomem *l2cache_base; | ||||
| #endif | ||||
| 
 | ||||
| void __iomem *gic_dist_base_addr; | ||||
| 
 | ||||
| 
 | ||||
| void __init gic_init_irq(void) | ||||
| { | ||||
| 	void __iomem *omap_irq_base; | ||||
| 	void __iomem *gic_dist_base_addr; | ||||
| 
 | ||||
| 	/* Static mapping, never released */ | ||||
| 	gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); | ||||
| 	BUG_ON(!gic_dist_base_addr); | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
| #include <linux/irqdomain.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_address.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/of_platform.h> | ||||
| 
 | ||||
| #include <asm/mach/arch.h> | ||||
| @ -33,22 +34,20 @@ static const char *picoxcell_dt_match[] = { | ||||
| }; | ||||
| 
 | ||||
| static const struct of_device_id vic_of_match[] __initconst = { | ||||
| 	{ .compatible = "arm,pl192-vic" }, | ||||
| 	{ .compatible = "arm,pl192-vic", .data = vic_of_init, }, | ||||
| 	{ /* Sentinel */ } | ||||
| }; | ||||
| 
 | ||||
| static void __init picoxcell_init_irq(void) | ||||
| { | ||||
| 	vic_init(IO_ADDRESS(PICOXCELL_VIC0_BASE), 0, ~0, 0); | ||||
| 	vic_init(IO_ADDRESS(PICOXCELL_VIC1_BASE), 32, ~0, 0); | ||||
| 	irq_domain_generate_simple(vic_of_match, PICOXCELL_VIC0_BASE, 0); | ||||
| 	irq_domain_generate_simple(vic_of_match, PICOXCELL_VIC1_BASE, 32); | ||||
| 	of_irq_init(vic_of_match); | ||||
| } | ||||
| 
 | ||||
| DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") | ||||
| 	.map_io		= picoxcell_map_io, | ||||
| 	.nr_irqs	= ARCH_NR_IRQS, | ||||
| 	.init_irq	= picoxcell_init_irq, | ||||
| 	.handle_irq	= vic_handle_irq, | ||||
| 	.timer		= &picoxcell_timer, | ||||
| 	.init_machine	= picoxcell_init_machine, | ||||
| 	.dt_compat	= picoxcell_dt_match, | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user