mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-24 04:19:51 +00:00
Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel
Conflicts: arch/arm/mach-at91/gpio.c
This commit is contained in:
commit
97fb44eb6b
1
CREDITS
1
CREDITS
@ -2166,7 +2166,6 @@ D: Initial implementation of VC's, pty's and select()
|
||||
|
||||
N: Pavel Machek
|
||||
E: pavel@ucw.cz
|
||||
E: pavel@suse.cz
|
||||
D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd
|
||||
D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB,
|
||||
D: work on suspend-to-ram/disk, killing duplicates from ioctl32
|
||||
|
@ -1,3 +1,46 @@
|
||||
What: /sys/bus/pci/drivers/.../bind
|
||||
Date: December 2003
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description:
|
||||
Writing a device location to this file will cause
|
||||
the driver to attempt to bind to the device found at
|
||||
this location. This is useful for overriding default
|
||||
bindings. The format for the location is: DDDD:BB:DD.F.
|
||||
That is Domain:Bus:Device.Function and is the same as
|
||||
found in /sys/bus/pci/devices/. For example:
|
||||
# echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind
|
||||
(Note: kernels before 2.6.28 may require echo -n).
|
||||
|
||||
What: /sys/bus/pci/drivers/.../unbind
|
||||
Date: December 2003
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description:
|
||||
Writing a device location to this file will cause the
|
||||
driver to attempt to unbind from the device found at
|
||||
this location. This may be useful when overriding default
|
||||
bindings. The format for the location is: DDDD:BB:DD.F.
|
||||
That is Domain:Bus:Device.Function and is the same as
|
||||
found in /sys/bus/pci/devices/. For example:
|
||||
# echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind
|
||||
(Note: kernels before 2.6.28 may require echo -n).
|
||||
|
||||
What: /sys/bus/pci/drivers/.../new_id
|
||||
Date: December 2003
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description:
|
||||
Writing a device ID to this file will attempt to
|
||||
dynamically add a new device ID to a PCI device driver.
|
||||
This may allow the driver to support more hardware than
|
||||
was included in the driver's static device ID support
|
||||
table at compile time. The format for the device ID is:
|
||||
VVVV DDDD SVVV SDDD CCCC MMMM PPPP. That is Vendor ID,
|
||||
Device ID, Subsystem Vendor ID, Subsystem Device ID,
|
||||
Class, Class Mask, and Private Driver Data. The Vendor ID
|
||||
and Device ID fields are required, the rest are optional.
|
||||
Upon successfully adding an ID, the driver will probe
|
||||
for the device and attempt to bind to it. For example:
|
||||
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
|
||||
|
||||
What: /sys/bus/pci/devices/.../vpd
|
||||
Date: February 2008
|
||||
Contact: Ben Hutchings <bhutchings@solarflare.com>
|
||||
|
@ -1,6 +1,6 @@
|
||||
What: /sys/firmware/memmap/
|
||||
Date: June 2008
|
||||
Contact: Bernhard Walle <bwalle@suse.de>
|
||||
Contact: Bernhard Walle <bernhard.walle@gmx.de>
|
||||
Description:
|
||||
On all platforms, the firmware provides a memory map which the
|
||||
kernel reads. The resources from that memory map are registered
|
||||
|
@ -6,7 +6,7 @@
|
||||
# To add a new book the only step required is to add the book to the
|
||||
# list of DOCBOOKS.
|
||||
|
||||
DOCBOOKS := z8530book.xml mcabook.xml \
|
||||
DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
|
||||
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
|
||||
procfs-guide.xml writing_usb_driver.xml networking.xml \
|
||||
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
||||
|
418
Documentation/DocBook/device-drivers.tmpl
Normal file
418
Documentation/DocBook/device-drivers.tmpl
Normal file
@ -0,0 +1,418 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||
|
||||
<book id="LinuxDriversAPI">
|
||||
<bookinfo>
|
||||
<title>Linux Device Drivers</title>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
This documentation is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more details see the file COPYING in the source
|
||||
distribution of Linux.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="Basics">
|
||||
<title>Driver Basics</title>
|
||||
<sect1><title>Driver Entry and Exit points</title>
|
||||
!Iinclude/linux/init.h
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Atomic and pointer manipulation</title>
|
||||
!Iarch/x86/include/asm/atomic_32.h
|
||||
!Iarch/x86/include/asm/unaligned.h
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Delaying, scheduling, and timer routines</title>
|
||||
!Iinclude/linux/sched.h
|
||||
!Ekernel/sched.c
|
||||
!Ekernel/timer.c
|
||||
</sect1>
|
||||
<sect1><title>High-resolution timers</title>
|
||||
!Iinclude/linux/ktime.h
|
||||
!Iinclude/linux/hrtimer.h
|
||||
!Ekernel/hrtimer.c
|
||||
</sect1>
|
||||
<sect1><title>Workqueues and Kevents</title>
|
||||
!Ekernel/workqueue.c
|
||||
</sect1>
|
||||
<sect1><title>Internal Functions</title>
|
||||
!Ikernel/exit.c
|
||||
!Ikernel/signal.c
|
||||
!Iinclude/linux/kthread.h
|
||||
!Ekernel/kthread.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Kernel objects manipulation</title>
|
||||
<!--
|
||||
X!Iinclude/linux/kobject.h
|
||||
-->
|
||||
!Elib/kobject.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Kernel utility functions</title>
|
||||
!Iinclude/linux/kernel.h
|
||||
!Ekernel/printk.c
|
||||
!Ekernel/panic.c
|
||||
!Ekernel/sys.c
|
||||
!Ekernel/rcupdate.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Device Resource Management</title>
|
||||
!Edrivers/base/devres.c
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="devdrivers">
|
||||
<title>Device drivers infrastructure</title>
|
||||
<sect1><title>Device Drivers Base</title>
|
||||
<!--
|
||||
X!Iinclude/linux/device.h
|
||||
-->
|
||||
!Edrivers/base/driver.c
|
||||
!Edrivers/base/core.c
|
||||
!Edrivers/base/class.c
|
||||
!Edrivers/base/firmware_class.c
|
||||
!Edrivers/base/transport_class.c
|
||||
<!-- Cannot be included, because
|
||||
attribute_container_add_class_device_adapter
|
||||
and attribute_container_classdev_to_container
|
||||
exceed allowed 44 characters maximum
|
||||
X!Edrivers/base/attribute_container.c
|
||||
-->
|
||||
!Edrivers/base/sys.c
|
||||
<!--
|
||||
X!Edrivers/base/interface.c
|
||||
-->
|
||||
!Edrivers/base/platform.c
|
||||
!Edrivers/base/bus.c
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers Power Management</title>
|
||||
!Edrivers/base/power/main.c
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers ACPI Support</title>
|
||||
<!-- Internal functions only
|
||||
X!Edrivers/acpi/sleep/main.c
|
||||
X!Edrivers/acpi/sleep/wakeup.c
|
||||
X!Edrivers/acpi/motherboard.c
|
||||
X!Edrivers/acpi/bus.c
|
||||
-->
|
||||
!Edrivers/acpi/scan.c
|
||||
!Idrivers/acpi/scan.c
|
||||
<!-- No correct structured comments
|
||||
X!Edrivers/acpi/pci_bind.c
|
||||
-->
|
||||
</sect1>
|
||||
<sect1><title>Device drivers PnP support</title>
|
||||
!Idrivers/pnp/core.c
|
||||
<!-- No correct structured comments
|
||||
X!Edrivers/pnp/system.c
|
||||
-->
|
||||
!Edrivers/pnp/card.c
|
||||
!Idrivers/pnp/driver.c
|
||||
!Edrivers/pnp/manager.c
|
||||
!Edrivers/pnp/support.c
|
||||
</sect1>
|
||||
<sect1><title>Userspace IO devices</title>
|
||||
!Edrivers/uio/uio.c
|
||||
!Iinclude/linux/uio_driver.h
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="parportdev">
|
||||
<title>Parallel Port Devices</title>
|
||||
!Iinclude/linux/parport.h
|
||||
!Edrivers/parport/ieee1284.c
|
||||
!Edrivers/parport/share.c
|
||||
!Idrivers/parport/daisy.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="message_devices">
|
||||
<title>Message-based devices</title>
|
||||
<sect1><title>Fusion message devices</title>
|
||||
!Edrivers/message/fusion/mptbase.c
|
||||
!Idrivers/message/fusion/mptbase.c
|
||||
!Edrivers/message/fusion/mptscsih.c
|
||||
!Idrivers/message/fusion/mptscsih.c
|
||||
!Idrivers/message/fusion/mptctl.c
|
||||
!Idrivers/message/fusion/mptspi.c
|
||||
!Idrivers/message/fusion/mptfc.c
|
||||
!Idrivers/message/fusion/mptlan.c
|
||||
</sect1>
|
||||
<sect1><title>I2O message devices</title>
|
||||
!Iinclude/linux/i2o.h
|
||||
!Idrivers/message/i2o/core.h
|
||||
!Edrivers/message/i2o/iop.c
|
||||
!Idrivers/message/i2o/iop.c
|
||||
!Idrivers/message/i2o/config-osm.c
|
||||
!Edrivers/message/i2o/exec-osm.c
|
||||
!Idrivers/message/i2o/exec-osm.c
|
||||
!Idrivers/message/i2o/bus-osm.c
|
||||
!Edrivers/message/i2o/device.c
|
||||
!Idrivers/message/i2o/device.c
|
||||
!Idrivers/message/i2o/driver.c
|
||||
!Idrivers/message/i2o/pci.c
|
||||
!Idrivers/message/i2o/i2o_block.c
|
||||
!Idrivers/message/i2o/i2o_scsi.c
|
||||
!Idrivers/message/i2o/i2o_proc.c
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="snddev">
|
||||
<title>Sound Devices</title>
|
||||
!Iinclude/sound/core.h
|
||||
!Esound/sound_core.c
|
||||
!Iinclude/sound/pcm.h
|
||||
!Esound/core/pcm.c
|
||||
!Esound/core/device.c
|
||||
!Esound/core/info.c
|
||||
!Esound/core/rawmidi.c
|
||||
!Esound/core/sound.c
|
||||
!Esound/core/memory.c
|
||||
!Esound/core/pcm_memory.c
|
||||
!Esound/core/init.c
|
||||
!Esound/core/isadma.c
|
||||
!Esound/core/control.c
|
||||
!Esound/core/pcm_lib.c
|
||||
!Esound/core/hwdep.c
|
||||
!Esound/core/pcm_native.c
|
||||
!Esound/core/memalloc.c
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Isound/sound_firmware.c
|
||||
-->
|
||||
</chapter>
|
||||
|
||||
<chapter id="uart16x50">
|
||||
<title>16x50 UART Driver</title>
|
||||
!Iinclude/linux/serial_core.h
|
||||
!Edrivers/serial/serial_core.c
|
||||
!Edrivers/serial/8250.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="fbdev">
|
||||
<title>Frame Buffer Library</title>
|
||||
|
||||
<para>
|
||||
The frame buffer drivers depend heavily on four data structures.
|
||||
These structures are declared in include/linux/fb.h. They are
|
||||
fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs.
|
||||
The last three can be made available to and from userland.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
fb_info defines the current state of a particular video card.
|
||||
Inside fb_info, there exists a fb_ops structure which is a
|
||||
collection of needed functions to make fbdev and fbcon work.
|
||||
fb_info is only visible to the kernel.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
fb_var_screeninfo is used to describe the features of a video card
|
||||
that are user defined. With fb_var_screeninfo, things such as
|
||||
depth and the resolution may be defined.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The next structure is fb_fix_screeninfo. This defines the
|
||||
properties of a card that are created when a mode is set and can't
|
||||
be changed otherwise. A good example of this is the start of the
|
||||
frame buffer memory. This "locks" the address of the frame buffer
|
||||
memory, so that it cannot be changed or moved.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The last structure is fb_monospecs. In the old API, there was
|
||||
little importance for fb_monospecs. This allowed for forbidden things
|
||||
such as setting a mode of 800x600 on a fix frequency monitor. With
|
||||
the new API, fb_monospecs prevents such things, and if used
|
||||
correctly, can prevent a monitor from being cooked. fb_monospecs
|
||||
will not be useful until kernels 2.5.x.
|
||||
</para>
|
||||
|
||||
<sect1><title>Frame Buffer Memory</title>
|
||||
!Edrivers/video/fbmem.c
|
||||
</sect1>
|
||||
<!--
|
||||
<sect1><title>Frame Buffer Console</title>
|
||||
X!Edrivers/video/console/fbcon.c
|
||||
</sect1>
|
||||
-->
|
||||
<sect1><title>Frame Buffer Colormap</title>
|
||||
!Edrivers/video/fbcmap.c
|
||||
</sect1>
|
||||
<!-- FIXME:
|
||||
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
|
||||
out until somebody adds docs. KAO
|
||||
<sect1><title>Frame Buffer Generic Functions</title>
|
||||
X!Idrivers/video/fbgen.c
|
||||
</sect1>
|
||||
KAO -->
|
||||
<sect1><title>Frame Buffer Video Mode Database</title>
|
||||
!Idrivers/video/modedb.c
|
||||
!Edrivers/video/modedb.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
|
||||
!Edrivers/video/macmodes.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Fonts</title>
|
||||
<para>
|
||||
Refer to the file drivers/video/console/fonts.c for more information.
|
||||
</para>
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Idrivers/video/console/fonts.c
|
||||
-->
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="input_subsystem">
|
||||
<title>Input Subsystem</title>
|
||||
!Iinclude/linux/input.h
|
||||
!Edrivers/input/input.c
|
||||
!Edrivers/input/ff-core.c
|
||||
!Edrivers/input/ff-memless.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="spi">
|
||||
<title>Serial Peripheral Interface (SPI)</title>
|
||||
<para>
|
||||
SPI is the "Serial Peripheral Interface", widely used with
|
||||
embedded systems because it is a simple and efficient
|
||||
interface: basically a multiplexed shift register.
|
||||
Its three signal wires hold a clock (SCK, often in the range
|
||||
of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
|
||||
a "Master In, Slave Out" (MISO) data line.
|
||||
SPI is a full duplex protocol; for each bit shifted out the
|
||||
MOSI line (one per clock) another is shifted in on the MISO line.
|
||||
Those bits are assembled into words of various sizes on the
|
||||
way to and from system memory.
|
||||
An additional chipselect line is usually active-low (nCS);
|
||||
four signals are normally used for each peripheral, plus
|
||||
sometimes an interrupt.
|
||||
</para>
|
||||
<para>
|
||||
The SPI bus facilities listed here provide a generalized
|
||||
interface to declare SPI busses and devices, manage them
|
||||
according to the standard Linux driver model, and perform
|
||||
input/output operations.
|
||||
At this time, only "master" side interfaces are supported,
|
||||
where Linux talks to SPI peripherals and does not implement
|
||||
such a peripheral itself.
|
||||
(Interfaces to support implementing SPI slaves would
|
||||
necessarily look different.)
|
||||
</para>
|
||||
<para>
|
||||
The programming interface is structured around two kinds of driver,
|
||||
and two kinds of device.
|
||||
A "Controller Driver" abstracts the controller hardware, which may
|
||||
be as simple as a set of GPIO pins or as complex as a pair of FIFOs
|
||||
connected to dual DMA engines on the other side of the SPI shift
|
||||
register (maximizing throughput). Such drivers bridge between
|
||||
whatever bus they sit on (often the platform bus) and SPI, and
|
||||
expose the SPI side of their device as a
|
||||
<structname>struct spi_master</structname>.
|
||||
SPI devices are children of that master, represented as a
|
||||
<structname>struct spi_device</structname> and manufactured from
|
||||
<structname>struct spi_board_info</structname> descriptors which
|
||||
are usually provided by board-specific initialization code.
|
||||
A <structname>struct spi_driver</structname> is called a
|
||||
"Protocol Driver", and is bound to a spi_device using normal
|
||||
driver model calls.
|
||||
</para>
|
||||
<para>
|
||||
The I/O model is a set of queued messages. Protocol drivers
|
||||
submit one or more <structname>struct spi_message</structname>
|
||||
objects, which are processed and completed asynchronously.
|
||||
(There are synchronous wrappers, however.) Messages are
|
||||
built from one or more <structname>struct spi_transfer</structname>
|
||||
objects, each of which wraps a full duplex SPI transfer.
|
||||
A variety of protocol tweaking options are needed, because
|
||||
different chips adopt very different policies for how they
|
||||
use the bits transferred with SPI.
|
||||
</para>
|
||||
!Iinclude/linux/spi/spi.h
|
||||
!Fdrivers/spi/spi.c spi_register_board_info
|
||||
!Edrivers/spi/spi.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="i2c">
|
||||
<title>I<superscript>2</superscript>C and SMBus Subsystem</title>
|
||||
|
||||
<para>
|
||||
I<superscript>2</superscript>C (or without fancy typography, "I2C")
|
||||
is an acronym for the "Inter-IC" bus, a simple bus protocol which is
|
||||
widely used where low data rate communications suffice.
|
||||
Since it's also a licensed trademark, some vendors use another
|
||||
name (such as "Two-Wire Interface", TWI) for the same bus.
|
||||
I2C only needs two signals (SCL for clock, SDA for data), conserving
|
||||
board real estate and minimizing signal quality issues.
|
||||
Most I2C devices use seven bit addresses, and bus speeds of up
|
||||
to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
|
||||
found wide use.
|
||||
I2C is a multi-master bus; open drain signaling is used to
|
||||
arbitrate between masters, as well as to handshake and to
|
||||
synchronize clocks from slower clients.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Linux I2C programming interfaces support only the master
|
||||
side of bus interactions, not the slave side.
|
||||
The programming interface is structured around two kinds of driver,
|
||||
and two kinds of device.
|
||||
An I2C "Adapter Driver" abstracts the controller hardware; it binds
|
||||
to a physical device (perhaps a PCI device or platform_device) and
|
||||
exposes a <structname>struct i2c_adapter</structname> representing
|
||||
each I2C bus segment it manages.
|
||||
On each I2C bus segment will be I2C devices represented by a
|
||||
<structname>struct i2c_client</structname>. Those devices will
|
||||
be bound to a <structname>struct i2c_driver</structname>,
|
||||
which should follow the standard Linux driver model.
|
||||
(At this writing, a legacy model is more widely used.)
|
||||
There are functions to perform various I2C protocol operations; at
|
||||
this writing all such functions are usable only from task context.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The System Management Bus (SMBus) is a sibling protocol. Most SMBus
|
||||
systems are also I2C conformant. The electrical constraints are
|
||||
tighter for SMBus, and it standardizes particular protocol messages
|
||||
and idioms. Controllers that support I2C can also support most
|
||||
SMBus operations, but SMBus controllers don't support all the protocol
|
||||
options that an I2C controller will.
|
||||
There are functions to perform various SMBus protocol operations,
|
||||
either using I2C primitives or by issuing SMBus commands to
|
||||
i2c_adapter devices which don't support those I2C operations.
|
||||
</para>
|
||||
|
||||
!Iinclude/linux/i2c.h
|
||||
!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
|
||||
!Edrivers/i2c/i2c-core.c
|
||||
</chapter>
|
||||
|
||||
</book>
|
@ -38,58 +38,6 @@
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="Basics">
|
||||
<title>Driver Basics</title>
|
||||
<sect1><title>Driver Entry and Exit points</title>
|
||||
!Iinclude/linux/init.h
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Atomic and pointer manipulation</title>
|
||||
!Iarch/x86/include/asm/atomic_32.h
|
||||
!Iarch/x86/include/asm/unaligned.h
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Delaying, scheduling, and timer routines</title>
|
||||
!Iinclude/linux/sched.h
|
||||
!Ekernel/sched.c
|
||||
!Ekernel/timer.c
|
||||
</sect1>
|
||||
<sect1><title>High-resolution timers</title>
|
||||
!Iinclude/linux/ktime.h
|
||||
!Iinclude/linux/hrtimer.h
|
||||
!Ekernel/hrtimer.c
|
||||
</sect1>
|
||||
<sect1><title>Workqueues and Kevents</title>
|
||||
!Ekernel/workqueue.c
|
||||
</sect1>
|
||||
<sect1><title>Internal Functions</title>
|
||||
!Ikernel/exit.c
|
||||
!Ikernel/signal.c
|
||||
!Iinclude/linux/kthread.h
|
||||
!Ekernel/kthread.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Kernel objects manipulation</title>
|
||||
<!--
|
||||
X!Iinclude/linux/kobject.h
|
||||
-->
|
||||
!Elib/kobject.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Kernel utility functions</title>
|
||||
!Iinclude/linux/kernel.h
|
||||
!Ekernel/printk.c
|
||||
!Ekernel/panic.c
|
||||
!Ekernel/sys.c
|
||||
!Ekernel/rcupdate.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Device Resource Management</title>
|
||||
!Edrivers/base/devres.c
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="adt">
|
||||
<title>Data Types</title>
|
||||
<sect1><title>Doubly Linked Lists</title>
|
||||
@ -298,62 +246,6 @@ X!Earch/x86/kernel/mca_32.c
|
||||
!Ikernel/acct.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="devdrivers">
|
||||
<title>Device drivers infrastructure</title>
|
||||
<sect1><title>Device Drivers Base</title>
|
||||
<!--
|
||||
X!Iinclude/linux/device.h
|
||||
-->
|
||||
!Edrivers/base/driver.c
|
||||
!Edrivers/base/core.c
|
||||
!Edrivers/base/class.c
|
||||
!Edrivers/base/firmware_class.c
|
||||
!Edrivers/base/transport_class.c
|
||||
<!-- Cannot be included, because
|
||||
attribute_container_add_class_device_adapter
|
||||
and attribute_container_classdev_to_container
|
||||
exceed allowed 44 characters maximum
|
||||
X!Edrivers/base/attribute_container.c
|
||||
-->
|
||||
!Edrivers/base/sys.c
|
||||
<!--
|
||||
X!Edrivers/base/interface.c
|
||||
-->
|
||||
!Edrivers/base/platform.c
|
||||
!Edrivers/base/bus.c
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers Power Management</title>
|
||||
!Edrivers/base/power/main.c
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers ACPI Support</title>
|
||||
<!-- Internal functions only
|
||||
X!Edrivers/acpi/sleep/main.c
|
||||
X!Edrivers/acpi/sleep/wakeup.c
|
||||
X!Edrivers/acpi/motherboard.c
|
||||
X!Edrivers/acpi/bus.c
|
||||
-->
|
||||
!Edrivers/acpi/scan.c
|
||||
!Idrivers/acpi/scan.c
|
||||
<!-- No correct structured comments
|
||||
X!Edrivers/acpi/pci_bind.c
|
||||
-->
|
||||
</sect1>
|
||||
<sect1><title>Device drivers PnP support</title>
|
||||
!Idrivers/pnp/core.c
|
||||
<!-- No correct structured comments
|
||||
X!Edrivers/pnp/system.c
|
||||
-->
|
||||
!Edrivers/pnp/card.c
|
||||
!Idrivers/pnp/driver.c
|
||||
!Edrivers/pnp/manager.c
|
||||
!Edrivers/pnp/support.c
|
||||
</sect1>
|
||||
<sect1><title>Userspace IO devices</title>
|
||||
!Edrivers/uio/uio.c
|
||||
!Iinclude/linux/uio_driver.h
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="blkdev">
|
||||
<title>Block Devices</title>
|
||||
!Eblock/blk-core.c
|
||||
@ -381,275 +273,6 @@ X!Edrivers/pnp/system.c
|
||||
!Edrivers/char/misc.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="parportdev">
|
||||
<title>Parallel Port Devices</title>
|
||||
!Iinclude/linux/parport.h
|
||||
!Edrivers/parport/ieee1284.c
|
||||
!Edrivers/parport/share.c
|
||||
!Idrivers/parport/daisy.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="message_devices">
|
||||
<title>Message-based devices</title>
|
||||
<sect1><title>Fusion message devices</title>
|
||||
!Edrivers/message/fusion/mptbase.c
|
||||
!Idrivers/message/fusion/mptbase.c
|
||||
!Edrivers/message/fusion/mptscsih.c
|
||||
!Idrivers/message/fusion/mptscsih.c
|
||||
!Idrivers/message/fusion/mptctl.c
|
||||
!Idrivers/message/fusion/mptspi.c
|
||||
!Idrivers/message/fusion/mptfc.c
|
||||
!Idrivers/message/fusion/mptlan.c
|
||||
</sect1>
|
||||
<sect1><title>I2O message devices</title>
|
||||
!Iinclude/linux/i2o.h
|
||||
!Idrivers/message/i2o/core.h
|
||||
!Edrivers/message/i2o/iop.c
|
||||
!Idrivers/message/i2o/iop.c
|
||||
!Idrivers/message/i2o/config-osm.c
|
||||
!Edrivers/message/i2o/exec-osm.c
|
||||
!Idrivers/message/i2o/exec-osm.c
|
||||
!Idrivers/message/i2o/bus-osm.c
|
||||
!Edrivers/message/i2o/device.c
|
||||
!Idrivers/message/i2o/device.c
|
||||
!Idrivers/message/i2o/driver.c
|
||||
!Idrivers/message/i2o/pci.c
|
||||
!Idrivers/message/i2o/i2o_block.c
|
||||
!Idrivers/message/i2o/i2o_scsi.c
|
||||
!Idrivers/message/i2o/i2o_proc.c
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="snddev">
|
||||
<title>Sound Devices</title>
|
||||
!Iinclude/sound/core.h
|
||||
!Esound/sound_core.c
|
||||
!Iinclude/sound/pcm.h
|
||||
!Esound/core/pcm.c
|
||||
!Esound/core/device.c
|
||||
!Esound/core/info.c
|
||||
!Esound/core/rawmidi.c
|
||||
!Esound/core/sound.c
|
||||
!Esound/core/memory.c
|
||||
!Esound/core/pcm_memory.c
|
||||
!Esound/core/init.c
|
||||
!Esound/core/isadma.c
|
||||
!Esound/core/control.c
|
||||
!Esound/core/pcm_lib.c
|
||||
!Esound/core/hwdep.c
|
||||
!Esound/core/pcm_native.c
|
||||
!Esound/core/memalloc.c
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Isound/sound_firmware.c
|
||||
-->
|
||||
</chapter>
|
||||
|
||||
<chapter id="uart16x50">
|
||||
<title>16x50 UART Driver</title>
|
||||
!Iinclude/linux/serial_core.h
|
||||
!Edrivers/serial/serial_core.c
|
||||
!Edrivers/serial/8250.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="fbdev">
|
||||
<title>Frame Buffer Library</title>
|
||||
|
||||
<para>
|
||||
The frame buffer drivers depend heavily on four data structures.
|
||||
These structures are declared in include/linux/fb.h. They are
|
||||
fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs.
|
||||
The last three can be made available to and from userland.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
fb_info defines the current state of a particular video card.
|
||||
Inside fb_info, there exists a fb_ops structure which is a
|
||||
collection of needed functions to make fbdev and fbcon work.
|
||||
fb_info is only visible to the kernel.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
fb_var_screeninfo is used to describe the features of a video card
|
||||
that are user defined. With fb_var_screeninfo, things such as
|
||||
depth and the resolution may be defined.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The next structure is fb_fix_screeninfo. This defines the
|
||||
properties of a card that are created when a mode is set and can't
|
||||
be changed otherwise. A good example of this is the start of the
|
||||
frame buffer memory. This "locks" the address of the frame buffer
|
||||
memory, so that it cannot be changed or moved.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The last structure is fb_monospecs. In the old API, there was
|
||||
little importance for fb_monospecs. This allowed for forbidden things
|
||||
such as setting a mode of 800x600 on a fix frequency monitor. With
|
||||
the new API, fb_monospecs prevents such things, and if used
|
||||
correctly, can prevent a monitor from being cooked. fb_monospecs
|
||||
will not be useful until kernels 2.5.x.
|
||||
</para>
|
||||
|
||||
<sect1><title>Frame Buffer Memory</title>
|
||||
!Edrivers/video/fbmem.c
|
||||
</sect1>
|
||||
<!--
|
||||
<sect1><title>Frame Buffer Console</title>
|
||||
X!Edrivers/video/console/fbcon.c
|
||||
</sect1>
|
||||
-->
|
||||
<sect1><title>Frame Buffer Colormap</title>
|
||||
!Edrivers/video/fbcmap.c
|
||||
</sect1>
|
||||
<!-- FIXME:
|
||||
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
|
||||
out until somebody adds docs. KAO
|
||||
<sect1><title>Frame Buffer Generic Functions</title>
|
||||
X!Idrivers/video/fbgen.c
|
||||
</sect1>
|
||||
KAO -->
|
||||
<sect1><title>Frame Buffer Video Mode Database</title>
|
||||
!Idrivers/video/modedb.c
|
||||
!Edrivers/video/modedb.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
|
||||
!Edrivers/video/macmodes.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Fonts</title>
|
||||
<para>
|
||||
Refer to the file drivers/video/console/fonts.c for more information.
|
||||
</para>
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Idrivers/video/console/fonts.c
|
||||
-->
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="input_subsystem">
|
||||
<title>Input Subsystem</title>
|
||||
!Iinclude/linux/input.h
|
||||
!Edrivers/input/input.c
|
||||
!Edrivers/input/ff-core.c
|
||||
!Edrivers/input/ff-memless.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="spi">
|
||||
<title>Serial Peripheral Interface (SPI)</title>
|
||||
<para>
|
||||
SPI is the "Serial Peripheral Interface", widely used with
|
||||
embedded systems because it is a simple and efficient
|
||||
interface: basically a multiplexed shift register.
|
||||
Its three signal wires hold a clock (SCK, often in the range
|
||||
of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
|
||||
a "Master In, Slave Out" (MISO) data line.
|
||||
SPI is a full duplex protocol; for each bit shifted out the
|
||||
MOSI line (one per clock) another is shifted in on the MISO line.
|
||||
Those bits are assembled into words of various sizes on the
|
||||
way to and from system memory.
|
||||
An additional chipselect line is usually active-low (nCS);
|
||||
four signals are normally used for each peripheral, plus
|
||||
sometimes an interrupt.
|
||||
</para>
|
||||
<para>
|
||||
The SPI bus facilities listed here provide a generalized
|
||||
interface to declare SPI busses and devices, manage them
|
||||
according to the standard Linux driver model, and perform
|
||||
input/output operations.
|
||||
At this time, only "master" side interfaces are supported,
|
||||
where Linux talks to SPI peripherals and does not implement
|
||||
such a peripheral itself.
|
||||
(Interfaces to support implementing SPI slaves would
|
||||
necessarily look different.)
|
||||
</para>
|
||||
<para>
|
||||
The programming interface is structured around two kinds of driver,
|
||||
and two kinds of device.
|
||||
A "Controller Driver" abstracts the controller hardware, which may
|
||||
be as simple as a set of GPIO pins or as complex as a pair of FIFOs
|
||||
connected to dual DMA engines on the other side of the SPI shift
|
||||
register (maximizing throughput). Such drivers bridge between
|
||||
whatever bus they sit on (often the platform bus) and SPI, and
|
||||
expose the SPI side of their device as a
|
||||
<structname>struct spi_master</structname>.
|
||||
SPI devices are children of that master, represented as a
|
||||
<structname>struct spi_device</structname> and manufactured from
|
||||
<structname>struct spi_board_info</structname> descriptors which
|
||||
are usually provided by board-specific initialization code.
|
||||
A <structname>struct spi_driver</structname> is called a
|
||||
"Protocol Driver", and is bound to a spi_device using normal
|
||||
driver model calls.
|
||||
</para>
|
||||
<para>
|
||||
The I/O model is a set of queued messages. Protocol drivers
|
||||
submit one or more <structname>struct spi_message</structname>
|
||||
objects, which are processed and completed asynchronously.
|
||||
(There are synchronous wrappers, however.) Messages are
|
||||
built from one or more <structname>struct spi_transfer</structname>
|
||||
objects, each of which wraps a full duplex SPI transfer.
|
||||
A variety of protocol tweaking options are needed, because
|
||||
different chips adopt very different policies for how they
|
||||
use the bits transferred with SPI.
|
||||
</para>
|
||||
!Iinclude/linux/spi/spi.h
|
||||
!Fdrivers/spi/spi.c spi_register_board_info
|
||||
!Edrivers/spi/spi.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="i2c">
|
||||
<title>I<superscript>2</superscript>C and SMBus Subsystem</title>
|
||||
|
||||
<para>
|
||||
I<superscript>2</superscript>C (or without fancy typography, "I2C")
|
||||
is an acronym for the "Inter-IC" bus, a simple bus protocol which is
|
||||
widely used where low data rate communications suffice.
|
||||
Since it's also a licensed trademark, some vendors use another
|
||||
name (such as "Two-Wire Interface", TWI) for the same bus.
|
||||
I2C only needs two signals (SCL for clock, SDA for data), conserving
|
||||
board real estate and minimizing signal quality issues.
|
||||
Most I2C devices use seven bit addresses, and bus speeds of up
|
||||
to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
|
||||
found wide use.
|
||||
I2C is a multi-master bus; open drain signaling is used to
|
||||
arbitrate between masters, as well as to handshake and to
|
||||
synchronize clocks from slower clients.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Linux I2C programming interfaces support only the master
|
||||
side of bus interactions, not the slave side.
|
||||
The programming interface is structured around two kinds of driver,
|
||||
and two kinds of device.
|
||||
An I2C "Adapter Driver" abstracts the controller hardware; it binds
|
||||
to a physical device (perhaps a PCI device or platform_device) and
|
||||
exposes a <structname>struct i2c_adapter</structname> representing
|
||||
each I2C bus segment it manages.
|
||||
On each I2C bus segment will be I2C devices represented by a
|
||||
<structname>struct i2c_client</structname>. Those devices will
|
||||
be bound to a <structname>struct i2c_driver</structname>,
|
||||
which should follow the standard Linux driver model.
|
||||
(At this writing, a legacy model is more widely used.)
|
||||
There are functions to perform various I2C protocol operations; at
|
||||
this writing all such functions are usable only from task context.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The System Management Bus (SMBus) is a sibling protocol. Most SMBus
|
||||
systems are also I2C conformant. The electrical constraints are
|
||||
tighter for SMBus, and it standardizes particular protocol messages
|
||||
and idioms. Controllers that support I2C can also support most
|
||||
SMBus operations, but SMBus controllers don't support all the protocol
|
||||
options that an I2C controller will.
|
||||
There are functions to perform various SMBus protocol operations,
|
||||
either using I2C primitives or by issuing SMBus commands to
|
||||
i2c_adapter devices which don't support those I2C operations.
|
||||
</para>
|
||||
|
||||
!Iinclude/linux/i2c.h
|
||||
!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
|
||||
!Edrivers/i2c/i2c-core.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="clk">
|
||||
<title>Clock Framework</title>
|
||||
|
||||
|
@ -93,7 +93,7 @@ the PCI Express Port Bus driver from loading a service driver.
|
||||
|
||||
int pcie_port_service_register(struct pcie_port_service_driver *new)
|
||||
|
||||
This API replaces the Linux Driver Model's pci_module_init API. A
|
||||
This API replaces the Linux Driver Model's pci_register_driver API. A
|
||||
service driver should always calls pcie_port_service_register at
|
||||
module init. Note that after service driver being loaded, calls
|
||||
such as pci_enable_device(dev) and pci_set_master(dev) are no longer
|
||||
|
@ -298,3 +298,15 @@ over a rather long period of time, but improvements are always welcome!
|
||||
|
||||
Note that, rcu_assign_pointer() and rcu_dereference() relate to
|
||||
SRCU just as they do to other forms of RCU.
|
||||
|
||||
15. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||
is to wait until all pre-existing readers have finished before
|
||||
carrying out some otherwise-destructive operation. It is
|
||||
therefore critically important to -first- remove any path
|
||||
that readers can follow that could be affected by the
|
||||
destructive operation, and -only- -then- invoke call_rcu(),
|
||||
synchronize_rcu(), or friends.
|
||||
|
||||
Because these primitives only wait for pre-existing readers,
|
||||
it is the caller's responsibility to guarantee safety to
|
||||
any subsequent readers.
|
||||
|
@ -252,10 +252,8 @@ cgroup file system directories.
|
||||
When a task is moved from one cgroup to another, it gets a new
|
||||
css_set pointer - if there's an already existing css_set with the
|
||||
desired collection of cgroups then that group is reused, else a new
|
||||
css_set is allocated. Note that the current implementation uses a
|
||||
linear search to locate an appropriate existing css_set, so isn't
|
||||
very efficient. A future version will use a hash table for better
|
||||
performance.
|
||||
css_set is allocated. The appropriate existing css_set is located by
|
||||
looking into a hash table.
|
||||
|
||||
To allow access from a cgroup to the css_sets (and hence tasks)
|
||||
that comprise it, a set of cg_cgroup_link objects form a lattice;
|
||||
|
@ -142,7 +142,7 @@ into the rest of the kernel, none in performance critical paths:
|
||||
- in fork and exit, to attach and detach a task from its cpuset.
|
||||
- in sched_setaffinity, to mask the requested CPUs by what's
|
||||
allowed in that tasks cpuset.
|
||||
- in sched.c migrate_all_tasks(), to keep migrating tasks within
|
||||
- in sched.c migrate_live_tasks(), to keep migrating tasks within
|
||||
the CPUs allowed by their cpuset, if possible.
|
||||
- in the mbind and set_mempolicy system calls, to mask the requested
|
||||
Memory Nodes by what's allowed in that tasks cpuset.
|
||||
@ -175,6 +175,10 @@ files describing that cpuset:
|
||||
- mem_exclusive flag: is memory placement exclusive?
|
||||
- mem_hardwall flag: is memory allocation hardwalled
|
||||
- memory_pressure: measure of how much paging pressure in cpuset
|
||||
- memory_spread_page flag: if set, spread page cache evenly on allowed nodes
|
||||
- memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes
|
||||
- sched_load_balance flag: if set, load balance within CPUs on that cpuset
|
||||
- sched_relax_domain_level: the searching range when migrating tasks
|
||||
|
||||
In addition, the root cpuset only has the following file:
|
||||
- memory_pressure_enabled flag: compute memory_pressure?
|
||||
@ -252,7 +256,7 @@ is causing.
|
||||
|
||||
This is useful both on tightly managed systems running a wide mix of
|
||||
submitted jobs, which may choose to terminate or re-prioritize jobs that
|
||||
are trying to use more memory than allowed on the nodes assigned them,
|
||||
are trying to use more memory than allowed on the nodes assigned to them,
|
||||
and with tightly coupled, long running, massively parallel scientific
|
||||
computing jobs that will dramatically fail to meet required performance
|
||||
goals if they start to use more memory than allowed to them.
|
||||
@ -378,7 +382,7 @@ as cpusets and sched_setaffinity.
|
||||
The algorithmic cost of load balancing and its impact on key shared
|
||||
kernel data structures such as the task list increases more than
|
||||
linearly with the number of CPUs being balanced. So the scheduler
|
||||
has support to partition the systems CPUs into a number of sched
|
||||
has support to partition the systems CPUs into a number of sched
|
||||
domains such that it only load balances within each sched domain.
|
||||
Each sched domain covers some subset of the CPUs in the system;
|
||||
no two sched domains overlap; some CPUs might not be in any sched
|
||||
@ -485,17 +489,22 @@ of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
|
||||
The internal kernel cpuset to scheduler interface passes from the
|
||||
cpuset code to the scheduler code a partition of the load balanced
|
||||
CPUs in the system. This partition is a set of subsets (represented
|
||||
as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all
|
||||
the CPUs that must be load balanced.
|
||||
as an array of struct cpumask) of CPUs, pairwise disjoint, that cover
|
||||
all the CPUs that must be load balanced.
|
||||
|
||||
Whenever the 'sched_load_balance' flag changes, or CPUs come or go
|
||||
from a cpuset with this flag enabled, or a cpuset with this flag
|
||||
enabled is removed, the cpuset code builds a new such partition and
|
||||
passes it to the scheduler sched domain setup code, to have the sched
|
||||
domains rebuilt as necessary.
|
||||
The cpuset code builds a new such partition and passes it to the
|
||||
scheduler sched domain setup code, to have the sched domains rebuilt
|
||||
as necessary, whenever:
|
||||
- the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes,
|
||||
- or CPUs come or go from a cpuset with this flag enabled,
|
||||
- or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs
|
||||
and with this flag enabled changes,
|
||||
- or a cpuset with non-empty CPUs and with this flag enabled is removed,
|
||||
- or a cpu is offlined/onlined.
|
||||
|
||||
This partition exactly defines what sched domains the scheduler should
|
||||
setup - one sched domain for each element (cpumask_t) in the partition.
|
||||
setup - one sched domain for each element (struct cpumask) in the
|
||||
partition.
|
||||
|
||||
The scheduler remembers the currently active sched domain partitions.
|
||||
When the scheduler routine partition_sched_domains() is invoked from
|
||||
@ -559,7 +568,7 @@ domain, the largest value among those is used. Be careful, if one
|
||||
requests 0 and others are -1 then 0 is used.
|
||||
|
||||
Note that modifying this file will have both good and bad effects,
|
||||
and whether it is acceptable or not will be depend on your situation.
|
||||
and whether it is acceptable or not depends on your situation.
|
||||
Don't modify this file if you are not sure.
|
||||
|
||||
If your situation is:
|
||||
@ -600,19 +609,15 @@ to allocate a page of memory for that task.
|
||||
|
||||
If a cpuset has its 'cpus' modified, then each task in that cpuset
|
||||
will have its allowed CPU placement changed immediately. Similarly,
|
||||
if a tasks pid is written to a cpusets 'tasks' file, in either its
|
||||
current cpuset or another cpuset, then its allowed CPU placement is
|
||||
changed immediately. If such a task had been bound to some subset
|
||||
of its cpuset using the sched_setaffinity() call, the task will be
|
||||
allowed to run on any CPU allowed in its new cpuset, negating the
|
||||
affect of the prior sched_setaffinity() call.
|
||||
if a tasks pid is written to another cpusets 'tasks' file, then its
|
||||
allowed CPU placement is changed immediately. If such a task had been
|
||||
bound to some subset of its cpuset using the sched_setaffinity() call,
|
||||
the task will be allowed to run on any CPU allowed in its new cpuset,
|
||||
negating the effect of the prior sched_setaffinity() call.
|
||||
|
||||
In summary, the memory placement of a task whose cpuset is changed is
|
||||
updated by the kernel, on the next allocation of a page for that task,
|
||||
but the processor placement is not updated, until that tasks pid is
|
||||
rewritten to the 'tasks' file of its cpuset. This is done to avoid
|
||||
impacting the scheduler code in the kernel with a check for changes
|
||||
in a tasks processor placement.
|
||||
and the processor placement is updated immediately.
|
||||
|
||||
Normally, once a page is allocated (given a physical page
|
||||
of main memory) then that page stays on whatever node it
|
||||
@ -681,10 +686,14 @@ and then start a subshell 'sh' in that cpuset:
|
||||
# The next line should display '/Charlie'
|
||||
cat /proc/self/cpuset
|
||||
|
||||
In the future, a C library interface to cpusets will likely be
|
||||
available. For now, the only way to query or modify cpusets is
|
||||
via the cpuset file system, using the various cd, mkdir, echo, cat,
|
||||
rmdir commands from the shell, or their equivalent from C.
|
||||
There are ways to query or modify cpusets:
|
||||
- via the cpuset file system directly, using the various cd, mkdir, echo,
|
||||
cat, rmdir commands from the shell, or their equivalent from C.
|
||||
- via the C library libcpuset.
|
||||
- via the C library libcgroup.
|
||||
(http://sourceforge.net/proects/libcg/)
|
||||
- via the python application cset.
|
||||
(http://developer.novell.com/wiki/index.php/Cpuset)
|
||||
|
||||
The sched_setaffinity calls can also be done at the shell prompt using
|
||||
SGI's runon or Robert Love's taskset. The mbind and set_mempolicy
|
||||
@ -756,7 +765,7 @@ mount -t cpuset X /dev/cpuset
|
||||
|
||||
is equivalent to
|
||||
|
||||
mount -t cgroup -ocpuset X /dev/cpuset
|
||||
mount -t cgroup -ocpuset,noprefix X /dev/cpuset
|
||||
echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
|
||||
|
||||
2.2 Adding/removing cpus
|
||||
|
@ -137,7 +137,7 @@ static void cn_test_timer_func(unsigned long __data)
|
||||
|
||||
memcpy(m + 1, data, m->len);
|
||||
|
||||
cn_netlink_send(m, 0, gfp_any());
|
||||
cn_netlink_send(m, 0, GFP_ATOMIC);
|
||||
kfree(m);
|
||||
}
|
||||
|
||||
@ -160,10 +160,8 @@ static int cn_test_init(void)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
init_timer(&cn_test_timer);
|
||||
cn_test_timer.function = cn_test_timer_func;
|
||||
setup_timer(&cn_test_timer, cn_test_timer_func, 0);
|
||||
cn_test_timer.expires = jiffies + HZ;
|
||||
cn_test_timer.data = 0;
|
||||
add_timer(&cn_test_timer);
|
||||
|
||||
return 0;
|
||||
|
@ -195,19 +195,3 @@ scaling_setspeed. By "echoing" a new frequency into this
|
||||
you can change the speed of the CPU,
|
||||
but only within the limits of
|
||||
scaling_min_freq and scaling_max_freq.
|
||||
|
||||
|
||||
3.2 Deprecated Interfaces
|
||||
-------------------------
|
||||
|
||||
Depending on your kernel configuration, you might find the following
|
||||
cpufreq-related files:
|
||||
/proc/cpufreq
|
||||
/proc/sys/cpu/*/speed
|
||||
/proc/sys/cpu/*/speed-min
|
||||
/proc/sys/cpu/*/speed-max
|
||||
|
||||
These are files for deprecated interfaces to cpufreq, which offer far
|
||||
less functionality. Because of this, these interfaces aren't described
|
||||
here.
|
||||
|
||||
|
@ -127,9 +127,11 @@ void unlock_device(struct device * dev);
|
||||
Attributes
|
||||
~~~~~~~~~~
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
|
||||
ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
Attributes of devices can be exported via drivers using a simple
|
||||
|
@ -1,205 +0,0 @@
|
||||
This README escorted the skystar2-driver rewriting procedure. It describes the
|
||||
state of the new flexcop-driver set and some internals are written down here
|
||||
too.
|
||||
|
||||
This document hopefully describes things about the flexcop and its
|
||||
device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
|
||||
drivers based on the skystar2.c and other information.
|
||||
|
||||
Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
|
||||
touched and rewritten.
|
||||
|
||||
History & News
|
||||
==============
|
||||
2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
|
||||
|
||||
|
||||
|
||||
|
||||
General coding processing
|
||||
=========================
|
||||
|
||||
We should proceed as follows (as long as no one complains):
|
||||
|
||||
0) Think before start writing code!
|
||||
|
||||
1) rewriting the skystar2.c with the help of the flexcop register descriptions
|
||||
and splitting up the files to a pci-bus-part and a flexcop-part.
|
||||
The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
|
||||
device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
|
||||
|
||||
2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
|
||||
and other pci drivers)
|
||||
|
||||
3) make some beautification (see 'Improvements when rewriting (refactoring) is
|
||||
done')
|
||||
|
||||
4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
|
||||
a wider tester audience.
|
||||
|
||||
5) creating an usb-bus-part using the already written flexcop code for the pci
|
||||
card.
|
||||
|
||||
Idea: create a kernel-object for the flexcop and export all important
|
||||
functions. This option saves kernel-memory, but maybe a lot of functions have
|
||||
to be exported to kernel namespace.
|
||||
|
||||
|
||||
Current situation
|
||||
=================
|
||||
|
||||
0) Done :)
|
||||
1) Done (some minor issues left)
|
||||
2) Done
|
||||
3) Not ready yet, more information is necessary
|
||||
4) next to be done (see the table below)
|
||||
5) USB driver is working (yes, there are some minor issues)
|
||||
|
||||
What seems to be ready?
|
||||
-----------------------
|
||||
|
||||
1) Rewriting
|
||||
1a) i2c is cut off from the flexcop-pci.c and seems to work
|
||||
1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
|
||||
1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
|
||||
1e) eeprom (reading MAC address)
|
||||
1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
|
||||
1f) misc. register accesses for reading parameters (e.g. resetting, revision)
|
||||
1g) pid/mac filter (flexcop-hw-filter.c)
|
||||
1i) dvb-stuff initialization in flexcop.c (done)
|
||||
1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
|
||||
1j) remove flexcop initialization from flexcop-pci.c completely (done)
|
||||
1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
|
||||
1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
|
||||
non-static where possible, moved code to proper places)
|
||||
|
||||
2) Search for errors in the leftover of flexcop-pci.c (partially done)
|
||||
5a) add MAC address reading
|
||||
5c) feeding of ISOC data to the software demux (format of the isochronous data
|
||||
and speed optimization, no real error) (thanks to Vadim Catana)
|
||||
|
||||
What to do in the near future?
|
||||
--------------------------------------
|
||||
(no special order here)
|
||||
|
||||
5) USB driver
|
||||
5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
|
||||
|
||||
Testing changes
|
||||
---------------
|
||||
|
||||
O = item is working
|
||||
P = item is partially working
|
||||
X = item is not working
|
||||
N = item does not apply here
|
||||
<empty field> = item need to be examined
|
||||
|
||||
| PCI | USB
|
||||
item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
|
||||
-------+-------+---------+---------+-------+-------+---------+---------+-------
|
||||
1a) | O | | | | N | N | N | N
|
||||
1b) | O | | | | | | O |
|
||||
1c) | N | N | | | N | N | O |
|
||||
1d) | O | O
|
||||
1e) | O | O
|
||||
1f) | P
|
||||
1g) | O
|
||||
1h) | P |
|
||||
1i) | O | N
|
||||
1j) | O | N
|
||||
1l) | O | N
|
||||
2) | O | N
|
||||
5a) | N | O
|
||||
5b)* | N |
|
||||
5c) | N | O
|
||||
|
||||
* - not done yet
|
||||
|
||||
Known bugs and problems and TODO
|
||||
--------------------------------
|
||||
|
||||
1g/h/l) when pid filtering is enabled on the pci card
|
||||
|
||||
DMA usage currently:
|
||||
The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
|
||||
address and triggers an IRQ when it's full and starts writing to the second
|
||||
address. When the second address is full, the IRQ is triggered again, and
|
||||
the flexcop writes to first address again, and so on.
|
||||
The buffersize of each address is currently 640*188 bytes.
|
||||
|
||||
Problem is, when using hw-pid-filtering and doing some low-bandwidth
|
||||
operation (like scanning) the buffers won't be filled enough to trigger
|
||||
the IRQ. That's why:
|
||||
|
||||
When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
|
||||
is triggered. Is the current write address of DMA1 different to the one
|
||||
during the last IRQ, then the data is passed to the demuxer.
|
||||
|
||||
There is an additional DMA-IRQ-method: packet count IRQ. This isn't
|
||||
implemented correctly yet.
|
||||
|
||||
The solution is to disable HW PID filtering, but I don't know how the DVB
|
||||
API software demux behaves on slow systems with 45MBit/s TS.
|
||||
|
||||
Solved bugs :)
|
||||
--------------
|
||||
1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
|
||||
working)
|
||||
SOLUTION: also index 0 was affected, because net_translation is done for
|
||||
these indexes by default
|
||||
|
||||
5b) isochronous transfer does only work in the first attempt (for the Sky2PC
|
||||
USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
|
||||
woke up again (don't know if this need fixes, see
|
||||
flexcop-fe-tuner.c:flexcop_sleep)
|
||||
|
||||
NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
|
||||
anything in the while the driver is loaded the first time), no transfers take
|
||||
place anymore.
|
||||
|
||||
Improvements when rewriting (refactoring) is done
|
||||
=================================================
|
||||
|
||||
- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
|
||||
(enable sleeping for other demods than dvb-s)
|
||||
- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
|
||||
|
||||
Debugging
|
||||
---------
|
||||
- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
|
||||
with this flexcop, this is important, because i2c is now using the
|
||||
flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
|
||||
that, please tell us so).
|
||||
|
||||
Everything which is identical in the following table, can be put into a common
|
||||
flexcop-module.
|
||||
|
||||
PCI USB
|
||||
-------------------------------------------------------------------------------
|
||||
Different:
|
||||
Register access: accessing IO memory USB control message
|
||||
I2C bus: I2C bus of the FC USB control message
|
||||
Data transfer: DMA isochronous transfer
|
||||
EEPROM transfer: through i2c bus not clear yet
|
||||
|
||||
Identical:
|
||||
Streaming: accessing registers
|
||||
PID Filtering: accessing registers
|
||||
Sram destinations: accessing registers
|
||||
Tuner/Demod: I2C bus
|
||||
DVB-stuff: can be written for common use
|
||||
|
||||
Acknowledgements (just for the rewriting part)
|
||||
================
|
||||
|
||||
Bjarne Steinsbo thought a lot in the first place of the pci part for this code
|
||||
sharing idea.
|
||||
|
||||
Andreas Oberritter for providing a recent PCI initialization template
|
||||
(pluto2.c).
|
||||
|
||||
Boleslaw Ciesielski for pointing out a problem with firmware loader.
|
||||
|
||||
Vadim Catana for correcting the USB transfer.
|
||||
|
||||
comments, critics and ideas to linux-dvb@linuxtv.org.
|
@ -1,5 +1,5 @@
|
||||
How to set up the Technisat devices
|
||||
===================================
|
||||
How to set up the Technisat/B2C2 Flexcop devices
|
||||
================================================
|
||||
|
||||
1) Find out what device you have
|
||||
================================
|
||||
@ -16,54 +16,60 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)...
|
||||
|
||||
If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one:
|
||||
"Multimedia devices" => "Customise analog and hybrid tuner modules to build"
|
||||
In this directory uncheck every driver which is activated there.
|
||||
In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only).
|
||||
|
||||
Then please activate:
|
||||
2a) Main module part:
|
||||
|
||||
a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
|
||||
b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR
|
||||
b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card
|
||||
OR
|
||||
c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter
|
||||
d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
|
||||
Notice: d.) is helpful for troubleshooting
|
||||
|
||||
2b) Frontend module part:
|
||||
|
||||
1.) Revision 2.3:
|
||||
1.) SkyStar DVB-S Revision 2.3:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based"
|
||||
|
||||
2.) Revision 2.6:
|
||||
2.) SkyStar DVB-S Revision 2.6:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based"
|
||||
|
||||
3.) Revision 2.7:
|
||||
3.) SkyStar DVB-S Revision 2.7:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
|
||||
d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
|
||||
|
||||
4.) Revision 2.8:
|
||||
4.) SkyStar DVB-S Revision 2.8:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based"
|
||||
d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
|
||||
|
||||
5.) DVB-T card:
|
||||
5.) AirStar DVB-T card:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based"
|
||||
|
||||
6.) DVB-C card:
|
||||
6.) CableStar DVB-C card:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based"
|
||||
|
||||
7.) ATSC card 1st generation:
|
||||
7.) AirStar ATSC card 1st generation:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
|
||||
|
||||
8.) ATSC card 2nd generation:
|
||||
8.) AirStar ATSC card 2nd generation:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners"
|
||||
|
||||
Author: Uwe Bugla <uwe.bugla@gmx.de> December 2008
|
||||
9.) AirStar ATSC card 3rd generation:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
|
||||
c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support"
|
||||
|
||||
Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009
|
||||
|
@ -335,3 +335,12 @@ Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
|
||||
Secmark, it is time to deprecate the older mechanism and start the
|
||||
process of removing the old code.
|
||||
Who: Paul Moore <paul.moore@hp.com>
|
||||
---------------------------
|
||||
|
||||
What: sysfs ui for changing p4-clockmod parameters
|
||||
When: September 2009
|
||||
Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
|
||||
e088e4c9cdb618675874becb91b2fd581ee707e6.
|
||||
Removal is subject to fixing any remaining bugs in ACPI which may
|
||||
cause the thermal throttling not to happen at the right time.
|
||||
Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
|
||||
|
@ -22,7 +22,7 @@ Squashfs filesystem features versus Cramfs:
|
||||
|
||||
Squashfs Cramfs
|
||||
|
||||
Max filesystem size: 2^64 16 MiB
|
||||
Max filesystem size: 2^64 256 MiB
|
||||
Max file size: ~ 2 TiB 16 MiB
|
||||
Max files: unlimited unlimited
|
||||
Max directories: unlimited unlimited
|
||||
|
@ -9,6 +9,7 @@ that support it. For example, a given bus might look like this:
|
||||
| |-- class
|
||||
| |-- config
|
||||
| |-- device
|
||||
| |-- enable
|
||||
| |-- irq
|
||||
| |-- local_cpus
|
||||
| |-- resource
|
||||
@ -32,6 +33,7 @@ files, each with their own function.
|
||||
class PCI class (ascii, ro)
|
||||
config PCI config space (binary, rw)
|
||||
device PCI device (ascii, ro)
|
||||
enable Whether the device is enabled (ascii, rw)
|
||||
irq IRQ number (ascii, ro)
|
||||
local_cpus nearby CPU mask (cpumask, ro)
|
||||
resource PCI resource host addresses (ascii, ro)
|
||||
@ -57,10 +59,19 @@ used to do actual device programming from userspace. Note that some platforms
|
||||
don't support mmapping of certain resources, so be sure to check the return
|
||||
value from any attempted mmap.
|
||||
|
||||
The 'enable' file provides a counter that indicates how many times the device
|
||||
has been enabled. If the 'enable' file currently returns '4', and a '1' is
|
||||
echoed into it, it will then return '5'. Echoing a '0' into it will decrease
|
||||
the count. Even when it returns to 0, though, some of the initialisation
|
||||
may not be reversed.
|
||||
|
||||
The 'rom' file is special in that it provides read-only access to the device's
|
||||
ROM file, if available. It's disabled by default, however, so applications
|
||||
should write the string "1" to the file to enable it before attempting a read
|
||||
call, and disable it following the access by writing "0" to the file.
|
||||
call, and disable it following the access by writing "0" to the file. Note
|
||||
that the device must be enabled for a rom read to return data succesfully.
|
||||
In the event a driver is not bound to the device, it can be enabled using the
|
||||
'enable' file, documented above.
|
||||
|
||||
Accessing legacy resources through sysfs
|
||||
----------------------------------------
|
||||
|
@ -2,8 +2,10 @@
|
||||
sysfs - _The_ filesystem for exporting kernel objects.
|
||||
|
||||
Patrick Mochel <mochel@osdl.org>
|
||||
Mike Murphy <mamurph@cs.clemson.edu>
|
||||
|
||||
10 January 2003
|
||||
Revised: 22 February 2009
|
||||
Original: 10 January 2003
|
||||
|
||||
|
||||
What it is:
|
||||
@ -64,12 +66,13 @@ An attribute definition is simply:
|
||||
|
||||
struct attribute {
|
||||
char * name;
|
||||
struct module *owner;
|
||||
mode_t mode;
|
||||
};
|
||||
|
||||
|
||||
int sysfs_create_file(struct kobject * kobj, struct attribute * attr);
|
||||
void sysfs_remove_file(struct kobject * kobj, struct attribute * attr);
|
||||
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
|
||||
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
|
||||
|
||||
|
||||
A bare attribute contains no means to read or write the value of the
|
||||
@ -80,9 +83,11 @@ a specific object type.
|
||||
For example, the driver model defines struct device_attribute like:
|
||||
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device * dev, char * buf);
|
||||
ssize_t (*store)(struct device * dev, const char * buf);
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
int device_create_file(struct device *, struct device_attribute *);
|
||||
@ -90,12 +95,8 @@ void device_remove_file(struct device *, struct device_attribute *);
|
||||
|
||||
It also defines this helper for defining device attributes:
|
||||
|
||||
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
||||
struct device_attribute dev_attr_##_name = { \
|
||||
.attr = {.name = __stringify(_name) , .mode = _mode }, \
|
||||
.show = _show, \
|
||||
.store = _store, \
|
||||
};
|
||||
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
||||
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
||||
|
||||
For example, declaring
|
||||
|
||||
@ -107,9 +108,9 @@ static struct device_attribute dev_attr_foo = {
|
||||
.attr = {
|
||||
.name = "foo",
|
||||
.mode = S_IWUSR | S_IRUGO,
|
||||
.show = show_foo,
|
||||
.store = store_foo,
|
||||
},
|
||||
.show = show_foo,
|
||||
.store = store_foo,
|
||||
};
|
||||
|
||||
|
||||
@ -161,10 +162,12 @@ To read or write attributes, show() or store() methods must be
|
||||
specified when declaring the attribute. The method types should be as
|
||||
simple as those defined for device attributes:
|
||||
|
||||
ssize_t (*show)(struct device * dev, char * buf);
|
||||
ssize_t (*store)(struct device * dev, const char * buf);
|
||||
ssize_t (*show)(struct device * dev, struct device_attribute * attr,
|
||||
char * buf);
|
||||
ssize_t (*store)(struct device * dev, struct device_attribute * attr,
|
||||
const char * buf);
|
||||
|
||||
IOW, they should take only an object and a buffer as parameters.
|
||||
IOW, they should take only an object, an attribute, and a buffer as parameters.
|
||||
|
||||
|
||||
sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the
|
||||
@ -299,14 +302,16 @@ The following interface layers currently exist in sysfs:
|
||||
Structure:
|
||||
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device * dev, char * buf);
|
||||
ssize_t (*store)(struct device * dev, const char * buf);
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
Declaring:
|
||||
|
||||
DEVICE_ATTR(_name, _str, _mode, _show, _store);
|
||||
DEVICE_ATTR(_name, _mode, _show, _store);
|
||||
|
||||
Creation/Removal:
|
||||
|
||||
@ -342,7 +347,8 @@ Structure:
|
||||
struct driver_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device_driver *, char * buf);
|
||||
ssize_t (*store)(struct device_driver *, const char * buf);
|
||||
ssize_t (*store)(struct device_driver *, const char * buf,
|
||||
size_t count);
|
||||
};
|
||||
|
||||
Declaring:
|
||||
|
101
Documentation/hwmon/hpfall.c
Normal file
101
Documentation/hwmon/hpfall.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* Disk protection for HP machines.
|
||||
*
|
||||
* Copyright 2008 Eric Piel
|
||||
* Copyright 2009 Pavel Machek <pavel@suse.cz>
|
||||
*
|
||||
* GPLv2.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
void write_int(char *path, int i)
|
||||
{
|
||||
char buf[1024];
|
||||
int fd = open(path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
sprintf(buf, "%d", i);
|
||||
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
|
||||
perror("write");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void set_led(int on)
|
||||
{
|
||||
write_int("/sys/class/leds/hp::hddprotect/brightness", on);
|
||||
}
|
||||
|
||||
void protect(int seconds)
|
||||
{
|
||||
write_int("/sys/block/sda/device/unload_heads", seconds*1000);
|
||||
}
|
||||
|
||||
int on_ac(void)
|
||||
{
|
||||
// /sys/class/power_supply/AC0/online
|
||||
}
|
||||
|
||||
int lid_open(void)
|
||||
{
|
||||
// /proc/acpi/button/lid/LID/state
|
||||
}
|
||||
|
||||
void ignore_me(void)
|
||||
{
|
||||
protect(0);
|
||||
set_led(0);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
fd = open("/dev/freefall", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
signal(SIGALRM, ignore_me);
|
||||
|
||||
for (;;) {
|
||||
unsigned char count;
|
||||
|
||||
ret = read(fd, &count, sizeof(count));
|
||||
alarm(0);
|
||||
if ((ret == -1) && (errno == EINTR)) {
|
||||
/* Alarm expired, time to unpark the heads */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret != sizeof(count)) {
|
||||
perror("read");
|
||||
break;
|
||||
}
|
||||
|
||||
protect(21);
|
||||
set_led(1);
|
||||
if (1 || on_ac() || lid_open()) {
|
||||
alarm(2);
|
||||
} else {
|
||||
alarm(20);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -33,6 +33,14 @@ rate - reports the sampling rate of the accelerometer device in HZ
|
||||
This driver also provides an absolute input class device, allowing
|
||||
the laptop to act as a pinball machine-esque joystick.
|
||||
|
||||
Another feature of the driver is misc device called "freefall" that
|
||||
acts similar to /dev/rtc and reacts on free-fall interrupts received
|
||||
from the device. It supports blocking operations, poll/select and
|
||||
fasync operation modes. You must read 1 bytes from the device. The
|
||||
result is number of free-fall interrupts since the last successful
|
||||
read (or 255 if number of interrupts would not fit).
|
||||
|
||||
|
||||
Axes orientation
|
||||
----------------
|
||||
|
||||
|
@ -43,7 +43,8 @@ Only comments so marked will be considered by the kernel-doc scripts,
|
||||
and any comment so marked must be in kernel-doc format. Do not use
|
||||
"/**" to be begin a comment block unless the comment block contains
|
||||
kernel-doc formatted comments. The closing comment marker for
|
||||
kernel-doc comments can be either "*/" or "**/".
|
||||
kernel-doc comments can be either "*/" or "**/", but "*/" is
|
||||
preferred in the Linux kernel tree.
|
||||
|
||||
Kernel-doc comments should be placed just before the function
|
||||
or data structure being described.
|
||||
@ -63,7 +64,7 @@ Example kernel-doc function comment:
|
||||
* comment lines.
|
||||
*
|
||||
* The longer description can have multiple paragraphs.
|
||||
**/
|
||||
*/
|
||||
|
||||
The first line, with the short description, must be on a single line.
|
||||
|
||||
@ -85,7 +86,7 @@ Example kernel-doc data structure comment.
|
||||
* perhaps with more lines and words.
|
||||
*
|
||||
* Longer description of this structure.
|
||||
**/
|
||||
*/
|
||||
|
||||
The kernel-doc function comments describe each parameter to the
|
||||
function, in order, with the @name lines.
|
||||
|
@ -114,7 +114,7 @@ In addition, the following text indicates that the option:
|
||||
Parameters denoted with BOOT are actually interpreted by the boot
|
||||
loader, and have no meaning to the kernel directly.
|
||||
Do not modify the syntax of boot loader parameters without extreme
|
||||
need or coordination with <Documentation/x86/i386/boot.txt>.
|
||||
need or coordination with <Documentation/x86/boot.txt>.
|
||||
|
||||
There are also arch-specific kernel-parameters not documented here.
|
||||
See for example <Documentation/x86/x86_64/boot-options.txt>.
|
||||
@ -134,7 +134,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
|
||||
acpi= [HW,ACPI,X86-64,i386]
|
||||
Advanced Configuration and Power Interface
|
||||
Format: { force | off | ht | strict | noirq }
|
||||
Format: { force | off | ht | strict | noirq | rsdt }
|
||||
force -- enable ACPI if default was off
|
||||
off -- disable ACPI if default was on
|
||||
noirq -- do not use ACPI for IRQ routing
|
||||
@ -868,8 +868,10 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
icn= [HW,ISDN]
|
||||
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
|
||||
|
||||
ide= [HW] (E)IDE subsystem
|
||||
Format: ide=nodma or ide=doubler
|
||||
ide-core.nodma= [HW] (E)IDE subsystem
|
||||
Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
|
||||
.vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom
|
||||
.chs .ignore_cable are additional options
|
||||
See Documentation/ide/ide.txt.
|
||||
|
||||
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
|
||||
@ -937,6 +939,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
|
||||
|
||||
intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
|
||||
on
|
||||
Enable intel iommu driver.
|
||||
off
|
||||
Disable intel iommu driver.
|
||||
igfx_off [Default Off]
|
||||
@ -2447,7 +2451,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
See Documentation/fb/modedb.txt.
|
||||
|
||||
vga= [BOOT,X86-32] Select a particular video mode
|
||||
See Documentation/x86/i386/boot.txt and
|
||||
See Documentation/x86/boot.txt and
|
||||
Documentation/svga.txt.
|
||||
Use vga=ask for menu.
|
||||
This is actually a boot loader parameter; the value is
|
||||
|
35
Documentation/networking/ipv6.txt
Normal file
35
Documentation/networking/ipv6.txt
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
Options for the ipv6 module are supplied as parameters at load time.
|
||||
|
||||
Module options may be given as command line arguments to the insmod
|
||||
or modprobe command, but are usually specified in either the
|
||||
/etc/modules.conf or /etc/modprobe.conf configuration file, or in a
|
||||
distro-specific configuration file.
|
||||
|
||||
The available ipv6 module parameters are listed below. If a parameter
|
||||
is not specified the default value is used.
|
||||
|
||||
The parameters are as follows:
|
||||
|
||||
disable
|
||||
|
||||
Specifies whether to load the IPv6 module, but disable all
|
||||
its functionality. This might be used when another module
|
||||
has a dependency on the IPv6 module being loaded, but no
|
||||
IPv6 addresses or operations are desired.
|
||||
|
||||
The possible values and their effects are:
|
||||
|
||||
0
|
||||
IPv6 is enabled.
|
||||
|
||||
This is the default value.
|
||||
|
||||
1
|
||||
IPv6 is disabled.
|
||||
|
||||
No IPv6 addresses will be added to interfaces, and
|
||||
it will not be possible to open an IPv6 socket.
|
||||
|
||||
A reboot is required to enable IPv6.
|
||||
|
@ -4,7 +4,7 @@ Introduction
|
||||
============
|
||||
|
||||
The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc.
|
||||
series of products) supports iSCSI acceleration and iSCSI Direct Data Placement
|
||||
series of products) support iSCSI acceleration and iSCSI Direct Data Placement
|
||||
(DDP) where the hardware handles the expensive byte touching operations, such
|
||||
as CRC computation and verification, and direct DMA to the final host memory
|
||||
destination:
|
||||
@ -31,9 +31,9 @@ destination:
|
||||
the TCP segments onto the wire. It handles TCP retransmission if
|
||||
needed.
|
||||
|
||||
On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP
|
||||
On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP
|
||||
segments, separating the header and data, calculating and verifying
|
||||
the digests, then forwards the header to the host. The payload data,
|
||||
the digests, then forwarding the header to the host. The payload data,
|
||||
if possible, will be directly placed into the pre-posted host DDP
|
||||
buffer. Otherwise, the payload data will be sent to the host too.
|
||||
|
||||
@ -68,9 +68,8 @@ The following steps need to be taken to accelerates the open-iscsi initiator:
|
||||
sure the ip address is unique in the network.
|
||||
|
||||
3. edit /etc/iscsi/iscsid.conf
|
||||
The default setting for MaxRecvDataSegmentLength (131072) is too big,
|
||||
replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no
|
||||
bigger than 15360 (for example 8192):
|
||||
The default setting for MaxRecvDataSegmentLength (131072) is too big;
|
||||
replace with a value no bigger than 15360 (for example 8192):
|
||||
|
||||
node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192
|
||||
|
||||
|
@ -78,12 +78,10 @@ to view your kernel log and look for "mmiotrace has lost events" warning. If
|
||||
events were lost, the trace is incomplete. You should enlarge the buffers and
|
||||
try again. Buffers are enlarged by first seeing how large the current buffers
|
||||
are:
|
||||
$ cat /debug/tracing/trace_entries
|
||||
$ cat /debug/tracing/buffer_size_kb
|
||||
gives you a number. Approximately double this number and write it back, for
|
||||
instance:
|
||||
$ echo 0 > /debug/tracing/tracing_enabled
|
||||
$ echo 128000 > /debug/tracing/trace_entries
|
||||
$ echo 1 > /debug/tracing/tracing_enabled
|
||||
$ echo 128000 > /debug/tracing/buffer_size_kb
|
||||
Then start again from the top.
|
||||
|
||||
If you are doing a trace for a driver project, e.g. Nouveau, you should also
|
||||
|
43
MAINTAINERS
43
MAINTAINERS
@ -692,6 +692,13 @@ M: kernel@wantstofly.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
ARM/NUVOTON W90X900 ARM ARCHITECTURE
|
||||
P: Wan ZongShun
|
||||
M: mcuos.com@gmail.com
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.mcuos.com
|
||||
S: Maintained
|
||||
|
||||
ARPD SUPPORT
|
||||
P: Jonathan Layes
|
||||
L: netdev@vger.kernel.org
|
||||
@ -1202,6 +1209,8 @@ S: Supported
|
||||
CONTROL GROUPS (CGROUPS)
|
||||
P: Paul Menage
|
||||
M: menage@google.com
|
||||
P: Li Zefan
|
||||
M: lizf@cn.fujitsu.com
|
||||
L: containers@lists.linux-foundation.org
|
||||
S: Maintained
|
||||
|
||||
@ -1903,10 +1912,10 @@ W: http://gigaset307x.sourceforge.net/
|
||||
S: Maintained
|
||||
|
||||
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
|
||||
P: Robert Love
|
||||
M: rlove@rlove.org
|
||||
M: linux-kernel@vger.kernel.org
|
||||
W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
|
||||
P: Frank Seidel
|
||||
M: frank@f-seidel.de
|
||||
L: lm-sensors@lm-sensors.org
|
||||
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
|
||||
S: Maintained
|
||||
|
||||
GSPCA FINEPIX SUBDRIVER
|
||||
@ -1999,7 +2008,7 @@ S: Maintained
|
||||
|
||||
HIBERNATION (aka Software Suspend, aka swsusp)
|
||||
P: Pavel Machek
|
||||
M: pavel@suse.cz
|
||||
M: pavel@ucw.cz
|
||||
P: Rafael J. Wysocki
|
||||
M: rjw@sisk.pl
|
||||
L: linux-pm@lists.linux-foundation.org
|
||||
@ -2455,7 +2464,7 @@ S: Maintained
|
||||
|
||||
ISDN SUBSYSTEM
|
||||
P: Karsten Keil
|
||||
M: kkeil@suse.de
|
||||
M: isdn@linux-pingi.de
|
||||
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
|
||||
W: http://www.isdn4linux.de
|
||||
T: git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
|
||||
@ -3325,8 +3334,8 @@ P: Jeremy Fitzhardinge
|
||||
M: jeremy@xensource.com
|
||||
P: Chris Wright
|
||||
M: chrisw@sous-sol.org
|
||||
P: Zachary Amsden
|
||||
M: zach@vmware.com
|
||||
P: Alok Kataria
|
||||
M: akataria@vmware.com
|
||||
P: Rusty Russell
|
||||
M: rusty@rustcorp.com.au
|
||||
L: virtualization@lists.osdl.org
|
||||
@ -3537,6 +3546,12 @@ S: Maintained
|
||||
PXA MMCI DRIVER
|
||||
S: Orphan
|
||||
|
||||
PXA RTC DRIVER
|
||||
P: Robert Jarzmik
|
||||
M: robert.jarzmik@free.fr
|
||||
L: rtc-linux@googlegroups.com
|
||||
S: Maintained
|
||||
|
||||
QLOGIC QLA2XXX FC-SCSI DRIVER
|
||||
P: Andrew Vasquez
|
||||
M: linux-driver@qlogic.com
|
||||
@ -4164,7 +4179,7 @@ SUSPEND TO RAM
|
||||
P: Len Brown
|
||||
M: len.brown@intel.com
|
||||
P: Pavel Machek
|
||||
M: pavel@suse.cz
|
||||
M: pavel@ucw.cz
|
||||
P: Rafael J. Wysocki
|
||||
M: rjw@sisk.pl
|
||||
L: linux-pm@lists.linux-foundation.org
|
||||
@ -4285,8 +4300,8 @@ P: Rajiv Andrade
|
||||
M: srajiv@linux.vnet.ibm.com
|
||||
W: http://tpmdd.sourceforge.net
|
||||
P: Marcel Selhorst
|
||||
M: tpm@selhorst.net
|
||||
W: http://www.prosec.rub.de/tpm/
|
||||
M: m.selhorst@sirrix.com
|
||||
W: http://www.sirrix.com
|
||||
L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
|
||||
@ -4916,11 +4931,11 @@ L: zd1211-devs@lists.sourceforge.net (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
ZR36067 VIDEO FOR LINUX DRIVER
|
||||
P: Ronald Bultje
|
||||
M: rbultje@ronald.bitfreak.net
|
||||
L: mjpeg-users@lists.sourceforge.net
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://mjpeg.sourceforge.net/driver-zoran/
|
||||
S: Maintained
|
||||
T: Mercurial http://linuxtv.org/hg/v4l-dvb
|
||||
S: Odd Fixes
|
||||
|
||||
ZS DECSTATION Z85C30 SERIAL DRIVER
|
||||
P: Maciej W. Rozycki
|
||||
|
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 29
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Erotic Pickled Herring
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -389,6 +389,7 @@ PHONY += outputmakefile
|
||||
# output directory.
|
||||
outputmakefile:
|
||||
ifneq ($(KBUILD_SRC),)
|
||||
$(Q)ln -fsn $(srctree) source
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
|
||||
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
|
||||
endif
|
||||
@ -946,7 +947,6 @@ ifneq ($(KBUILD_SRC),)
|
||||
mkdir -p include2; \
|
||||
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
|
||||
fi
|
||||
ln -fsn $(srctree) source
|
||||
endif
|
||||
|
||||
# prepare2 creates a makefile if using a separate output directory
|
||||
|
2
README
2
README
@ -188,7 +188,7 @@ CONFIGURING the kernel:
|
||||
values to random values.
|
||||
|
||||
You can find more information on using the Linux kernel config tools
|
||||
in Documentation/kbuild/make-configs.txt.
|
||||
in Documentation/kbuild/kconfig.txt.
|
||||
|
||||
NOTES on "make config":
|
||||
- having unnecessary drivers will make the kernel bigger, and can
|
||||
|
@ -93,8 +93,8 @@ common_shutdown_1(void *generic_ptr)
|
||||
if (cpuid != boot_cpuid) {
|
||||
flags |= 0x00040000UL; /* "remain halted" */
|
||||
*pflags = flags;
|
||||
cpu_clear(cpuid, cpu_present_map);
|
||||
cpu_clear(cpuid, cpu_possible_map);
|
||||
set_cpu_present(cpuid, false);
|
||||
set_cpu_possible(cpuid, false);
|
||||
halt();
|
||||
}
|
||||
#endif
|
||||
@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Wait for the secondaries to halt. */
|
||||
cpu_clear(boot_cpuid, cpu_present_map);
|
||||
cpu_clear(boot_cpuid, cpu_possible_map);
|
||||
set_cpu_present(boot_cpuid, false);
|
||||
set_cpu_possible(boot_cpuid, false);
|
||||
while (cpus_weight(cpu_present_map))
|
||||
barrier();
|
||||
#endif
|
||||
|
@ -120,12 +120,12 @@ void __cpuinit
|
||||
smp_callin(void)
|
||||
{
|
||||
int cpuid = hard_smp_processor_id();
|
||||
cpumask_t mask = cpu_online_map;
|
||||
|
||||
if (cpu_test_and_set(cpuid, mask)) {
|
||||
if (cpu_online(cpuid)) {
|
||||
printk("??, cpu 0x%x already present??\n", cpuid);
|
||||
BUG();
|
||||
}
|
||||
set_cpu_online(cpuid, true);
|
||||
|
||||
/* Turn on machine checks. */
|
||||
wrmces(7);
|
||||
@ -436,8 +436,8 @@ setup_smp(void)
|
||||
((char *)cpubase + i*hwrpb->processor_size);
|
||||
if ((cpu->flags & 0x1cc) == 0x1cc) {
|
||||
smp_num_probed++;
|
||||
cpu_set(i, cpu_possible_map);
|
||||
cpu_set(i, cpu_present_map);
|
||||
set_cpu_possible(i, true);
|
||||
set_cpu_present(i, true);
|
||||
cpu->pal_revision = boot_cpu_palrev;
|
||||
}
|
||||
|
||||
@ -470,8 +470,8 @@ smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
||||
/* Nothing to do on a UP box, or when told not to. */
|
||||
if (smp_num_probed == 1 || max_cpus == 0) {
|
||||
cpu_possible_map = cpumask_of_cpu(boot_cpuid);
|
||||
cpu_present_map = cpumask_of_cpu(boot_cpuid);
|
||||
init_cpu_possible(cpumask_of(boot_cpuid));
|
||||
init_cpu_present(cpumask_of(boot_cpuid));
|
||||
printk(KERN_INFO "SMP mode deactivated.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -700,7 +700,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -710,7 +710,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -606,7 +606,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# Sonics Silicon Backplane
|
||||
|
@ -727,7 +727,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
# CONFIG_AT91SAM9_WATCHDOG is not set
|
||||
# CONFIG_AT91SAM9X_WATCHDOG is not set
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -74,9 +74,9 @@ EXPORT_SYMBOL(elf_set_personality);
|
||||
*/
|
||||
int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
|
||||
{
|
||||
if (executable_stack != EXSTACK_ENABLE_X)
|
||||
if (executable_stack != EXSTACK_DISABLE_X)
|
||||
return 1;
|
||||
if (cpu_architecture() <= CPU_ARCH_ARMv6)
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv6)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
const extern unsigned char relocate_new_kernel[];
|
||||
const extern unsigned int relocate_new_kernel_size;
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
extern const unsigned int relocate_new_kernel_size;
|
||||
|
||||
extern void setup_mm_for_reboot(char mode);
|
||||
|
||||
|
@ -234,12 +234,13 @@ static void __init cacheid_init(void)
|
||||
unsigned int cachetype = read_cpuid_cachetype();
|
||||
unsigned int arch = cpu_architecture();
|
||||
|
||||
if (arch >= CPU_ARCH_ARMv7) {
|
||||
cacheid = CACHEID_VIPT_NONALIASING;
|
||||
if ((cachetype & (3 << 14)) == 1 << 14)
|
||||
cacheid |= CACHEID_ASID_TAGGED;
|
||||
} else if (arch >= CPU_ARCH_ARMv6) {
|
||||
if (cachetype & (1 << 23))
|
||||
if (arch >= CPU_ARCH_ARMv6) {
|
||||
if ((cachetype & (7 << 29)) == 4 << 29) {
|
||||
/* ARMv7 register format */
|
||||
cacheid = CACHEID_VIPT_NONALIASING;
|
||||
if ((cachetype & (3 << 14)) == 1 << 14)
|
||||
cacheid |= CACHEID_ASID_TAGGED;
|
||||
} else if (cachetype & (1 << 23))
|
||||
cacheid = CACHEID_VIPT_ALIASING;
|
||||
else
|
||||
cacheid = CACHEID_VIPT_NONALIASING;
|
||||
|
@ -697,7 +697,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91cap9_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -643,7 +643,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9260_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -621,7 +621,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9261_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -347,6 +347,111 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
|
||||
void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Compact Flash (PCMCIA or IDE)
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \
|
||||
defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
|
||||
|
||||
static struct at91_cf_data cf0_data;
|
||||
|
||||
static struct resource cf0_resources[] = {
|
||||
[0] = {
|
||||
.start = AT91_CHIPSELECT_4,
|
||||
.end = AT91_CHIPSELECT_4 + SZ_256M - 1,
|
||||
.flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device cf0_device = {
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &cf0_data,
|
||||
},
|
||||
.resource = cf0_resources,
|
||||
.num_resources = ARRAY_SIZE(cf0_resources),
|
||||
};
|
||||
|
||||
static struct at91_cf_data cf1_data;
|
||||
|
||||
static struct resource cf1_resources[] = {
|
||||
[0] = {
|
||||
.start = AT91_CHIPSELECT_5,
|
||||
.end = AT91_CHIPSELECT_5 + SZ_256M - 1,
|
||||
.flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device cf1_device = {
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &cf1_data,
|
||||
},
|
||||
.resource = cf1_resources,
|
||||
.num_resources = ARRAY_SIZE(cf1_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_cf(struct at91_cf_data *data)
|
||||
{
|
||||
unsigned long ebi0_csa;
|
||||
struct platform_device *pdev;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
/*
|
||||
* assign CS4 or CS5 to SMC with Compact Flash logic support,
|
||||
* we assume SMC timings are configured by board code,
|
||||
* except True IDE where timings are controlled by driver
|
||||
*/
|
||||
ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
|
||||
switch (data->chipselect) {
|
||||
case 4:
|
||||
at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */
|
||||
ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1;
|
||||
cf0_data = *data;
|
||||
pdev = &cf0_device;
|
||||
break;
|
||||
case 5:
|
||||
at91_set_A_periph(AT91_PIN_PD7, 0); /* EBI0_NCS5/CFCS1 */
|
||||
ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2;
|
||||
cf1_data = *data;
|
||||
pdev = &cf1_device;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
|
||||
data->chipselect);
|
||||
return;
|
||||
}
|
||||
at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
|
||||
|
||||
if (data->det_pin) {
|
||||
at91_set_gpio_input(data->det_pin, 1);
|
||||
at91_set_deglitch(data->det_pin, 1);
|
||||
}
|
||||
|
||||
if (data->irq_pin) {
|
||||
at91_set_gpio_input(data->irq_pin, 1);
|
||||
at91_set_deglitch(data->irq_pin, 1);
|
||||
}
|
||||
|
||||
if (data->vcc_pin)
|
||||
/* initially off */
|
||||
at91_set_gpio_output(data->vcc_pin, 0);
|
||||
|
||||
/* enable EBI controlled pins */
|
||||
at91_set_A_periph(AT91_PIN_PD5, 1); /* NWAIT */
|
||||
at91_set_A_periph(AT91_PIN_PD8, 0); /* CFCE1 */
|
||||
at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */
|
||||
at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */
|
||||
|
||||
pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf";
|
||||
platform_device_register(pdev);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_cf(struct at91_cf_data *data) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* NAND / SmartMedia
|
||||
@ -854,7 +959,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9263_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -609,7 +609,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9rl_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -437,7 +437,68 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/* This lock class tells lockdep that GPIO irqs are in a different
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
static int at91_gpio_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
int bank, j;
|
||||
|
||||
/* print heading */
|
||||
seq_printf(s, "Pin\t");
|
||||
for (bank = 0; bank < gpio_banks; bank++) {
|
||||
seq_printf(s, "PIO%c\t", 'A' + bank);
|
||||
};
|
||||
seq_printf(s, "\n\n");
|
||||
|
||||
/* print pin status */
|
||||
for (j = 0; j < 32; j++) {
|
||||
seq_printf(s, "%i:\t", j);
|
||||
|
||||
for (bank = 0; bank < gpio_banks; bank++) {
|
||||
unsigned pin = PIN_BASE + (32 * bank) + j;
|
||||
void __iomem *pio = pin_to_controller(pin);
|
||||
unsigned mask = pin_to_mask(pin);
|
||||
|
||||
if (__raw_readl(pio + PIO_PSR) & mask)
|
||||
seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
|
||||
else
|
||||
seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
|
||||
|
||||
seq_printf(s, "\t");
|
||||
}
|
||||
|
||||
seq_printf(s, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at91_gpio_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, at91_gpio_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations at91_gpio_operations = {
|
||||
.open = at91_gpio_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init at91_gpio_debugfs_init(void)
|
||||
{
|
||||
/* /sys/kernel/debug/at91_gpio */
|
||||
(void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations);
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(at91_gpio_debugfs_init);
|
||||
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* This lock class tells lockdep that GPIO irqs are in a different
|
||||
* category than their parents, so it won't report false recursion.
|
||||
*/
|
||||
static struct lock_class_key gpio_lock_class;
|
||||
@ -456,9 +517,6 @@ void __init at91_gpio_irq_setup(void)
|
||||
unsigned id = this->bank->id;
|
||||
unsigned i;
|
||||
|
||||
/* enable PIO controller's clock */
|
||||
clk_enable(this->bank->clock);
|
||||
|
||||
__raw_writel(~0, this->regbase + PIO_IDR);
|
||||
|
||||
for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
|
||||
@ -589,6 +647,9 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
|
||||
at91_gpio->regbase = at91_gpio->bank->offset +
|
||||
(void __iomem *)AT91_VA_BASE_SYS;
|
||||
|
||||
/* enable PIO controller's clock */
|
||||
clk_enable(at91_gpio->bank->clock);
|
||||
|
||||
/* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
|
||||
if (last && last->bank->id == at91_gpio->bank->id)
|
||||
last->next = at91_gpio;
|
||||
|
@ -56,6 +56,9 @@ struct at91_cf_data {
|
||||
u8 vcc_pin; /* power switching */
|
||||
u8 rst_pin; /* card reset */
|
||||
u8 chipselect; /* EBI Chip Select number */
|
||||
u8 flags;
|
||||
#define AT91_CF_TRUE_IDE 0x01
|
||||
#define AT91_IDE_SWAP_A0_A2 0x02
|
||||
};
|
||||
extern void __init at91_add_device_cf(struct at91_cf_data *data);
|
||||
|
||||
@ -93,6 +96,7 @@ struct atmel_nand_data {
|
||||
u8 enable_pin; /* chip enable */
|
||||
u8 det_pin; /* card detect */
|
||||
u8 rdy_pin; /* ready/busy */
|
||||
u8 rdy_pin_active_low; /* rdy_pin value is inverted */
|
||||
u8 ale; /* address line number connected to ALE */
|
||||
u8 cle; /* address line number connected to CLE */
|
||||
u8 bus_width_16; /* buswidth is 16 bit */
|
||||
|
@ -332,7 +332,6 @@ static int at91_pm_enter(suspend_state_t state)
|
||||
at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));
|
||||
|
||||
error:
|
||||
sdram_selfrefresh_disable();
|
||||
target_state = PM_SUSPEND_ON;
|
||||
at91_irq_resume();
|
||||
at91_gpio_resume();
|
||||
|
@ -311,6 +311,9 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
|
||||
gpio_request(gpio + 7, "nCF_SEL");
|
||||
gpio_direction_output(gpio + 7, 1);
|
||||
|
||||
/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
|
||||
setup_usb(500, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -417,9 +420,6 @@ static __init void davinci_evm_init(void)
|
||||
platform_add_devices(davinci_evm_devices,
|
||||
ARRAY_SIZE(davinci_evm_devices));
|
||||
evm_init_i2c();
|
||||
|
||||
/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
|
||||
setup_usb(500, 8);
|
||||
}
|
||||
|
||||
static __init void davinci_evm_irq_init(void)
|
||||
|
@ -230,6 +230,11 @@ static struct clk davinci_clks[] = {
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_GPIO,
|
||||
},
|
||||
{
|
||||
.name = "usb",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_USB,
|
||||
},
|
||||
{
|
||||
.name = "AEMIFCLK",
|
||||
.rate = &commonrate,
|
||||
|
@ -47,6 +47,7 @@ static struct musb_hdrc_platform_data usb_data = {
|
||||
#elif defined(CONFIG_USB_MUSB_HOST)
|
||||
.mode = MUSB_HOST,
|
||||
#endif
|
||||
.clock = "usb",
|
||||
.config = &musb_config,
|
||||
};
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
/*
|
||||
* arch/arm/mach-ep93xx/include/mach/gesbc9312.h
|
||||
*/
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "gesbc9312.h"
|
||||
#include "ts72xx.h"
|
||||
|
||||
#endif
|
||||
|
@ -42,7 +42,7 @@ void __init kirkwood_init_irq(void)
|
||||
writel(0, GPIO_EDGE_CAUSE(32));
|
||||
|
||||
for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) {
|
||||
set_irq_chip(i, &orion_gpio_irq_level_chip);
|
||||
set_irq_chip(i, &orion_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
irq_desc[i].status |= IRQ_LEVEL;
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
|
@ -40,7 +40,7 @@ void __init mv78xx0_init_irq(void)
|
||||
writel(0, GPIO_EDGE_CAUSE(0));
|
||||
|
||||
for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) {
|
||||
set_irq_chip(i, &orion_gpio_irq_level_chip);
|
||||
set_irq_chip(i, &orion_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
irq_desc[i].status |= IRQ_LEVEL;
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
|
@ -1,6 +1,6 @@
|
||||
if ARCH_MX1
|
||||
|
||||
comment "MX1 Platforms"
|
||||
comment "MX1 platforms:"
|
||||
|
||||
config MACH_MXLADS
|
||||
bool
|
||||
@ -11,4 +11,9 @@ config ARCH_MX1ADS
|
||||
help
|
||||
Say Y here if you are using Motorola MX1ADS/MXLADS boards
|
||||
|
||||
config MACH_SCB9328
|
||||
bool "Synertronixx scb9328"
|
||||
help
|
||||
Say Y here if you are using a Synertronixx scb9328 board
|
||||
|
||||
endif
|
||||
|
@ -8,3 +8,4 @@ obj-y += generic.o clock.o devices.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
|
||||
obj-$(CONFIG_MACH_SCB9328) += scb9328.o
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <mach/clock.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include "crm_regs.h"
|
||||
|
||||
static int _clk_enable(struct clk *clk)
|
||||
@ -87,33 +88,6 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
|
||||
return clk->parent->set_rate(clk->parent, rate);
|
||||
}
|
||||
|
||||
/*
|
||||
* get the system pll clock in Hz
|
||||
*
|
||||
* mfi + mfn / (mfd +1)
|
||||
* f = 2 * f_ref * --------------------
|
||||
* pd + 1
|
||||
*/
|
||||
static unsigned long mx1_decode_pll(unsigned int pll, u32 f_ref)
|
||||
{
|
||||
unsigned long long ll;
|
||||
unsigned long quot;
|
||||
|
||||
u32 mfi = (pll >> 10) & 0xf;
|
||||
u32 mfn = pll & 0x3ff;
|
||||
u32 mfd = (pll >> 16) & 0x3ff;
|
||||
u32 pd = (pll >> 26) & 0xf;
|
||||
|
||||
mfi = mfi <= 5 ? 5 : mfi;
|
||||
|
||||
ll = 2 * (unsigned long long)f_ref *
|
||||
((mfi << 16) + (mfn << 16) / (mfd + 1));
|
||||
quot = (pd + 1) * (1 << 16);
|
||||
ll += quot / 2;
|
||||
do_div(ll, quot);
|
||||
return (unsigned long)ll;
|
||||
}
|
||||
|
||||
static unsigned long clk16m_get_rate(struct clk *clk)
|
||||
{
|
||||
return 16000000;
|
||||
@ -188,7 +162,7 @@ static struct clk prem_clk = {
|
||||
|
||||
static unsigned long system_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return mx1_decode_pll(__raw_readl(CCM_SPCTL0),
|
||||
return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
|
||||
clk_get_rate(clk->parent));
|
||||
}
|
||||
|
||||
@ -200,7 +174,7 @@ static struct clk system_clk = {
|
||||
|
||||
static unsigned long mcu_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return mx1_decode_pll(__raw_readl(CCM_MPCTL0),
|
||||
return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
|
||||
clk_get_rate(clk->parent));
|
||||
}
|
||||
|
||||
@ -488,7 +462,7 @@ static struct clk clko_clk = {
|
||||
};
|
||||
|
||||
static struct clk dma_clk = {
|
||||
.name = "dma_clk",
|
||||
.name = "dma",
|
||||
.parent = &hclk,
|
||||
.round_rate = _clk_parent_round_rate,
|
||||
.set_rate = _clk_parent_set_rate,
|
||||
@ -539,7 +513,7 @@ static struct clk gpt_clk = {
|
||||
};
|
||||
|
||||
static struct clk uart_clk = {
|
||||
.name = "uart_clk",
|
||||
.name = "uart",
|
||||
.parent = &perclk[0],
|
||||
.round_rate = _clk_parent_round_rate,
|
||||
.set_rate = _clk_parent_set_rate,
|
||||
@ -621,7 +595,7 @@ static struct clk *mxc_clks[] = {
|
||||
&rtc_clk,
|
||||
};
|
||||
|
||||
int __init mxc_clocks_init(unsigned long fref)
|
||||
int __init mx1_clocks_init(unsigned long fref)
|
||||
{
|
||||
struct clk **clkp;
|
||||
unsigned int reg;
|
||||
@ -652,5 +626,7 @@ int __init mxc_clocks_init(unsigned long fref)
|
||||
clk_enable(&hclk);
|
||||
clk_enable(&fclk);
|
||||
|
||||
mxc_timer_init(&gpt_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,8 +23,11 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
static struct resource imx_csi_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x00224000,
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/pcf857x.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -24,7 +26,11 @@
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx1-mx2.h>
|
||||
#include <mach/irqs.h>
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
#include <mach/i2c.h>
|
||||
#endif
|
||||
#include <mach/iomux.h>
|
||||
#include "devices.h"
|
||||
|
||||
/*
|
||||
@ -103,6 +109,55 @@ static struct platform_device flash_device = {
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* I2C
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
static int i2c_pins[] = {
|
||||
PA15_PF_I2C_SDA,
|
||||
PA16_PF_I2C_SCL,
|
||||
};
|
||||
|
||||
static int i2c_init(struct device *dev)
|
||||
{
|
||||
return mxc_gpio_setup_multiple_pins(i2c_pins,
|
||||
ARRAY_SIZE(i2c_pins), "I2C");
|
||||
}
|
||||
|
||||
static void i2c_exit(struct device *dev)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(i2c_pins,
|
||||
ARRAY_SIZE(i2c_pins));
|
||||
}
|
||||
|
||||
static struct pcf857x_platform_data pcf857x_data[] = {
|
||||
{
|
||||
.gpio_base = 4 * 32,
|
||||
}, {
|
||||
.gpio_base = 4 * 32 + 16,
|
||||
}
|
||||
};
|
||||
|
||||
static struct imxi2c_platform_data mx1ads_i2c_data = {
|
||||
.bitrate = 100000,
|
||||
.init = i2c_init,
|
||||
.exit = i2c_exit,
|
||||
};
|
||||
|
||||
static struct i2c_board_info mx1ads_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("pcf857x", 0x22),
|
||||
.type = "pcf8575",
|
||||
.platform_data = &pcf857x_data[0],
|
||||
}, {
|
||||
I2C_BOARD_INFO("pcf857x", 0x24),
|
||||
.type = "pcf8575",
|
||||
.platform_data = &pcf857x_data[1],
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Board init
|
||||
*/
|
||||
@ -114,12 +169,19 @@ static void __init mx1ads_init(void)
|
||||
|
||||
/* Physmap flash */
|
||||
mxc_register_device(&flash_device, &mx1ads_flash_data);
|
||||
|
||||
/* I2C */
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
i2c_register_board_info(0, mx1ads_i2c_devices,
|
||||
ARRAY_SIZE(mx1ads_i2c_devices));
|
||||
|
||||
mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init mx1ads_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(32000);
|
||||
mxc_timer_init("gpt_clk");
|
||||
mx1_clocks_init(32000);
|
||||
}
|
||||
|
||||
struct sys_timer mx1ads_timer = {
|
||||
|
160
arch/arm/mach-mx1/scb9328.c
Normal file
160
arch/arm/mach-mx1/scb9328.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-mx1/scb9328.c
|
||||
*
|
||||
* Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
|
||||
* Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include <mach/common.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/*
|
||||
* This scb9328 has a 32MiB flash
|
||||
*/
|
||||
static struct resource flash_resource = {
|
||||
.start = IMX_CS0_PHYS,
|
||||
.end = IMX_CS0_PHYS + (32 * 1024 * 1024) - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct physmap_flash_data scb_flash_data = {
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct platform_device scb_flash_device = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &scb_flash_data,
|
||||
},
|
||||
.resource = &flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* scb9328 has a DM9000 network controller
|
||||
* connected to CS5, with 16 bit data path
|
||||
* and interrupt connected to GPIO 3
|
||||
*/
|
||||
|
||||
/*
|
||||
* internal datapath is fixed 16 bit
|
||||
*/
|
||||
static struct dm9000_plat_data dm9000_platdata = {
|
||||
.flags = DM9000_PLATF_16BITONLY,
|
||||
};
|
||||
|
||||
/*
|
||||
* the DM9000 drivers wants two defined address spaces
|
||||
* to gain access to address latch registers and the data path.
|
||||
*/
|
||||
static struct resource dm9000x_resources[] = {
|
||||
[0] = {
|
||||
.name = "address area",
|
||||
.start = IMX_CS5_PHYS,
|
||||
.end = IMX_CS5_PHYS + 1,
|
||||
.flags = IORESOURCE_MEM /* address access */
|
||||
},
|
||||
[1] = {
|
||||
.name = "data area",
|
||||
.start = IMX_CS5_PHYS + 4,
|
||||
.end = IMX_CS5_PHYS + 5,
|
||||
.flags = IORESOURCE_MEM /* data access */
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_GPIOC(3),
|
||||
.end = IRQ_GPIOC(3),
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device dm9000x_device = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(dm9000x_resources),
|
||||
.resource = dm9000x_resources,
|
||||
.dev = {
|
||||
.platform_data = &dm9000_platdata,
|
||||
}
|
||||
};
|
||||
|
||||
static int mxc_uart1_pins[] = {
|
||||
PC9_PF_UART1_CTS,
|
||||
PC10_PF_UART1_RTS,
|
||||
PC11_PF_UART1_TXD,
|
||||
PC12_PF_UART1_RXD,
|
||||
};
|
||||
|
||||
static int uart1_mxc_init(struct platform_device *pdev)
|
||||
{
|
||||
return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
|
||||
ARRAY_SIZE(mxc_uart1_pins), "UART1");
|
||||
}
|
||||
|
||||
static int uart1_mxc_exit(struct platform_device *pdev)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(mxc_uart1_pins,
|
||||
ARRAY_SIZE(mxc_uart1_pins));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct imxuart_platform_data uart_pdata = {
|
||||
.init = uart1_mxc_init,
|
||||
.exit = uart1_mxc_exit,
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&scb_flash_device,
|
||||
&dm9000x_device,
|
||||
};
|
||||
|
||||
/*
|
||||
* scb9328_init - Init the CPU card itself
|
||||
*/
|
||||
static void __init scb9328_init(void)
|
||||
{
|
||||
mxc_register_device(&imx_uart1_device, &uart_pdata);
|
||||
|
||||
printk(KERN_INFO"Scb9328: Adding devices\n");
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
||||
static void __init scb9328_timer_init(void)
|
||||
{
|
||||
mx1_clocks_init(32000);
|
||||
}
|
||||
|
||||
static struct sys_timer scb9328_timer = {
|
||||
.init = scb9328_timer_init,
|
||||
};
|
||||
|
||||
MACHINE_START(SCB9328, "Synertronixx scb9328")
|
||||
/* Sascha Hauer */
|
||||
.phys_io = 0x00200000,
|
||||
.io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x08000100,
|
||||
.map_io = mxc_map_io,
|
||||
.init_irq = mxc_init_irq,
|
||||
.timer = &scb9328_timer,
|
||||
.init_machine = scb9328_init,
|
||||
MACHINE_END
|
@ -1,14 +1,22 @@
|
||||
comment "MX2 family CPU support"
|
||||
depends on ARCH_MX2
|
||||
if ARCH_MX2
|
||||
|
||||
choice
|
||||
prompt "CPUs:"
|
||||
default MACH_MX21
|
||||
|
||||
config MACH_MX21
|
||||
bool "i.MX21 support"
|
||||
help
|
||||
This enables support for Freescale's MX2 based i.MX21 processor.
|
||||
|
||||
config MACH_MX27
|
||||
bool "i.MX27 support"
|
||||
depends on ARCH_MX2
|
||||
help
|
||||
This enables support for Freescale's MX2 based i.MX27 processor.
|
||||
|
||||
comment "MX2 Platforms"
|
||||
depends on ARCH_MX2
|
||||
endchoice
|
||||
|
||||
comment "MX2 platforms:"
|
||||
|
||||
config MACH_MX27ADS
|
||||
bool "MX27ADS platform"
|
||||
@ -37,3 +45,5 @@ config MACH_PCM970_BASEBOARD
|
||||
PCM970 evaluation board.
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
obj-y := system.o generic.o devices.o serial.o
|
||||
|
||||
obj-$(CONFIG_MACH_MX21) += clock_imx21.o
|
||||
|
||||
obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
|
||||
obj-$(CONFIG_MACH_MX27) += clock_imx27.o
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
zreladdr-y := 0xA0008000
|
||||
params_phys-y := 0xA0000100
|
||||
initrd_phys-y := 0xA0800000
|
||||
zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
|
||||
params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
|
||||
initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
|
||||
|
||||
zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
|
||||
params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
|
||||
initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
|
||||
|
984
arch/arm/mach-mx2/clock_imx21.c
Normal file
984
arch/arm/mach-mx2/clock_imx21.c
Normal file
@ -0,0 +1,984 @@
|
||||
/*
|
||||
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
|
||||
* Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
#include <asm/clkdev.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "crm_regs.h"
|
||||
|
||||
static int _clk_enable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg |= 1 << clk->enable_shift;
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _clk_disable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg &= ~(1 << clk->enable_shift);
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
}
|
||||
|
||||
static int _clk_spll_enable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(CCM_CSCR);
|
||||
reg |= CCM_CSCR_SPEN;
|
||||
__raw_writel(reg, CCM_CSCR);
|
||||
|
||||
while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _clk_spll_disable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(CCM_CSCR);
|
||||
reg &= ~CCM_CSCR_SPEN;
|
||||
__raw_writel(reg, CCM_CSCR);
|
||||
}
|
||||
|
||||
|
||||
#define CSCR() (__raw_readl(CCM_CSCR))
|
||||
#define PCDR0() (__raw_readl(CCM_PCDR0))
|
||||
#define PCDR1() (__raw_readl(CCM_PCDR1))
|
||||
|
||||
static unsigned long _clk_perclkx_round_rate(struct clk *clk,
|
||||
unsigned long rate)
|
||||
{
|
||||
u32 div;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
div = parent_rate / rate;
|
||||
if (parent_rate % rate)
|
||||
div++;
|
||||
|
||||
if (div > 64)
|
||||
div = 64;
|
||||
|
||||
return parent_rate / div;
|
||||
}
|
||||
|
||||
static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 reg;
|
||||
u32 div;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
if (clk->id < 0 || clk->id > 3)
|
||||
return -EINVAL;
|
||||
|
||||
div = parent_rate / rate;
|
||||
if (div > 64 || div < 1 || ((parent_rate / div) != rate))
|
||||
return -EINVAL;
|
||||
div--;
|
||||
|
||||
reg =
|
||||
__raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
|
||||
(clk->id << 3));
|
||||
reg |= div << (clk->id << 3);
|
||||
__raw_writel(reg, CCM_PCDR1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long _clk_usb_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned long usb_pdf;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
|
||||
|
||||
return parent_rate / (usb_pdf + 1U);
|
||||
}
|
||||
|
||||
static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
|
||||
{
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
|
||||
|
||||
return 2UL * parent_rate / pdf;
|
||||
}
|
||||
|
||||
static unsigned long _clk_ssi1_recalc(struct clk *clk)
|
||||
{
|
||||
return _clk_ssix_recalc(clk,
|
||||
(PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
|
||||
>> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
|
||||
}
|
||||
|
||||
static unsigned long _clk_ssi2_recalc(struct clk *clk)
|
||||
{
|
||||
return _clk_ssix_recalc(clk,
|
||||
(PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
|
||||
CCM_PCDR0_SSI2BAUDDIV_OFFSET);
|
||||
}
|
||||
|
||||
static unsigned long _clk_nfc_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned long nfc_pdf;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
|
||||
>> CCM_PCDR0_NFCDIV_OFFSET;
|
||||
|
||||
return parent_rate / (nfc_pdf + 1);
|
||||
}
|
||||
|
||||
static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
return clk->parent->round_rate(clk->parent, rate);
|
||||
}
|
||||
|
||||
static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
return clk->parent->set_rate(clk->parent, rate);
|
||||
}
|
||||
|
||||
static unsigned long external_high_reference; /* in Hz */
|
||||
|
||||
static unsigned long get_high_reference_clock_rate(struct clk *clk)
|
||||
{
|
||||
return external_high_reference;
|
||||
}
|
||||
|
||||
/*
|
||||
* the high frequency external clock reference
|
||||
* Default case is 26MHz.
|
||||
*/
|
||||
static struct clk ckih_clk = {
|
||||
.get_rate = get_high_reference_clock_rate,
|
||||
};
|
||||
|
||||
static unsigned long external_low_reference; /* in Hz */
|
||||
|
||||
static unsigned long get_low_reference_clock_rate(struct clk *clk)
|
||||
{
|
||||
return external_low_reference;
|
||||
}
|
||||
|
||||
/*
|
||||
* the low frequency external clock reference
|
||||
* Default case is 32.768kHz.
|
||||
*/
|
||||
static struct clk ckil_clk = {
|
||||
.get_rate = get_low_reference_clock_rate,
|
||||
};
|
||||
|
||||
|
||||
static unsigned long _clk_fpm_recalc(struct clk *clk)
|
||||
{
|
||||
return clk_get_rate(clk->parent) * 512;
|
||||
}
|
||||
|
||||
/* Output of frequency pre multiplier */
|
||||
static struct clk fpm_clk = {
|
||||
.parent = &ckil_clk,
|
||||
.get_rate = _clk_fpm_recalc,
|
||||
};
|
||||
|
||||
static unsigned long get_mpll_clk(struct clk *clk)
|
||||
{
|
||||
uint32_t reg;
|
||||
unsigned long ref_clk;
|
||||
unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
|
||||
unsigned long long temp;
|
||||
|
||||
ref_clk = clk_get_rate(clk->parent);
|
||||
|
||||
reg = __raw_readl(CCM_MPCTL0);
|
||||
pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
|
||||
mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
|
||||
mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
|
||||
mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
|
||||
|
||||
mfi = (mfi <= 5) ? 5 : mfi;
|
||||
temp = 2LL * ref_clk * mfn;
|
||||
do_div(temp, mfd + 1);
|
||||
temp = 2LL * ref_clk * mfi + temp;
|
||||
do_div(temp, pdf + 1);
|
||||
|
||||
return (unsigned long)temp;
|
||||
}
|
||||
|
||||
static struct clk mpll_clk = {
|
||||
.parent = &ckih_clk,
|
||||
.get_rate = get_mpll_clk,
|
||||
};
|
||||
|
||||
static unsigned long _clk_fclk_get_rate(struct clk *clk)
|
||||
{
|
||||
unsigned long parent_rate;
|
||||
u32 div;
|
||||
|
||||
div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
return parent_rate / (div+1);
|
||||
}
|
||||
|
||||
static struct clk fclk_clk = {
|
||||
.parent = &mpll_clk,
|
||||
.get_rate = _clk_fclk_get_rate
|
||||
};
|
||||
|
||||
static unsigned long get_spll_clk(struct clk *clk)
|
||||
{
|
||||
uint32_t reg;
|
||||
unsigned long ref_clk;
|
||||
unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
|
||||
unsigned long long temp;
|
||||
|
||||
ref_clk = clk_get_rate(clk->parent);
|
||||
|
||||
reg = __raw_readl(CCM_SPCTL0);
|
||||
pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
|
||||
mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
|
||||
mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
|
||||
mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
|
||||
|
||||
mfi = (mfi <= 5) ? 5 : mfi;
|
||||
temp = 2LL * ref_clk * mfn;
|
||||
do_div(temp, mfd + 1);
|
||||
temp = 2LL * ref_clk * mfi + temp;
|
||||
do_div(temp, pdf + 1);
|
||||
|
||||
return (unsigned long)temp;
|
||||
}
|
||||
|
||||
static struct clk spll_clk = {
|
||||
.parent = &ckih_clk,
|
||||
.get_rate = get_spll_clk,
|
||||
.enable = _clk_spll_enable,
|
||||
.disable = _clk_spll_disable,
|
||||
};
|
||||
|
||||
static unsigned long get_hclk_clk(struct clk *clk)
|
||||
{
|
||||
unsigned long rate;
|
||||
unsigned long bclk_pdf;
|
||||
|
||||
bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
|
||||
>> CCM_CSCR_BCLK_OFFSET;
|
||||
|
||||
rate = clk_get_rate(clk->parent);
|
||||
return rate / (bclk_pdf + 1);
|
||||
}
|
||||
|
||||
static struct clk hclk_clk = {
|
||||
.parent = &fclk_clk,
|
||||
.get_rate = get_hclk_clk,
|
||||
};
|
||||
|
||||
static unsigned long get_ipg_clk(struct clk *clk)
|
||||
{
|
||||
unsigned long rate;
|
||||
unsigned long ipg_pdf;
|
||||
|
||||
ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
|
||||
|
||||
rate = clk_get_rate(clk->parent);
|
||||
return rate / (ipg_pdf + 1);
|
||||
}
|
||||
|
||||
static struct clk ipg_clk = {
|
||||
.parent = &hclk_clk,
|
||||
.get_rate = get_ipg_clk,
|
||||
};
|
||||
|
||||
static unsigned long _clk_perclkx_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned long perclk_pdf;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
if (clk->id < 0 || clk->id > 3)
|
||||
return 0;
|
||||
|
||||
perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
|
||||
|
||||
return parent_rate / (perclk_pdf + 1);
|
||||
}
|
||||
|
||||
static struct clk per_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &mpll_clk,
|
||||
.get_rate = _clk_perclkx_recalc,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &mpll_clk,
|
||||
.get_rate = _clk_perclkx_recalc,
|
||||
}, {
|
||||
.id = 2,
|
||||
.parent = &mpll_clk,
|
||||
.round_rate = _clk_perclkx_round_rate,
|
||||
.set_rate = _clk_perclkx_set_rate,
|
||||
.get_rate = _clk_perclkx_recalc,
|
||||
/* Enable/Disable done via lcd_clkc[1] */
|
||||
}, {
|
||||
.id = 3,
|
||||
.parent = &mpll_clk,
|
||||
.round_rate = _clk_perclkx_round_rate,
|
||||
.set_rate = _clk_perclkx_set_rate,
|
||||
.get_rate = _clk_perclkx_recalc,
|
||||
/* Enable/Disable done via csi_clk[1] */
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk uart_ipg_clk[];
|
||||
|
||||
static struct clk uart_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &uart_ipg_clk[0],
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &uart_ipg_clk[1],
|
||||
}, {
|
||||
.id = 2,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &uart_ipg_clk[2],
|
||||
}, {
|
||||
.id = 3,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &uart_ipg_clk[3],
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk uart_ipg_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_UART1_REG,
|
||||
.enable_shift = CCM_PCCR_UART1_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_UART2_REG,
|
||||
.enable_shift = CCM_PCCR_UART2_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 2,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_UART3_REG,
|
||||
.enable_shift = CCM_PCCR_UART3_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 3,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_UART4_REG,
|
||||
.enable_shift = CCM_PCCR_UART4_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk gpt_ipg_clk[];
|
||||
|
||||
static struct clk gpt_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &gpt_ipg_clk[0],
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &gpt_ipg_clk[1],
|
||||
}, {
|
||||
.id = 2,
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &gpt_ipg_clk[2],
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk gpt_ipg_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_GPT1_REG,
|
||||
.enable_shift = CCM_PCCR_GPT1_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_GPT2_REG,
|
||||
.enable_shift = CCM_PCCR_GPT2_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 2,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_GPT3_REG,
|
||||
.enable_shift = CCM_PCCR_GPT3_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk pwm_clk[] = {
|
||||
{
|
||||
.parent = &per_clk[0],
|
||||
.secondary = &pwm_clk[1],
|
||||
}, {
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_PWM_REG,
|
||||
.enable_shift = CCM_PCCR_PWM_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk sdhc_ipg_clk[];
|
||||
|
||||
static struct clk sdhc_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &per_clk[1],
|
||||
.secondary = &sdhc_ipg_clk[0],
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &per_clk[1],
|
||||
.secondary = &sdhc_ipg_clk[1],
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk sdhc_ipg_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SDHC1_REG,
|
||||
.enable_shift = CCM_PCCR_SDHC1_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SDHC2_REG,
|
||||
.enable_shift = CCM_PCCR_SDHC2_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk cspi_ipg_clk[];
|
||||
|
||||
static struct clk cspi_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &per_clk[1],
|
||||
.secondary = &cspi_ipg_clk[0],
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &per_clk[1],
|
||||
.secondary = &cspi_ipg_clk[1],
|
||||
}, {
|
||||
.id = 2,
|
||||
.parent = &per_clk[1],
|
||||
.secondary = &cspi_ipg_clk[2],
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk cspi_ipg_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_CSPI1_REG,
|
||||
.enable_shift = CCM_PCCR_CSPI1_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_CSPI2_REG,
|
||||
.enable_shift = CCM_PCCR_CSPI2_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 3,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_CSPI3_REG,
|
||||
.enable_shift = CCM_PCCR_CSPI3_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk lcdc_clk[] = {
|
||||
{
|
||||
.parent = &per_clk[2],
|
||||
.secondary = &lcdc_clk[1],
|
||||
.round_rate = _clk_parent_round_rate,
|
||||
.set_rate = _clk_parent_set_rate,
|
||||
}, {
|
||||
.parent = &ipg_clk,
|
||||
.secondary = &lcdc_clk[2],
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_LCDC_REG,
|
||||
.enable_shift = CCM_PCCR_LCDC_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_LCDC_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk csi_clk[] = {
|
||||
{
|
||||
.parent = &per_clk[3],
|
||||
.secondary = &csi_clk[1],
|
||||
.round_rate = _clk_parent_round_rate,
|
||||
.set_rate = _clk_parent_set_rate,
|
||||
}, {
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_CSI_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk usb_clk[] = {
|
||||
{
|
||||
.parent = &spll_clk,
|
||||
.get_rate = _clk_usb_recalc,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_USBOTG_REG,
|
||||
.enable_shift = CCM_PCCR_USBOTG_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}
|
||||
};
|
||||
|
||||
static struct clk ssi_ipg_clk[];
|
||||
|
||||
static struct clk ssi_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &mpll_clk,
|
||||
.secondary = &ssi_ipg_clk[0],
|
||||
.get_rate = _clk_ssi1_recalc,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SSI1_BAUD_REG,
|
||||
.enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &mpll_clk,
|
||||
.secondary = &ssi_ipg_clk[1],
|
||||
.get_rate = _clk_ssi2_recalc,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SSI2_BAUD_REG,
|
||||
.enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk ssi_ipg_clk[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SSI1_REG,
|
||||
.enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}, {
|
||||
.id = 1,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SSI2_REG,
|
||||
.enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct clk nfc_clk = {
|
||||
.parent = &fclk_clk,
|
||||
.get_rate = _clk_nfc_recalc,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_NFC_REG,
|
||||
.enable_shift = CCM_PCCR_NFC_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk dma_clk[] = {
|
||||
{
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_DMA_REG,
|
||||
.enable_shift = CCM_PCCR_DMA_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
.secondary = &dma_clk[1],
|
||||
}, {
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_DMA_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk brom_clk = {
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_BROM_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk emma_clk[] = {
|
||||
{
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_EMMA_REG,
|
||||
.enable_shift = CCM_PCCR_EMMA_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
.secondary = &emma_clk[1],
|
||||
}, {
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_EMMA_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}
|
||||
};
|
||||
|
||||
static struct clk slcdc_clk[] = {
|
||||
{
|
||||
.parent = &hclk_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_SLCDC_REG,
|
||||
.enable_shift = CCM_PCCR_SLCDC_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
.secondary = &slcdc_clk[1],
|
||||
}, {
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
|
||||
.enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
}
|
||||
};
|
||||
|
||||
static struct clk wdog_clk = {
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_WDT_REG,
|
||||
.enable_shift = CCM_PCCR_WDT_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk gpio_clk = {
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_GPIO_REG,
|
||||
.enable_shift = CCM_PCCR_GPIO_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk i2c_clk = {
|
||||
.id = 0,
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_I2C1_REG,
|
||||
.enable_shift = CCM_PCCR_I2C1_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk kpp_clk = {
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_KPP_REG,
|
||||
.enable_shift = CCM_PCCR_KPP_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk owire_clk = {
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_OWIRE_REG,
|
||||
.enable_shift = CCM_PCCR_OWIRE_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static struct clk rtc_clk = {
|
||||
.parent = &ipg_clk,
|
||||
.enable = _clk_enable,
|
||||
.enable_reg = CCM_PCCR_RTC_REG,
|
||||
.enable_shift = CCM_PCCR_RTC_OFFSET,
|
||||
.disable = _clk_disable,
|
||||
};
|
||||
|
||||
static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 div;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
div = parent_rate / rate;
|
||||
if (parent_rate % rate)
|
||||
div++;
|
||||
|
||||
if (div > 8)
|
||||
div = 8;
|
||||
|
||||
return parent_rate / div;
|
||||
}
|
||||
|
||||
static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 reg;
|
||||
u32 div;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
div = parent_rate / rate;
|
||||
|
||||
if (div > 8 || div < 1 || ((parent_rate / div) != rate))
|
||||
return -EINVAL;
|
||||
div--;
|
||||
|
||||
reg = __raw_readl(CCM_PCDR0);
|
||||
|
||||
if (clk->parent == &usb_clk[0]) {
|
||||
reg &= ~CCM_PCDR0_48MDIV_MASK;
|
||||
reg |= div << CCM_PCDR0_48MDIV_OFFSET;
|
||||
}
|
||||
__raw_writel(reg, CCM_PCDR0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long _clk_clko_recalc(struct clk *clk)
|
||||
{
|
||||
u32 div = 0;
|
||||
unsigned long parent_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
if (clk->parent == &usb_clk[0]) /* 48M */
|
||||
div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
|
||||
>> CCM_PCDR0_48MDIV_OFFSET;
|
||||
div++;
|
||||
|
||||
return parent_rate / div;
|
||||
}
|
||||
|
||||
static struct clk clko_clk;
|
||||
|
||||
static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
|
||||
|
||||
if (parent == &ckil_clk)
|
||||
reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &fpm_clk)
|
||||
reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &ckih_clk)
|
||||
reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == mpll_clk.parent)
|
||||
reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == spll_clk.parent)
|
||||
reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &mpll_clk)
|
||||
reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &spll_clk)
|
||||
reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &fclk_clk)
|
||||
reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &hclk_clk)
|
||||
reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &ipg_clk)
|
||||
reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &per_clk[0])
|
||||
reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &per_clk[1])
|
||||
reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &per_clk[2])
|
||||
reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &per_clk[3])
|
||||
reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &ssi_clk[0])
|
||||
reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &ssi_clk[1])
|
||||
reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &nfc_clk)
|
||||
reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &usb_clk[0])
|
||||
reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else if (parent == &clko_clk)
|
||||
reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
__raw_writel(reg, CCM_CCSR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk clko_clk = {
|
||||
.get_rate = _clk_clko_recalc,
|
||||
.set_rate = _clk_clko_set_rate,
|
||||
.round_rate = _clk_clko_round_rate,
|
||||
.set_parent = _clk_clko_set_parent,
|
||||
};
|
||||
|
||||
|
||||
#define _REGISTER_CLOCK(d, n, c) \
|
||||
{ \
|
||||
.dev_id = d, \
|
||||
.con_id = n, \
|
||||
.clk = &c, \
|
||||
},
|
||||
static struct clk_lookup lookups[] __initdata = {
|
||||
/* It's unlikely that any driver wants one of them directly:
|
||||
_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
|
||||
_REGISTER_CLOCK(NULL, "ckil", ckil_clk)
|
||||
_REGISTER_CLOCK(NULL, "fpm", fpm_clk)
|
||||
_REGISTER_CLOCK(NULL, "mpll", mpll_clk)
|
||||
_REGISTER_CLOCK(NULL, "spll", spll_clk)
|
||||
_REGISTER_CLOCK(NULL, "fclk", fclk_clk)
|
||||
_REGISTER_CLOCK(NULL, "hclk", hclk_clk)
|
||||
_REGISTER_CLOCK(NULL, "ipg", ipg_clk)
|
||||
*/
|
||||
_REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
|
||||
_REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
|
||||
_REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
|
||||
_REGISTER_CLOCK(NULL, "clko", clko_clk)
|
||||
_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
|
||||
_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
|
||||
_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
|
||||
_REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
|
||||
_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
|
||||
_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
|
||||
_REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
|
||||
_REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
|
||||
_REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
|
||||
_REGISTER_CLOCK(NULL, "lcdc", lcdc_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "usb", usb_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
|
||||
_REGISTER_CLOCK(NULL, "nfc", nfc_clk)
|
||||
_REGISTER_CLOCK(NULL, "dma", dma_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "brom", brom_clk)
|
||||
_REGISTER_CLOCK(NULL, "emma", emma_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
|
||||
_REGISTER_CLOCK(NULL, "wdog", wdog_clk)
|
||||
_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
|
||||
_REGISTER_CLOCK(NULL, "i2c", i2c_clk)
|
||||
_REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
|
||||
_REGISTER_CLOCK(NULL, "owire", owire_clk)
|
||||
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
|
||||
};
|
||||
|
||||
/*
|
||||
* must be called very early to get information about the
|
||||
* available clock rate when the timer framework starts
|
||||
*/
|
||||
int __init mx21_clocks_init(unsigned long lref, unsigned long href)
|
||||
{
|
||||
int i;
|
||||
u32 cscr;
|
||||
|
||||
external_low_reference = lref;
|
||||
external_high_reference = href;
|
||||
|
||||
/* detect clock reference for both system PLL */
|
||||
cscr = CSCR();
|
||||
if (cscr & CCM_CSCR_MCU)
|
||||
mpll_clk.parent = &ckih_clk;
|
||||
else
|
||||
mpll_clk.parent = &fpm_clk;
|
||||
|
||||
if (cscr & CCM_CSCR_SP)
|
||||
spll_clk.parent = &ckih_clk;
|
||||
else
|
||||
spll_clk.parent = &fpm_clk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lookups); i++)
|
||||
clkdev_add(&lookups[i]);
|
||||
|
||||
/* Turn off all clock gates */
|
||||
__raw_writel(0, CCM_PCCR0);
|
||||
__raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
|
||||
|
||||
/* This turns of the serial PLL as well */
|
||||
spll_clk.disable(&spll_clk);
|
||||
|
||||
/* This will propagate to all children and init all the clock rates. */
|
||||
clk_enable(&per_clk[0]);
|
||||
clk_enable(&gpio_clk);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LL_CONSOLE
|
||||
clk_enable(&uart_clk[0]);
|
||||
#endif
|
||||
|
||||
mxc_timer_init(&gpt_clk[0]);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -26,11 +26,11 @@
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "crm_regs.h"
|
||||
|
||||
static int cpu_silicon_rev = -1;
|
||||
static int cpu_partnumber;
|
||||
|
||||
#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
|
||||
|
||||
static void query_silicon_parameter(void)
|
||||
{
|
||||
u32 val;
|
||||
|
@ -38,42 +38,36 @@
|
||||
#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
|
||||
#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
|
||||
|
||||
#define CCM_CSCR_USB_OFFSET 28
|
||||
#define CCM_CSCR_USB_MASK (0x7 << 28)
|
||||
#define CCM_CSCR_PRESC_OFFSET 29
|
||||
#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
|
||||
|
||||
#define CCM_CSCR_USB_OFFSET 26
|
||||
#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
|
||||
#define CCM_CSCR_SD_OFFSET 24
|
||||
#define CCM_CSCR_SD_MASK (0x3 << 24)
|
||||
#define CCM_CSCR_SSI2 (1 << 23)
|
||||
#define CCM_CSCR_SSI2_OFFSET 23
|
||||
#define CCM_CSCR_SSI1 (1 << 22)
|
||||
#define CCM_CSCR_SSI1_OFFSET 22
|
||||
#define CCM_CSCR_VPU (1 << 21)
|
||||
#define CCM_CSCR_VPU_OFFSET 21
|
||||
#define CCM_CSCR_MSHC (1 << 20)
|
||||
#define CCM_CSCR_SPLLRES (1 << 19)
|
||||
#define CCM_CSCR_MPLLRES (1 << 18)
|
||||
#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
|
||||
#define CCM_CSCR_SPLLRES (1 << 22)
|
||||
#define CCM_CSCR_MPLLRES (1 << 21)
|
||||
#define CCM_CSCR_SSI2_OFFSET 20
|
||||
#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
|
||||
#define CCM_CSCR_SSI1_OFFSET 19
|
||||
#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
|
||||
#define CCM_CSCR_FIR_OFFSET 18
|
||||
#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
|
||||
#define CCM_CSCR_SP (1 << 17)
|
||||
#define CCM_CSCR_MCU (1 << 16)
|
||||
/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
|
||||
#define CCM_CSCR_ARM_SRC (1 << 15)
|
||||
#define CCM_CSCR_ARM_OFFSET 12
|
||||
#define CCM_CSCR_ARM_MASK (0x3 << 12)
|
||||
/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
|
||||
#define CCM_CSCR_PRESC_OFFSET 13
|
||||
#define CCM_CSCR_PRESC_MASK (0x7 << 13)
|
||||
#define CCM_CSCR_BCLK_OFFSET 9
|
||||
#define CCM_CSCR_BCLK_MASK (0xf << 9)
|
||||
#define CCM_CSCR_IPDIV_OFFSET 8
|
||||
#define CCM_CSCR_IPDIV (1 << 8)
|
||||
/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
|
||||
#define CCM_CSCR_AHB_OFFSET 8
|
||||
#define CCM_CSCR_AHB_MASK (0x3 << 8)
|
||||
/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
|
||||
#define CCM_CSCR_BCLK_OFFSET 10
|
||||
#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
|
||||
#define CCM_CSCR_IPDIV_OFFSET 9
|
||||
#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
|
||||
|
||||
#define CCM_CSCR_OSC26MDIV (1 << 4)
|
||||
#define CCM_CSCR_OSC26M (1 << 3)
|
||||
#define CCM_CSCR_FPM (1 << 2)
|
||||
#define CCM_CSCR_SPEN (1 << 1)
|
||||
#define CCM_CSCR_MPEN 1
|
||||
|
||||
|
||||
|
||||
#define CCM_MPCTL0_CPLM (1 << 31)
|
||||
#define CCM_MPCTL0_PD_OFFSET 26
|
||||
#define CCM_MPCTL0_PD_MASK (0xf << 26)
|
||||
@ -109,25 +103,14 @@
|
||||
|
||||
#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
|
||||
#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
|
||||
#define CCM_PCDR0_CLKO_EN 25
|
||||
#define CCM_PCDR0_CLKODIV_OFFSET 22
|
||||
#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22)
|
||||
#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
|
||||
#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
|
||||
/*The difinition for i.MX27 TO2*/
|
||||
#define CCM_PCDR0_VPUDIV2_OFFSET 10
|
||||
#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10)
|
||||
#define CCM_PCDR0_NFCDIV2_OFFSET 6
|
||||
#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6)
|
||||
#define CCM_PCDR0_MSHCDIV2_MASK 0x3f
|
||||
/*The difinition for i.MX27 TO2*/
|
||||
#define CCM_PCDR0_NFCDIV_OFFSET 12
|
||||
#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
|
||||
#define CCM_PCDR0_VPUDIV_OFFSET 8
|
||||
#define CCM_PCDR0_VPUDIV_MASK (0xf << 8)
|
||||
#define CCM_PCDR0_MSHCDIV_OFFSET 0
|
||||
#define CCM_PCDR0_MSHCDIV_MASK 0x1f
|
||||
|
||||
#define CCM_PCDR0_48MDIV_OFFSET 5
|
||||
#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
|
||||
#define CCM_PCDR0_FIRIDIV_OFFSET 0
|
||||
#define CCM_PCDR0_FIRIDIV_MASK 0x1f
|
||||
#define CCM_PCDR1_PERDIV4_OFFSET 24
|
||||
#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
|
||||
#define CCM_PCDR1_PERDIV3_OFFSET 16
|
||||
@ -137,133 +120,135 @@
|
||||
#define CCM_PCDR1_PERDIV1_OFFSET 0
|
||||
#define CCM_PCDR1_PERDIV1_MASK 0x3f
|
||||
|
||||
#define CCM_PCCR0_CSPI1_OFFSET 31
|
||||
#define CCM_PCCR0_CSPI1_MASK (1 << 31)
|
||||
#define CCM_PCCR0_CSPI2_OFFSET 30
|
||||
#define CCM_PCCR0_CSPI2_MASK (1 << 30)
|
||||
#define CCM_PCCR0_CSPI3_OFFSET 29
|
||||
#define CCM_PCCR0_CSPI3_MASK (1 << 29)
|
||||
#define CCM_PCCR0_DMA_OFFSET 28
|
||||
#define CCM_PCCR0_DMA_MASK (1 << 28)
|
||||
#define CCM_PCCR0_EMMA_OFFSET 27
|
||||
#define CCM_PCCR0_EMMA_MASK (1 << 27)
|
||||
#define CCM_PCCR0_FEC_OFFSET 26
|
||||
#define CCM_PCCR0_FEC_MASK (1 << 26)
|
||||
#define CCM_PCCR0_GPIO_OFFSET 25
|
||||
#define CCM_PCCR0_GPIO_MASK (1 << 25)
|
||||
#define CCM_PCCR0_GPT1_OFFSET 24
|
||||
#define CCM_PCCR0_GPT1_MASK (1 << 24)
|
||||
#define CCM_PCCR0_GPT2_OFFSET 23
|
||||
#define CCM_PCCR0_GPT2_MASK (1 << 23)
|
||||
#define CCM_PCCR0_GPT3_OFFSET 22
|
||||
#define CCM_PCCR0_GPT3_MASK (1 << 22)
|
||||
#define CCM_PCCR0_GPT4_OFFSET 21
|
||||
#define CCM_PCCR0_GPT4_MASK (1 << 21)
|
||||
#define CCM_PCCR0_GPT5_OFFSET 20
|
||||
#define CCM_PCCR0_GPT5_MASK (1 << 20)
|
||||
#define CCM_PCCR0_GPT6_OFFSET 19
|
||||
#define CCM_PCCR0_GPT6_MASK (1 << 19)
|
||||
#define CCM_PCCR0_I2C1_OFFSET 18
|
||||
#define CCM_PCCR0_I2C1_MASK (1 << 18)
|
||||
#define CCM_PCCR0_I2C2_OFFSET 17
|
||||
#define CCM_PCCR0_I2C2_MASK (1 << 17)
|
||||
#define CCM_PCCR0_IIM_OFFSET 16
|
||||
#define CCM_PCCR0_IIM_MASK (1 << 16)
|
||||
#define CCM_PCCR0_KPP_OFFSET 15
|
||||
#define CCM_PCCR0_KPP_MASK (1 << 15)
|
||||
#define CCM_PCCR0_LCDC_OFFSET 14
|
||||
#define CCM_PCCR0_LCDC_MASK (1 << 14)
|
||||
#define CCM_PCCR0_MSHC_OFFSET 13
|
||||
#define CCM_PCCR0_MSHC_MASK (1 << 13)
|
||||
#define CCM_PCCR0_OWIRE_OFFSET 12
|
||||
#define CCM_PCCR0_OWIRE_MASK (1 << 12)
|
||||
#define CCM_PCCR0_PWM_OFFSET 11
|
||||
#define CCM_PCCR0_PWM_MASK (1 << 11)
|
||||
#define CCM_PCCR0_RTC_OFFSET 9
|
||||
#define CCM_PCCR0_RTC_MASK (1 << 9)
|
||||
#define CCM_PCCR0_RTIC_OFFSET 8
|
||||
#define CCM_PCCR0_RTIC_MASK (1 << 8)
|
||||
#define CCM_PCCR0_SAHARA_OFFSET 7
|
||||
#define CCM_PCCR0_SAHARA_MASK (1 << 7)
|
||||
#define CCM_PCCR0_SCC_OFFSET 6
|
||||
#define CCM_PCCR0_SCC_MASK (1 << 6)
|
||||
#define CCM_PCCR0_SDHC1_OFFSET 5
|
||||
#define CCM_PCCR0_SDHC1_MASK (1 << 5)
|
||||
#define CCM_PCCR0_SDHC2_OFFSET 4
|
||||
#define CCM_PCCR0_SDHC2_MASK (1 << 4)
|
||||
#define CCM_PCCR0_SDHC3_OFFSET 3
|
||||
#define CCM_PCCR0_SDHC3_MASK (1 << 3)
|
||||
#define CCM_PCCR0_SLCDC_OFFSET 2
|
||||
#define CCM_PCCR0_SLCDC_MASK (1 << 2)
|
||||
#define CCM_PCCR0_SSI1_IPG_OFFSET 1
|
||||
#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1)
|
||||
#define CCM_PCCR0_SSI2_IPG_OFFSET 0
|
||||
#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0)
|
||||
#define CCM_PCCR_HCLK_CSI_OFFSET 31
|
||||
#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_DMA_OFFSET 30
|
||||
#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_BROM_OFFSET 28
|
||||
#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_EMMA_OFFSET 27
|
||||
#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_LCDC_OFFSET 26
|
||||
#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
|
||||
#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
|
||||
#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
|
||||
#define CCM_PCCR_HCLK_BMI_OFFSET 23
|
||||
#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
|
||||
#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
|
||||
#define CCM_PCCR_PERCLK4_OFFSET 22
|
||||
#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SLCDC_OFFSET 21
|
||||
#define CCM_PCCR_SLCDC_REG CCM_PCCR0
|
||||
#define CCM_PCCR_FIRI_BAUD_OFFSET 20
|
||||
#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
|
||||
#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
|
||||
#define CCM_PCCR_NFC_OFFSET 19
|
||||
#define CCM_PCCR_NFC_REG CCM_PCCR0
|
||||
#define CCM_PCCR_LCDC_OFFSET 18
|
||||
#define CCM_PCCR_LCDC_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SSI1_BAUD_OFFSET 17
|
||||
#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SSI2_BAUD_OFFSET 16
|
||||
#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
|
||||
#define CCM_PCCR_EMMA_OFFSET 15
|
||||
#define CCM_PCCR_EMMA_REG CCM_PCCR0
|
||||
#define CCM_PCCR_USBOTG_OFFSET 14
|
||||
#define CCM_PCCR_USBOTG_REG CCM_PCCR0
|
||||
#define CCM_PCCR_DMA_OFFSET 13
|
||||
#define CCM_PCCR_DMA_REG CCM_PCCR0
|
||||
#define CCM_PCCR_I2C1_OFFSET 12
|
||||
#define CCM_PCCR_I2C1_REG CCM_PCCR0
|
||||
#define CCM_PCCR_GPIO_OFFSET 11
|
||||
#define CCM_PCCR_GPIO_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SDHC2_OFFSET 10
|
||||
#define CCM_PCCR_SDHC2_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SDHC1_OFFSET 9
|
||||
#define CCM_PCCR_SDHC1_REG CCM_PCCR0
|
||||
#define CCM_PCCR_FIRI_OFFSET 8
|
||||
#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
|
||||
#define CCM_PCCR_FIRI_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SSI2_IPG_OFFSET 7
|
||||
#define CCM_PCCR_SSI2_REG CCM_PCCR0
|
||||
#define CCM_PCCR_SSI1_IPG_OFFSET 6
|
||||
#define CCM_PCCR_SSI1_REG CCM_PCCR0
|
||||
#define CCM_PCCR_CSPI2_OFFSET 5
|
||||
#define CCM_PCCR_CSPI2_REG CCM_PCCR0
|
||||
#define CCM_PCCR_CSPI1_OFFSET 4
|
||||
#define CCM_PCCR_CSPI1_REG CCM_PCCR0
|
||||
#define CCM_PCCR_UART4_OFFSET 3
|
||||
#define CCM_PCCR_UART4_REG CCM_PCCR0
|
||||
#define CCM_PCCR_UART3_OFFSET 2
|
||||
#define CCM_PCCR_UART3_REG CCM_PCCR0
|
||||
#define CCM_PCCR_UART2_OFFSET 1
|
||||
#define CCM_PCCR_UART2_REG CCM_PCCR0
|
||||
#define CCM_PCCR_UART1_OFFSET 0
|
||||
#define CCM_PCCR_UART1_REG CCM_PCCR0
|
||||
|
||||
#define CCM_PCCR_OWIRE_OFFSET 31
|
||||
#define CCM_PCCR_OWIRE_REG CCM_PCCR1
|
||||
#define CCM_PCCR_KPP_OFFSET 30
|
||||
#define CCM_PCCR_KPP_REG CCM_PCCR1
|
||||
#define CCM_PCCR_RTC_OFFSET 29
|
||||
#define CCM_PCCR_RTC_REG CCM_PCCR1
|
||||
#define CCM_PCCR_PWM_OFFSET 28
|
||||
#define CCM_PCCR_PWM_REG CCM_PCCR1
|
||||
#define CCM_PCCR_GPT3_OFFSET 27
|
||||
#define CCM_PCCR_GPT3_REG CCM_PCCR1
|
||||
#define CCM_PCCR_GPT2_OFFSET 26
|
||||
#define CCM_PCCR_GPT2_REG CCM_PCCR1
|
||||
#define CCM_PCCR_GPT1_OFFSET 25
|
||||
#define CCM_PCCR_GPT1_REG CCM_PCCR1
|
||||
#define CCM_PCCR_WDT_OFFSET 24
|
||||
#define CCM_PCCR_WDT_REG CCM_PCCR1
|
||||
#define CCM_PCCR_CSPI3_OFFSET 23
|
||||
#define CCM_PCCR_CSPI3_REG CCM_PCCR1
|
||||
|
||||
#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
|
||||
#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
|
||||
#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
|
||||
#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
|
||||
#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
|
||||
#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
|
||||
#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
|
||||
#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
|
||||
#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
|
||||
#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
|
||||
#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
|
||||
#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
|
||||
#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
|
||||
#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
|
||||
#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
|
||||
#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
|
||||
#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
|
||||
#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
|
||||
#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
|
||||
#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
|
||||
#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
|
||||
#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
|
||||
#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
|
||||
#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
|
||||
#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
|
||||
#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
|
||||
#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
|
||||
#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
|
||||
#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
|
||||
#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
|
||||
#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
|
||||
#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
|
||||
#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
|
||||
#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
|
||||
#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
|
||||
#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
|
||||
#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
|
||||
|
||||
#define CCM_PCCR1_UART1_OFFSET 31
|
||||
#define CCM_PCCR1_UART1_MASK (1 << 31)
|
||||
#define CCM_PCCR1_UART2_OFFSET 30
|
||||
#define CCM_PCCR1_UART2_MASK (1 << 30)
|
||||
#define CCM_PCCR1_UART3_OFFSET 29
|
||||
#define CCM_PCCR1_UART3_MASK (1 << 29)
|
||||
#define CCM_PCCR1_UART4_OFFSET 28
|
||||
#define CCM_PCCR1_UART4_MASK (1 << 28)
|
||||
#define CCM_PCCR1_UART5_OFFSET 27
|
||||
#define CCM_PCCR1_UART5_MASK (1 << 27)
|
||||
#define CCM_PCCR1_UART6_OFFSET 26
|
||||
#define CCM_PCCR1_UART6_MASK (1 << 26)
|
||||
#define CCM_PCCR1_USBOTG_OFFSET 25
|
||||
#define CCM_PCCR1_USBOTG_MASK (1 << 25)
|
||||
#define CCM_PCCR1_WDT_OFFSET 24
|
||||
#define CCM_PCCR1_WDT_MASK (1 << 24)
|
||||
#define CCM_PCCR1_HCLK_ATA_OFFSET 23
|
||||
#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23)
|
||||
#define CCM_PCCR1_HCLK_BROM_OFFSET 22
|
||||
#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22)
|
||||
#define CCM_PCCR1_HCLK_CSI_OFFSET 21
|
||||
#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21)
|
||||
#define CCM_PCCR1_HCLK_DMA_OFFSET 20
|
||||
#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20)
|
||||
#define CCM_PCCR1_HCLK_EMI_OFFSET 19
|
||||
#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19)
|
||||
#define CCM_PCCR1_HCLK_EMMA_OFFSET 18
|
||||
#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18)
|
||||
#define CCM_PCCR1_HCLK_FEC_OFFSET 17
|
||||
#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17)
|
||||
#define CCM_PCCR1_HCLK_VPU_OFFSET 16
|
||||
#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16)
|
||||
#define CCM_PCCR1_HCLK_LCDC_OFFSET 15
|
||||
#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15)
|
||||
#define CCM_PCCR1_HCLK_RTIC_OFFSET 14
|
||||
#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14)
|
||||
#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13
|
||||
#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13)
|
||||
#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12
|
||||
#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12)
|
||||
#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11
|
||||
#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11)
|
||||
#define CCM_PCCR1_PERCLK1_OFFSET 10
|
||||
#define CCM_PCCR1_PERCLK1_MASK (1 << 10)
|
||||
#define CCM_PCCR1_PERCLK2_OFFSET 9
|
||||
#define CCM_PCCR1_PERCLK2_MASK (1 << 9)
|
||||
#define CCM_PCCR1_PERCLK3_OFFSET 8
|
||||
#define CCM_PCCR1_PERCLK3_MASK (1 << 8)
|
||||
#define CCM_PCCR1_PERCLK4_OFFSET 7
|
||||
#define CCM_PCCR1_PERCLK4_MASK (1 << 7)
|
||||
#define CCM_PCCR1_VPU_BAUD_OFFSET 6
|
||||
#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6)
|
||||
#define CCM_PCCR1_SSI1_BAUD_OFFSET 5
|
||||
#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5)
|
||||
#define CCM_PCCR1_SSI2_BAUD_OFFSET 4
|
||||
#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4)
|
||||
#define CCM_PCCR1_NFC_BAUD_OFFSET 3
|
||||
#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3)
|
||||
#define CCM_PCCR1_MSHC_BAUD_OFFSET 2
|
||||
#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2)
|
||||
|
||||
#define CCM_CCSR_32KSR (1 << 15)
|
||||
|
||||
#define CCM_CCSR_CLKMODE1 (1 << 9)
|
||||
#define CCM_CCSR_CLKMODE0 (1 << 8)
|
||||
|
||||
#define CCM_CCSR_CLKOSEL_OFFSET 0
|
||||
#define CCM_CCSR_CLKOSEL_MASK 0x1f
|
||||
|
||||
|
@ -34,6 +34,10 @@
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/mmc.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/*
|
||||
* Resource definition for the MXC IrDA
|
||||
@ -225,37 +229,217 @@ struct platform_device mxc_nand_device = {
|
||||
.resource = mxc_nand_resources,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FB_IMX
|
||||
/*
|
||||
* lcdc:
|
||||
* - i.MX1: the basic controller
|
||||
* - i.MX21: to be checked
|
||||
* - i.MX27: like i.MX1, with slightly variations
|
||||
*/
|
||||
static struct resource mxc_fb[] = {
|
||||
{
|
||||
.start = LCDC_BASE_ADDR,
|
||||
.end = LCDC_BASE_ADDR + 0xFFF,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MXC_INT_LCDC,
|
||||
.end = MXC_INT_LCDC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
/* mxc lcd driver */
|
||||
struct platform_device mxc_fb_device = {
|
||||
.name = "imx-fb",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxc_fb),
|
||||
.resource = mxc_fb,
|
||||
.dev = {
|
||||
.coherent_dma_mask = 0xFFFFFFFF,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_MX27
|
||||
static struct resource mxc_fec_resources[] = {
|
||||
{
|
||||
.start = FEC_BASE_ADDR,
|
||||
.end = FEC_BASE_ADDR + 0xfff,
|
||||
.flags = IORESOURCE_MEM
|
||||
}, {
|
||||
.start = MXC_INT_FEC,
|
||||
.end = MXC_INT_FEC,
|
||||
.flags = IORESOURCE_IRQ
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mxc_fec_device = {
|
||||
.name = "fec",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxc_fec_resources),
|
||||
.resource = mxc_fec_resources,
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct resource mxc_i2c_1_resources[] = {
|
||||
[0] = {
|
||||
.start = I2C_BASE_ADDR,
|
||||
.end = I2C_BASE_ADDR + 0x0fff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = MXC_INT_I2C,
|
||||
.end = MXC_INT_I2C,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
struct platform_device mxc_i2c_device0 = {
|
||||
.name = "imx-i2c",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
|
||||
.resource = mxc_i2c_1_resources
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MACH_MX27
|
||||
static struct resource mxc_i2c_2_resources[] = {
|
||||
[0] = {
|
||||
.start = I2C2_BASE_ADDR,
|
||||
.end = I2C2_BASE_ADDR + 0x0fff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = MXC_INT_I2C2,
|
||||
.end = MXC_INT_I2C2,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
struct platform_device mxc_i2c_device1 = {
|
||||
.name = "imx-i2c",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
|
||||
.resource = mxc_i2c_2_resources
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct resource mxc_pwm_resources[] = {
|
||||
[0] = {
|
||||
.start = PWM_BASE_ADDR,
|
||||
.end = PWM_BASE_ADDR + 0x0fff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = MXC_INT_PWM,
|
||||
.end = MXC_INT_PWM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
struct platform_device mxc_pwm_device = {
|
||||
.name = "mxc_pwm",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxc_pwm_resources),
|
||||
.resource = mxc_pwm_resources
|
||||
};
|
||||
|
||||
/*
|
||||
* Resource definition for the MXC SDHC
|
||||
*/
|
||||
static struct resource mxc_sdhc1_resources[] = {
|
||||
[0] = {
|
||||
.start = SDHC1_BASE_ADDR,
|
||||
.end = SDHC1_BASE_ADDR + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MXC_INT_SDHC1,
|
||||
.end = MXC_INT_SDHC1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = DMA_REQ_SDHC1,
|
||||
.end = DMA_REQ_SDHC1,
|
||||
.flags = IORESOURCE_DMA
|
||||
},
|
||||
};
|
||||
|
||||
static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
|
||||
|
||||
struct platform_device mxc_sdhc_device0 = {
|
||||
.name = "mxc-mmc",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &mxc_sdhc1_dmamask,
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
|
||||
.resource = mxc_sdhc1_resources,
|
||||
};
|
||||
|
||||
static struct resource mxc_sdhc2_resources[] = {
|
||||
[0] = {
|
||||
.start = SDHC2_BASE_ADDR,
|
||||
.end = SDHC2_BASE_ADDR + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MXC_INT_SDHC2,
|
||||
.end = MXC_INT_SDHC2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = DMA_REQ_SDHC2,
|
||||
.end = DMA_REQ_SDHC2,
|
||||
.flags = IORESOURCE_DMA
|
||||
},
|
||||
};
|
||||
|
||||
static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
|
||||
|
||||
struct platform_device mxc_sdhc_device1 = {
|
||||
.name = "mxc-mmc",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.dma_mask = &mxc_sdhc2_dmamask,
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(mxc_sdhc2_resources),
|
||||
.resource = mxc_sdhc2_resources,
|
||||
};
|
||||
|
||||
/* GPIO port description */
|
||||
static struct mxc_gpio_port imx_gpio_ports[] = {
|
||||
[0] = {
|
||||
.chip.label = "gpio-0",
|
||||
.irq = MXC_INT_GPIO,
|
||||
.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0),
|
||||
.base = IO_ADDRESS(GPIO_BASE_ADDR),
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START,
|
||||
},
|
||||
[1] = {
|
||||
.chip.label = "gpio-1",
|
||||
.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1),
|
||||
.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
|
||||
},
|
||||
[2] = {
|
||||
.chip.label = "gpio-2",
|
||||
.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2),
|
||||
.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
|
||||
},
|
||||
[3] = {
|
||||
.chip.label = "gpio-3",
|
||||
.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3),
|
||||
.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
|
||||
},
|
||||
[4] = {
|
||||
.chip.label = "gpio-4",
|
||||
.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4),
|
||||
.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 128,
|
||||
},
|
||||
[5] = {
|
||||
.chip.label = "gpio-5",
|
||||
.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5),
|
||||
.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 160,
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
extern struct platform_device mxc_gpt1;
|
||||
extern struct platform_device mxc_gpt2;
|
||||
extern struct platform_device mxc_gpt3;
|
||||
@ -14,3 +13,10 @@ extern struct platform_device mxc_uart_device4;
|
||||
extern struct platform_device mxc_uart_device5;
|
||||
extern struct platform_device mxc_w1_master_device;
|
||||
extern struct platform_device mxc_nand_device;
|
||||
extern struct platform_device mxc_fb_device;
|
||||
extern struct platform_device mxc_fec_device;
|
||||
extern struct platform_device mxc_pwm_device;
|
||||
extern struct platform_device mxc_i2c_device0;
|
||||
extern struct platform_device mxc_i2c_device1;
|
||||
extern struct platform_device mxc_sdhc_device0;
|
||||
extern struct platform_device mxc_sdhc_device1;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx1-mx2.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/board-mx27ads.h>
|
||||
|
||||
#include "devices.h"
|
||||
@ -135,6 +135,7 @@ static int uart_mxc_port3_exit(struct platform_device *pdev)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(mxc_uart3_pins,
|
||||
ARRAY_SIZE(mxc_uart3_pins));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_uart4_pins[] = {
|
||||
@ -179,6 +180,7 @@ static int uart_mxc_port5_exit(struct platform_device *pdev)
|
||||
|
||||
static struct platform_device *platform_devices[] __initdata = {
|
||||
&mx27ads_nor_mtd_device,
|
||||
&mxc_fec_device,
|
||||
};
|
||||
|
||||
static int mxc_fec_pins[] = {
|
||||
@ -196,7 +198,7 @@ static int mxc_fec_pins[] = {
|
||||
PD11_AOUT_FEC_TX_CLK,
|
||||
PD12_AOUT_FEC_RXD0,
|
||||
PD13_AOUT_FEC_RX_DV,
|
||||
PD14_AOUT_FEC_CLR,
|
||||
PD14_AOUT_FEC_RX_CLK,
|
||||
PD15_AOUT_FEC_COL,
|
||||
PD16_AIN_FEC_TX_ER,
|
||||
PF23_AIN_FEC_TX_EN
|
||||
@ -208,12 +210,6 @@ static void gpio_fec_active(void)
|
||||
ARRAY_SIZE(mxc_fec_pins), "FEC");
|
||||
}
|
||||
|
||||
static void gpio_fec_inactive(void)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(mxc_fec_pins,
|
||||
ARRAY_SIZE(mxc_fec_pins));
|
||||
}
|
||||
|
||||
static struct imxuart_platform_data uart_pdata[] = {
|
||||
{
|
||||
.init = uart_mxc_port0_init,
|
||||
@ -263,11 +259,10 @@ static void __init mx27ads_timer_init(void)
|
||||
if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
|
||||
fref = 27000000;
|
||||
|
||||
mxc_clocks_init(fref);
|
||||
mxc_timer_init("gpt_clk.0");
|
||||
mx27_clocks_init(fref);
|
||||
}
|
||||
|
||||
struct sys_timer mx27ads_timer = {
|
||||
static struct sys_timer mx27ads_timer = {
|
||||
.init = mx27ads_timer_init,
|
||||
};
|
||||
|
||||
@ -280,7 +275,7 @@ static struct map_desc mx27ads_io_desc[] __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
void __init mx27ads_map_io(void)
|
||||
static void __init mx27ads_map_io(void)
|
||||
{
|
||||
mxc_map_io();
|
||||
iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
|
||||
|
@ -20,11 +20,18 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mtd/plat-ram.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/at24.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/iomux-mx1-mx2.h>
|
||||
#include <mach/iomux.h>
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
#include <mach/i2c.h>
|
||||
#endif
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/board-pcm038.h>
|
||||
@ -121,10 +128,10 @@ static int uart_mxc_port1_exit(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS,
|
||||
static int mxc_uart2_pins[] = { PE8_PF_UART3_TXD,
|
||||
PE9_PF_UART3_RXD,
|
||||
PE10_PF_UART3_CTS,
|
||||
PE9_PF_UART3_RXD };
|
||||
PE11_PF_UART3_RTS };
|
||||
|
||||
static int uart_mxc_port2_init(struct platform_device *pdev)
|
||||
{
|
||||
@ -170,7 +177,7 @@ static int mxc_fec_pins[] = {
|
||||
PD11_AOUT_FEC_TX_CLK,
|
||||
PD12_AOUT_FEC_RXD0,
|
||||
PD13_AOUT_FEC_RX_DV,
|
||||
PD14_AOUT_FEC_CLR,
|
||||
PD14_AOUT_FEC_RX_CLK,
|
||||
PD15_AOUT_FEC_COL,
|
||||
PD16_AIN_FEC_TX_ER,
|
||||
PF23_AIN_FEC_TX_EN
|
||||
@ -182,12 +189,6 @@ static void gpio_fec_active(void)
|
||||
ARRAY_SIZE(mxc_fec_pins), "FEC");
|
||||
}
|
||||
|
||||
static void gpio_fec_inactive(void)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(mxc_fec_pins,
|
||||
ARRAY_SIZE(mxc_fec_pins));
|
||||
}
|
||||
|
||||
static struct mxc_nand_platform_data pcm038_nand_board_info = {
|
||||
.width = 1,
|
||||
.hw_ecc = 1,
|
||||
@ -196,6 +197,7 @@ static struct mxc_nand_platform_data pcm038_nand_board_info = {
|
||||
static struct platform_device *platform_devices[] __initdata = {
|
||||
&pcm038_nor_mtd_device,
|
||||
&mxc_w1_master_device,
|
||||
&mxc_fec_device,
|
||||
&pcm038_sram_mtd_device,
|
||||
};
|
||||
|
||||
@ -208,6 +210,51 @@ static void __init pcm038_init_sram(void)
|
||||
__raw_writel(0x22220a00, CSCR_A(1));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
static int mxc_i2c1_pins[] = {
|
||||
PC5_PF_I2C2_SDA,
|
||||
PC6_PF_I2C2_SCL
|
||||
};
|
||||
|
||||
static int pcm038_i2c_1_init(struct device *dev)
|
||||
{
|
||||
return mxc_gpio_setup_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins),
|
||||
"I2C1");
|
||||
}
|
||||
|
||||
static void pcm038_i2c_1_exit(struct device *dev)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins));
|
||||
}
|
||||
|
||||
static struct imxi2c_platform_data pcm038_i2c_1_data = {
|
||||
.bitrate = 100000,
|
||||
.init = pcm038_i2c_1_init,
|
||||
.exit = pcm038_i2c_1_exit,
|
||||
};
|
||||
|
||||
static struct at24_platform_data board_eeprom = {
|
||||
.byte_len = 4096,
|
||||
.page_size = 32,
|
||||
.flags = AT24_FLAG_ADDR16,
|
||||
};
|
||||
|
||||
static struct i2c_board_info pcm038_i2c_devices[] = {
|
||||
[0] = {
|
||||
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
|
||||
.platform_data = &board_eeprom,
|
||||
},
|
||||
[1] = {
|
||||
I2C_BOARD_INFO("rtc-pcf8563", 0x51),
|
||||
.type = "pcf8563"
|
||||
},
|
||||
[2] = {
|
||||
I2C_BOARD_INFO("lm75", 0x4a),
|
||||
.type = "lm75"
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init pcm038_init(void)
|
||||
{
|
||||
gpio_fec_active();
|
||||
@ -217,9 +264,17 @@ static void __init pcm038_init(void)
|
||||
mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
|
||||
mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
|
||||
|
||||
mxc_gpio_mode(PE16_AF_RTCK); /* OWIRE */
|
||||
mxc_gpio_mode(PE16_AF_OWIRE);
|
||||
mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info);
|
||||
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
/* only the i2c master 1 is used on this CPU card */
|
||||
i2c_register_board_info(1, pcm038_i2c_devices,
|
||||
ARRAY_SIZE(pcm038_i2c_devices));
|
||||
|
||||
mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
|
||||
#endif
|
||||
|
||||
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
|
||||
|
||||
#ifdef CONFIG_MACH_PCM970_BASEBOARD
|
||||
@ -229,11 +284,10 @@ static void __init pcm038_init(void)
|
||||
|
||||
static void __init pcm038_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(26000000);
|
||||
mxc_timer_init("gpt_clk.0");
|
||||
mx27_clocks_init(26000000);
|
||||
}
|
||||
|
||||
struct sys_timer pcm038_timer = {
|
||||
static struct sys_timer pcm038_timer = {
|
||||
.init = pcm038_timer_init,
|
||||
};
|
||||
|
||||
|
@ -17,9 +17,138 @@
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/mmc.h>
|
||||
#include <mach/imxfb.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
static int pcm970_sdhc2_get_ro(struct device *dev)
|
||||
{
|
||||
return gpio_get_value(GPIO_PORTC + 28);
|
||||
}
|
||||
|
||||
static int pcm970_sdhc2_pins[] = {
|
||||
PB4_PF_SD2_D0,
|
||||
PB5_PF_SD2_D1,
|
||||
PB6_PF_SD2_D2,
|
||||
PB7_PF_SD2_D3,
|
||||
PB8_PF_SD2_CMD,
|
||||
PB9_PF_SD2_CLK,
|
||||
};
|
||||
|
||||
static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mxc_gpio_setup_multiple_pins(pcm970_sdhc2_pins,
|
||||
ARRAY_SIZE(pcm970_sdhc2_pins), "sdhc2");
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
ret = request_irq(IRQ_GPIOC(29), detect_irq, 0,
|
||||
"imx-mmc-detect", data);
|
||||
if (ret)
|
||||
goto out_release_gpio;
|
||||
|
||||
set_irq_type(IRQ_GPIOC(29), IRQF_TRIGGER_FALLING);
|
||||
|
||||
ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
|
||||
if (ret)
|
||||
goto out_release_gpio;
|
||||
|
||||
mxc_gpio_mode((GPIO_PORTC | 28) | GPIO_GPIO | GPIO_IN);
|
||||
gpio_direction_input(GPIO_PORTC + 28);
|
||||
|
||||
return 0;
|
||||
|
||||
out_release_gpio:
|
||||
mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
|
||||
ARRAY_SIZE(pcm970_sdhc2_pins));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pcm970_sdhc2_exit(struct device *dev, void *data)
|
||||
{
|
||||
free_irq(IRQ_GPIOC(29), data);
|
||||
gpio_free(GPIO_PORTC + 28);
|
||||
mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
|
||||
ARRAY_SIZE(pcm970_sdhc2_pins));
|
||||
}
|
||||
|
||||
static struct imxmmc_platform_data sdhc_pdata = {
|
||||
.get_ro = pcm970_sdhc2_get_ro,
|
||||
.init = pcm970_sdhc2_init,
|
||||
.exit = pcm970_sdhc2_exit,
|
||||
};
|
||||
|
||||
static int mxc_fb_pins[] = {
|
||||
PA5_PF_LSCLK, PA6_PF_LD0, PA7_PF_LD1, PA8_PF_LD2,
|
||||
PA9_PF_LD3, PA10_PF_LD4, PA11_PF_LD5, PA12_PF_LD6,
|
||||
PA13_PF_LD7, PA14_PF_LD8, PA15_PF_LD9, PA16_PF_LD10,
|
||||
PA17_PF_LD11, PA18_PF_LD12, PA19_PF_LD13, PA20_PF_LD14,
|
||||
PA21_PF_LD15, PA22_PF_LD16, PA23_PF_LD17, PA24_PF_REV,
|
||||
PA25_PF_CLS, PA26_PF_PS, PA27_PF_SPL_SPR, PA28_PF_HSYNC,
|
||||
PA29_PF_VSYNC, PA30_PF_CONTRAST, PA31_PF_OE_ACD
|
||||
};
|
||||
|
||||
static int pcm038_fb_init(struct platform_device *pdev)
|
||||
{
|
||||
return mxc_gpio_setup_multiple_pins(mxc_fb_pins,
|
||||
ARRAY_SIZE(mxc_fb_pins), "FB");
|
||||
}
|
||||
|
||||
static int pcm038_fb_exit(struct platform_device *pdev)
|
||||
{
|
||||
mxc_gpio_release_multiple_pins(mxc_fb_pins, ARRAY_SIZE(mxc_fb_pins));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connected is a portrait Sharp-QVGA display
|
||||
* of type: LQ035Q7DH06
|
||||
*/
|
||||
static struct imx_fb_platform_data pcm038_fb_data = {
|
||||
.pixclock = 188679, /* in ps (5.3MHz) */
|
||||
.xres = 240,
|
||||
.yres = 320,
|
||||
|
||||
.bpp = 16,
|
||||
.hsync_len = 7,
|
||||
.left_margin = 5,
|
||||
.right_margin = 16,
|
||||
|
||||
.vsync_len = 1,
|
||||
.upper_margin = 7,
|
||||
.lower_margin = 9,
|
||||
.fixed_screen_cpu = 0,
|
||||
|
||||
/*
|
||||
* - HSYNC active high
|
||||
* - VSYNC active high
|
||||
* - clk notenabled while idle
|
||||
* - clock not inverted
|
||||
* - data not inverted
|
||||
* - data enable low active
|
||||
* - enable sharp mode
|
||||
*/
|
||||
.pcr = 0xFA0080C0,
|
||||
.pwmr = 0x00A903FF,
|
||||
.lscr1 = 0x00120300,
|
||||
.dmacr = 0x00020010,
|
||||
|
||||
.init = pcm038_fb_init,
|
||||
.exit = pcm038_fb_exit,
|
||||
};
|
||||
|
||||
/*
|
||||
* system init for baseboard usage. Will be called by pcm038 init.
|
||||
*
|
||||
@ -28,4 +157,6 @@
|
||||
*/
|
||||
void __init pcm970_baseboard_init(void)
|
||||
{
|
||||
mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
|
||||
mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/serial.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include "devices.h"
|
||||
|
||||
static struct resource uart0[] = {
|
||||
{
|
||||
@ -99,6 +100,7 @@ struct platform_device mxc_uart_device3 = {
|
||||
.num_resources = ARRAY_SIZE(uart3),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MACH_MX27
|
||||
static struct resource uart4[] = {
|
||||
{
|
||||
.start = UART5_BASE_ADDR,
|
||||
@ -136,3 +138,4 @@ struct platform_device mxc_uart_device5 = {
|
||||
.resource = uart5,
|
||||
.num_resources = ARRAY_SIZE(uart5),
|
||||
};
|
||||
#endif
|
||||
|
@ -1,21 +1,40 @@
|
||||
menu "MX3 Options"
|
||||
depends on ARCH_MX3
|
||||
if ARCH_MX3
|
||||
|
||||
config ARCH_MX31
|
||||
bool
|
||||
|
||||
config ARCH_MX35
|
||||
bool
|
||||
|
||||
comment "MX3 platforms:"
|
||||
|
||||
config MACH_MX31ADS
|
||||
bool "Support MX31ADS platforms"
|
||||
select ARCH_MX31
|
||||
default y
|
||||
help
|
||||
Include support for MX31ADS platform. This includes specific
|
||||
configurations for the board and its peripherals.
|
||||
|
||||
config MACH_MX31ADS_WM1133_EV1
|
||||
bool "Support Wolfson Microelectronics 1133-EV1 module"
|
||||
depends on MACH_MX31ADS
|
||||
select MFD_WM8350_CONFIG_MODE_0
|
||||
select MFD_WM8352_CONFIG_MODE_0
|
||||
help
|
||||
Include support for the Wolfson Microelectronics 1133-EV1 PMU
|
||||
and audio module for the MX31ADS platform.
|
||||
|
||||
config MACH_PCM037
|
||||
bool "Support Phytec pcm037 platforms"
|
||||
bool "Support Phytec pcm037 (i.MX31) platforms"
|
||||
select ARCH_MX31
|
||||
help
|
||||
Include support for Phytec pcm037 platform. This includes
|
||||
specific configurations for the board and its peripherals.
|
||||
|
||||
config MACH_MX31LITE
|
||||
bool "Support MX31 LITEKIT (LogicPD)"
|
||||
select ARCH_MX31
|
||||
default n
|
||||
help
|
||||
Include support for MX31 LITEKIT platform. This includes specific
|
||||
@ -23,6 +42,7 @@ config MACH_MX31LITE
|
||||
|
||||
config MACH_MX31_3DS
|
||||
bool "Support MX31PDK (3DS)"
|
||||
select ARCH_MX31
|
||||
default n
|
||||
help
|
||||
Include support for MX31PDK (3DS) platform. This includes specific
|
||||
@ -30,10 +50,18 @@ config MACH_MX31_3DS
|
||||
|
||||
config MACH_MX31MOBOARD
|
||||
bool "Support mx31moboard platforms (EPFL Mobots group)"
|
||||
select ARCH_MX31
|
||||
default n
|
||||
help
|
||||
Include support for mx31moboard platform. This includes specific
|
||||
configurations for the board and its peripherals.
|
||||
|
||||
endmenu
|
||||
config MACH_QONG
|
||||
bool "Support Dave/DENX QongEVB-LITE platform"
|
||||
select ARCH_MX31
|
||||
default n
|
||||
help
|
||||
Include support for Dave/DENX QongEVB-LITE platform. This includes
|
||||
specific configurations for the board and its peripherals.
|
||||
|
||||
endif
|
||||
|
@ -4,9 +4,13 @@
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y := mm.o clock.o devices.o iomux.o
|
||||
obj-y := mm.o devices.o
|
||||
obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o
|
||||
obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
|
||||
obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
|
||||
obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o
|
||||
obj-$(CONFIG_MACH_PCM037) += pcm037.o
|
||||
obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o
|
||||
obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o
|
||||
obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \
|
||||
mx31moboard-marxbot.o
|
||||
obj-$(CONFIG_MACH_QONG) += qong.o
|
||||
|
487
arch/arm/mach-mx3/clock-imx35.c
Normal file
487
arch/arm/mach-mx3/clock-imx35.c
Normal file
@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (C) 2009 by Sascha Hauer, Pengutronix
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/clkdev.h>
|
||||
|
||||
#include <mach/clock.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#define CCM_BASE IO_ADDRESS(CCM_BASE_ADDR)
|
||||
|
||||
#define CCM_CCMR 0x00
|
||||
#define CCM_PDR0 0x04
|
||||
#define CCM_PDR1 0x08
|
||||
#define CCM_PDR2 0x0C
|
||||
#define CCM_PDR3 0x10
|
||||
#define CCM_PDR4 0x14
|
||||
#define CCM_RCSR 0x18
|
||||
#define CCM_MPCTL 0x1C
|
||||
#define CCM_PPCTL 0x20
|
||||
#define CCM_ACMR 0x24
|
||||
#define CCM_COSR 0x28
|
||||
#define CCM_CGR0 0x2C
|
||||
#define CCM_CGR1 0x30
|
||||
#define CCM_CGR2 0x34
|
||||
#define CCM_CGR3 0x38
|
||||
|
||||
#ifdef HAVE_SET_RATE_SUPPORT
|
||||
static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
|
||||
{
|
||||
u32 min_pre, temp_pre, old_err, err;
|
||||
|
||||
min_pre = (div - 1) / maxpost + 1;
|
||||
old_err = 8;
|
||||
|
||||
for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
|
||||
if (div > (temp_pre * maxpost))
|
||||
break;
|
||||
|
||||
if (div < (temp_pre * temp_pre))
|
||||
continue;
|
||||
|
||||
err = div % temp_pre;
|
||||
|
||||
if (err == 0) {
|
||||
*pre = temp_pre;
|
||||
break;
|
||||
}
|
||||
|
||||
err = temp_pre - err;
|
||||
|
||||
if (err < old_err) {
|
||||
old_err = err;
|
||||
*pre = temp_pre;
|
||||
}
|
||||
}
|
||||
|
||||
*post = (div + *pre - 1) / *pre;
|
||||
}
|
||||
|
||||
/* get the best values for a 3-bit divider combined with a 6-bit divider */
|
||||
static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
|
||||
{
|
||||
if (div >= 512) {
|
||||
*pre = 8;
|
||||
*post = 64;
|
||||
} else if (div >= 64) {
|
||||
calc_dividers(div, pre, post, 64);
|
||||
} else if (div <= 8) {
|
||||
*pre = div;
|
||||
*post = 1;
|
||||
} else {
|
||||
*pre = 1;
|
||||
*post = div;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the best values for two cascaded 3-bit dividers */
|
||||
static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
|
||||
{
|
||||
if (div >= 64) {
|
||||
*pre = *post = 8;
|
||||
} else if (div > 8) {
|
||||
calc_dividers(div, pre, post, 8);
|
||||
} else {
|
||||
*pre = 1;
|
||||
*post = div;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned long get_rate_mpll(void)
|
||||
{
|
||||
ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
|
||||
|
||||
return mxc_decode_pll(mpctl, 24000000);
|
||||
}
|
||||
|
||||
static unsigned long get_rate_ppll(void)
|
||||
{
|
||||
ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
|
||||
|
||||
return mxc_decode_pll(ppctl, 24000000);
|
||||
}
|
||||
|
||||
struct arm_ahb_div {
|
||||
unsigned char arm, ahb, sel;
|
||||
};
|
||||
|
||||
static struct arm_ahb_div clk_consumer[] = {
|
||||
{ .arm = 1, .ahb = 4, .sel = 0},
|
||||
{ .arm = 1, .ahb = 3, .sel = 1},
|
||||
{ .arm = 2, .ahb = 2, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 4, .ahb = 1, .sel = 0},
|
||||
{ .arm = 1, .ahb = 5, .sel = 0},
|
||||
{ .arm = 1, .ahb = 8, .sel = 0},
|
||||
{ .arm = 1, .ahb = 6, .sel = 1},
|
||||
{ .arm = 2, .ahb = 4, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 4, .ahb = 2, .sel = 0},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
};
|
||||
|
||||
static struct arm_ahb_div clk_automotive[] = {
|
||||
{ .arm = 1, .ahb = 3, .sel = 0},
|
||||
{ .arm = 1, .ahb = 2, .sel = 1},
|
||||
{ .arm = 2, .ahb = 1, .sel = 1},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
{ .arm = 1, .ahb = 6, .sel = 0},
|
||||
{ .arm = 1, .ahb = 4, .sel = 1},
|
||||
{ .arm = 2, .ahb = 2, .sel = 1},
|
||||
{ .arm = 0, .ahb = 0, .sel = 0},
|
||||
};
|
||||
|
||||
static unsigned long get_rate_arm(void)
|
||||
{
|
||||
unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
|
||||
struct arm_ahb_div *aad;
|
||||
unsigned long fref = get_rate_mpll();
|
||||
|
||||
if (pdr0 & 1) {
|
||||
/* consumer path */
|
||||
aad = &clk_consumer[(pdr0 >> 16) & 0xf];
|
||||
if (aad->sel)
|
||||
fref = fref * 2 / 3;
|
||||
} else {
|
||||
/* auto path */
|
||||
aad = &clk_automotive[(pdr0 >> 9) & 0x7];
|
||||
if (aad->sel)
|
||||
fref = fref * 3 / 4;
|
||||
}
|
||||
return fref / aad->arm;
|
||||
}
|
||||
|
||||
static unsigned long get_rate_ahb(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
|
||||
struct arm_ahb_div *aad;
|
||||
unsigned long fref = get_rate_mpll();
|
||||
|
||||
if (pdr0 & 1)
|
||||
/* consumer path */
|
||||
aad = &clk_consumer[(pdr0 >> 16) & 0xf];
|
||||
else
|
||||
/* auto path */
|
||||
aad = &clk_automotive[(pdr0 >> 9) & 0x7];
|
||||
|
||||
return fref / aad->ahb;
|
||||
}
|
||||
|
||||
static unsigned long get_rate_ipg(struct clk *clk)
|
||||
{
|
||||
return get_rate_ahb(NULL) >> 1;
|
||||
}
|
||||
|
||||
static unsigned long get_3_3_div(unsigned long in)
|
||||
{
|
||||
return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1);
|
||||
}
|
||||
|
||||
static unsigned long get_rate_uart(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
|
||||
unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
|
||||
unsigned long div = get_3_3_div(pdr4 >> 10);
|
||||
|
||||
if (pdr3 & (1 << 14))
|
||||
return get_rate_arm() / div;
|
||||
else
|
||||
return get_rate_ppll() / div;
|
||||
}
|
||||
|
||||
static unsigned long get_rate_sdhc(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
|
||||
unsigned long div, rate;
|
||||
|
||||
if (pdr3 & (1 << 6))
|
||||
rate = get_rate_arm();
|
||||
else
|
||||
rate = get_rate_ppll();
|
||||
|
||||
switch (clk->id) {
|
||||
default:
|
||||
case 0:
|
||||
div = pdr3 & 0x3f;
|
||||
break;
|
||||
case 1:
|
||||
div = (pdr3 >> 8) & 0x3f;
|
||||
break;
|
||||
case 2:
|
||||
div = (pdr3 >> 16) & 0x3f;
|
||||
break;
|
||||
}
|
||||
|
||||
return rate / get_3_3_div(div);
|
||||
}
|
||||
|
||||
static unsigned long get_rate_mshc(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
|
||||
unsigned long div1, div2, rate;
|
||||
|
||||
if (pdr1 & (1 << 7))
|
||||
rate = get_rate_arm();
|
||||
else
|
||||
rate = get_rate_ppll();
|
||||
|
||||
div1 = (pdr1 >> 29) & 0x7;
|
||||
div2 = (pdr1 >> 22) & 0x3f;
|
||||
|
||||
return rate / ((div1 + 1) * (div2 + 1));
|
||||
}
|
||||
|
||||
static unsigned long get_rate_ssi(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
|
||||
unsigned long div1, div2, rate;
|
||||
|
||||
if (pdr2 & (1 << 6))
|
||||
rate = get_rate_arm();
|
||||
else
|
||||
rate = get_rate_ppll();
|
||||
|
||||
switch (clk->id) {
|
||||
default:
|
||||
case 0:
|
||||
div1 = pdr2 & 0x3f;
|
||||
div2 = (pdr2 >> 24) & 0x7;
|
||||
break;
|
||||
case 1:
|
||||
div1 = (pdr2 >> 8) & 0x3f;
|
||||
div2 = (pdr2 >> 27) & 0x7;
|
||||
break;
|
||||
}
|
||||
|
||||
return rate / ((div1 + 1) * (div2 + 1));
|
||||
}
|
||||
|
||||
static unsigned long get_rate_csi(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
|
||||
unsigned long rate;
|
||||
|
||||
if (pdr2 & (1 << 7))
|
||||
rate = get_rate_arm();
|
||||
else
|
||||
rate = get_rate_ppll();
|
||||
|
||||
return rate / get_3_3_div((pdr2 >> 16) & 0x3f);
|
||||
}
|
||||
|
||||
static unsigned long get_rate_ipg_per(struct clk *clk)
|
||||
{
|
||||
unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
|
||||
unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
|
||||
unsigned long div1, div2;
|
||||
|
||||
if (pdr0 & (1 << 26)) {
|
||||
div1 = (pdr4 >> 19) & 0x7;
|
||||
div2 = (pdr4 >> 16) & 0x7;
|
||||
return get_rate_arm() / ((div1 + 1) * (div2 + 1));
|
||||
} else {
|
||||
div1 = (pdr0 >> 12) & 0x7;
|
||||
return get_rate_ahb(NULL) / div1;
|
||||
}
|
||||
}
|
||||
|
||||
static int clk_cgr_enable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg |= 3 << clk->enable_shift;
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_cgr_disable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg &= ~(3 << clk->enable_shift);
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
}
|
||||
|
||||
#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
|
||||
static struct clk name = { \
|
||||
.id = i, \
|
||||
.enable_reg = CCM_BASE + er, \
|
||||
.enable_shift = es, \
|
||||
.get_rate = gr, \
|
||||
.set_rate = sr, \
|
||||
.enable = clk_cgr_enable, \
|
||||
.disable = clk_cgr_disable, \
|
||||
}
|
||||
|
||||
DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL);
|
||||
DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL);
|
||||
DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL);
|
||||
DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL);
|
||||
DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
|
||||
DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
|
||||
DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
|
||||
|
||||
DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL);
|
||||
DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL);
|
||||
DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL);
|
||||
DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
|
||||
DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, NULL, NULL);
|
||||
DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL);
|
||||
DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL);
|
||||
DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
|
||||
DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL);
|
||||
|
||||
DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL);
|
||||
DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL);
|
||||
DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL);
|
||||
DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL);
|
||||
DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL);
|
||||
DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL);
|
||||
DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL);
|
||||
DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL);
|
||||
DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL);
|
||||
DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL);
|
||||
DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL);
|
||||
DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL);
|
||||
DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL);
|
||||
|
||||
DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL);
|
||||
DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL);
|
||||
DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL);
|
||||
|
||||
#define _REGISTER_CLOCK(d, n, c) \
|
||||
{ \
|
||||
.dev_id = d, \
|
||||
.con_id = n, \
|
||||
.clk = &c, \
|
||||
},
|
||||
|
||||
static struct clk_lookup lookups[] __initdata = {
|
||||
_REGISTER_CLOCK(NULL, "asrc", asrc_clk)
|
||||
_REGISTER_CLOCK(NULL, "ata", ata_clk)
|
||||
_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
|
||||
_REGISTER_CLOCK(NULL, "can", can1_clk)
|
||||
_REGISTER_CLOCK(NULL, "can", can2_clk)
|
||||
_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
|
||||
_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
|
||||
_REGISTER_CLOCK(NULL, "ect", ect_clk)
|
||||
_REGISTER_CLOCK(NULL, "edio", edio_clk)
|
||||
_REGISTER_CLOCK(NULL, "emi", emi_clk)
|
||||
_REGISTER_CLOCK(NULL, "epit", epit1_clk)
|
||||
_REGISTER_CLOCK(NULL, "epit", epit2_clk)
|
||||
_REGISTER_CLOCK(NULL, "esai", esai_clk)
|
||||
_REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk)
|
||||
_REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk)
|
||||
_REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk)
|
||||
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
|
||||
_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
|
||||
_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
|
||||
_REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
|
||||
_REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
|
||||
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
|
||||
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
|
||||
_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
|
||||
_REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
|
||||
_REGISTER_CLOCK(NULL, "ipu", ipu_clk)
|
||||
_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
|
||||
_REGISTER_CLOCK(NULL, "mlb", mlb_clk)
|
||||
_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
|
||||
_REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
|
||||
_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
|
||||
_REGISTER_CLOCK(NULL, "rngc", rngc_clk)
|
||||
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
|
||||
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
|
||||
_REGISTER_CLOCK(NULL, "scc", scc_clk)
|
||||
_REGISTER_CLOCK(NULL, "sdma", sdma_clk)
|
||||
_REGISTER_CLOCK(NULL, "spba", spba_clk)
|
||||
_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
|
||||
_REGISTER_CLOCK(NULL, "ssi", ssi1_clk)
|
||||
_REGISTER_CLOCK(NULL, "ssi", ssi2_clk)
|
||||
_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
|
||||
_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
|
||||
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
|
||||
_REGISTER_CLOCK(NULL, "usbotg", usbotg_clk)
|
||||
_REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
|
||||
_REGISTER_CLOCK(NULL, "max", max_clk)
|
||||
_REGISTER_CLOCK(NULL, "admux", admux_clk)
|
||||
_REGISTER_CLOCK(NULL, "csi", csi_clk)
|
||||
_REGISTER_CLOCK(NULL, "iim", iim_clk)
|
||||
_REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
|
||||
};
|
||||
|
||||
int __init mx35_clocks_init()
|
||||
{
|
||||
int i;
|
||||
unsigned int ll = 0;
|
||||
|
||||
mxc_set_cpu_type(MXC_CPU_MX35);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LL_CONSOLE
|
||||
ll = (3 << 16);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lookups); i++)
|
||||
clkdev_add(&lookups[i]);
|
||||
|
||||
/* Turn off all clocks except the ones we need to survive, namely:
|
||||
* EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
|
||||
*/
|
||||
__raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
|
||||
__raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
|
||||
CCM_BASE + CCM_CGR1);
|
||||
__raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
|
||||
__raw_writel(0, CCM_BASE + CCM_CGR3);
|
||||
|
||||
mxc_timer_init(&gpt_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -91,47 +91,6 @@
|
||||
#define MXC_CCM_PDR0_MCU_PODF_OFFSET 0
|
||||
#define MXC_CCM_PDR0_MCU_PODF_MASK 0x7
|
||||
|
||||
#define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11)
|
||||
#define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11)
|
||||
|
||||
#define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6)
|
||||
#define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6)
|
||||
#define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6)
|
||||
#define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6)
|
||||
|
||||
#define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3)
|
||||
#define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3)
|
||||
|
||||
#define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8)
|
||||
#define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8)
|
||||
|
||||
#define MXC_CCM_PDR0_MCU_DIV_1 0x0
|
||||
#define MXC_CCM_PDR0_MCU_DIV_2 0x1
|
||||
#define MXC_CCM_PDR0_MCU_DIV_3 0x2
|
||||
#define MXC_CCM_PDR0_MCU_DIV_4 0x3
|
||||
#define MXC_CCM_PDR0_MCU_DIV_5 0x4
|
||||
#define MXC_CCM_PDR0_MCU_DIV_6 0x5
|
||||
#define MXC_CCM_PDR0_MCU_DIV_7 0x6
|
||||
#define MXC_CCM_PDR0_MCU_DIV_8 0x7
|
||||
|
||||
#define MXC_CCM_PDR1_USB_PRDF_OFFSET 30
|
||||
#define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30)
|
||||
#define MXC_CCM_PDR1_USB_PODF_OFFSET 27
|
||||
@ -152,118 +111,6 @@
|
||||
/* Bit definitions for RCSR */
|
||||
#define MXC_CCM_RCSR_NF16B 0x80000000
|
||||
|
||||
/* Bit definitions for both MCU, USB and SR PLL control registers */
|
||||
#define MXC_CCM_PCTL_BRM 0x80000000
|
||||
#define MXC_CCM_PCTL_PD_OFFSET 26
|
||||
#define MXC_CCM_PCTL_PD_MASK (0xF << 26)
|
||||
#define MXC_CCM_PCTL_MFD_OFFSET 16
|
||||
#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16)
|
||||
#define MXC_CCM_PCTL_MFI_OFFSET 10
|
||||
#define MXC_CCM_PCTL_MFI_MASK (0xF << 10)
|
||||
#define MXC_CCM_PCTL_MFN_OFFSET 0
|
||||
#define MXC_CCM_PCTL_MFN_MASK 0x3FF
|
||||
|
||||
#define MXC_CCM_CGR0_SD_MMC1_OFFSET 0
|
||||
#define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR0_SD_MMC2_OFFSET 2
|
||||
#define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR0_GPT_OFFSET 4
|
||||
#define MXC_CCM_CGR0_GPT_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CGR0_EPIT1_OFFSET 6
|
||||
#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CGR0_EPIT2_OFFSET 8
|
||||
#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CGR0_IIM_OFFSET 10
|
||||
#define MXC_CCM_CGR0_IIM_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CGR0_ATA_OFFSET 12
|
||||
#define MXC_CCM_CGR0_ATA_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CGR0_SDMA_OFFSET 14
|
||||
#define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CGR0_CSPI3_OFFSET 16
|
||||
#define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CGR0_RNG_OFFSET 18
|
||||
#define MXC_CCM_CGR0_RNG_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CGR0_UART1_OFFSET 20
|
||||
#define MXC_CCM_CGR0_UART1_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CGR0_UART2_OFFSET 22
|
||||
#define MXC_CCM_CGR0_UART2_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CGR0_SSI1_OFFSET 24
|
||||
#define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CGR0_I2C1_OFFSET 26
|
||||
#define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CGR0_I2C2_OFFSET 28
|
||||
#define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CGR0_I2C3_OFFSET 30
|
||||
#define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30)
|
||||
|
||||
#define MXC_CCM_CGR1_HANTRO_OFFSET 0
|
||||
#define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2
|
||||
#define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4
|
||||
#define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CGR1_CSI_OFFSET 6
|
||||
#define MXC_CCM_CGR1_CSI_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CGR1_RTC_OFFSET 8
|
||||
#define MXC_CCM_CGR1_RTC_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CGR1_WDOG_OFFSET 10
|
||||
#define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CGR1_PWM_OFFSET 12
|
||||
#define MXC_CCM_CGR1_PWM_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CGR1_SIM_OFFSET 14
|
||||
#define MXC_CCM_CGR1_SIM_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CGR1_ECT_OFFSET 16
|
||||
#define MXC_CCM_CGR1_ECT_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CGR1_USBOTG_OFFSET 18
|
||||
#define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CGR1_KPP_OFFSET 20
|
||||
#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CGR1_IPU_OFFSET 22
|
||||
#define MXC_CCM_CGR1_IPU_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CGR1_UART3_OFFSET 24
|
||||
#define MXC_CCM_CGR1_UART3_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CGR1_UART4_OFFSET 26
|
||||
#define MXC_CCM_CGR1_UART4_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CGR1_UART5_OFFSET 28
|
||||
#define MXC_CCM_CGR1_UART5_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CGR1_OWIRE_OFFSET 30
|
||||
#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30)
|
||||
|
||||
#define MXC_CCM_CGR2_SSI2_OFFSET 0
|
||||
#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR2_CSPI1_OFFSET 2
|
||||
#define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR2_CSPI2_OFFSET 4
|
||||
#define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CGR2_GACC_OFFSET 6
|
||||
#define MXC_CCM_CGR2_GACC_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CGR2_EMI_OFFSET 8
|
||||
#define MXC_CCM_CGR2_EMI_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CGR2_RTIC_OFFSET 10
|
||||
#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CGR2_FIRI_OFFSET 12
|
||||
#define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CGR2_IPMUX1_OFFSET 14
|
||||
#define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CGR2_IPMUX2_OFFSET 16
|
||||
#define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16)
|
||||
|
||||
/* These new CGR2 bits are added in MX32 */
|
||||
#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18
|
||||
#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20
|
||||
#define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22
|
||||
#define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24
|
||||
#define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24)
|
||||
#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25
|
||||
#define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25)
|
||||
#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26
|
||||
#define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26)
|
||||
#define MXC_CCM_CGR2_APMENA_OFFSET 30
|
||||
#define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30)
|
||||
|
||||
/*
|
||||
* LTR0 register offsets
|
||||
*/
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/imx-uart.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
static struct resource uart0[] = {
|
||||
{
|
||||
.start = UART1_BASE_ADDR,
|
||||
@ -82,6 +84,7 @@ struct platform_device mxc_uart_device2 = {
|
||||
.num_resources = ARRAY_SIZE(uart2),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_MX31
|
||||
static struct resource uart3[] = {
|
||||
{
|
||||
.start = UART4_BASE_ADDR,
|
||||
@ -119,6 +122,7 @@ struct platform_device mxc_uart_device4 = {
|
||||
.resource = uart4,
|
||||
.num_resources = ARRAY_SIZE(uart4),
|
||||
};
|
||||
#endif /* CONFIG_ARCH_MX31 */
|
||||
|
||||
/* GPIO port description */
|
||||
static struct mxc_gpio_port imx_gpio_ports[] = {
|
||||
@ -164,8 +168,8 @@ struct platform_device mxc_w1_master_device = {
|
||||
|
||||
static struct resource mxc_nand_resources[] = {
|
||||
{
|
||||
.start = NFC_BASE_ADDR,
|
||||
.end = NFC_BASE_ADDR + 0xfff,
|
||||
.start = 0, /* runtime dependent */
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM
|
||||
}, {
|
||||
.start = MXC_INT_NANDFC,
|
||||
@ -180,3 +184,188 @@ struct platform_device mxc_nand_device = {
|
||||
.num_resources = ARRAY_SIZE(mxc_nand_resources),
|
||||
.resource = mxc_nand_resources,
|
||||
};
|
||||
|
||||
static struct resource mxc_i2c0_resources[] = {
|
||||
{
|
||||
.start = I2C_BASE_ADDR,
|
||||
.end = I2C_BASE_ADDR + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MXC_INT_I2C,
|
||||
.end = MXC_INT_I2C,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mxc_i2c_device0 = {
|
||||
.name = "imx-i2c",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxc_i2c0_resources),
|
||||
.resource = mxc_i2c0_resources,
|
||||
};
|
||||
|
||||
static struct resource mxc_i2c1_resources[] = {
|
||||
{
|
||||
.start = I2C2_BASE_ADDR,
|
||||
.end = I2C2_BASE_ADDR + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MXC_INT_I2C2,
|
||||
.end = MXC_INT_I2C2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mxc_i2c_device1 = {
|
||||
.name = "imx-i2c",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mxc_i2c1_resources),
|
||||
.resource = mxc_i2c1_resources,
|
||||
};
|
||||
|
||||
static struct resource mxc_i2c2_resources[] = {
|
||||
{
|
||||
.start = I2C3_BASE_ADDR,
|
||||
.end = I2C3_BASE_ADDR + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MXC_INT_I2C3,
|
||||
.end = MXC_INT_I2C3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mxc_i2c_device2 = {
|
||||
.name = "imx-i2c",
|
||||
.id = 2,
|
||||
.num_resources = ARRAY_SIZE(mxc_i2c2_resources),
|
||||
.resource = mxc_i2c2_resources,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_MX31
|
||||
static struct resource mxcsdhc0_resources[] = {
|
||||
{
|
||||
.start = MMC_SDHC1_BASE_ADDR,
|
||||
.end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = MXC_INT_MMC_SDHC1,
|
||||
.end = MXC_INT_MMC_SDHC1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource mxcsdhc1_resources[] = {
|
||||
{
|
||||
.start = MMC_SDHC2_BASE_ADDR,
|
||||
.end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = MXC_INT_MMC_SDHC2,
|
||||
.end = MXC_INT_MMC_SDHC2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mxcsdhc_device0 = {
|
||||
.name = "mxc-mmc",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxcsdhc0_resources),
|
||||
.resource = mxcsdhc0_resources,
|
||||
};
|
||||
|
||||
struct platform_device mxcsdhc_device1 = {
|
||||
.name = "mxc-mmc",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mxcsdhc1_resources),
|
||||
.resource = mxcsdhc1_resources,
|
||||
};
|
||||
#endif /* CONFIG_ARCH_MX31 */
|
||||
|
||||
/* i.MX31 Image Processing Unit */
|
||||
|
||||
/* The resource order is important! */
|
||||
static struct resource mx3_ipu_rsrc[] = {
|
||||
{
|
||||
.start = IPU_CTRL_BASE_ADDR,
|
||||
.end = IPU_CTRL_BASE_ADDR + 0x5F,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = IPU_CTRL_BASE_ADDR + 0x88,
|
||||
.end = IPU_CTRL_BASE_ADDR + 0xB3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = MXC_INT_IPU_SYN,
|
||||
.end = MXC_INT_IPU_SYN,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.start = MXC_INT_IPU_ERR,
|
||||
.end = MXC_INT_IPU_ERR,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mx3_ipu = {
|
||||
.name = "ipu-core",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(mx3_ipu_rsrc),
|
||||
.resource = mx3_ipu_rsrc,
|
||||
};
|
||||
|
||||
static struct resource fb_resources[] = {
|
||||
{
|
||||
.start = IPU_CTRL_BASE_ADDR + 0xB4,
|
||||
.end = IPU_CTRL_BASE_ADDR + 0x1BF,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mx3_fb = {
|
||||
.name = "mx3_sdc_fb",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(fb_resources),
|
||||
.resource = fb_resources,
|
||||
.dev = {
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_MX35
|
||||
static struct resource mxc_fec_resources[] = {
|
||||
{
|
||||
.start = MXC_FEC_BASE_ADDR,
|
||||
.end = MXC_FEC_BASE_ADDR + 0xfff,
|
||||
.flags = IORESOURCE_MEM
|
||||
}, {
|
||||
.start = MXC_INT_FEC,
|
||||
.end = MXC_INT_FEC,
|
||||
.flags = IORESOURCE_IRQ
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device mxc_fec_device = {
|
||||
.name = "fec",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mxc_fec_resources),
|
||||
.resource = mxc_fec_resources,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int mx3_devices_init(void)
|
||||
{
|
||||
if (cpu_is_mx31()) {
|
||||
mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
|
||||
mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
|
||||
}
|
||||
if (cpu_is_mx35()) {
|
||||
mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
|
||||
mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(mx3_devices_init);
|
||||
|
@ -6,3 +6,11 @@ extern struct platform_device mxc_uart_device3;
|
||||
extern struct platform_device mxc_uart_device4;
|
||||
extern struct platform_device mxc_w1_master_device;
|
||||
extern struct platform_device mxc_nand_device;
|
||||
extern struct platform_device mxc_i2c_device0;
|
||||
extern struct platform_device mxc_i2c_device1;
|
||||
extern struct platform_device mxc_i2c_device2;
|
||||
extern struct platform_device mx3_ipu;
|
||||
extern struct platform_device mx3_fb;
|
||||
extern struct platform_device mxc_fec_device;
|
||||
extern struct platform_device mxcsdhc_device0;
|
||||
extern struct platform_device mxcsdhc_device1;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
|
||||
* Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -21,6 +22,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
@ -38,6 +40,8 @@
|
||||
static DEFINE_SPINLOCK(gpio_mux_lock);
|
||||
|
||||
#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
|
||||
|
||||
unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
|
||||
/*
|
||||
* set the mode for a IOMUX pin.
|
||||
*/
|
||||
@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode)
|
||||
field = pin_mode & 0x3;
|
||||
mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
|
||||
|
||||
pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n",
|
||||
__func__, (pin_mode & IOMUX_REG_MASK), field, mode);
|
||||
|
||||
spin_lock(&gpio_mux_lock);
|
||||
|
||||
l = __raw_readl(reg);
|
||||
@ -92,6 +93,86 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_iomux_set_pad);
|
||||
|
||||
/*
|
||||
* setups a single pin:
|
||||
* - reserves the pin so that it is not claimed by another driver
|
||||
* - setups the iomux according to the configuration
|
||||
* - if the pin is configured as a GPIO, we claim it through kernel gpiolib
|
||||
*/
|
||||
int mxc_iomux_setup_pin(const unsigned int pin, const char *label)
|
||||
{
|
||||
unsigned pad = pin & IOMUX_PADNUM_MASK;
|
||||
unsigned gpio;
|
||||
|
||||
if (pad >= (PIN_MAX + 1)) {
|
||||
printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
|
||||
pad, label ? label : "?");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
|
||||
printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
|
||||
pad, label ? label : "?");
|
||||
return -EINVAL;
|
||||
}
|
||||
mxc_iomux_mode(pin);
|
||||
|
||||
/* if we have a gpio, we can allocate it */
|
||||
gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
|
||||
if (gpio < (GPIO_PORT_MAX + 1) * 32)
|
||||
if (gpio_request(gpio, label))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_iomux_setup_pin);
|
||||
|
||||
int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
|
||||
const char *label)
|
||||
{
|
||||
unsigned int *p = pin_list;
|
||||
int i;
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (mxc_iomux_setup_pin(*p, label))
|
||||
goto setup_error;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
|
||||
setup_error:
|
||||
mxc_iomux_release_multiple_pins(pin_list, i);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
|
||||
|
||||
void mxc_iomux_release_pin(const unsigned int pin)
|
||||
{
|
||||
unsigned pad = pin & IOMUX_PADNUM_MASK;
|
||||
unsigned gpio;
|
||||
|
||||
if (pad < (PIN_MAX + 1))
|
||||
clear_bit(pad, mxc_pin_alloc_map);
|
||||
|
||||
gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
|
||||
if (gpio < (GPIO_PORT_MAX + 1) * 32)
|
||||
gpio_free(gpio);
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_iomux_release_pin);
|
||||
|
||||
void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
|
||||
{
|
||||
unsigned int *p = pin_list;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
mxc_iomux_release_pin(*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
|
||||
|
||||
/*
|
||||
* This function enables/disables the general purpose function for a particular
|
||||
* signal.
|
||||
@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
|
||||
spin_unlock(&gpio_mux_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_iomux_set_gpr);
|
||||
|
||||
|
@ -22,10 +22,14 @@
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
|
||||
#include <mach/common.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
/*!
|
||||
* @file mm.c
|
||||
@ -50,6 +54,16 @@ static struct map_desc mxc_io_desc[] __initdata = {
|
||||
.pfn = __phys_to_pfn(AVIC_BASE_ADDR),
|
||||
.length = AVIC_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
},
|
||||
};
|
||||
|
||||
@ -62,3 +76,24 @@ void __init mxc_map_io(void)
|
||||
{
|
||||
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
static int mxc_init_l2x0(void)
|
||||
{
|
||||
void __iomem *l2x0_base;
|
||||
|
||||
l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
|
||||
if (IS_ERR(l2x0_base)) {
|
||||
printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
|
||||
PTR_ERR(l2x0_base));
|
||||
return 0;
|
||||
}
|
||||
|
||||
l2x0_init(l2x0_base, 0x00030024, 0x00000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mxc_init_l2x0);
|
||||
#endif
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
@ -35,6 +37,12 @@
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
|
||||
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
|
||||
#include <linux/mfd/wm8350/audio.h>
|
||||
#include <linux/mfd/wm8350/core.h>
|
||||
#include <linux/mfd/wm8350/pmic.h>
|
||||
#endif
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/*!
|
||||
@ -94,13 +102,16 @@ static struct imxuart_platform_data uart_pdata = {
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
|
||||
static int uart_pins[] = {
|
||||
MX31_PIN_CTS1__CTS1,
|
||||
MX31_PIN_RTS1__RTS1,
|
||||
MX31_PIN_TXD1__TXD1,
|
||||
MX31_PIN_RXD1__RXD1
|
||||
};
|
||||
|
||||
static inline void mxc_init_imx_uart(void)
|
||||
{
|
||||
mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
|
||||
mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
|
||||
mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
|
||||
mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
|
||||
|
||||
mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
|
||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||
}
|
||||
#else /* !SERIAL_IMX */
|
||||
@ -176,7 +187,7 @@ static void __init mx31ads_init_expio(void)
|
||||
/*
|
||||
* Configure INT line as GPIO input
|
||||
*/
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
|
||||
mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
|
||||
|
||||
/* disable the interrupt and clear the status */
|
||||
__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
|
||||
@ -191,25 +202,300 @@ static void __init mx31ads_init_expio(void)
|
||||
set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
|
||||
/* This section defines setup for the Wolfson Microelectronics
|
||||
* 1133-EV1 PMU/audio board. When other PMU boards are supported the
|
||||
* regulator definitions may be shared with them, but for now they can
|
||||
* only be used with this board so would generate warnings about
|
||||
* unused statics and some of the configuration is specific to this
|
||||
* module.
|
||||
*/
|
||||
|
||||
/* CPU */
|
||||
static struct regulator_consumer_supply sw1a_consumers[] = {
|
||||
{
|
||||
.supply = "cpu_vcc",
|
||||
}
|
||||
};
|
||||
|
||||
static struct regulator_init_data sw1a_data = {
|
||||
.constraints = {
|
||||
.name = "SW1A",
|
||||
.min_uV = 1275000,
|
||||
.max_uV = 1600000,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
|
||||
REGULATOR_CHANGE_MODE,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL |
|
||||
REGULATOR_MODE_FAST,
|
||||
.state_mem = {
|
||||
.uV = 1400000,
|
||||
.mode = REGULATOR_MODE_NORMAL,
|
||||
.enabled = 1,
|
||||
},
|
||||
.initial_state = PM_SUSPEND_MEM,
|
||||
.always_on = 1,
|
||||
.boot_on = 1,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
|
||||
.consumer_supplies = sw1a_consumers,
|
||||
};
|
||||
|
||||
/* System IO - High */
|
||||
static struct regulator_init_data viohi_data = {
|
||||
.constraints = {
|
||||
.name = "VIOHO",
|
||||
.min_uV = 2800000,
|
||||
.max_uV = 2800000,
|
||||
.state_mem = {
|
||||
.uV = 2800000,
|
||||
.mode = REGULATOR_MODE_NORMAL,
|
||||
.enabled = 1,
|
||||
},
|
||||
.initial_state = PM_SUSPEND_MEM,
|
||||
.always_on = 1,
|
||||
.boot_on = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* System IO - Low */
|
||||
static struct regulator_init_data violo_data = {
|
||||
.constraints = {
|
||||
.name = "VIOLO",
|
||||
.min_uV = 1800000,
|
||||
.max_uV = 1800000,
|
||||
.state_mem = {
|
||||
.uV = 1800000,
|
||||
.mode = REGULATOR_MODE_NORMAL,
|
||||
.enabled = 1,
|
||||
},
|
||||
.initial_state = PM_SUSPEND_MEM,
|
||||
.always_on = 1,
|
||||
.boot_on = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* DDR RAM */
|
||||
static struct regulator_init_data sw2a_data = {
|
||||
.constraints = {
|
||||
.name = "SW2A",
|
||||
.min_uV = 1800000,
|
||||
.max_uV = 1800000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
.state_mem = {
|
||||
.uV = 1800000,
|
||||
.mode = REGULATOR_MODE_NORMAL,
|
||||
.enabled = 1,
|
||||
},
|
||||
.state_disk = {
|
||||
.mode = REGULATOR_MODE_NORMAL,
|
||||
.enabled = 0,
|
||||
},
|
||||
.always_on = 1,
|
||||
.boot_on = 1,
|
||||
.initial_state = PM_SUSPEND_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct regulator_init_data ldo1_data = {
|
||||
.constraints = {
|
||||
.name = "VCAM/VMMC1/VMMC2",
|
||||
.min_uV = 2800000,
|
||||
.max_uV = 2800000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
.apply_uV = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply ldo2_consumers[] = {
|
||||
{
|
||||
.supply = "AVDD",
|
||||
},
|
||||
{
|
||||
.supply = "HPVDD",
|
||||
},
|
||||
};
|
||||
|
||||
/* CODEC and SIM */
|
||||
static struct regulator_init_data ldo2_data = {
|
||||
.constraints = {
|
||||
.name = "VESIM/VSIM/AVDD",
|
||||
.min_uV = 3300000,
|
||||
.max_uV = 3300000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
.apply_uV = 1,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
|
||||
.consumer_supplies = ldo2_consumers,
|
||||
};
|
||||
|
||||
/* General */
|
||||
static struct regulator_init_data vdig_data = {
|
||||
.constraints = {
|
||||
.name = "VDIG",
|
||||
.min_uV = 1500000,
|
||||
.max_uV = 1500000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
.apply_uV = 1,
|
||||
.always_on = 1,
|
||||
.boot_on = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* Tranceivers */
|
||||
static struct regulator_init_data ldo4_data = {
|
||||
.constraints = {
|
||||
.name = "VRF1/CVDD_2.775",
|
||||
.min_uV = 2500000,
|
||||
.max_uV = 2500000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
.apply_uV = 1,
|
||||
.always_on = 1,
|
||||
.boot_on = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct wm8350_led_platform_data wm8350_led_data = {
|
||||
.name = "wm8350:white",
|
||||
.default_trigger = "heartbeat",
|
||||
.max_uA = 27899,
|
||||
};
|
||||
|
||||
static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
|
||||
.vmid_discharge_msecs = 1000,
|
||||
.drain_msecs = 30,
|
||||
.cap_discharge_msecs = 700,
|
||||
.vmid_charge_msecs = 700,
|
||||
.vmid_s_curve = WM8350_S_CURVE_SLOW,
|
||||
.dis_out4 = WM8350_DISCHARGE_SLOW,
|
||||
.dis_out3 = WM8350_DISCHARGE_SLOW,
|
||||
.dis_out2 = WM8350_DISCHARGE_SLOW,
|
||||
.dis_out1 = WM8350_DISCHARGE_SLOW,
|
||||
.vroi_out4 = WM8350_TIE_OFF_500R,
|
||||
.vroi_out3 = WM8350_TIE_OFF_500R,
|
||||
.vroi_out2 = WM8350_TIE_OFF_500R,
|
||||
.vroi_out1 = WM8350_TIE_OFF_500R,
|
||||
.vroi_enable = 0,
|
||||
.codec_current_on = WM8350_CODEC_ISEL_1_0,
|
||||
.codec_current_standby = WM8350_CODEC_ISEL_0_5,
|
||||
.codec_current_charge = WM8350_CODEC_ISEL_1_5,
|
||||
};
|
||||
|
||||
static int mx31_wm8350_init(struct wm8350 *wm8350)
|
||||
{
|
||||
int i;
|
||||
|
||||
wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
|
||||
WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
|
||||
WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_ON);
|
||||
|
||||
wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
|
||||
WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
|
||||
WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_ON);
|
||||
|
||||
wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
|
||||
WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
|
||||
WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_OFF);
|
||||
|
||||
wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
|
||||
WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
|
||||
WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_OFF);
|
||||
|
||||
wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
|
||||
WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
|
||||
WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_OFF);
|
||||
|
||||
wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
|
||||
WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
|
||||
WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_OFF);
|
||||
|
||||
wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
|
||||
WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
|
||||
WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
|
||||
WM8350_GPIO_DEBOUNCE_OFF);
|
||||
|
||||
/* Fix up for our own supplies. */
|
||||
for (i = 0; i < ARRAY_SIZE(ldo2_consumers); i++)
|
||||
ldo2_consumers[i].dev = wm8350->dev;
|
||||
|
||||
wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
|
||||
wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
|
||||
|
||||
/* LEDs */
|
||||
wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
|
||||
WM8350_DC5_ERRACT_SHUTDOWN_CONV);
|
||||
wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
|
||||
WM8350_ISINK_FLASH_DISABLE,
|
||||
WM8350_ISINK_FLASH_TRIG_BIT,
|
||||
WM8350_ISINK_FLASH_DUR_32MS,
|
||||
WM8350_ISINK_FLASH_ON_INSTANT,
|
||||
WM8350_ISINK_FLASH_OFF_INSTANT,
|
||||
WM8350_ISINK_FLASH_MODE_EN);
|
||||
wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
|
||||
WM8350_ISINK_MODE_BOOST,
|
||||
WM8350_ISINK_ILIM_NORMAL,
|
||||
WM8350_DC5_RMP_20V,
|
||||
WM8350_DC5_FBSRC_ISINKA);
|
||||
wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
|
||||
&wm8350_led_data);
|
||||
|
||||
wm8350->codec.platform_data = &imx32ads_wm8350_setup;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
|
||||
.init = mx31_wm8350_init,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
|
||||
static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
|
||||
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
|
||||
{
|
||||
I2C_BOARD_INFO("wm8350", 0x1a),
|
||||
.platform_data = &mx31_wm8350_pdata,
|
||||
.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static void mxc_init_i2c(void)
|
||||
{
|
||||
i2c_register_board_info(1, mx31ads_i2c1_devices,
|
||||
ARRAY_SIZE(mx31ads_i2c1_devices));
|
||||
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1));
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1));
|
||||
|
||||
mxc_register_device(&mxc_i2c_device1, NULL);
|
||||
}
|
||||
#else
|
||||
static void mxc_init_i2c(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* This structure defines static mappings for the i.MX31ADS board.
|
||||
*/
|
||||
static struct map_desc mx31ads_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = SPBA0_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
|
||||
.length = SPBA0_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = CS4_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(CS4_BASE_ADDR),
|
||||
@ -221,13 +507,13 @@ static struct map_desc mx31ads_io_desc[] __initdata = {
|
||||
/*!
|
||||
* Set up static virtual mappings.
|
||||
*/
|
||||
void __init mx31ads_map_io(void)
|
||||
static void __init mx31ads_map_io(void)
|
||||
{
|
||||
mxc_map_io();
|
||||
iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
|
||||
}
|
||||
|
||||
void __init mx31ads_init_irq(void)
|
||||
static void __init mx31ads_init_irq(void)
|
||||
{
|
||||
mxc_init_irq();
|
||||
mx31ads_init_expio();
|
||||
@ -240,15 +526,15 @@ static void __init mxc_board_init(void)
|
||||
{
|
||||
mxc_init_extuart();
|
||||
mxc_init_imx_uart();
|
||||
mxc_init_i2c();
|
||||
}
|
||||
|
||||
static void __init mx31ads_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(26000000);
|
||||
mxc_timer_init("ipg_clk.0");
|
||||
mx31_clocks_init(26000000);
|
||||
}
|
||||
|
||||
struct sys_timer mx31ads_timer = {
|
||||
static struct sys_timer mx31ads_timer = {
|
||||
.init = mx31ads_timer_init,
|
||||
};
|
||||
|
||||
|
@ -42,20 +42,10 @@
|
||||
*/
|
||||
static struct map_desc mx31lite_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = SPBA0_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
|
||||
.length = SPBA0_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = CS4_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(CS4_BASE_ADDR),
|
||||
@ -82,8 +72,7 @@ static void __init mxc_board_init(void)
|
||||
|
||||
static void __init mx31lite_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(26000000);
|
||||
mxc_timer_init("ipg_clk.0");
|
||||
mx31_clocks_init(26000000);
|
||||
}
|
||||
|
||||
struct sys_timer mx31lite_timer = {
|
||||
|
48
arch/arm/mach-mx3/mx31moboard-devboard.c
Normal file
48
arch/arm/mach-mx3/mx31moboard-devboard.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
static struct imxuart_platform_data uart_pdata = {
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
|
||||
static int mxc_uart1_pins[] = {
|
||||
MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
|
||||
MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
|
||||
};
|
||||
|
||||
/*
|
||||
* system init for baseboard usage. Will be called by mx31moboard init.
|
||||
*/
|
||||
void __init mx31moboard_devboard_init(void)
|
||||
{
|
||||
printk(KERN_INFO "Initializing mx31devboard peripherals\n");
|
||||
mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1");
|
||||
mxc_register_device(&mxc_uart_device1, &uart_pdata);
|
||||
}
|
37
arch/arm/mach-mx3/mx31moboard-marxbot.c
Normal file
37
arch/arm/mach-mx3/mx31moboard-marxbot.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/*
|
||||
* system init for baseboard usage. Will be called by mx31moboard init.
|
||||
*/
|
||||
void __init mx31moboard_marxbot_init(void)
|
||||
{
|
||||
printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
|
||||
}
|
@ -32,6 +32,7 @@
|
||||
#include <mach/common.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
#include <mach/board-mx31moboard.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
@ -63,6 +64,18 @@ static struct platform_device *devices[] __initdata = {
|
||||
&mx31moboard_flash,
|
||||
};
|
||||
|
||||
static int mxc_uart0_pins[] = {
|
||||
MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1,
|
||||
MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
|
||||
};
|
||||
static int mxc_uart4_pins[] = {
|
||||
MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
|
||||
MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
|
||||
};
|
||||
|
||||
static int mx31moboard_baseboard;
|
||||
core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
|
||||
|
||||
/*
|
||||
* Board specific initialization.
|
||||
*/
|
||||
@ -70,58 +83,29 @@ static void __init mxc_board_init(void)
|
||||
{
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
||||
mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
|
||||
mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
|
||||
mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
|
||||
mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
|
||||
|
||||
mxc_iomux_setup_multiple_pins(mxc_uart0_pins, ARRAY_SIZE(mxc_uart0_pins), "uart0");
|
||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||
|
||||
mxc_iomux_mode(MX31_PIN_CTS2__CTS2);
|
||||
mxc_iomux_mode(MX31_PIN_RTS2__RTS2);
|
||||
mxc_iomux_mode(MX31_PIN_TXD2__TXD2);
|
||||
mxc_iomux_mode(MX31_PIN_RXD2__RXD2);
|
||||
|
||||
mxc_register_device(&mxc_uart_device1, &uart_pdata);
|
||||
|
||||
mxc_iomux_mode(MX31_PIN_PC_RST__CTS5);
|
||||
mxc_iomux_mode(MX31_PIN_PC_VS2__RTS5);
|
||||
mxc_iomux_mode(MX31_PIN_PC_BVD2__TXD5);
|
||||
mxc_iomux_mode(MX31_PIN_PC_BVD1__RXD5);
|
||||
|
||||
mxc_iomux_setup_multiple_pins(mxc_uart4_pins, ARRAY_SIZE(mxc_uart4_pins), "uart4");
|
||||
mxc_register_device(&mxc_uart_device4, &uart_pdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* This structure defines static mappings for the mx31moboard.
|
||||
*/
|
||||
static struct map_desc mx31moboard_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up static virtual mappings.
|
||||
*/
|
||||
void __init mx31moboard_map_io(void)
|
||||
{
|
||||
mxc_map_io();
|
||||
iotable_init(mx31moboard_io_desc, ARRAY_SIZE(mx31moboard_io_desc));
|
||||
switch (mx31moboard_baseboard) {
|
||||
case MX31NOBOARD:
|
||||
break;
|
||||
case MX31DEVBOARD:
|
||||
mx31moboard_devboard_init();
|
||||
break;
|
||||
case MX31MARXBOT:
|
||||
mx31moboard_marxbot_init();
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", mx31moboard_baseboard);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init mx31moboard_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(26000000);
|
||||
mxc_timer_init("ipg_clk.0");
|
||||
mx31_clocks_init(26000000);
|
||||
}
|
||||
|
||||
struct sys_timer mx31moboard_timer = {
|
||||
@ -133,7 +117,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
|
||||
.phys_io = AIPS1_BASE_ADDR,
|
||||
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
|
||||
.boot_params = PHYS_OFFSET + 0x100,
|
||||
.map_io = mx31moboard_map_io,
|
||||
.map_io = mxc_map_io,
|
||||
.init_irq = mxc_init_irq,
|
||||
.init_machine = mxc_board_init,
|
||||
.timer = &mx31moboard_timer,
|
||||
|
@ -45,40 +45,17 @@ static struct imxuart_platform_data uart_pdata = {
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
|
||||
static inline void mxc_init_imx_uart(void)
|
||||
{
|
||||
mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
|
||||
mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
|
||||
mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
|
||||
mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
|
||||
|
||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||
}
|
||||
|
||||
/*!
|
||||
* This structure defines static mappings for the i.MX31PDK board.
|
||||
*/
|
||||
static struct map_desc mx31pdk_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
},
|
||||
static int uart_pins[] = {
|
||||
MX31_PIN_CTS1__CTS1,
|
||||
MX31_PIN_RTS1__RTS1,
|
||||
MX31_PIN_TXD1__TXD1,
|
||||
MX31_PIN_RXD1__RXD1
|
||||
};
|
||||
|
||||
/*!
|
||||
* Set up static virtual mappings.
|
||||
*/
|
||||
static void __init mx31pdk_map_io(void)
|
||||
static inline void mxc_init_imx_uart(void)
|
||||
{
|
||||
mxc_map_io();
|
||||
iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
|
||||
mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
|
||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -91,8 +68,7 @@ static void __init mxc_board_init(void)
|
||||
|
||||
static void __init mx31pdk_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(26000000);
|
||||
mxc_timer_init("ipg_clk.0");
|
||||
mx31_clocks_init(26000000);
|
||||
}
|
||||
|
||||
static struct sys_timer mx31pdk_timer = {
|
||||
@ -108,7 +84,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
|
||||
.phys_io = AIPS1_BASE_ADDR,
|
||||
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
|
||||
.boot_params = PHYS_OFFSET + 0x100,
|
||||
.map_io = mx31pdk_map_io,
|
||||
.map_io = mxc_map_io,
|
||||
.init_irq = mxc_init_irq,
|
||||
.init_machine = mxc_board_init,
|
||||
.timer = &mx31pdk_timer,
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/smc911x.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/at24.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -37,6 +39,10 @@
|
||||
#include <mach/iomux-mx3.h>
|
||||
#include <mach/board-pcm037.h>
|
||||
#include <mach/mxc_nand.h>
|
||||
#include <mach/mmc.h>
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
#include <mach/i2c.h>
|
||||
#endif
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
@ -117,12 +123,90 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = {
|
||||
.hw_ecc = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
static int i2c_1_pins[] = {
|
||||
MX31_PIN_CSPI2_MOSI__SCL,
|
||||
MX31_PIN_CSPI2_MISO__SDA,
|
||||
};
|
||||
|
||||
static int pcm037_i2c_1_init(struct device *dev)
|
||||
{
|
||||
return mxc_iomux_setup_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins),
|
||||
"i2c-1");
|
||||
}
|
||||
|
||||
static void pcm037_i2c_1_exit(struct device *dev)
|
||||
{
|
||||
mxc_iomux_release_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins));
|
||||
}
|
||||
|
||||
static struct imxi2c_platform_data pcm037_i2c_1_data = {
|
||||
.bitrate = 100000,
|
||||
.init = pcm037_i2c_1_init,
|
||||
.exit = pcm037_i2c_1_exit,
|
||||
};
|
||||
|
||||
static struct at24_platform_data board_eeprom = {
|
||||
.byte_len = 4096,
|
||||
.page_size = 32,
|
||||
.flags = AT24_FLAG_ADDR16,
|
||||
};
|
||||
|
||||
static struct i2c_board_info pcm037_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
|
||||
.platform_data = &board_eeprom,
|
||||
}, {
|
||||
I2C_BOARD_INFO("rtc-pcf8563", 0x51),
|
||||
.type = "pcf8563",
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static int sdhc1_pins[] = {
|
||||
MX31_PIN_SD1_DATA3__SD1_DATA3,
|
||||
MX31_PIN_SD1_DATA2__SD1_DATA2,
|
||||
MX31_PIN_SD1_DATA1__SD1_DATA1,
|
||||
MX31_PIN_SD1_DATA0__SD1_DATA0,
|
||||
MX31_PIN_SD1_CLK__SD1_CLK,
|
||||
MX31_PIN_SD1_CMD__SD1_CMD,
|
||||
};
|
||||
|
||||
static int pcm970_sdhc1_init(struct device *dev, irq_handler_t h, void *data)
|
||||
{
|
||||
return mxc_iomux_setup_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins),
|
||||
"sdhc-1");
|
||||
}
|
||||
|
||||
static void pcm970_sdhc1_exit(struct device *dev, void *data)
|
||||
{
|
||||
mxc_iomux_release_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins));
|
||||
}
|
||||
|
||||
/* No card and rw detection at the moment */
|
||||
static struct imxmmc_platform_data sdhc_pdata = {
|
||||
.init = pcm970_sdhc1_init,
|
||||
.exit = pcm970_sdhc1_exit,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&pcm037_flash,
|
||||
&pcm037_eth,
|
||||
&pcm037_sram_device,
|
||||
};
|
||||
|
||||
static int uart0_pins[] = {
|
||||
MX31_PIN_CTS1__CTS1,
|
||||
MX31_PIN_RTS1__RTS1,
|
||||
MX31_PIN_TXD1__TXD1,
|
||||
MX31_PIN_RXD1__RXD1
|
||||
};
|
||||
|
||||
static int uart2_pins[] = {
|
||||
MX31_PIN_CSPI3_MOSI__RXD3,
|
||||
MX31_PIN_CSPI3_MISO__TXD3
|
||||
};
|
||||
|
||||
/*
|
||||
* Board specific initialization.
|
||||
*/
|
||||
@ -130,59 +214,33 @@ static void __init mxc_board_init(void)
|
||||
{
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
||||
mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
|
||||
mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
|
||||
mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
|
||||
mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
|
||||
|
||||
mxc_iomux_setup_multiple_pins(uart0_pins, ARRAY_SIZE(uart0_pins), "uart-0");
|
||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||
|
||||
mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3);
|
||||
mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3);
|
||||
|
||||
mxc_iomux_setup_multiple_pins(uart2_pins, ARRAY_SIZE(uart2_pins), "uart-2");
|
||||
mxc_register_device(&mxc_uart_device2, &uart_pdata);
|
||||
|
||||
mxc_iomux_mode(MX31_PIN_BATT_LINE__OWIRE);
|
||||
mxc_iomux_setup_pin(MX31_PIN_BATT_LINE__OWIRE, "batt-0wire");
|
||||
mxc_register_device(&mxc_w1_master_device, NULL);
|
||||
|
||||
/* SMSC9215 IRQ pin */
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO));
|
||||
if (!gpio_request(MX31_PIN_GPIO3_1, "pcm037-eth"))
|
||||
if (!mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
|
||||
"pcm037-eth"))
|
||||
gpio_direction_input(MX31_PIN_GPIO3_1);
|
||||
|
||||
#ifdef CONFIG_I2C_IMX
|
||||
i2c_register_board_info(1, pcm037_i2c_devices,
|
||||
ARRAY_SIZE(pcm037_i2c_devices));
|
||||
|
||||
mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
|
||||
#endif
|
||||
mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* This structure defines static mappings for the pcm037 board.
|
||||
*/
|
||||
static struct map_desc pcm037_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up static virtual mappings.
|
||||
*/
|
||||
void __init pcm037_map_io(void)
|
||||
{
|
||||
mxc_map_io();
|
||||
iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc));
|
||||
mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
|
||||
}
|
||||
|
||||
static void __init pcm037_timer_init(void)
|
||||
{
|
||||
mxc_clocks_init(26000000);
|
||||
mxc_timer_init("ipg_clk.0");
|
||||
mx31_clocks_init(26000000);
|
||||
}
|
||||
|
||||
struct sys_timer pcm037_timer = {
|
||||
@ -194,7 +252,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
|
||||
.phys_io = AIPS1_BASE_ADDR,
|
||||
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
|
||||
.boot_params = PHYS_OFFSET + 0x100,
|
||||
.map_io = pcm037_map_io,
|
||||
.map_io = mxc_map_io,
|
||||
.init_irq = mxc_init_irq,
|
||||
.init_machine = mxc_board_init,
|
||||
.timer = &pcm037_timer,
|
||||
|
312
arch/arm/mach-mx3/qong.c
Normal file
312
arch/arm/mach-mx3/qong.c
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/common.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/setup.h>
|
||||
#include <mach/board-qong.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
#include "devices.h"
|
||||
|
||||
/* FPGA defines */
|
||||
#define QONG_FPGA_VERSION(major, minor, rev) \
|
||||
(((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
|
||||
|
||||
#define QONG_FPGA_BASEADDR CS1_BASE_ADDR
|
||||
#define QONG_FPGA_PERIPH_SIZE (1 << 24)
|
||||
|
||||
#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR
|
||||
#define QONG_FPGA_CTRL_SIZE 0x10
|
||||
/* FPGA control registers */
|
||||
#define QONG_FPGA_CTRL_VERSION 0x00
|
||||
|
||||
#define QONG_DNET_ID 1
|
||||
#define QONG_DNET_BASEADDR \
|
||||
(QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
|
||||
#define QONG_DNET_SIZE 0x00001000
|
||||
|
||||
#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
|
||||
|
||||
/*
|
||||
* This file contains the board-specific initialization routines.
|
||||
*/
|
||||
|
||||
static struct imxuart_platform_data uart_pdata = {
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
|
||||
static int uart_pins[] = {
|
||||
MX31_PIN_CTS1__CTS1,
|
||||
MX31_PIN_RTS1__RTS1,
|
||||
MX31_PIN_TXD1__TXD1,
|
||||
MX31_PIN_RXD1__RXD1
|
||||
};
|
||||
|
||||
static inline void mxc_init_imx_uart(void)
|
||||
{
|
||||
mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
|
||||
"uart-0");
|
||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||
}
|
||||
|
||||
static struct resource dnet_resources[] = {
|
||||
[0] = {
|
||||
.name = "dnet-memory",
|
||||
.start = QONG_DNET_BASEADDR,
|
||||
.end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = QONG_FPGA_IRQ,
|
||||
.end = QONG_FPGA_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device dnet_device = {
|
||||
.name = "dnet",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(dnet_resources),
|
||||
.resource = dnet_resources,
|
||||
};
|
||||
|
||||
static int __init qong_init_dnet(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_device_register(&dnet_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MTD NOR flash */
|
||||
|
||||
static struct physmap_flash_data qong_flash_data = {
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct resource qong_flash_resource = {
|
||||
.start = CS0_BASE_ADDR,
|
||||
.end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device qong_nor_mtd_device = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &qong_flash_data,
|
||||
},
|
||||
.resource = &qong_flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static void qong_init_nor_mtd(void)
|
||||
{
|
||||
(void)platform_device_register(&qong_nor_mtd_device);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware specific access to control-lines
|
||||
*/
|
||||
static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
|
||||
if (cmd == NAND_CMD_NONE)
|
||||
return;
|
||||
|
||||
if (ctrl & NAND_CLE)
|
||||
writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
|
||||
else
|
||||
writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the Device Ready pin.
|
||||
*/
|
||||
static int qong_nand_device_ready(struct mtd_info *mtd)
|
||||
{
|
||||
return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
|
||||
}
|
||||
|
||||
static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
|
||||
{
|
||||
if (chip >= 0)
|
||||
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
|
||||
else
|
||||
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
|
||||
}
|
||||
|
||||
static struct platform_nand_data qong_nand_data = {
|
||||
.chip = {
|
||||
.chip_delay = 20,
|
||||
.options = 0,
|
||||
},
|
||||
.ctrl = {
|
||||
.cmd_ctrl = qong_nand_cmd_ctrl,
|
||||
.dev_ready = qong_nand_device_ready,
|
||||
.select_chip = qong_nand_select_chip,
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource qong_nand_resource = {
|
||||
.start = CS3_BASE_ADDR,
|
||||
.end = CS3_BASE_ADDR + SZ_32M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device qong_nand_device = {
|
||||
.name = "gen_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &qong_nand_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &qong_nand_resource,
|
||||
};
|
||||
|
||||
static void __init qong_init_nand_mtd(void)
|
||||
{
|
||||
/* init CS */
|
||||
__raw_writel(0x00004f00, CSCR_U(3));
|
||||
__raw_writel(0x20013b31, CSCR_L(3));
|
||||
__raw_writel(0x00020800, CSCR_A(3));
|
||||
mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
|
||||
|
||||
/* enable pin */
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
|
||||
if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
|
||||
gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
|
||||
|
||||
/* ready/busy pin */
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
|
||||
if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
|
||||
gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
|
||||
|
||||
/* write protect pin */
|
||||
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
|
||||
if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
|
||||
gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
|
||||
|
||||
platform_device_register(&qong_nand_device);
|
||||
}
|
||||
|
||||
static void __init qong_init_fpga(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 fpga_ver;
|
||||
|
||||
regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
|
||||
if (!regs) {
|
||||
printk(KERN_ERR "%s: failed to map registers, aborting.\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
|
||||
iounmap(regs);
|
||||
printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
|
||||
(fpga_ver & 0xF000) >> 12,
|
||||
(fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
|
||||
if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
|
||||
printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
|
||||
"devices won't be registered!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* register FPGA-based devices */
|
||||
qong_init_nand_mtd();
|
||||
qong_init_dnet();
|
||||
}
|
||||
|
||||
/*
|
||||
* This structure defines the MX31 memory map.
|
||||
*/
|
||||
static struct map_desc qong_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up static virtual mappings.
|
||||
*/
|
||||
static void __init qong_map_io(void)
|
||||
{
|
||||
mxc_map_io();
|
||||
iotable_init(qong_io_desc, ARRAY_SIZE(qong_io_desc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Board specific initialization.
|
||||
*/
|
||||
static void __init mxc_board_init(void)
|
||||
{
|
||||
mxc_init_imx_uart();
|
||||
qong_init_nor_mtd();
|
||||
qong_init_fpga();
|
||||
}
|
||||
|
||||
static void __init qong_timer_init(void)
|
||||
{
|
||||
mx31_clocks_init(26000000);
|
||||
}
|
||||
|
||||
static struct sys_timer qong_timer = {
|
||||
.init = qong_timer_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* The following uses standard kernel macros defined in arch.h in order to
|
||||
* initialize __mach_desc_QONG data structure.
|
||||
*/
|
||||
|
||||
MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
|
||||
/* Maintainer: DENX Software Engineering GmbH */
|
||||
.phys_io = AIPS1_BASE_ADDR,
|
||||
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
|
||||
.boot_params = PHYS_OFFSET + 0x100,
|
||||
.map_io = qong_map_io,
|
||||
.init_irq = mxc_init_irq,
|
||||
.init_machine = mxc_board_init,
|
||||
.timer = &qong_timer,
|
||||
MACHINE_END
|
@ -81,7 +81,7 @@ static inline void __init ldp_init_smc911x(void)
|
||||
}
|
||||
|
||||
ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
|
||||
ldp_smc911x_resources[0].end = cs_mem_base + 0xf;
|
||||
ldp_smc911x_resources[0].end = cs_mem_base + 0xff;
|
||||
udelay(100);
|
||||
|
||||
eth_gpio = LDP_SMC911X_GPIO;
|
||||
|
@ -565,7 +565,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
|
||||
*
|
||||
* Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
|
||||
* find the corresponding register field value. The return register value is
|
||||
* the value before left-shifting. Returns 0xffffffff on error
|
||||
* the value before left-shifting. Returns ~0 on error
|
||||
*/
|
||||
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
{
|
||||
@ -577,7 +577,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
|
||||
clks = omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (clks == NULL)
|
||||
return 0;
|
||||
return ~0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->div == div))
|
||||
@ -588,7 +588,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
printk(KERN_ERR "clock: Could not find divisor %d for "
|
||||
"clock %s parent %s\n", div, clk->name,
|
||||
clk->parent->name);
|
||||
return 0;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
return clkr->val;
|
||||
@ -708,7 +708,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
|
||||
return 0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (clkr->flags & (cpu_mask | DEFAULT_RATE))
|
||||
if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
|
||||
break; /* Found the default rate for this platform */
|
||||
}
|
||||
|
||||
@ -746,7 +746,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->usecount > 0)
|
||||
_omap2_clk_disable(clk);
|
||||
omap2_clk_disable(clk);
|
||||
|
||||
/* Set new source value (previous dividers if any in effect) */
|
||||
reg_val = __raw_readl(src_addr) & ~field_mask;
|
||||
@ -759,11 +759,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
wmb();
|
||||
}
|
||||
|
||||
if (clk->usecount > 0)
|
||||
_omap2_clk_enable(clk);
|
||||
|
||||
clk->parent = new_parent;
|
||||
|
||||
if (clk->usecount > 0)
|
||||
omap2_clk_enable(clk);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
clk->rate = new_parent->rate;
|
||||
|
||||
|
@ -44,7 +44,7 @@ void __init orion5x_init_irq(void)
|
||||
* User can use set_type() if he wants to use edge types handlers.
|
||||
*/
|
||||
for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) {
|
||||
set_irq_chip(i, &orion_gpio_irq_level_chip);
|
||||
set_irq_chip(i, &orion_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
irq_desc[i].status |= IRQ_LEVEL;
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include <asm/elf.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -201,8 +202,13 @@ static struct platform_device *devs[] __initdata = {
|
||||
&pata_device,
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c_rtc = {
|
||||
I2C_BOARD_INFO("pcf8583", 0x50)
|
||||
};
|
||||
|
||||
static int __init rpc_init(void)
|
||||
{
|
||||
i2c_register_board_info(0, &i2c_rtc, 1);
|
||||
return platform_add_devices(devs, ARRAY_SIZE(devs));
|
||||
}
|
||||
|
||||
|
@ -704,7 +704,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
|
||||
|
||||
config CACHE_L2X0
|
||||
bool "Enable the L2x0 outer cache controller"
|
||||
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || REALVIEW_EB_A9MP
|
||||
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
|
||||
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31
|
||||
default y
|
||||
select OUTER_CACHE
|
||||
help
|
||||
|
@ -23,7 +23,8 @@ ENTRY(v6_early_abort)
|
||||
#ifdef CONFIG_CPU_32v6K
|
||||
clrex
|
||||
#else
|
||||
strex r0, r1, [sp] @ Clear the exclusive monitor
|
||||
sub r1, sp, #4 @ Get unused stack location
|
||||
strex r0, r1, [r1] @ Clear the exclusive monitor
|
||||
#endif
|
||||
mrc p15, 0, r1, c5, c0, 0 @ get FSR
|
||||
mrc p15, 0, r0, c6, c0, 0 @ get FAR
|
||||
|
@ -716,7 +716,8 @@ static void __init sanity_check_meminfo(void)
|
||||
* Check whether this memory bank would entirely overlap
|
||||
* the vmalloc area.
|
||||
*/
|
||||
if (__va(bank->start) >= VMALLOC_MIN) {
|
||||
if (__va(bank->start) >= VMALLOC_MIN ||
|
||||
__va(bank->start) < PAGE_OFFSET) {
|
||||
printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
|
||||
"(vmalloc region overlap).\n",
|
||||
bank->start, bank->start + bank->size - 1);
|
||||
|
@ -3,7 +3,7 @@ if ARCH_MXC
|
||||
menu "Freescale MXC Implementations"
|
||||
|
||||
choice
|
||||
prompt "MXC/iMX Base Type"
|
||||
prompt "Freescale CPU family:"
|
||||
default ARCH_MX3
|
||||
|
||||
config ARCH_MX1
|
||||
@ -15,12 +15,14 @@ config ARCH_MX1
|
||||
config ARCH_MX2
|
||||
bool "MX2-based"
|
||||
select CPU_ARM926T
|
||||
select COMMON_CLKDEV
|
||||
help
|
||||
This enables support for systems based on the Freescale i.MX2 family
|
||||
|
||||
config ARCH_MX3
|
||||
bool "MX3-based"
|
||||
select CPU_V6
|
||||
select COMMON_CLKDEV
|
||||
help
|
||||
This enables support for systems based on the Freescale i.MX3 family
|
||||
|
||||
@ -43,4 +45,10 @@ config MXC_IRQ_PRIOR
|
||||
requirements for timing.
|
||||
Say N here, unless you have a specialized requirement.
|
||||
|
||||
config MXC_PWM
|
||||
tristate "Enable PWM driver"
|
||||
depends on ARCH_MXC
|
||||
help
|
||||
Enable support for the i.MX PWM controller(s).
|
||||
|
||||
endif
|
||||
|
@ -3,7 +3,8 @@
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := irq.o clock.o gpio.o time.o devices.o
|
||||
obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o
|
||||
|
||||
obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
|
||||
obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
|
||||
obj-$(CONFIG_MXC_PWM) += pwm.o
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user