Merge branch 'linus' into sched/clock
This commit is contained in:
commit
cf206bffbb
@ -89,8 +89,6 @@ cciss.txt
|
|||||||
- info, major/minor #'s for Compaq's SMART Array Controllers.
|
- info, major/minor #'s for Compaq's SMART Array Controllers.
|
||||||
cdrom/
|
cdrom/
|
||||||
- directory with information on the CD-ROM drivers that Linux has.
|
- directory with information on the CD-ROM drivers that Linux has.
|
||||||
cli-sti-removal.txt
|
|
||||||
- cli()/sti() removal guide.
|
|
||||||
computone.txt
|
computone.txt
|
||||||
- info on Computone Intelliport II/Plus Multiport Serial Driver.
|
- info on Computone Intelliport II/Plus Multiport Serial Driver.
|
||||||
connector/
|
connector/
|
||||||
|
315
Documentation/ABI/testing/sysfs-class-regulator
Normal file
315
Documentation/ABI/testing/sysfs-class-regulator
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
What: /sys/class/regulator/.../state
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
state. This holds the regulator output state.
|
||||||
|
|
||||||
|
This will be one of the following strings:
|
||||||
|
|
||||||
|
'enabled'
|
||||||
|
'disabled'
|
||||||
|
'unknown'
|
||||||
|
|
||||||
|
'enabled' means the regulator output is ON and is supplying
|
||||||
|
power to the system.
|
||||||
|
|
||||||
|
'disabled' means the regulator output is OFF and is not
|
||||||
|
supplying power to the system..
|
||||||
|
|
||||||
|
'unknown' means software cannot determine the state.
|
||||||
|
|
||||||
|
NOTE: this field can be used in conjunction with microvolts
|
||||||
|
and microamps to determine regulator output levels.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../type
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
type. This holds the regulator type.
|
||||||
|
|
||||||
|
This will be one of the following strings:
|
||||||
|
|
||||||
|
'voltage'
|
||||||
|
'current'
|
||||||
|
'unknown'
|
||||||
|
|
||||||
|
'voltage' means the regulator output voltage can be controlled
|
||||||
|
by software.
|
||||||
|
|
||||||
|
'current' means the regulator output current limit can be
|
||||||
|
controlled by software.
|
||||||
|
|
||||||
|
'unknown' means software cannot control either voltage or
|
||||||
|
current limit.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../microvolts
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
microvolts. This holds the regulator output voltage setting
|
||||||
|
measured in microvolts (i.e. E-6 Volts).
|
||||||
|
|
||||||
|
NOTE: This value should not be used to determine the regulator
|
||||||
|
output voltage level as this value is the same regardless of
|
||||||
|
whether the regulator is enabled or disabled.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../microamps
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
microamps. This holds the regulator output current limit
|
||||||
|
setting measured in microamps (i.e. E-6 Amps).
|
||||||
|
|
||||||
|
NOTE: This value should not be used to determine the regulator
|
||||||
|
output current level as this value is the same regardless of
|
||||||
|
whether the regulator is enabled or disabled.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../opmode
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
opmode. This holds the regulator operating mode setting.
|
||||||
|
|
||||||
|
The opmode value can be one of the following strings:
|
||||||
|
|
||||||
|
'fast'
|
||||||
|
'normal'
|
||||||
|
'idle'
|
||||||
|
'standby'
|
||||||
|
'unknown'
|
||||||
|
|
||||||
|
The modes are described in include/linux/regulator/regulator.h
|
||||||
|
|
||||||
|
NOTE: This value should not be used to determine the regulator
|
||||||
|
output operating mode as this value is the same regardless of
|
||||||
|
whether the regulator is enabled or disabled.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../min_microvolts
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
min_microvolts. This holds the minimum safe working regulator
|
||||||
|
output voltage setting for this domain measured in microvolts.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'constraint not defined' if
|
||||||
|
the power domain has no min microvolts constraint defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../max_microvolts
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
max_microvolts. This holds the maximum safe working regulator
|
||||||
|
output voltage setting for this domain measured in microvolts.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'constraint not defined' if
|
||||||
|
the power domain has no max microvolts constraint defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../min_microamps
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
min_microamps. This holds the minimum safe working regulator
|
||||||
|
output current limit setting for this domain measured in
|
||||||
|
microamps.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'constraint not defined' if
|
||||||
|
the power domain has no min microamps constraint defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../max_microamps
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
max_microamps. This holds the maximum safe working regulator
|
||||||
|
output current limit setting for this domain measured in
|
||||||
|
microamps.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'constraint not defined' if
|
||||||
|
the power domain has no max microamps constraint defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../num_users
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
num_users. This holds the number of consumer devices that
|
||||||
|
have called regulator_enable() on this regulator.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../requested_microamps
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
requested_microamps. This holds the total requested load
|
||||||
|
current in microamps for this regulator from all its consumer
|
||||||
|
devices.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../parent
|
||||||
|
Date: April 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Some regulator directories will contain a link called parent.
|
||||||
|
This points to the parent or supply regulator if one exists.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_mem_microvolts
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_mem_microvolts. This holds the regulator output
|
||||||
|
voltage setting for this domain measured in microvolts when
|
||||||
|
the system is suspended to memory.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'not defined' if
|
||||||
|
the power domain has no suspend to memory voltage defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_disk_microvolts
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_disk_microvolts. This holds the regulator output
|
||||||
|
voltage setting for this domain measured in microvolts when
|
||||||
|
the system is suspended to disk.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'not defined' if
|
||||||
|
the power domain has no suspend to disk voltage defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_standby_microvolts
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_standby_microvolts. This holds the regulator output
|
||||||
|
voltage setting for this domain measured in microvolts when
|
||||||
|
the system is suspended to standby.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'not defined' if
|
||||||
|
the power domain has no suspend to standby voltage defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_mem_mode
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_mem_mode. This holds the regulator operating mode
|
||||||
|
setting for this domain when the system is suspended to
|
||||||
|
memory.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'not defined' if
|
||||||
|
the power domain has no suspend to memory mode defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_disk_mode
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_disk_mode. This holds the regulator operating mode
|
||||||
|
setting for this domain when the system is suspended to disk.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'not defined' if
|
||||||
|
the power domain has no suspend to disk mode defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_standby_mode
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_standby_mode. This holds the regulator operating mode
|
||||||
|
setting for this domain when the system is suspended to
|
||||||
|
standby.
|
||||||
|
|
||||||
|
NOTE: this will return the string 'not defined' if
|
||||||
|
the power domain has no suspend to standby mode defined by
|
||||||
|
platform code.
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_mem_state
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_mem_state. This holds the regulator operating state
|
||||||
|
when suspended to memory.
|
||||||
|
|
||||||
|
This will be one of the following strings:
|
||||||
|
|
||||||
|
'enabled'
|
||||||
|
'disabled'
|
||||||
|
'not defined'
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_disk_state
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_disk_state. This holds the regulator operating state
|
||||||
|
when suspended to disk.
|
||||||
|
|
||||||
|
This will be one of the following strings:
|
||||||
|
|
||||||
|
'enabled'
|
||||||
|
'disabled'
|
||||||
|
'not defined'
|
||||||
|
|
||||||
|
What: /sys/class/regulator/.../suspend_standby_state
|
||||||
|
Date: May 2008
|
||||||
|
KernelVersion: 2.6.26
|
||||||
|
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
Description:
|
||||||
|
Each regulator directory will contain a field called
|
||||||
|
suspend_standby_state. This holds the regulator operating
|
||||||
|
state when suspended to standby.
|
||||||
|
|
||||||
|
This will be one of the following strings:
|
||||||
|
|
||||||
|
'enabled'
|
||||||
|
'disabled'
|
||||||
|
'not defined'
|
@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
|
|||||||
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
||||||
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
||||||
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
||||||
mac80211.xml debugobjects.xml
|
mac80211.xml debugobjects.xml sh.xml
|
||||||
|
|
||||||
###
|
###
|
||||||
# The build process is as follows (targets):
|
# The build process is as follows (targets):
|
||||||
|
@ -98,6 +98,24 @@
|
|||||||
"Kernel debugging" select "KGDB: kernel debugging with remote gdb".
|
"Kernel debugging" select "KGDB: kernel debugging with remote gdb".
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
|
It is advised, but not required that you turn on the
|
||||||
|
CONFIG_FRAME_POINTER kernel option. This option inserts code to
|
||||||
|
into the compiled executable which saves the frame information in
|
||||||
|
registers or on the stack at different points which will allow a
|
||||||
|
debugger such as gdb to more accurately construct stack back traces
|
||||||
|
while debugging the kernel.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If the architecture that you are using supports the kernel option
|
||||||
|
CONFIG_DEBUG_RODATA, you should consider turning it off. This
|
||||||
|
option will prevent the use of software breakpoints because it
|
||||||
|
marks certain regions of the kernel's memory space as read-only.
|
||||||
|
If kgdb supports it for the architecture you are using, you can
|
||||||
|
use hardware breakpoints if you desire to run with the
|
||||||
|
CONFIG_DEBUG_RODATA option turned on, else you need to turn off
|
||||||
|
this option.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
Next you should choose one of more I/O drivers to interconnect debugging
|
Next you should choose one of more I/O drivers to interconnect debugging
|
||||||
host and debugged target. Early boot debugging requires a KGDB
|
host and debugged target. Early boot debugging requires a KGDB
|
||||||
I/O driver that supports early debugging and the driver must be
|
I/O driver that supports early debugging and the driver must be
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
the hardware structures represented here, please consult the Principles
|
the hardware structures represented here, please consult the Principles
|
||||||
of Operation.
|
of Operation.
|
||||||
</para>
|
</para>
|
||||||
!Iinclude/asm-s390/cio.h
|
!Iarch/s390/include/asm/cio.h
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1 id="ccwdev">
|
<sect1 id="ccwdev">
|
||||||
<title>ccw devices</title>
|
<title>ccw devices</title>
|
||||||
@ -114,7 +114,7 @@
|
|||||||
ccw device structure. Device drivers must not bypass those functions
|
ccw device structure. Device drivers must not bypass those functions
|
||||||
or strange side effects may happen.
|
or strange side effects may happen.
|
||||||
</para>
|
</para>
|
||||||
!Iinclude/asm-s390/ccwdev.h
|
!Iarch/s390/include/asm/ccwdev.h
|
||||||
!Edrivers/s390/cio/device.c
|
!Edrivers/s390/cio/device.c
|
||||||
!Edrivers/s390/cio/device_ops.c
|
!Edrivers/s390/cio/device_ops.c
|
||||||
</sect1>
|
</sect1>
|
||||||
@ -125,7 +125,7 @@
|
|||||||
measurement data which is made available by the channel subsystem
|
measurement data which is made available by the channel subsystem
|
||||||
for each channel attached device.
|
for each channel attached device.
|
||||||
</para>
|
</para>
|
||||||
!Iinclude/asm-s390/cmb.h
|
!Iarch/s390/include/asm/cmb.h
|
||||||
!Edrivers/s390/cio/cmf.c
|
!Edrivers/s390/cio/cmf.c
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
@ -142,7 +142,7 @@
|
|||||||
</para>
|
</para>
|
||||||
<sect1 id="ccwgroupdevices">
|
<sect1 id="ccwgroupdevices">
|
||||||
<title>ccw group devices</title>
|
<title>ccw group devices</title>
|
||||||
!Iinclude/asm-s390/ccwgroup.h
|
!Iarch/s390/include/asm/ccwgroup.h
|
||||||
!Edrivers/s390/cio/ccwgroup.c
|
!Edrivers/s390/cio/ccwgroup.c
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
105
Documentation/DocBook/sh.tmpl
Normal file
105
Documentation/DocBook/sh.tmpl
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?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="sh-drivers">
|
||||||
|
<bookinfo>
|
||||||
|
<title>SuperH Interfaces Guide</title>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<firstname>Paul</firstname>
|
||||||
|
<surname>Mundt</surname>
|
||||||
|
<affiliation>
|
||||||
|
<address>
|
||||||
|
<email>lethal@linux-sh.org</email>
|
||||||
|
</address>
|
||||||
|
</affiliation>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
<year>2008</year>
|
||||||
|
<holder>Paul Mundt</holder>
|
||||||
|
</copyright>
|
||||||
|
<copyright>
|
||||||
|
<year>2008</year>
|
||||||
|
<holder>Renesas Technology Corp.</holder>
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<legalnotice>
|
||||||
|
<para>
|
||||||
|
This documentation 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.
|
||||||
|
</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="mm">
|
||||||
|
<title>Memory Management</title>
|
||||||
|
<sect1 id="sh4">
|
||||||
|
<title>SH-4</title>
|
||||||
|
<sect2 id="sq">
|
||||||
|
<title>Store Queue API</title>
|
||||||
|
!Earch/sh/kernel/cpu/sh4/sq.c
|
||||||
|
</sect2>
|
||||||
|
</sect1>
|
||||||
|
<sect1 id="sh5">
|
||||||
|
<title>SH-5</title>
|
||||||
|
<sect2 id="tlb">
|
||||||
|
<title>TLB Interfaces</title>
|
||||||
|
!Iarch/sh/mm/tlb-sh5.c
|
||||||
|
!Iarch/sh/include/asm/tlb_64.h
|
||||||
|
</sect2>
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="clk">
|
||||||
|
<title>Clock Framework Extensions</title>
|
||||||
|
!Iarch/sh/include/asm/clock.h
|
||||||
|
</chapter>
|
||||||
|
<chapter id="mach">
|
||||||
|
<title>Machine Specific Interfaces</title>
|
||||||
|
<sect1 id="dreamcast">
|
||||||
|
<title>mach-dreamcast</title>
|
||||||
|
!Iarch/sh/boards/mach-dreamcast/rtc.c
|
||||||
|
</sect1>
|
||||||
|
<sect1 id="x3proto">
|
||||||
|
<title>mach-x3proto</title>
|
||||||
|
!Earch/sh/boards/mach-x3proto/ilsel.c
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="busses">
|
||||||
|
<title>Busses</title>
|
||||||
|
<sect1 id="superhyway">
|
||||||
|
<title>SuperHyway</title>
|
||||||
|
!Edrivers/sh/superhyway/superhyway.c
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1 id="maple">
|
||||||
|
<title>Maple</title>
|
||||||
|
!Edrivers/sh/maple/maple.c
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
</book>
|
@ -1648,7 +1648,7 @@ static struct video_buffer capture_fb;
|
|||||||
|
|
||||||
<chapter id="pubfunctions">
|
<chapter id="pubfunctions">
|
||||||
<title>Public Functions Provided</title>
|
<title>Public Functions Provided</title>
|
||||||
!Edrivers/media/video/videodev.c
|
!Edrivers/media/video/v4l2-dev.c
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
@ -69,12 +69,6 @@
|
|||||||
device to be used as both a tty interface and as a synchronous
|
device to be used as both a tty interface and as a synchronous
|
||||||
controller is a project for Linux post the 2.4 release
|
controller is a project for Linux post the 2.4 release
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
The support code handles most common card configurations and
|
|
||||||
supports running both Cisco HDLC and Synchronous PPP. With extra
|
|
||||||
glue the frame relay and X.25 protocols can also be used with this
|
|
||||||
driver.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="Driver_Modes">
|
<chapter id="Driver_Modes">
|
||||||
@ -179,35 +173,27 @@
|
|||||||
<para>
|
<para>
|
||||||
If you wish to use the network interface facilities of the driver,
|
If you wish to use the network interface facilities of the driver,
|
||||||
then you need to attach a network device to each channel that is
|
then you need to attach a network device to each channel that is
|
||||||
present and in use. In addition to use the SyncPPP and Cisco HDLC
|
present and in use. In addition to use the generic HDLC
|
||||||
you need to follow some additional plumbing rules. They may seem
|
you need to follow some additional plumbing rules. They may seem
|
||||||
complex but a look at the example hostess_sv11 driver should
|
complex but a look at the example hostess_sv11 driver should
|
||||||
reassure you.
|
reassure you.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The network device used for each channel should be pointed to by
|
The network device used for each channel should be pointed to by
|
||||||
the netdevice field of each channel. The dev-> priv field of the
|
the netdevice field of each channel. The hdlc-> priv field of the
|
||||||
network device points to your private data - you will need to be
|
network device points to your private data - you will need to be
|
||||||
able to find your ppp device from this. In addition to use the
|
able to find your private data from this.
|
||||||
sync ppp layer the private data must start with a void * pointer
|
|
||||||
to the syncppp structures.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The way most drivers approach this particular problem is to
|
The way most drivers approach this particular problem is to
|
||||||
create a structure holding the Z8530 device definition and
|
create a structure holding the Z8530 device definition and
|
||||||
put that and the syncppp pointer into the private field of
|
put that into the private field of the network device. The
|
||||||
the network device. The network device fields of the channels
|
network device fields of the channels then point back to the
|
||||||
then point back to the network devices. The ppp_device can also
|
network devices.
|
||||||
be put in the private structure conveniently.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If you wish to use the synchronous ppp then you need to attach
|
If you wish to use the generic HDLC then you need to register
|
||||||
the syncppp layer to the network device. You should do this before
|
the HDLC device.
|
||||||
you register the network device. The
|
|
||||||
<function>sppp_attach</function> requires that the first void *
|
|
||||||
pointer in your private data is pointing to an empty struct
|
|
||||||
ppp_device. The function fills in the initial data for the
|
|
||||||
ppp/hdlc layer.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Before you register your network device you will also need to
|
Before you register your network device you will also need to
|
||||||
@ -314,10 +300,10 @@
|
|||||||
buffer in sk_buff format and queues it for transmission. The
|
buffer in sk_buff format and queues it for transmission. The
|
||||||
caller must provide the entire packet with the exception of the
|
caller must provide the entire packet with the exception of the
|
||||||
bitstuffing and CRC. This is normally done by the caller via
|
bitstuffing and CRC. This is normally done by the caller via
|
||||||
the syncppp interface layer. It returns 0 if the buffer has been
|
the generic HDLC interface layer. It returns 0 if the buffer has been
|
||||||
queued and non zero values for queue full. If the function accepts
|
queued and non zero values for queue full. If the function accepts
|
||||||
the buffer it becomes property of the Z8530 layer and the caller
|
the buffer it becomes property of the Z8530 layer and the caller
|
||||||
should not free it.
|
should not free it.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The function <function>z8530_get_stats</function> returns a pointer
|
The function <function>z8530_get_stats</function> returns a pointer
|
||||||
|
@ -32,7 +32,7 @@ Linux currently supports the following features on the IXP4xx chips:
|
|||||||
- Flash access (MTD/JFFS)
|
- Flash access (MTD/JFFS)
|
||||||
- I2C through GPIO on IXP42x
|
- I2C through GPIO on IXP42x
|
||||||
- GPIO for input/output/interrupts
|
- GPIO for input/output/interrupts
|
||||||
See include/asm-arm/arch-ixp4xx/platform.h for access functions.
|
See arch/arm/mach-ixp4xx/include/mach/platform.h for access functions.
|
||||||
- Timers (watchdog, OS)
|
- Timers (watchdog, OS)
|
||||||
|
|
||||||
The following components of the chips are not supported by Linux and
|
The following components of the chips are not supported by Linux and
|
||||||
|
@ -158,7 +158,7 @@ So, what's changed?
|
|||||||
be re-checked for pending events. (see the Neponset IRQ handler for
|
be re-checked for pending events. (see the Neponset IRQ handler for
|
||||||
details).
|
details).
|
||||||
|
|
||||||
7. fixup_irq() is gone, as is include/asm-arm/arch-*/irq.h
|
7. fixup_irq() is gone, as is arch/arm/mach-*/include/mach/irq.h
|
||||||
|
|
||||||
Please note that this will not solve all problems - some of them are
|
Please note that this will not solve all problems - some of them are
|
||||||
hardware based. Mixing level-based and edge-based IRQs on the same
|
hardware based. Mixing level-based and edge-based IRQs on the same
|
||||||
|
@ -79,7 +79,7 @@ Machine/Platform support
|
|||||||
To this end, we now have arch/arm/mach-$(MACHINE) directories which are
|
To this end, we now have arch/arm/mach-$(MACHINE) directories which are
|
||||||
designed to house the non-driver files for a particular machine (eg, PCI,
|
designed to house the non-driver files for a particular machine (eg, PCI,
|
||||||
memory management, architecture definitions etc). For all future
|
memory management, architecture definitions etc). For all future
|
||||||
machines, there should be a corresponding include/asm-arm/arch-$(MACHINE)
|
machines, there should be a corresponding arch/arm/mach-$(MACHINE)/include/mach
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ Kernel entry (head.S)
|
|||||||
class typically based around one or more system on a chip devices, and
|
class typically based around one or more system on a chip devices, and
|
||||||
acts as a natural container around the actual implementations. These
|
acts as a natural container around the actual implementations. These
|
||||||
classes are given directories - arch/arm/mach-<class> and
|
classes are given directories - arch/arm/mach-<class> and
|
||||||
include/asm-arm/arch-<class> - which contain the source files to
|
arch/arm/mach-<class> - which contain the source files to/include/mach
|
||||||
support the machine class. This directories also contain any machine
|
support the machine class. This directories also contain any machine
|
||||||
specific supporting code.
|
specific supporting code.
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ Introduction
|
|||||||
Headers
|
Headers
|
||||||
-------
|
-------
|
||||||
|
|
||||||
See include/asm-arm/arch-s3c2410/regs-gpio.h for the list
|
See arch/arm/mach-s3c2410/include/mach/regs-gpio.h for the list
|
||||||
of GPIO pins, and the configuration values for them. This
|
of GPIO pins, and the configuration values for them. This
|
||||||
is included by using #include <asm/arch/regs-gpio.h>
|
is included by using #include <mach/regs-gpio.h>
|
||||||
|
|
||||||
The GPIO management functions are defined in the hardware
|
The GPIO management functions are defined in the hardware
|
||||||
header include/asm-arm/arch-s3c2410/hardware.h which can be
|
header arch/arm/mach-s3c2410/include/mach/hardware.h which can be
|
||||||
included by #include <asm/arch/hardware.h>
|
included by #include <mach/hardware.h>
|
||||||
|
|
||||||
A useful amount of documentation can be found in the hardware
|
A useful amount of documentation can be found in the hardware
|
||||||
header on how the GPIO functions (and others) work.
|
header on how the GPIO functions (and others) work.
|
||||||
|
@ -36,7 +36,7 @@ Layout
|
|||||||
in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
|
in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
|
||||||
|
|
||||||
Register, kernel and platform data definitions are held in the
|
Register, kernel and platform data definitions are held in the
|
||||||
include/asm-arm/arch-s3c2410 directory.
|
arch/arm/mach-s3c2410 directory./include/mach
|
||||||
|
|
||||||
|
|
||||||
Machines
|
Machines
|
||||||
|
@ -49,7 +49,7 @@ Board Support
|
|||||||
Platform Data
|
Platform Data
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
See linux/include/asm-arm/arch-s3c2410/usb-control.h for the
|
See arch/arm/mach-s3c2410/include/mach/usb-control.h for the
|
||||||
descriptions of the platform device data. An implementation
|
descriptions of the platform device data. An implementation
|
||||||
can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .
|
can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .
|
||||||
|
|
||||||
|
@ -112,27 +112,18 @@ Hot plug support for SCSI tape drives
|
|||||||
|
|
||||||
Hot plugging of SCSI tape drives is supported, with some caveats.
|
Hot plugging of SCSI tape drives is supported, with some caveats.
|
||||||
The cciss driver must be informed that changes to the SCSI bus
|
The cciss driver must be informed that changes to the SCSI bus
|
||||||
have been made, in addition to and prior to informing the SCSI
|
have been made. This may be done via the /proc filesystem.
|
||||||
mid layer. This may be done via the /proc filesystem. For example:
|
For example:
|
||||||
|
|
||||||
echo "rescan" > /proc/scsi/cciss0/1
|
echo "rescan" > /proc/scsi/cciss0/1
|
||||||
|
|
||||||
This causes the adapter to query the adapter about changes to the
|
This causes the driver to query the adapter about changes to the
|
||||||
physical SCSI buses and/or fibre channel arbitrated loop and the
|
physical SCSI buses and/or fibre channel arbitrated loop and the
|
||||||
driver to make note of any new or removed sequential access devices
|
driver to make note of any new or removed sequential access devices
|
||||||
or medium changers. The driver will output messages indicating what
|
or medium changers. The driver will output messages indicating what
|
||||||
devices have been added or removed and the controller, bus, target and
|
devices have been added or removed and the controller, bus, target and
|
||||||
lun used to address the device. Once this is done, the SCSI mid layer
|
lun used to address the device. It then notifies the SCSI mid layer
|
||||||
can be informed of changes to the virtual SCSI bus which the driver
|
of these changes.
|
||||||
presents to it in the usual way. For example:
|
|
||||||
|
|
||||||
echo scsi add-single-device 3 2 1 0 > /proc/scsi/scsi
|
|
||||||
|
|
||||||
to add a device on controller 3, bus 2, target 1, lun 0. Note that
|
|
||||||
the driver makes an effort to preserve the devices positions
|
|
||||||
in the virtual SCSI bus, so if you are only moving tape drives
|
|
||||||
around on the same adapter and not adding or removing tape drives
|
|
||||||
from the adapter, informing the SCSI mid layer may not be necessary.
|
|
||||||
|
|
||||||
Note that the naming convention of the /proc filesystem entries
|
Note that the naming convention of the /proc filesystem entries
|
||||||
contains a number in addition to the driver name. (E.g. "cciss0"
|
contains a number in addition to the driver name. (E.g. "cciss0"
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
|
|
||||||
#### cli()/sti() removal guide, started by Ingo Molnar <mingo@redhat.com>
|
|
||||||
|
|
||||||
|
|
||||||
as of 2.5.28, five popular macros have been removed on SMP, and
|
|
||||||
are being phased out on UP:
|
|
||||||
|
|
||||||
cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags)
|
|
||||||
|
|
||||||
until now it was possible to protect driver code against interrupt
|
|
||||||
handlers via a cli(), but from now on other, more lightweight methods
|
|
||||||
have to be used for synchronization, such as spinlocks or semaphores.
|
|
||||||
|
|
||||||
for example, driver code that used to do something like:
|
|
||||||
|
|
||||||
struct driver_data;
|
|
||||||
|
|
||||||
irq_handler (...)
|
|
||||||
{
|
|
||||||
....
|
|
||||||
driver_data.finish = 1;
|
|
||||||
driver_data.new_work = 0;
|
|
||||||
....
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
ioctl_func (...)
|
|
||||||
{
|
|
||||||
...
|
|
||||||
cli();
|
|
||||||
...
|
|
||||||
driver_data.finish = 0;
|
|
||||||
driver_data.new_work = 2;
|
|
||||||
...
|
|
||||||
sti();
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
was SMP-correct because the cli() function ensured that no
|
|
||||||
interrupt handler (amongst them the above irq_handler()) function
|
|
||||||
would execute while the cli()-ed section is executing.
|
|
||||||
|
|
||||||
but from now on a more direct method of locking has to be used:
|
|
||||||
|
|
||||||
DEFINE_SPINLOCK(driver_lock);
|
|
||||||
struct driver_data;
|
|
||||||
|
|
||||||
irq_handler (...)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
....
|
|
||||||
spin_lock_irqsave(&driver_lock, flags);
|
|
||||||
....
|
|
||||||
driver_data.finish = 1;
|
|
||||||
driver_data.new_work = 0;
|
|
||||||
....
|
|
||||||
spin_unlock_irqrestore(&driver_lock, flags);
|
|
||||||
....
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
ioctl_func (...)
|
|
||||||
{
|
|
||||||
...
|
|
||||||
spin_lock_irq(&driver_lock);
|
|
||||||
...
|
|
||||||
driver_data.finish = 0;
|
|
||||||
driver_data.new_work = 2;
|
|
||||||
...
|
|
||||||
spin_unlock_irq(&driver_lock);
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
the above code has a number of advantages:
|
|
||||||
|
|
||||||
- the locking relation is easier to understand - actual lock usage
|
|
||||||
pinpoints the critical sections. cli() usage is too opaque.
|
|
||||||
Easier to understand means it's easier to debug.
|
|
||||||
|
|
||||||
- it's faster, because spinlocks are faster to acquire than the
|
|
||||||
potentially heavily-used IRQ lock. Furthermore, your driver does
|
|
||||||
not have to wait eg. for a big heavy SCSI interrupt to finish,
|
|
||||||
because the driver_lock spinlock is only used by your driver.
|
|
||||||
cli() on the other hand was used by many drivers, and extended
|
|
||||||
the critical section to the whole IRQ handler function - creating
|
|
||||||
serious lock contention.
|
|
||||||
|
|
||||||
|
|
||||||
to make the transition easier, we've still kept the cli(), sti(),
|
|
||||||
save_flags(), save_flags_cli() and restore_flags() macros defined
|
|
||||||
on UP systems - but their usage will be phased out until 2.6 is
|
|
||||||
released.
|
|
||||||
|
|
||||||
drivers that want to disable local interrupts (interrupts on the
|
|
||||||
current CPU), can use the following five macros:
|
|
||||||
|
|
||||||
local_irq_disable(), local_irq_enable(), local_save_flags(flags),
|
|
||||||
local_irq_save(flags), local_irq_restore(flags)
|
|
||||||
|
|
||||||
but beware, their meaning and semantics are much simpler, far from
|
|
||||||
that of the old cli(), sti(), save_flags(flags) and restore_flags(flags)
|
|
||||||
SMP meaning:
|
|
||||||
|
|
||||||
local_irq_disable() => turn local IRQs off
|
|
||||||
|
|
||||||
local_irq_enable() => turn local IRQs on
|
|
||||||
|
|
||||||
local_save_flags(flags) => save the current IRQ state into flags. The
|
|
||||||
state can be on or off. (on some
|
|
||||||
architectures there's even more bits in it.)
|
|
||||||
|
|
||||||
local_irq_save(flags) => save the current IRQ state into flags and
|
|
||||||
disable interrupts.
|
|
||||||
|
|
||||||
local_irq_restore(flags) => restore the IRQ state from flags.
|
|
||||||
|
|
||||||
(local_irq_save can save both irqs on and irqs off state, and
|
|
||||||
local_irq_restore can restore into both irqs on and irqs off state.)
|
|
||||||
|
|
||||||
another related change is that synchronize_irq() now takes a parameter:
|
|
||||||
synchronize_irq(irq). This change too has the purpose of making SMP
|
|
||||||
synchronization more lightweight - this way you can wait for your own
|
|
||||||
interrupt handler to finish, no need to wait for other IRQ sources.
|
|
||||||
|
|
||||||
|
|
||||||
why were these changes done? The main reason was the architectural burden
|
|
||||||
of maintaining the cli()/sti() interface - it became a real problem. The
|
|
||||||
new interrupt system is much more streamlined, easier to understand, debug,
|
|
||||||
and it's also a bit faster - the same happened to it that will happen to
|
|
||||||
cli()/sti() using drivers once they convert to spinlocks :-)
|
|
||||||
|
|
@ -311,9 +311,20 @@ the subsystem must be ready for it.
|
|||||||
[An Example]
|
[An Example]
|
||||||
|
|
||||||
The best example of these basic concepts is the simple_children
|
The best example of these basic concepts is the simple_children
|
||||||
subsystem/group and the simple_child item in configfs_example.c It
|
subsystem/group and the simple_child item in configfs_example_explicit.c
|
||||||
shows a trivial object displaying and storing an attribute, and a simple
|
and configfs_example_macros.c. It shows a trivial object displaying and
|
||||||
group creating and destroying these children.
|
storing an attribute, and a simple group creating and destroying these
|
||||||
|
children.
|
||||||
|
|
||||||
|
The only difference between configfs_example_explicit.c and
|
||||||
|
configfs_example_macros.c is how the attributes of the childless item
|
||||||
|
are defined. The childless item has extended attributes, each with
|
||||||
|
their own show()/store() operation. This follows a convention commonly
|
||||||
|
used in sysfs. configfs_example_explicit.c creates these attributes
|
||||||
|
by explicitly defining the structures involved. Conversely
|
||||||
|
configfs_example_macros.c uses some convenience macros from configfs.h
|
||||||
|
to define the attributes. These macros are similar to their sysfs
|
||||||
|
counterparts.
|
||||||
|
|
||||||
[Hierarchy Navigation and the Subsystem Mutex]
|
[Hierarchy Navigation and the Subsystem Mutex]
|
||||||
|
|
||||||
|
@ -1,485 +0,0 @@
|
|||||||
/*
|
|
||||||
* vim: noexpandtab ts=8 sts=0 sw=8:
|
|
||||||
*
|
|
||||||
* configfs_example.c - This file is a demonstration module containing
|
|
||||||
* a number of configfs subsystems.
|
|
||||||
*
|
|
||||||
* 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 021110-1307, USA.
|
|
||||||
*
|
|
||||||
* Based on sysfs:
|
|
||||||
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
|
|
||||||
*
|
|
||||||
* configfs Copyright (C) 2005 Oracle. All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
|
|
||||||
#include <linux/configfs.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 01-childless
|
|
||||||
*
|
|
||||||
* This first example is a childless subsystem. It cannot create
|
|
||||||
* any config_items. It just has attributes.
|
|
||||||
*
|
|
||||||
* Note that we are enclosing the configfs_subsystem inside a container.
|
|
||||||
* This is not necessary if a subsystem has no attributes directly
|
|
||||||
* on the subsystem. See the next example, 02-simple-children, for
|
|
||||||
* such a subsystem.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct childless {
|
|
||||||
struct configfs_subsystem subsys;
|
|
||||||
int showme;
|
|
||||||
int storeme;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct childless_attribute {
|
|
||||||
struct configfs_attribute attr;
|
|
||||||
ssize_t (*show)(struct childless *, char *);
|
|
||||||
ssize_t (*store)(struct childless *, const char *, size_t);
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct childless *to_childless(struct config_item *item)
|
|
||||||
{
|
|
||||||
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t childless_showme_read(struct childless *childless,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
ssize_t pos;
|
|
||||||
|
|
||||||
pos = sprintf(page, "%d\n", childless->showme);
|
|
||||||
childless->showme++;
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t childless_storeme_read(struct childless *childless,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
return sprintf(page, "%d\n", childless->storeme);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t childless_storeme_write(struct childless *childless,
|
|
||||||
const char *page,
|
|
||||||
size_t count)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
char *p = (char *) page;
|
|
||||||
|
|
||||||
tmp = simple_strtoul(p, &p, 10);
|
|
||||||
if (!p || (*p && (*p != '\n')))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (tmp > INT_MAX)
|
|
||||||
return -ERANGE;
|
|
||||||
|
|
||||||
childless->storeme = tmp;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t childless_description_read(struct childless *childless,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
return sprintf(page,
|
|
||||||
"[01-childless]\n"
|
|
||||||
"\n"
|
|
||||||
"The childless subsystem is the simplest possible subsystem in\n"
|
|
||||||
"configfs. It does not support the creation of child config_items.\n"
|
|
||||||
"It only has a few attributes. In fact, it isn't much different\n"
|
|
||||||
"than a directory in /proc.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct childless_attribute childless_attr_showme = {
|
|
||||||
.attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
|
|
||||||
.show = childless_showme_read,
|
|
||||||
};
|
|
||||||
static struct childless_attribute childless_attr_storeme = {
|
|
||||||
.attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
|
|
||||||
.show = childless_storeme_read,
|
|
||||||
.store = childless_storeme_write,
|
|
||||||
};
|
|
||||||
static struct childless_attribute childless_attr_description = {
|
|
||||||
.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
|
|
||||||
.show = childless_description_read,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct configfs_attribute *childless_attrs[] = {
|
|
||||||
&childless_attr_showme.attr,
|
|
||||||
&childless_attr_storeme.attr,
|
|
||||||
&childless_attr_description.attr,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t childless_attr_show(struct config_item *item,
|
|
||||||
struct configfs_attribute *attr,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
struct childless *childless = to_childless(item);
|
|
||||||
struct childless_attribute *childless_attr =
|
|
||||||
container_of(attr, struct childless_attribute, attr);
|
|
||||||
ssize_t ret = 0;
|
|
||||||
|
|
||||||
if (childless_attr->show)
|
|
||||||
ret = childless_attr->show(childless, page);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t childless_attr_store(struct config_item *item,
|
|
||||||
struct configfs_attribute *attr,
|
|
||||||
const char *page, size_t count)
|
|
||||||
{
|
|
||||||
struct childless *childless = to_childless(item);
|
|
||||||
struct childless_attribute *childless_attr =
|
|
||||||
container_of(attr, struct childless_attribute, attr);
|
|
||||||
ssize_t ret = -EINVAL;
|
|
||||||
|
|
||||||
if (childless_attr->store)
|
|
||||||
ret = childless_attr->store(childless, page, count);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_item_operations childless_item_ops = {
|
|
||||||
.show_attribute = childless_attr_show,
|
|
||||||
.store_attribute = childless_attr_store,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct config_item_type childless_type = {
|
|
||||||
.ct_item_ops = &childless_item_ops,
|
|
||||||
.ct_attrs = childless_attrs,
|
|
||||||
.ct_owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct childless childless_subsys = {
|
|
||||||
.subsys = {
|
|
||||||
.su_group = {
|
|
||||||
.cg_item = {
|
|
||||||
.ci_namebuf = "01-childless",
|
|
||||||
.ci_type = &childless_type,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 02-simple-children
|
|
||||||
*
|
|
||||||
* This example merely has a simple one-attribute child. Note that
|
|
||||||
* there is no extra attribute structure, as the child's attribute is
|
|
||||||
* known from the get-go. Also, there is no container for the
|
|
||||||
* subsystem, as it has no attributes of its own.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct simple_child {
|
|
||||||
struct config_item item;
|
|
||||||
int storeme;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct simple_child *to_simple_child(struct config_item *item)
|
|
||||||
{
|
|
||||||
return item ? container_of(item, struct simple_child, item) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_attribute simple_child_attr_storeme = {
|
|
||||||
.ca_owner = THIS_MODULE,
|
|
||||||
.ca_name = "storeme",
|
|
||||||
.ca_mode = S_IRUGO | S_IWUSR,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct configfs_attribute *simple_child_attrs[] = {
|
|
||||||
&simple_child_attr_storeme,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t simple_child_attr_show(struct config_item *item,
|
|
||||||
struct configfs_attribute *attr,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
ssize_t count;
|
|
||||||
struct simple_child *simple_child = to_simple_child(item);
|
|
||||||
|
|
||||||
count = sprintf(page, "%d\n", simple_child->storeme);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t simple_child_attr_store(struct config_item *item,
|
|
||||||
struct configfs_attribute *attr,
|
|
||||||
const char *page, size_t count)
|
|
||||||
{
|
|
||||||
struct simple_child *simple_child = to_simple_child(item);
|
|
||||||
unsigned long tmp;
|
|
||||||
char *p = (char *) page;
|
|
||||||
|
|
||||||
tmp = simple_strtoul(p, &p, 10);
|
|
||||||
if (!p || (*p && (*p != '\n')))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (tmp > INT_MAX)
|
|
||||||
return -ERANGE;
|
|
||||||
|
|
||||||
simple_child->storeme = tmp;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simple_child_release(struct config_item *item)
|
|
||||||
{
|
|
||||||
kfree(to_simple_child(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_item_operations simple_child_item_ops = {
|
|
||||||
.release = simple_child_release,
|
|
||||||
.show_attribute = simple_child_attr_show,
|
|
||||||
.store_attribute = simple_child_attr_store,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct config_item_type simple_child_type = {
|
|
||||||
.ct_item_ops = &simple_child_item_ops,
|
|
||||||
.ct_attrs = simple_child_attrs,
|
|
||||||
.ct_owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct simple_children {
|
|
||||||
struct config_group group;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct simple_children *to_simple_children(struct config_item *item)
|
|
||||||
{
|
|
||||||
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
|
|
||||||
{
|
|
||||||
struct simple_child *simple_child;
|
|
||||||
|
|
||||||
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
|
||||||
if (!simple_child)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
|
|
||||||
config_item_init_type_name(&simple_child->item, name,
|
|
||||||
&simple_child_type);
|
|
||||||
|
|
||||||
simple_child->storeme = 0;
|
|
||||||
|
|
||||||
return &simple_child->item;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_attribute simple_children_attr_description = {
|
|
||||||
.ca_owner = THIS_MODULE,
|
|
||||||
.ca_name = "description",
|
|
||||||
.ca_mode = S_IRUGO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct configfs_attribute *simple_children_attrs[] = {
|
|
||||||
&simple_children_attr_description,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t simple_children_attr_show(struct config_item *item,
|
|
||||||
struct configfs_attribute *attr,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
return sprintf(page,
|
|
||||||
"[02-simple-children]\n"
|
|
||||||
"\n"
|
|
||||||
"This subsystem allows the creation of child config_items. These\n"
|
|
||||||
"items have only one attribute that is readable and writeable.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simple_children_release(struct config_item *item)
|
|
||||||
{
|
|
||||||
kfree(to_simple_children(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_item_operations simple_children_item_ops = {
|
|
||||||
.release = simple_children_release,
|
|
||||||
.show_attribute = simple_children_attr_show,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that, since no extra work is required on ->drop_item(),
|
|
||||||
* no ->drop_item() is provided.
|
|
||||||
*/
|
|
||||||
static struct configfs_group_operations simple_children_group_ops = {
|
|
||||||
.make_item = simple_children_make_item,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct config_item_type simple_children_type = {
|
|
||||||
.ct_item_ops = &simple_children_item_ops,
|
|
||||||
.ct_group_ops = &simple_children_group_ops,
|
|
||||||
.ct_attrs = simple_children_attrs,
|
|
||||||
.ct_owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct configfs_subsystem simple_children_subsys = {
|
|
||||||
.su_group = {
|
|
||||||
.cg_item = {
|
|
||||||
.ci_namebuf = "02-simple-children",
|
|
||||||
.ci_type = &simple_children_type,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 03-group-children
|
|
||||||
*
|
|
||||||
* This example reuses the simple_children group from above. However,
|
|
||||||
* the simple_children group is not the subsystem itself, it is a
|
|
||||||
* child of the subsystem. Creation of a group in the subsystem creates
|
|
||||||
* a new simple_children group. That group can then have simple_child
|
|
||||||
* children of its own.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
|
|
||||||
{
|
|
||||||
struct simple_children *simple_children;
|
|
||||||
|
|
||||||
simple_children = kzalloc(sizeof(struct simple_children),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!simple_children)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
|
|
||||||
config_group_init_type_name(&simple_children->group, name,
|
|
||||||
&simple_children_type);
|
|
||||||
|
|
||||||
return &simple_children->group;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_attribute group_children_attr_description = {
|
|
||||||
.ca_owner = THIS_MODULE,
|
|
||||||
.ca_name = "description",
|
|
||||||
.ca_mode = S_IRUGO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct configfs_attribute *group_children_attrs[] = {
|
|
||||||
&group_children_attr_description,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t group_children_attr_show(struct config_item *item,
|
|
||||||
struct configfs_attribute *attr,
|
|
||||||
char *page)
|
|
||||||
{
|
|
||||||
return sprintf(page,
|
|
||||||
"[03-group-children]\n"
|
|
||||||
"\n"
|
|
||||||
"This subsystem allows the creation of child config_groups. These\n"
|
|
||||||
"groups are like the subsystem simple-children.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_item_operations group_children_item_ops = {
|
|
||||||
.show_attribute = group_children_attr_show,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that, since no extra work is required on ->drop_item(),
|
|
||||||
* no ->drop_item() is provided.
|
|
||||||
*/
|
|
||||||
static struct configfs_group_operations group_children_group_ops = {
|
|
||||||
.make_group = group_children_make_group,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct config_item_type group_children_type = {
|
|
||||||
.ct_item_ops = &group_children_item_ops,
|
|
||||||
.ct_group_ops = &group_children_group_ops,
|
|
||||||
.ct_attrs = group_children_attrs,
|
|
||||||
.ct_owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct configfs_subsystem group_children_subsys = {
|
|
||||||
.su_group = {
|
|
||||||
.cg_item = {
|
|
||||||
.ci_namebuf = "03-group-children",
|
|
||||||
.ci_type = &group_children_type,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We're now done with our subsystem definitions.
|
|
||||||
* For convenience in this module, here's a list of them all. It
|
|
||||||
* allows the init function to easily register them. Most modules
|
|
||||||
* will only have one subsystem, and will only call register_subsystem
|
|
||||||
* on it directly.
|
|
||||||
*/
|
|
||||||
static struct configfs_subsystem *example_subsys[] = {
|
|
||||||
&childless_subsys.subsys,
|
|
||||||
&simple_children_subsys,
|
|
||||||
&group_children_subsys,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init configfs_example_init(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
struct configfs_subsystem *subsys;
|
|
||||||
|
|
||||||
for (i = 0; example_subsys[i]; i++) {
|
|
||||||
subsys = example_subsys[i];
|
|
||||||
|
|
||||||
config_group_init(&subsys->su_group);
|
|
||||||
mutex_init(&subsys->su_mutex);
|
|
||||||
ret = configfs_register_subsystem(subsys);
|
|
||||||
if (ret) {
|
|
||||||
printk(KERN_ERR "Error %d while registering subsystem %s\n",
|
|
||||||
ret,
|
|
||||||
subsys->su_group.cg_item.ci_namebuf);
|
|
||||||
goto out_unregister;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_unregister:
|
|
||||||
for (; i >= 0; i--) {
|
|
||||||
configfs_unregister_subsystem(example_subsys[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit configfs_example_exit(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; example_subsys[i]; i++) {
|
|
||||||
configfs_unregister_subsystem(example_subsys[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(configfs_example_init);
|
|
||||||
module_exit(configfs_example_exit);
|
|
||||||
MODULE_LICENSE("GPL");
|
|
485
Documentation/filesystems/configfs/configfs_example_explicit.c
Normal file
485
Documentation/filesystems/configfs/configfs_example_explicit.c
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
/*
|
||||||
|
* vim: noexpandtab ts=8 sts=0 sw=8:
|
||||||
|
*
|
||||||
|
* configfs_example_explicit.c - This file is a demonstration module
|
||||||
|
* containing a number of configfs subsystems. It explicitly defines
|
||||||
|
* each structure without using the helper macros defined in
|
||||||
|
* configfs.h.
|
||||||
|
*
|
||||||
|
* 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 021110-1307, USA.
|
||||||
|
*
|
||||||
|
* Based on sysfs:
|
||||||
|
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
|
||||||
|
*
|
||||||
|
* configfs Copyright (C) 2005 Oracle. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <linux/configfs.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 01-childless
|
||||||
|
*
|
||||||
|
* This first example is a childless subsystem. It cannot create
|
||||||
|
* any config_items. It just has attributes.
|
||||||
|
*
|
||||||
|
* Note that we are enclosing the configfs_subsystem inside a container.
|
||||||
|
* This is not necessary if a subsystem has no attributes directly
|
||||||
|
* on the subsystem. See the next example, 02-simple-children, for
|
||||||
|
* such a subsystem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct childless {
|
||||||
|
struct configfs_subsystem subsys;
|
||||||
|
int showme;
|
||||||
|
int storeme;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct childless_attribute {
|
||||||
|
struct configfs_attribute attr;
|
||||||
|
ssize_t (*show)(struct childless *, char *);
|
||||||
|
ssize_t (*store)(struct childless *, const char *, size_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct childless *to_childless(struct config_item *item)
|
||||||
|
{
|
||||||
|
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_showme_read(struct childless *childless,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
ssize_t pos;
|
||||||
|
|
||||||
|
pos = sprintf(page, "%d\n", childless->showme);
|
||||||
|
childless->showme++;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_storeme_read(struct childless *childless,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page, "%d\n", childless->storeme);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_storeme_write(struct childless *childless,
|
||||||
|
const char *page,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
char *p = (char *) page;
|
||||||
|
|
||||||
|
tmp = simple_strtoul(p, &p, 10);
|
||||||
|
if (!p || (*p && (*p != '\n')))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (tmp > INT_MAX)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
childless->storeme = tmp;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_description_read(struct childless *childless,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page,
|
||||||
|
"[01-childless]\n"
|
||||||
|
"\n"
|
||||||
|
"The childless subsystem is the simplest possible subsystem in\n"
|
||||||
|
"configfs. It does not support the creation of child config_items.\n"
|
||||||
|
"It only has a few attributes. In fact, it isn't much different\n"
|
||||||
|
"than a directory in /proc.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct childless_attribute childless_attr_showme = {
|
||||||
|
.attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
|
||||||
|
.show = childless_showme_read,
|
||||||
|
};
|
||||||
|
static struct childless_attribute childless_attr_storeme = {
|
||||||
|
.attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
|
||||||
|
.show = childless_storeme_read,
|
||||||
|
.store = childless_storeme_write,
|
||||||
|
};
|
||||||
|
static struct childless_attribute childless_attr_description = {
|
||||||
|
.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
|
||||||
|
.show = childless_description_read,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *childless_attrs[] = {
|
||||||
|
&childless_attr_showme.attr,
|
||||||
|
&childless_attr_storeme.attr,
|
||||||
|
&childless_attr_description.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t childless_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
struct childless *childless = to_childless(item);
|
||||||
|
struct childless_attribute *childless_attr =
|
||||||
|
container_of(attr, struct childless_attribute, attr);
|
||||||
|
ssize_t ret = 0;
|
||||||
|
|
||||||
|
if (childless_attr->show)
|
||||||
|
ret = childless_attr->show(childless, page);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_attr_store(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
const char *page, size_t count)
|
||||||
|
{
|
||||||
|
struct childless *childless = to_childless(item);
|
||||||
|
struct childless_attribute *childless_attr =
|
||||||
|
container_of(attr, struct childless_attribute, attr);
|
||||||
|
ssize_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (childless_attr->store)
|
||||||
|
ret = childless_attr->store(childless, page, count);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations childless_item_ops = {
|
||||||
|
.show_attribute = childless_attr_show,
|
||||||
|
.store_attribute = childless_attr_store,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type childless_type = {
|
||||||
|
.ct_item_ops = &childless_item_ops,
|
||||||
|
.ct_attrs = childless_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct childless childless_subsys = {
|
||||||
|
.subsys = {
|
||||||
|
.su_group = {
|
||||||
|
.cg_item = {
|
||||||
|
.ci_namebuf = "01-childless",
|
||||||
|
.ci_type = &childless_type,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 02-simple-children
|
||||||
|
*
|
||||||
|
* This example merely has a simple one-attribute child. Note that
|
||||||
|
* there is no extra attribute structure, as the child's attribute is
|
||||||
|
* known from the get-go. Also, there is no container for the
|
||||||
|
* subsystem, as it has no attributes of its own.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct simple_child {
|
||||||
|
struct config_item item;
|
||||||
|
int storeme;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct simple_child *to_simple_child(struct config_item *item)
|
||||||
|
{
|
||||||
|
return item ? container_of(item, struct simple_child, item) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_attribute simple_child_attr_storeme = {
|
||||||
|
.ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "storeme",
|
||||||
|
.ca_mode = S_IRUGO | S_IWUSR,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *simple_child_attrs[] = {
|
||||||
|
&simple_child_attr_storeme,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t simple_child_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
ssize_t count;
|
||||||
|
struct simple_child *simple_child = to_simple_child(item);
|
||||||
|
|
||||||
|
count = sprintf(page, "%d\n", simple_child->storeme);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t simple_child_attr_store(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
const char *page, size_t count)
|
||||||
|
{
|
||||||
|
struct simple_child *simple_child = to_simple_child(item);
|
||||||
|
unsigned long tmp;
|
||||||
|
char *p = (char *) page;
|
||||||
|
|
||||||
|
tmp = simple_strtoul(p, &p, 10);
|
||||||
|
if (!p || (*p && (*p != '\n')))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (tmp > INT_MAX)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
simple_child->storeme = tmp;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simple_child_release(struct config_item *item)
|
||||||
|
{
|
||||||
|
kfree(to_simple_child(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations simple_child_item_ops = {
|
||||||
|
.release = simple_child_release,
|
||||||
|
.show_attribute = simple_child_attr_show,
|
||||||
|
.store_attribute = simple_child_attr_store,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type simple_child_type = {
|
||||||
|
.ct_item_ops = &simple_child_item_ops,
|
||||||
|
.ct_attrs = simple_child_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct simple_children {
|
||||||
|
struct config_group group;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct simple_children *to_simple_children(struct config_item *item)
|
||||||
|
{
|
||||||
|
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
|
||||||
|
{
|
||||||
|
struct simple_child *simple_child;
|
||||||
|
|
||||||
|
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
||||||
|
if (!simple_child)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
config_item_init_type_name(&simple_child->item, name,
|
||||||
|
&simple_child_type);
|
||||||
|
|
||||||
|
simple_child->storeme = 0;
|
||||||
|
|
||||||
|
return &simple_child->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_attribute simple_children_attr_description = {
|
||||||
|
.ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "description",
|
||||||
|
.ca_mode = S_IRUGO,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *simple_children_attrs[] = {
|
||||||
|
&simple_children_attr_description,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t simple_children_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page,
|
||||||
|
"[02-simple-children]\n"
|
||||||
|
"\n"
|
||||||
|
"This subsystem allows the creation of child config_items. These\n"
|
||||||
|
"items have only one attribute that is readable and writeable.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simple_children_release(struct config_item *item)
|
||||||
|
{
|
||||||
|
kfree(to_simple_children(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations simple_children_item_ops = {
|
||||||
|
.release = simple_children_release,
|
||||||
|
.show_attribute = simple_children_attr_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that, since no extra work is required on ->drop_item(),
|
||||||
|
* no ->drop_item() is provided.
|
||||||
|
*/
|
||||||
|
static struct configfs_group_operations simple_children_group_ops = {
|
||||||
|
.make_item = simple_children_make_item,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type simple_children_type = {
|
||||||
|
.ct_item_ops = &simple_children_item_ops,
|
||||||
|
.ct_group_ops = &simple_children_group_ops,
|
||||||
|
.ct_attrs = simple_children_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_subsystem simple_children_subsys = {
|
||||||
|
.su_group = {
|
||||||
|
.cg_item = {
|
||||||
|
.ci_namebuf = "02-simple-children",
|
||||||
|
.ci_type = &simple_children_type,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 03-group-children
|
||||||
|
*
|
||||||
|
* This example reuses the simple_children group from above. However,
|
||||||
|
* the simple_children group is not the subsystem itself, it is a
|
||||||
|
* child of the subsystem. Creation of a group in the subsystem creates
|
||||||
|
* a new simple_children group. That group can then have simple_child
|
||||||
|
* children of its own.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
|
||||||
|
{
|
||||||
|
struct simple_children *simple_children;
|
||||||
|
|
||||||
|
simple_children = kzalloc(sizeof(struct simple_children),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!simple_children)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
config_group_init_type_name(&simple_children->group, name,
|
||||||
|
&simple_children_type);
|
||||||
|
|
||||||
|
return &simple_children->group;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_attribute group_children_attr_description = {
|
||||||
|
.ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "description",
|
||||||
|
.ca_mode = S_IRUGO,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *group_children_attrs[] = {
|
||||||
|
&group_children_attr_description,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t group_children_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page,
|
||||||
|
"[03-group-children]\n"
|
||||||
|
"\n"
|
||||||
|
"This subsystem allows the creation of child config_groups. These\n"
|
||||||
|
"groups are like the subsystem simple-children.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations group_children_item_ops = {
|
||||||
|
.show_attribute = group_children_attr_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that, since no extra work is required on ->drop_item(),
|
||||||
|
* no ->drop_item() is provided.
|
||||||
|
*/
|
||||||
|
static struct configfs_group_operations group_children_group_ops = {
|
||||||
|
.make_group = group_children_make_group,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type group_children_type = {
|
||||||
|
.ct_item_ops = &group_children_item_ops,
|
||||||
|
.ct_group_ops = &group_children_group_ops,
|
||||||
|
.ct_attrs = group_children_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_subsystem group_children_subsys = {
|
||||||
|
.su_group = {
|
||||||
|
.cg_item = {
|
||||||
|
.ci_namebuf = "03-group-children",
|
||||||
|
.ci_type = &group_children_type,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're now done with our subsystem definitions.
|
||||||
|
* For convenience in this module, here's a list of them all. It
|
||||||
|
* allows the init function to easily register them. Most modules
|
||||||
|
* will only have one subsystem, and will only call register_subsystem
|
||||||
|
* on it directly.
|
||||||
|
*/
|
||||||
|
static struct configfs_subsystem *example_subsys[] = {
|
||||||
|
&childless_subsys.subsys,
|
||||||
|
&simple_children_subsys,
|
||||||
|
&group_children_subsys,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init configfs_example_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
struct configfs_subsystem *subsys;
|
||||||
|
|
||||||
|
for (i = 0; example_subsys[i]; i++) {
|
||||||
|
subsys = example_subsys[i];
|
||||||
|
|
||||||
|
config_group_init(&subsys->su_group);
|
||||||
|
mutex_init(&subsys->su_mutex);
|
||||||
|
ret = configfs_register_subsystem(subsys);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_ERR "Error %d while registering subsystem %s\n",
|
||||||
|
ret,
|
||||||
|
subsys->su_group.cg_item.ci_namebuf);
|
||||||
|
goto out_unregister;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_unregister:
|
||||||
|
for (; i >= 0; i--) {
|
||||||
|
configfs_unregister_subsystem(example_subsys[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit configfs_example_exit(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; example_subsys[i]; i++) {
|
||||||
|
configfs_unregister_subsystem(example_subsys[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(configfs_example_init);
|
||||||
|
module_exit(configfs_example_exit);
|
||||||
|
MODULE_LICENSE("GPL");
|
448
Documentation/filesystems/configfs/configfs_example_macros.c
Normal file
448
Documentation/filesystems/configfs/configfs_example_macros.c
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
/*
|
||||||
|
* vim: noexpandtab ts=8 sts=0 sw=8:
|
||||||
|
*
|
||||||
|
* configfs_example_macros.c - This file is a demonstration module
|
||||||
|
* containing a number of configfs subsystems. It uses the helper
|
||||||
|
* macros defined by configfs.h
|
||||||
|
*
|
||||||
|
* 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 021110-1307, USA.
|
||||||
|
*
|
||||||
|
* Based on sysfs:
|
||||||
|
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
|
||||||
|
*
|
||||||
|
* configfs Copyright (C) 2005 Oracle. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <linux/configfs.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 01-childless
|
||||||
|
*
|
||||||
|
* This first example is a childless subsystem. It cannot create
|
||||||
|
* any config_items. It just has attributes.
|
||||||
|
*
|
||||||
|
* Note that we are enclosing the configfs_subsystem inside a container.
|
||||||
|
* This is not necessary if a subsystem has no attributes directly
|
||||||
|
* on the subsystem. See the next example, 02-simple-children, for
|
||||||
|
* such a subsystem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct childless {
|
||||||
|
struct configfs_subsystem subsys;
|
||||||
|
int showme;
|
||||||
|
int storeme;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct childless *to_childless(struct config_item *item)
|
||||||
|
{
|
||||||
|
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIGFS_ATTR_STRUCT(childless);
|
||||||
|
#define CHILDLESS_ATTR(_name, _mode, _show, _store) \
|
||||||
|
struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
|
||||||
|
#define CHILDLESS_ATTR_RO(_name, _show) \
|
||||||
|
struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show);
|
||||||
|
|
||||||
|
static ssize_t childless_showme_read(struct childless *childless,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
ssize_t pos;
|
||||||
|
|
||||||
|
pos = sprintf(page, "%d\n", childless->showme);
|
||||||
|
childless->showme++;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_storeme_read(struct childless *childless,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page, "%d\n", childless->storeme);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_storeme_write(struct childless *childless,
|
||||||
|
const char *page,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
char *p = (char *) page;
|
||||||
|
|
||||||
|
tmp = simple_strtoul(p, &p, 10);
|
||||||
|
if (!p || (*p && (*p != '\n')))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (tmp > INT_MAX)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
childless->storeme = tmp;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t childless_description_read(struct childless *childless,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page,
|
||||||
|
"[01-childless]\n"
|
||||||
|
"\n"
|
||||||
|
"The childless subsystem is the simplest possible subsystem in\n"
|
||||||
|
"configfs. It does not support the creation of child config_items.\n"
|
||||||
|
"It only has a few attributes. In fact, it isn't much different\n"
|
||||||
|
"than a directory in /proc.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
CHILDLESS_ATTR_RO(showme, childless_showme_read);
|
||||||
|
CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read,
|
||||||
|
childless_storeme_write);
|
||||||
|
CHILDLESS_ATTR_RO(description, childless_description_read);
|
||||||
|
|
||||||
|
static struct configfs_attribute *childless_attrs[] = {
|
||||||
|
&childless_attr_showme.attr,
|
||||||
|
&childless_attr_storeme.attr,
|
||||||
|
&childless_attr_description.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
CONFIGFS_ATTR_OPS(childless);
|
||||||
|
static struct configfs_item_operations childless_item_ops = {
|
||||||
|
.show_attribute = childless_attr_show,
|
||||||
|
.store_attribute = childless_attr_store,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type childless_type = {
|
||||||
|
.ct_item_ops = &childless_item_ops,
|
||||||
|
.ct_attrs = childless_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct childless childless_subsys = {
|
||||||
|
.subsys = {
|
||||||
|
.su_group = {
|
||||||
|
.cg_item = {
|
||||||
|
.ci_namebuf = "01-childless",
|
||||||
|
.ci_type = &childless_type,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 02-simple-children
|
||||||
|
*
|
||||||
|
* This example merely has a simple one-attribute child. Note that
|
||||||
|
* there is no extra attribute structure, as the child's attribute is
|
||||||
|
* known from the get-go. Also, there is no container for the
|
||||||
|
* subsystem, as it has no attributes of its own.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct simple_child {
|
||||||
|
struct config_item item;
|
||||||
|
int storeme;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct simple_child *to_simple_child(struct config_item *item)
|
||||||
|
{
|
||||||
|
return item ? container_of(item, struct simple_child, item) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_attribute simple_child_attr_storeme = {
|
||||||
|
.ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "storeme",
|
||||||
|
.ca_mode = S_IRUGO | S_IWUSR,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *simple_child_attrs[] = {
|
||||||
|
&simple_child_attr_storeme,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t simple_child_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
ssize_t count;
|
||||||
|
struct simple_child *simple_child = to_simple_child(item);
|
||||||
|
|
||||||
|
count = sprintf(page, "%d\n", simple_child->storeme);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t simple_child_attr_store(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
const char *page, size_t count)
|
||||||
|
{
|
||||||
|
struct simple_child *simple_child = to_simple_child(item);
|
||||||
|
unsigned long tmp;
|
||||||
|
char *p = (char *) page;
|
||||||
|
|
||||||
|
tmp = simple_strtoul(p, &p, 10);
|
||||||
|
if (!p || (*p && (*p != '\n')))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (tmp > INT_MAX)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
simple_child->storeme = tmp;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simple_child_release(struct config_item *item)
|
||||||
|
{
|
||||||
|
kfree(to_simple_child(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations simple_child_item_ops = {
|
||||||
|
.release = simple_child_release,
|
||||||
|
.show_attribute = simple_child_attr_show,
|
||||||
|
.store_attribute = simple_child_attr_store,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type simple_child_type = {
|
||||||
|
.ct_item_ops = &simple_child_item_ops,
|
||||||
|
.ct_attrs = simple_child_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct simple_children {
|
||||||
|
struct config_group group;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct simple_children *to_simple_children(struct config_item *item)
|
||||||
|
{
|
||||||
|
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
|
||||||
|
{
|
||||||
|
struct simple_child *simple_child;
|
||||||
|
|
||||||
|
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
||||||
|
if (!simple_child)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
config_item_init_type_name(&simple_child->item, name,
|
||||||
|
&simple_child_type);
|
||||||
|
|
||||||
|
simple_child->storeme = 0;
|
||||||
|
|
||||||
|
return &simple_child->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_attribute simple_children_attr_description = {
|
||||||
|
.ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "description",
|
||||||
|
.ca_mode = S_IRUGO,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *simple_children_attrs[] = {
|
||||||
|
&simple_children_attr_description,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t simple_children_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page,
|
||||||
|
"[02-simple-children]\n"
|
||||||
|
"\n"
|
||||||
|
"This subsystem allows the creation of child config_items. These\n"
|
||||||
|
"items have only one attribute that is readable and writeable.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simple_children_release(struct config_item *item)
|
||||||
|
{
|
||||||
|
kfree(to_simple_children(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations simple_children_item_ops = {
|
||||||
|
.release = simple_children_release,
|
||||||
|
.show_attribute = simple_children_attr_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that, since no extra work is required on ->drop_item(),
|
||||||
|
* no ->drop_item() is provided.
|
||||||
|
*/
|
||||||
|
static struct configfs_group_operations simple_children_group_ops = {
|
||||||
|
.make_item = simple_children_make_item,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type simple_children_type = {
|
||||||
|
.ct_item_ops = &simple_children_item_ops,
|
||||||
|
.ct_group_ops = &simple_children_group_ops,
|
||||||
|
.ct_attrs = simple_children_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_subsystem simple_children_subsys = {
|
||||||
|
.su_group = {
|
||||||
|
.cg_item = {
|
||||||
|
.ci_namebuf = "02-simple-children",
|
||||||
|
.ci_type = &simple_children_type,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 03-group-children
|
||||||
|
*
|
||||||
|
* This example reuses the simple_children group from above. However,
|
||||||
|
* the simple_children group is not the subsystem itself, it is a
|
||||||
|
* child of the subsystem. Creation of a group in the subsystem creates
|
||||||
|
* a new simple_children group. That group can then have simple_child
|
||||||
|
* children of its own.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
|
||||||
|
{
|
||||||
|
struct simple_children *simple_children;
|
||||||
|
|
||||||
|
simple_children = kzalloc(sizeof(struct simple_children),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!simple_children)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
config_group_init_type_name(&simple_children->group, name,
|
||||||
|
&simple_children_type);
|
||||||
|
|
||||||
|
return &simple_children->group;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_attribute group_children_attr_description = {
|
||||||
|
.ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "description",
|
||||||
|
.ca_mode = S_IRUGO,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_attribute *group_children_attrs[] = {
|
||||||
|
&group_children_attr_description,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t group_children_attr_show(struct config_item *item,
|
||||||
|
struct configfs_attribute *attr,
|
||||||
|
char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page,
|
||||||
|
"[03-group-children]\n"
|
||||||
|
"\n"
|
||||||
|
"This subsystem allows the creation of child config_groups. These\n"
|
||||||
|
"groups are like the subsystem simple-children.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations group_children_item_ops = {
|
||||||
|
.show_attribute = group_children_attr_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that, since no extra work is required on ->drop_item(),
|
||||||
|
* no ->drop_item() is provided.
|
||||||
|
*/
|
||||||
|
static struct configfs_group_operations group_children_group_ops = {
|
||||||
|
.make_group = group_children_make_group,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_item_type group_children_type = {
|
||||||
|
.ct_item_ops = &group_children_item_ops,
|
||||||
|
.ct_group_ops = &group_children_group_ops,
|
||||||
|
.ct_attrs = group_children_attrs,
|
||||||
|
.ct_owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct configfs_subsystem group_children_subsys = {
|
||||||
|
.su_group = {
|
||||||
|
.cg_item = {
|
||||||
|
.ci_namebuf = "03-group-children",
|
||||||
|
.ci_type = &group_children_type,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're now done with our subsystem definitions.
|
||||||
|
* For convenience in this module, here's a list of them all. It
|
||||||
|
* allows the init function to easily register them. Most modules
|
||||||
|
* will only have one subsystem, and will only call register_subsystem
|
||||||
|
* on it directly.
|
||||||
|
*/
|
||||||
|
static struct configfs_subsystem *example_subsys[] = {
|
||||||
|
&childless_subsys.subsys,
|
||||||
|
&simple_children_subsys,
|
||||||
|
&group_children_subsys,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init configfs_example_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
struct configfs_subsystem *subsys;
|
||||||
|
|
||||||
|
for (i = 0; example_subsys[i]; i++) {
|
||||||
|
subsys = example_subsys[i];
|
||||||
|
|
||||||
|
config_group_init(&subsys->su_group);
|
||||||
|
mutex_init(&subsys->su_mutex);
|
||||||
|
ret = configfs_register_subsystem(subsys);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_ERR "Error %d while registering subsystem %s\n",
|
||||||
|
ret,
|
||||||
|
subsys->su_group.cg_item.ci_namebuf);
|
||||||
|
goto out_unregister;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_unregister:
|
||||||
|
for (; i >= 0; i--) {
|
||||||
|
configfs_unregister_subsystem(example_subsys[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit configfs_example_exit(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; example_subsys[i]; i++) {
|
||||||
|
configfs_unregister_subsystem(example_subsys[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(configfs_example_init);
|
||||||
|
module_exit(configfs_example_exit);
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -4,6 +4,7 @@
|
|||||||
Copyright 2008 Red Hat Inc.
|
Copyright 2008 Red Hat Inc.
|
||||||
Author: Steven Rostedt <srostedt@redhat.com>
|
Author: Steven Rostedt <srostedt@redhat.com>
|
||||||
License: The GNU Free Documentation License, Version 1.2
|
License: The GNU Free Documentation License, Version 1.2
|
||||||
|
(dual licensed under the GPL v2)
|
||||||
Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton,
|
Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton,
|
||||||
John Kacur, and David Teigland.
|
John Kacur, and David Teigland.
|
||||||
|
|
||||||
|
@ -10,6 +10,10 @@ Supported chips:
|
|||||||
Prefix: 'sch311x'
|
Prefix: 'sch311x'
|
||||||
Addresses scanned: none, address read from Super-I/O config space
|
Addresses scanned: none, address read from Super-I/O config space
|
||||||
Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf
|
Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf
|
||||||
|
* SMSC SCH5027
|
||||||
|
Prefix: 'sch5027'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: Provided by SMSC upon request and under NDA
|
||||||
|
|
||||||
Authors:
|
Authors:
|
||||||
Juerg Haefliger <juergh@gmail.com>
|
Juerg Haefliger <juergh@gmail.com>
|
||||||
@ -22,34 +26,36 @@ Module Parameters
|
|||||||
and PWM output control functions. Using this parameter
|
and PWM output control functions. Using this parameter
|
||||||
shouldn't be required since the BIOS usually takes care
|
shouldn't be required since the BIOS usually takes care
|
||||||
of this.
|
of this.
|
||||||
|
* probe_all_addr: bool Include non-standard LPC addresses 0x162e and 0x164e
|
||||||
Note that there is no need to use this parameter if the driver loads without
|
when probing for ISA devices. This is required for the
|
||||||
complaining. The driver will say so if it is necessary.
|
following boards:
|
||||||
|
- VIA EPIA SN18000
|
||||||
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
This driver implements support for the hardware monitoring capabilities of the
|
This driver implements support for the hardware monitoring capabilities of the
|
||||||
SMSC DME1737 and Asus A8000 (which are the same) and SMSC SCH311x Super-I/O
|
SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, and SMSC
|
||||||
chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote
|
SCH311x Super-I/O chips. These chips feature monitoring of 3 temp sensors
|
||||||
diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up
|
temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and
|
||||||
to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM
|
1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement
|
||||||
outputs pwm[1-3,5-6] for controlling fan speeds both manually and
|
up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and
|
||||||
automatically.
|
automatically.
|
||||||
|
|
||||||
For the DME1737 and A8000, fan[1-2] and pwm[1-2] are always present. Fan[3-6]
|
For the DME1737, A8000 and SCH5027, fan[1-2] and pwm[1-2] are always present.
|
||||||
and pwm[3,5-6] are optional features and their availability depends on the
|
Fan[3-6] and pwm[3,5-6] are optional features and their availability depends on
|
||||||
configuration of the chip. The driver will detect which features are present
|
the configuration of the chip. The driver will detect which features are
|
||||||
during initialization and create the sysfs attributes accordingly.
|
present during initialization and create the sysfs attributes accordingly.
|
||||||
|
|
||||||
For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and
|
For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and
|
||||||
pwm[5-6] don't exist.
|
pwm[5-6] don't exist.
|
||||||
|
|
||||||
The hardware monitoring features of the DME1737 and A8000 are only accessible
|
The hardware monitoring features of the DME1737, A8000, and SCH5027 are only
|
||||||
via SMBus, while the SCH311x only provides access via the ISA bus. The driver
|
accessible via SMBus, while the SCH311x only provides access via the ISA bus.
|
||||||
will therefore register itself as an I2C client driver if it detects a DME1737
|
The driver will therefore register itself as an I2C client driver if it detects
|
||||||
or A8000 and as a platform driver if it detects a SCH311x chip.
|
a DME1737, A8000, or SCH5027 and as a platform driver if it detects a SCH311x
|
||||||
|
chip.
|
||||||
|
|
||||||
|
|
||||||
Voltage Monitoring
|
Voltage Monitoring
|
||||||
@ -60,6 +66,7 @@ scaling resistors. The values returned by the driver therefore reflect true
|
|||||||
millivolts and don't need scaling. The voltage inputs are mapped as follows
|
millivolts and don't need scaling. The voltage inputs are mapped as follows
|
||||||
(the last column indicates the input ranges):
|
(the last column indicates the input ranges):
|
||||||
|
|
||||||
|
DME1737, A8000:
|
||||||
in0: +5VTR (+5V standby) 0V - 6.64V
|
in0: +5VTR (+5V standby) 0V - 6.64V
|
||||||
in1: Vccp (processor core) 0V - 3V
|
in1: Vccp (processor core) 0V - 3V
|
||||||
in2: VCC (internal +3.3V) 0V - 4.38V
|
in2: VCC (internal +3.3V) 0V - 4.38V
|
||||||
@ -68,6 +75,24 @@ millivolts and don't need scaling. The voltage inputs are mapped as follows
|
|||||||
in5: VTR (+3.3V standby) 0V - 4.38V
|
in5: VTR (+3.3V standby) 0V - 4.38V
|
||||||
in6: Vbat (+3.0V) 0V - 4.38V
|
in6: Vbat (+3.0V) 0V - 4.38V
|
||||||
|
|
||||||
|
SCH311x:
|
||||||
|
in0: +2.5V 0V - 6.64V
|
||||||
|
in1: Vccp (processor core) 0V - 2V
|
||||||
|
in2: VCC (internal +3.3V) 0V - 4.38V
|
||||||
|
in3: +5V 0V - 6.64V
|
||||||
|
in4: +12V 0V - 16V
|
||||||
|
in5: VTR (+3.3V standby) 0V - 4.38V
|
||||||
|
in6: Vbat (+3.0V) 0V - 4.38V
|
||||||
|
|
||||||
|
SCH5027:
|
||||||
|
in0: +5VTR (+5V standby) 0V - 6.64V
|
||||||
|
in1: Vccp (processor core) 0V - 3V
|
||||||
|
in2: VCC (internal +3.3V) 0V - 4.38V
|
||||||
|
in3: V2_IN 0V - 1.5V
|
||||||
|
in4: V1_IN 0V - 1.5V
|
||||||
|
in5: VTR (+3.3V standby) 0V - 4.38V
|
||||||
|
in6: Vbat (+3.0V) 0V - 4.38V
|
||||||
|
|
||||||
Each voltage input has associated min and max limits which trigger an alarm
|
Each voltage input has associated min and max limits which trigger an alarm
|
||||||
when crossed.
|
when crossed.
|
||||||
|
|
||||||
|
@ -6,12 +6,14 @@ Supported chips:
|
|||||||
Prefix: 'it87'
|
Prefix: 'it87'
|
||||||
Addresses scanned: from Super I/O config space (8 I/O ports)
|
Addresses scanned: from Super I/O config space (8 I/O ports)
|
||||||
Datasheet: Publicly available at the ITE website
|
Datasheet: Publicly available at the ITE website
|
||||||
http://www.ite.com.tw/
|
http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf
|
||||||
* IT8712F
|
* IT8712F
|
||||||
Prefix: 'it8712'
|
Prefix: 'it8712'
|
||||||
Addresses scanned: from Super I/O config space (8 I/O ports)
|
Addresses scanned: from Super I/O config space (8 I/O ports)
|
||||||
Datasheet: Publicly available at the ITE website
|
Datasheet: Publicly available at the ITE website
|
||||||
http://www.ite.com.tw/
|
http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf
|
||||||
|
http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf
|
||||||
|
http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf
|
||||||
* IT8716F/IT8726F
|
* IT8716F/IT8726F
|
||||||
Prefix: 'it8716'
|
Prefix: 'it8716'
|
||||||
Addresses scanned: from Super I/O config space (8 I/O ports)
|
Addresses scanned: from Super I/O config space (8 I/O ports)
|
||||||
@ -90,14 +92,13 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you
|
|||||||
can't have both on a given board.
|
can't have both on a given board.
|
||||||
|
|
||||||
The IT8716F, IT8718F and later IT8712F revisions have support for
|
The IT8716F, IT8718F and later IT8712F revisions have support for
|
||||||
2 additional fans. They are supported by the driver for the IT8716F and
|
2 additional fans. The additional fans are supported by the driver.
|
||||||
IT8718F but not for the IT8712F
|
|
||||||
|
|
||||||
The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
|
The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
|
||||||
16-bit tachometer counters for fans 1 to 3. This is better (no more fan
|
16-bit tachometer counters for fans 1 to 3. This is better (no more fan
|
||||||
clock divider mess) but not compatible with the older chips and
|
clock divider mess) but not compatible with the older chips and
|
||||||
revisions. For now, the driver only uses the 16-bit mode on the
|
revisions. The 16-bit tachometer mode is enabled by the driver when one
|
||||||
IT8716F and IT8718F.
|
of the above chips is detected.
|
||||||
|
|
||||||
The IT8726F is just bit enhanced IT8716F with additional hardware
|
The IT8726F is just bit enhanced IT8716F with additional hardware
|
||||||
for AMD power sequencing. Therefore the chip will appear as IT8716F
|
for AMD power sequencing. Therefore the chip will appear as IT8716F
|
||||||
|
@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has
|
|||||||
confirmed this "bug". The ADT7463 is reported to work as described in the
|
confirmed this "bug". The ADT7463 is reported to work as described in the
|
||||||
documentation. The current lm85 driver does not show the offset register.
|
documentation. The current lm85 driver does not show the offset register.
|
||||||
|
|
||||||
The ADT7463 has a THERM asserted counter. This counter has a 22.76ms
|
|
||||||
resolution and a range of 5.8 seconds. The driver implements a 32-bit
|
|
||||||
accumulator of the counter value to extend the range to over a year. The
|
|
||||||
counter will stay at it's max value until read.
|
|
||||||
|
|
||||||
See the vendor datasheets for more information. There is application note
|
See the vendor datasheets for more information. There is application note
|
||||||
from National (AN-1260) with some additional information about the LM85.
|
from National (AN-1260) with some additional information about the LM85.
|
||||||
The Analog Devices datasheet is very detailed and describes a procedure for
|
The Analog Devices datasheet is very detailed and describes a procedure for
|
||||||
@ -206,13 +201,15 @@ Configuration choices:
|
|||||||
|
|
||||||
The National LM85's have two vendor specific configuration
|
The National LM85's have two vendor specific configuration
|
||||||
features. Tach. mode and Spinup Control. For more details on these,
|
features. Tach. mode and Spinup Control. For more details on these,
|
||||||
see the LM85 datasheet or Application Note AN-1260.
|
see the LM85 datasheet or Application Note AN-1260. These features
|
||||||
|
are not currently supported by the lm85 driver.
|
||||||
|
|
||||||
The Analog Devices ADM1027 has several vendor specific enhancements.
|
The Analog Devices ADM1027 has several vendor specific enhancements.
|
||||||
The number of pulses-per-rev of the fans can be set, Tach monitoring
|
The number of pulses-per-rev of the fans can be set, Tach monitoring
|
||||||
can be optimized for PWM operation, and an offset can be applied to
|
can be optimized for PWM operation, and an offset can be applied to
|
||||||
the temperatures to compensate for systemic errors in the
|
the temperatures to compensate for systemic errors in the
|
||||||
measurements.
|
measurements. These features are not currently supported by the lm85
|
||||||
|
driver.
|
||||||
|
|
||||||
In addition to the ADM1027 features, the ADT7463 also has Tmin control
|
In addition to the ADM1027 features, the ADT7463 also has Tmin control
|
||||||
and THERM asserted counts. Automatic Tmin control acts to adjust the
|
and THERM asserted counts. Automatic Tmin control acts to adjust the
|
||||||
|
@ -40,10 +40,6 @@ Module Parameters
|
|||||||
(default is 1)
|
(default is 1)
|
||||||
Use 'init=0' to bypass initializing the chip.
|
Use 'init=0' to bypass initializing the chip.
|
||||||
Try this if your computer crashes when you load the module.
|
Try this if your computer crashes when you load the module.
|
||||||
* reset: int
|
|
||||||
(default is 0)
|
|
||||||
The driver used to reset the chip on load, but does no more. Use
|
|
||||||
'reset=1' to restore the old behavior. Report if you need to do this.
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
@ -22,6 +22,7 @@ Credits:
|
|||||||
|
|
||||||
Additional contributors:
|
Additional contributors:
|
||||||
Sven Anders <anders@anduras.de>
|
Sven Anders <anders@anduras.de>
|
||||||
|
Marc Hulsman <m.hulsman@tudelft.nl>
|
||||||
|
|
||||||
Module Parameters
|
Module Parameters
|
||||||
-----------------
|
-----------------
|
||||||
@ -67,9 +68,8 @@ on until the temperature falls below the Hysteresis value.
|
|||||||
|
|
||||||
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
triggered if the rotation speed has dropped below a programmable limit. Fan
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
readings can be divided by a programmable divider (1, 2, 4, 8 for fan 1/2/3
|
readings can be divided by a programmable divider (1, 2, 4, 8, 16,
|
||||||
and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more
|
32, 64 or 128 for all fans) to give the readings more range or accuracy.
|
||||||
range or accuracy.
|
|
||||||
|
|
||||||
Voltage sensors (also known as IN sensors) report their values in millivolts.
|
Voltage sensors (also known as IN sensors) report their values in millivolts.
|
||||||
An alarm is triggered if the voltage has crossed a programmable minimum
|
An alarm is triggered if the voltage has crossed a programmable minimum
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
PM quality of Service interface.
|
PM Quality Of Service Interface.
|
||||||
|
|
||||||
This interface provides a kernel and user mode interface for registering
|
This interface provides a kernel and user mode interface for registering
|
||||||
performance expectations by drivers, subsystems and user space applications on
|
performance expectations by drivers, subsystems and user space applications on
|
||||||
@ -7,6 +7,11 @@ one of the parameters.
|
|||||||
Currently we have {cpu_dma_latency, network_latency, network_throughput} as the
|
Currently we have {cpu_dma_latency, network_latency, network_throughput} as the
|
||||||
initial set of pm_qos parameters.
|
initial set of pm_qos parameters.
|
||||||
|
|
||||||
|
Each parameters have defined units:
|
||||||
|
* latency: usec
|
||||||
|
* timeout: usec
|
||||||
|
* throughput: kbs (kilo bit / sec)
|
||||||
|
|
||||||
The infrastructure exposes multiple misc device nodes one per implemented
|
The infrastructure exposes multiple misc device nodes one per implemented
|
||||||
parameter. The set of parameters implement is defined by pm_qos_power_init()
|
parameter. The set of parameters implement is defined by pm_qos_power_init()
|
||||||
and pm_qos_params.h. This is done because having the available parameters
|
and pm_qos_params.h. This is done because having the available parameters
|
||||||
|
@ -101,6 +101,10 @@ of charge when battery became full/empty". It also could mean "value of
|
|||||||
charge when battery considered full/empty at given conditions (temperature,
|
charge when battery considered full/empty at given conditions (temperature,
|
||||||
age)". I.e. these attributes represents real thresholds, not design values.
|
age)". I.e. these attributes represents real thresholds, not design values.
|
||||||
|
|
||||||
|
CHARGE_COUNTER - the current charge counter (in µAh). This could easily
|
||||||
|
be negative; there is no empty or full value. It is only useful for
|
||||||
|
relative, time-based measurements.
|
||||||
|
|
||||||
ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
|
ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
|
||||||
|
|
||||||
CAPACITY - capacity in percents.
|
CAPACITY - capacity in percents.
|
||||||
|
182
Documentation/power/regulator/consumer.txt
Normal file
182
Documentation/power/regulator/consumer.txt
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
Regulator Consumer Driver Interface
|
||||||
|
===================================
|
||||||
|
|
||||||
|
This text describes the regulator interface for consumer device drivers.
|
||||||
|
Please see overview.txt for a description of the terms used in this text.
|
||||||
|
|
||||||
|
|
||||||
|
1. Consumer Regulator Access (static & dynamic drivers)
|
||||||
|
=======================================================
|
||||||
|
|
||||||
|
A consumer driver can get access to it's supply regulator by calling :-
|
||||||
|
|
||||||
|
regulator = regulator_get(dev, "Vcc");
|
||||||
|
|
||||||
|
The consumer passes in it's struct device pointer and power supply ID. The core
|
||||||
|
then finds the correct regulator by consulting a machine specific lookup table.
|
||||||
|
If the lookup is successful then this call will return a pointer to the struct
|
||||||
|
regulator that supplies this consumer.
|
||||||
|
|
||||||
|
To release the regulator the consumer driver should call :-
|
||||||
|
|
||||||
|
regulator_put(regulator);
|
||||||
|
|
||||||
|
Consumers can be supplied by more than one regulator e.g. codec consumer with
|
||||||
|
analog and digital supplies :-
|
||||||
|
|
||||||
|
digital = regulator_get(dev, "Vcc"); /* digital core */
|
||||||
|
analog = regulator_get(dev, "Avdd"); /* analog */
|
||||||
|
|
||||||
|
The regulator access functions regulator_get() and regulator_put() will
|
||||||
|
usually be called in your device drivers probe() and remove() respectively.
|
||||||
|
|
||||||
|
|
||||||
|
2. Regulator Output Enable & Disable (static & dynamic drivers)
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
A consumer can enable it's power supply by calling:-
|
||||||
|
|
||||||
|
int regulator_enable(regulator);
|
||||||
|
|
||||||
|
NOTE: The supply may already be enabled before regulator_enabled() is called.
|
||||||
|
This may happen if the consumer shares the regulator or the regulator has been
|
||||||
|
previously enabled by bootloader or kernel board initialization code.
|
||||||
|
|
||||||
|
A consumer can determine if a regulator is enabled by calling :-
|
||||||
|
|
||||||
|
int regulator_is_enabled(regulator);
|
||||||
|
|
||||||
|
This will return > zero when the regulator is enabled.
|
||||||
|
|
||||||
|
|
||||||
|
A consumer can disable it's supply when no longer needed by calling :-
|
||||||
|
|
||||||
|
int regulator_disable(regulator);
|
||||||
|
|
||||||
|
NOTE: This may not disable the supply if it's shared with other consumers. The
|
||||||
|
regulator will only be disabled when the enabled reference count is zero.
|
||||||
|
|
||||||
|
Finally, a regulator can be forcefully disabled in the case of an emergency :-
|
||||||
|
|
||||||
|
int regulator_force_disable(regulator);
|
||||||
|
|
||||||
|
NOTE: this will immediately and forcefully shutdown the regulator output. All
|
||||||
|
consumers will be powered off.
|
||||||
|
|
||||||
|
|
||||||
|
3. Regulator Voltage Control & Status (dynamic drivers)
|
||||||
|
======================================================
|
||||||
|
|
||||||
|
Some consumer drivers need to be able to dynamically change their supply
|
||||||
|
voltage to match system operating points. e.g. CPUfreq drivers can scale
|
||||||
|
voltage along with frequency to save power, SD drivers may need to select the
|
||||||
|
correct card voltage, etc.
|
||||||
|
|
||||||
|
Consumers can control their supply voltage by calling :-
|
||||||
|
|
||||||
|
int regulator_set_voltage(regulator, min_uV, max_uV);
|
||||||
|
|
||||||
|
Where min_uV and max_uV are the minimum and maximum acceptable voltages in
|
||||||
|
microvolts.
|
||||||
|
|
||||||
|
NOTE: this can be called when the regulator is enabled or disabled. If called
|
||||||
|
when enabled, then the voltage changes instantly, otherwise the voltage
|
||||||
|
configuration changes and the voltage is physically set when the regulator is
|
||||||
|
next enabled.
|
||||||
|
|
||||||
|
The regulators configured voltage output can be found by calling :-
|
||||||
|
|
||||||
|
int regulator_get_voltage(regulator);
|
||||||
|
|
||||||
|
NOTE: get_voltage() will return the configured output voltage whether the
|
||||||
|
regulator is enabled or disabled and should NOT be used to determine regulator
|
||||||
|
output state. However this can be used in conjunction with is_enabled() to
|
||||||
|
determine the regulator physical output voltage.
|
||||||
|
|
||||||
|
|
||||||
|
4. Regulator Current Limit Control & Status (dynamic drivers)
|
||||||
|
===========================================================
|
||||||
|
|
||||||
|
Some consumer drivers need to be able to dynamically change their supply
|
||||||
|
current limit to match system operating points. e.g. LCD backlight driver can
|
||||||
|
change the current limit to vary the backlight brightness, USB drivers may want
|
||||||
|
to set the limit to 500mA when supplying power.
|
||||||
|
|
||||||
|
Consumers can control their supply current limit by calling :-
|
||||||
|
|
||||||
|
int regulator_set_current_limit(regulator, min_uV, max_uV);
|
||||||
|
|
||||||
|
Where min_uA and max_uA are the minimum and maximum acceptable current limit in
|
||||||
|
microamps.
|
||||||
|
|
||||||
|
NOTE: this can be called when the regulator is enabled or disabled. If called
|
||||||
|
when enabled, then the current limit changes instantly, otherwise the current
|
||||||
|
limit configuration changes and the current limit is physically set when the
|
||||||
|
regulator is next enabled.
|
||||||
|
|
||||||
|
A regulators current limit can be found by calling :-
|
||||||
|
|
||||||
|
int regulator_get_current_limit(regulator);
|
||||||
|
|
||||||
|
NOTE: get_current_limit() will return the current limit whether the regulator
|
||||||
|
is enabled or disabled and should not be used to determine regulator current
|
||||||
|
load.
|
||||||
|
|
||||||
|
|
||||||
|
5. Regulator Operating Mode Control & Status (dynamic drivers)
|
||||||
|
=============================================================
|
||||||
|
|
||||||
|
Some consumers can further save system power by changing the operating mode of
|
||||||
|
their supply regulator to be more efficient when the consumers operating state
|
||||||
|
changes. e.g. consumer driver is idle and subsequently draws less current
|
||||||
|
|
||||||
|
Regulator operating mode can be changed indirectly or directly.
|
||||||
|
|
||||||
|
Indirect operating mode control.
|
||||||
|
--------------------------------
|
||||||
|
Consumer drivers can request a change in their supply regulator operating mode
|
||||||
|
by calling :-
|
||||||
|
|
||||||
|
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
||||||
|
|
||||||
|
This will cause the core to recalculate the total load on the regulator (based
|
||||||
|
on all it's consumers) and change operating mode (if necessary and permitted)
|
||||||
|
to best match the current operating load.
|
||||||
|
|
||||||
|
The load_uA value can be determined from the consumers datasheet. e.g.most
|
||||||
|
datasheets have tables showing the max current consumed in certain situations.
|
||||||
|
|
||||||
|
Most consumers will use indirect operating mode control since they have no
|
||||||
|
knowledge of the regulator or whether the regulator is shared with other
|
||||||
|
consumers.
|
||||||
|
|
||||||
|
Direct operating mode control.
|
||||||
|
------------------------------
|
||||||
|
Bespoke or tightly coupled drivers may want to directly control regulator
|
||||||
|
operating mode depending on their operating point. This can be achieved by
|
||||||
|
calling :-
|
||||||
|
|
||||||
|
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
|
||||||
|
unsigned int regulator_get_mode(struct regulator *regulator);
|
||||||
|
|
||||||
|
Direct mode will only be used by consumers that *know* about the regulator and
|
||||||
|
are not sharing the regulator with other consumers.
|
||||||
|
|
||||||
|
|
||||||
|
6. Regulator Events
|
||||||
|
===================
|
||||||
|
Regulators can notify consumers of external events. Events could be received by
|
||||||
|
consumers under regulator stress or failure conditions.
|
||||||
|
|
||||||
|
Consumers can register interest in regulator events by calling :-
|
||||||
|
|
||||||
|
int regulator_register_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
|
||||||
|
Consumers can uregister interest by calling :-
|
||||||
|
|
||||||
|
int regulator_unregister_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
|
||||||
|
Regulators use the kernel notifier framework to send event to thier interested
|
||||||
|
consumers.
|
101
Documentation/power/regulator/machine.txt
Normal file
101
Documentation/power/regulator/machine.txt
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
Regulator Machine Driver Interface
|
||||||
|
===================================
|
||||||
|
|
||||||
|
The regulator machine driver interface is intended for board/machine specific
|
||||||
|
initialisation code to configure the regulator subsystem. Typical things that
|
||||||
|
machine drivers would do are :-
|
||||||
|
|
||||||
|
1. Regulator -> Device mapping.
|
||||||
|
2. Regulator supply configuration.
|
||||||
|
3. Power Domain constraint setting.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. Regulator -> device mapping
|
||||||
|
==============================
|
||||||
|
Consider the following machine :-
|
||||||
|
|
||||||
|
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
||||||
|
|
|
||||||
|
+-> [Consumer B @ 3.3V]
|
||||||
|
|
||||||
|
The drivers for consumers A & B must be mapped to the correct regulator in
|
||||||
|
order to control their power supply. This mapping can be achieved in machine
|
||||||
|
initialisation code by calling :-
|
||||||
|
|
||||||
|
int regulator_set_device_supply(const char *regulator, struct device *dev,
|
||||||
|
const char *supply);
|
||||||
|
|
||||||
|
and is shown with the following code :-
|
||||||
|
|
||||||
|
regulator_set_device_supply("Regulator-1", devB, "Vcc");
|
||||||
|
regulator_set_device_supply("Regulator-2", devA, "Vcc");
|
||||||
|
|
||||||
|
This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2
|
||||||
|
to the 'Vcc' supply for Consumer A.
|
||||||
|
|
||||||
|
|
||||||
|
2. Regulator supply configuration.
|
||||||
|
==================================
|
||||||
|
Consider the following machine (again) :-
|
||||||
|
|
||||||
|
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
||||||
|
|
|
||||||
|
+-> [Consumer B @ 3.3V]
|
||||||
|
|
||||||
|
Regulator-1 supplies power to Regulator-2. This relationship must be registered
|
||||||
|
with the core so that Regulator-1 is also enabled when Consumer A enables it's
|
||||||
|
supply (Regulator-2).
|
||||||
|
|
||||||
|
This relationship can be register with the core via :-
|
||||||
|
|
||||||
|
int regulator_set_supply(const char *regulator, const char *regulator_supply);
|
||||||
|
|
||||||
|
In this example we would use the following code :-
|
||||||
|
|
||||||
|
regulator_set_supply("Regulator-2", "Regulator-1");
|
||||||
|
|
||||||
|
Relationships can be queried by calling :-
|
||||||
|
|
||||||
|
const char *regulator_get_supply(const char *regulator);
|
||||||
|
|
||||||
|
|
||||||
|
3. Power Domain constraint setting.
|
||||||
|
===================================
|
||||||
|
Each power domain within a system has physical constraints on voltage and
|
||||||
|
current. This must be defined in software so that the power domain is always
|
||||||
|
operated within specifications.
|
||||||
|
|
||||||
|
Consider the following machine (again) :-
|
||||||
|
|
||||||
|
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
||||||
|
|
|
||||||
|
+-> [Consumer B @ 3.3V]
|
||||||
|
|
||||||
|
This gives us two regulators and two power domains:
|
||||||
|
|
||||||
|
Domain 1: Regulator-2, Consumer B.
|
||||||
|
Domain 2: Consumer A.
|
||||||
|
|
||||||
|
Constraints can be registered by calling :-
|
||||||
|
|
||||||
|
int regulator_set_platform_constraints(const char *regulator,
|
||||||
|
struct regulation_constraints *constraints);
|
||||||
|
|
||||||
|
The example is defined as follows :-
|
||||||
|
|
||||||
|
struct regulation_constraints domain_1 = {
|
||||||
|
.min_uV = 3300000,
|
||||||
|
.max_uV = 3300000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regulation_constraints domain_2 = {
|
||||||
|
.min_uV = 1800000,
|
||||||
|
.max_uV = 2000000,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
regulator_set_platform_constraints("Regulator-1", &domain_1);
|
||||||
|
regulator_set_platform_constraints("Regulator-2", &domain_2);
|
171
Documentation/power/regulator/overview.txt
Normal file
171
Documentation/power/regulator/overview.txt
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
Linux voltage and current regulator framework
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
About
|
||||||
|
=====
|
||||||
|
|
||||||
|
This framework is designed to provide a standard kernel interface to control
|
||||||
|
voltage and current regulators.
|
||||||
|
|
||||||
|
The intention is to allow systems to dynamically control regulator power output
|
||||||
|
in order to save power and prolong battery life. This applies to both voltage
|
||||||
|
regulators (where voltage output is controllable) and current sinks (where
|
||||||
|
current limit is controllable).
|
||||||
|
|
||||||
|
(C) 2008 Wolfson Microelectronics PLC.
|
||||||
|
Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||||
|
|
||||||
|
|
||||||
|
Nomenclature
|
||||||
|
============
|
||||||
|
|
||||||
|
Some terms used in this document:-
|
||||||
|
|
||||||
|
o Regulator - Electronic device that supplies power to other devices.
|
||||||
|
Most regulators can enable and disable their output whilst
|
||||||
|
some can control their output voltage and or current.
|
||||||
|
|
||||||
|
Input Voltage -> Regulator -> Output Voltage
|
||||||
|
|
||||||
|
|
||||||
|
o PMIC - Power Management IC. An IC that contains numerous regulators
|
||||||
|
and often contains other susbsystems.
|
||||||
|
|
||||||
|
|
||||||
|
o Consumer - Electronic device that is supplied power by a regulator.
|
||||||
|
Consumers can be classified into two types:-
|
||||||
|
|
||||||
|
Static: consumer does not change it's supply voltage or
|
||||||
|
current limit. It only needs to enable or disable it's
|
||||||
|
power supply. It's supply voltage is set by the hardware,
|
||||||
|
bootloader, firmware or kernel board initialisation code.
|
||||||
|
|
||||||
|
Dynamic: consumer needs to change it's supply voltage or
|
||||||
|
current limit to meet operation demands.
|
||||||
|
|
||||||
|
|
||||||
|
o Power Domain - Electronic circuit that is supplied it's input power by the
|
||||||
|
output power of a regulator, switch or by another power
|
||||||
|
domain.
|
||||||
|
|
||||||
|
The supply regulator may be behind a switch(s). i.e.
|
||||||
|
|
||||||
|
Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A]
|
||||||
|
| |
|
||||||
|
| +-> [Consumer B], [Consumer C]
|
||||||
|
|
|
||||||
|
+-> [Consumer D], [Consumer E]
|
||||||
|
|
||||||
|
That is one regulator and three power domains:
|
||||||
|
|
||||||
|
Domain 1: Switch-1, Consumers D & E.
|
||||||
|
Domain 2: Switch-2, Consumers B & C.
|
||||||
|
Domain 3: Consumer A.
|
||||||
|
|
||||||
|
and this represents a "supplies" relationship:
|
||||||
|
|
||||||
|
Domain-1 --> Domain-2 --> Domain-3.
|
||||||
|
|
||||||
|
A power domain may have regulators that are supplied power
|
||||||
|
by other regulators. i.e.
|
||||||
|
|
||||||
|
Regulator-1 -+-> Regulator-2 -+-> [Consumer A]
|
||||||
|
|
|
||||||
|
+-> [Consumer B]
|
||||||
|
|
||||||
|
This gives us two regulators and two power domains:
|
||||||
|
|
||||||
|
Domain 1: Regulator-2, Consumer B.
|
||||||
|
Domain 2: Consumer A.
|
||||||
|
|
||||||
|
and a "supplies" relationship:
|
||||||
|
|
||||||
|
Domain-1 --> Domain-2
|
||||||
|
|
||||||
|
|
||||||
|
o Constraints - Constraints are used to define power levels for performance
|
||||||
|
and hardware protection. Constraints exist at three levels:
|
||||||
|
|
||||||
|
Regulator Level: This is defined by the regulator hardware
|
||||||
|
operating parameters and is specified in the regulator
|
||||||
|
datasheet. i.e.
|
||||||
|
|
||||||
|
- voltage output is in the range 800mV -> 3500mV.
|
||||||
|
- regulator current output limit is 20mA @ 5V but is
|
||||||
|
10mA @ 10V.
|
||||||
|
|
||||||
|
Power Domain Level: This is defined in software by kernel
|
||||||
|
level board initialisation code. It is used to constrain a
|
||||||
|
power domain to a particular power range. i.e.
|
||||||
|
|
||||||
|
- Domain-1 voltage is 3300mV
|
||||||
|
- Domain-2 voltage is 1400mV -> 1600mV
|
||||||
|
- Domain-3 current limit is 0mA -> 20mA.
|
||||||
|
|
||||||
|
Consumer Level: This is defined by consumer drivers
|
||||||
|
dynamically setting voltage or current limit levels.
|
||||||
|
|
||||||
|
e.g. a consumer backlight driver asks for a current increase
|
||||||
|
from 5mA to 10mA to increase LCD illumination. This passes
|
||||||
|
to through the levels as follows :-
|
||||||
|
|
||||||
|
Consumer: need to increase LCD brightness. Lookup and
|
||||||
|
request next current mA value in brightness table (the
|
||||||
|
consumer driver could be used on several different
|
||||||
|
personalities based upon the same reference device).
|
||||||
|
|
||||||
|
Power Domain: is the new current limit within the domain
|
||||||
|
operating limits for this domain and system state (e.g.
|
||||||
|
battery power, USB power)
|
||||||
|
|
||||||
|
Regulator Domains: is the new current limit within the
|
||||||
|
regulator operating parameters for input/ouput voltage.
|
||||||
|
|
||||||
|
If the regulator request passes all the constraint tests
|
||||||
|
then the new regulator value is applied.
|
||||||
|
|
||||||
|
|
||||||
|
Design
|
||||||
|
======
|
||||||
|
|
||||||
|
The framework is designed and targeted at SoC based devices but may also be
|
||||||
|
relevant to non SoC devices and is split into the following four interfaces:-
|
||||||
|
|
||||||
|
|
||||||
|
1. Consumer driver interface.
|
||||||
|
|
||||||
|
This uses a similar API to the kernel clock interface in that consumer
|
||||||
|
drivers can get and put a regulator (like they can with clocks atm) and
|
||||||
|
get/set voltage, current limit, mode, enable and disable. This should
|
||||||
|
allow consumers complete control over their supply voltage and current
|
||||||
|
limit. This also compiles out if not in use so drivers can be reused in
|
||||||
|
systems with no regulator based power control.
|
||||||
|
|
||||||
|
See Documentation/power/regulator/consumer.txt
|
||||||
|
|
||||||
|
2. Regulator driver interface.
|
||||||
|
|
||||||
|
This allows regulator drivers to register their regulators and provide
|
||||||
|
operations to the core. It also has a notifier call chain for propagating
|
||||||
|
regulator events to clients.
|
||||||
|
|
||||||
|
See Documentation/power/regulator/regulator.txt
|
||||||
|
|
||||||
|
3. Machine interface.
|
||||||
|
|
||||||
|
This interface is for machine specific code and allows the creation of
|
||||||
|
voltage/current domains (with constraints) for each regulator. It can
|
||||||
|
provide regulator constraints that will prevent device damage through
|
||||||
|
overvoltage or over current caused by buggy client drivers. It also
|
||||||
|
allows the creation of a regulator tree whereby some regulators are
|
||||||
|
supplied by others (similar to a clock tree).
|
||||||
|
|
||||||
|
See Documentation/power/regulator/machine.txt
|
||||||
|
|
||||||
|
4. Userspace ABI.
|
||||||
|
|
||||||
|
The framework also exports a lot of useful voltage/current/opmode data to
|
||||||
|
userspace via sysfs. This could be used to help monitor device power
|
||||||
|
consumption and status.
|
||||||
|
|
||||||
|
See Documentation/ABI/testing/regulator-sysfs.txt
|
30
Documentation/power/regulator/regulator.txt
Normal file
30
Documentation/power/regulator/regulator.txt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Regulator Driver Interface
|
||||||
|
==========================
|
||||||
|
|
||||||
|
The regulator driver interface is relatively simple and designed to allow
|
||||||
|
regulator drivers to register their services with the core framework.
|
||||||
|
|
||||||
|
|
||||||
|
Registration
|
||||||
|
============
|
||||||
|
|
||||||
|
Drivers can register a regulator by calling :-
|
||||||
|
|
||||||
|
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||||
|
void *reg_data);
|
||||||
|
|
||||||
|
This will register the regulators capabilities and operations the regulator
|
||||||
|
core. The core does not touch reg_data (private to regulator driver).
|
||||||
|
|
||||||
|
Regulators can be unregistered by calling :-
|
||||||
|
|
||||||
|
void regulator_unregister(struct regulator_dev *rdev);
|
||||||
|
|
||||||
|
|
||||||
|
Regulator Events
|
||||||
|
================
|
||||||
|
Regulators can send events (e.g. over temp, under voltage, etc) to consumer
|
||||||
|
drivers by calling :-
|
||||||
|
|
||||||
|
int regulator_notifier_call_chain(struct regulator_dev *rdev,
|
||||||
|
unsigned long event, void *data);
|
@ -20,8 +20,6 @@ mpc52xx-device-tree-bindings.txt
|
|||||||
- MPC5200 Device Tree Bindings
|
- MPC5200 Device Tree Bindings
|
||||||
ppc_htab.txt
|
ppc_htab.txt
|
||||||
- info about the Linux/PPC /proc/ppc_htab entry
|
- info about the Linux/PPC /proc/ppc_htab entry
|
||||||
SBC8260_memory_mapping.txt
|
|
||||||
- EST SBC8260 board info
|
|
||||||
smp.txt
|
smp.txt
|
||||||
- use and state info about Linux/PPC on MP machines
|
- use and state info about Linux/PPC on MP machines
|
||||||
sound.txt
|
sound.txt
|
||||||
|
@ -1,197 +0,0 @@
|
|||||||
Please mail me (Jon Diekema, diekema_jon@si.com or diekema@cideas.com)
|
|
||||||
if you have questions, comments or corrections.
|
|
||||||
|
|
||||||
* EST SBC8260 Linux memory mapping rules
|
|
||||||
|
|
||||||
http://www.estc.com/
|
|
||||||
http://www.estc.com/products/boards/SBC8260-8240_ds.html
|
|
||||||
|
|
||||||
Initial conditions:
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Tasks that need to be perform by the boot ROM before control is
|
|
||||||
transferred to zImage (compressed Linux kernel):
|
|
||||||
|
|
||||||
- Define the IMMR to 0xf0000000
|
|
||||||
|
|
||||||
- Initialize the memory controller so that RAM is available at
|
|
||||||
physical address 0x00000000. On the SBC8260 is this 16M (64M)
|
|
||||||
SDRAM.
|
|
||||||
|
|
||||||
- The boot ROM should only clear the RAM that it is using.
|
|
||||||
|
|
||||||
The reason for doing this is to enhances the chances of a
|
|
||||||
successful post mortem on a Linux panic. One of the first
|
|
||||||
items to examine is the 16k (LOG_BUF_LEN) circular console
|
|
||||||
buffer called log_buf which is defined in kernel/printk.c.
|
|
||||||
|
|
||||||
- To enhance boot ROM performance, the I-cache can be enabled.
|
|
||||||
|
|
||||||
Date: Mon, 22 May 2000 14:21:10 -0700
|
|
||||||
From: Neil Russell <caret@c-side.com>
|
|
||||||
|
|
||||||
LiMon (LInux MONitor) runs with and starts Linux with MMU
|
|
||||||
off, I-cache enabled, D-cache disabled. The I-cache doesn't
|
|
||||||
need hints from the MMU to work correctly as the D-cache
|
|
||||||
does. No D-cache means no special code to handle devices in
|
|
||||||
the presence of cache (no snooping, etc). The use of the
|
|
||||||
I-cache means that the monitor can run acceptably fast
|
|
||||||
directly from ROM, rather than having to copy it to RAM.
|
|
||||||
|
|
||||||
- Build the board information structure (see
|
|
||||||
include/asm-ppc/est8260.h for its definition)
|
|
||||||
|
|
||||||
- The compressed Linux kernel (zImage) contains a bootstrap loader
|
|
||||||
that is position independent; you can load it into any RAM,
|
|
||||||
ROM or FLASH memory address >= 0x00500000 (above 5 MB), or
|
|
||||||
at its link address of 0x00400000 (4 MB).
|
|
||||||
|
|
||||||
Note: If zImage is loaded at its link address of 0x00400000 (4 MB),
|
|
||||||
then zImage will skip the step of moving itself to
|
|
||||||
its link address.
|
|
||||||
|
|
||||||
- Load R3 with the address of the board information structure
|
|
||||||
|
|
||||||
- Transfer control to zImage
|
|
||||||
|
|
||||||
- The Linux console port is SMC1, and the baud rate is controlled
|
|
||||||
from the bi_baudrate field of the board information structure.
|
|
||||||
On thing to keep in mind when picking the baud rate, is that
|
|
||||||
there is no flow control on the SMC ports. I would stick
|
|
||||||
with something safe and standard like 19200.
|
|
||||||
|
|
||||||
On the EST SBC8260, the SMC1 port is on the COM1 connector of
|
|
||||||
the board.
|
|
||||||
|
|
||||||
|
|
||||||
EST SBC8260 defaults:
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Chip
|
|
||||||
Memory Sel Bus Use
|
|
||||||
--------------------- --- --- ----------------------------------
|
|
||||||
0x00000000-0x03FFFFFF CS2 60x (16M or 64M)/64M SDRAM
|
|
||||||
0x04000000-0x04FFFFFF CS4 local 4M/16M SDRAM (soldered to the board)
|
|
||||||
0x21000000-0x21000000 CS7 60x 1B/64K Flash present detect (from the flash SIMM)
|
|
||||||
0x21000001-0x21000001 CS7 60x 1B/64K Switches (read) and LEDs (write)
|
|
||||||
0x22000000-0x2200FFFF CS5 60x 8K/64K EEPROM
|
|
||||||
0xFC000000-0xFCFFFFFF CS6 60x 2M/16M flash (8 bits wide, soldered to the board)
|
|
||||||
0xFE000000-0xFFFFFFFF CS0 60x 4M/16M flash (SIMM)
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
------
|
|
||||||
|
|
||||||
- The chip selects can map 32K blocks and up (powers of 2)
|
|
||||||
|
|
||||||
- The SDRAM machine can handled up to 128Mbytes per chip select
|
|
||||||
|
|
||||||
- Linux uses the 60x bus memory (the SDRAM DIMM) for the
|
|
||||||
communications buffers.
|
|
||||||
|
|
||||||
- BATs can map 128K-256Mbytes each. There are four data BATs and
|
|
||||||
four instruction BATs. Generally the data and instruction BATs
|
|
||||||
are mapped the same.
|
|
||||||
|
|
||||||
- The IMMR must be set above the kernel virtual memory addresses,
|
|
||||||
which start at 0xC0000000. Otherwise, the kernel may crash as
|
|
||||||
soon as you start any threads or processes due to VM collisions
|
|
||||||
in the kernel or user process space.
|
|
||||||
|
|
||||||
|
|
||||||
Details from Dan Malek <dan_malek@mvista.com> on 10/29/1999:
|
|
||||||
|
|
||||||
The user application virtual space consumes the first 2 Gbytes
|
|
||||||
(0x00000000 to 0x7FFFFFFF). The kernel virtual text starts at
|
|
||||||
0xC0000000, with data following. There is a "protection hole"
|
|
||||||
between the end of kernel data and the start of the kernel
|
|
||||||
dynamically allocated space, but this space is still within
|
|
||||||
0xCxxxxxxx.
|
|
||||||
|
|
||||||
Obviously the kernel can't map any physical addresses 1:1 in
|
|
||||||
these ranges.
|
|
||||||
|
|
||||||
|
|
||||||
Details from Dan Malek <dan_malek@mvista.com> on 5/19/2000:
|
|
||||||
|
|
||||||
During the early kernel initialization, the kernel virtual
|
|
||||||
memory allocator is not operational. Prior to this KVM
|
|
||||||
initialization, we choose to map virtual to physical addresses
|
|
||||||
1:1. That is, the kernel virtual address exactly matches the
|
|
||||||
physical address on the bus. These mappings are typically done
|
|
||||||
in arch/ppc/kernel/head.S, or arch/ppc/mm/init.c. Only
|
|
||||||
absolutely necessary mappings should be done at this time, for
|
|
||||||
example board control registers or a serial uart. Normal device
|
|
||||||
driver initialization should map resources later when necessary.
|
|
||||||
|
|
||||||
Although platform dependent, and certainly the case for embedded
|
|
||||||
8xx, traditionally memory is mapped at physical address zero,
|
|
||||||
and I/O devices above physical address 0x80000000. The lowest
|
|
||||||
and highest (above 0xf0000000) I/O addresses are traditionally
|
|
||||||
used for devices or registers we need to map during kernel
|
|
||||||
initialization and prior to KVM operation. For this reason,
|
|
||||||
and since it followed prior PowerPC platform examples, I chose
|
|
||||||
to map the embedded 8xx kernel to the 0xc0000000 virtual address.
|
|
||||||
This way, we can enable the MMU to map the kernel for proper
|
|
||||||
operation, and still map a few windows before the KVM is operational.
|
|
||||||
|
|
||||||
On some systems, you could possibly run the kernel at the
|
|
||||||
0x80000000 or any other virtual address. It just depends upon
|
|
||||||
mapping that must be done prior to KVM operational. You can never
|
|
||||||
map devices or kernel spaces that overlap with the user virtual
|
|
||||||
space. This is why default IMMR mapping used by most BDM tools
|
|
||||||
won't work. They put the IMMR at something like 0x10000000 or
|
|
||||||
0x02000000 for example. You simply can't map these addresses early
|
|
||||||
in the kernel, and continue proper system operation.
|
|
||||||
|
|
||||||
The embedded 8xx/82xx kernel is mature enough that all you should
|
|
||||||
need to do is map the IMMR someplace at or above 0xf0000000 and it
|
|
||||||
should boot far enough to get serial console messages and KGDB
|
|
||||||
connected on any platform. There are lots of other subtle memory
|
|
||||||
management design features that you simply don't need to worry
|
|
||||||
about. If you are changing functions related to MMU initialization,
|
|
||||||
you are likely breaking things that are known to work and are
|
|
||||||
heading down a path of disaster and frustration. Your changes
|
|
||||||
should be to make the flexibility of the processor fit Linux,
|
|
||||||
not force arbitrary and non-workable memory mappings into Linux.
|
|
||||||
|
|
||||||
- You don't want to change KERNELLOAD or KERNELBASE, otherwise the
|
|
||||||
virtual memory and MMU code will get confused.
|
|
||||||
|
|
||||||
arch/ppc/Makefile:KERNELLOAD = 0xc0000000
|
|
||||||
|
|
||||||
include/asm-ppc/page.h:#define PAGE_OFFSET 0xc0000000
|
|
||||||
include/asm-ppc/page.h:#define KERNELBASE PAGE_OFFSET
|
|
||||||
|
|
||||||
- RAM is at physical address 0x00000000, and gets mapped to
|
|
||||||
virtual address 0xC0000000 for the kernel.
|
|
||||||
|
|
||||||
|
|
||||||
Physical addresses used by the Linux kernel:
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
0x00000000-0x3FFFFFFF 1GB reserved for RAM
|
|
||||||
0xF0000000-0xF001FFFF 128K IMMR 64K used for dual port memory,
|
|
||||||
64K for 8260 registers
|
|
||||||
|
|
||||||
|
|
||||||
Logical addresses used by the Linux kernel:
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
0xF0000000-0xFFFFFFFF 256M BAT0 (IMMR: dual port RAM, registers)
|
|
||||||
0xE0000000-0xEFFFFFFF 256M BAT1 (I/O space for custom boards)
|
|
||||||
0xC0000000-0xCFFFFFFF 256M BAT2 (RAM)
|
|
||||||
0xD0000000-0xDFFFFFFF 256M BAT3 (if RAM > 256MByte)
|
|
||||||
|
|
||||||
|
|
||||||
EST SBC8260 Linux mapping:
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
DBAT0, IBAT0, cache inhibited:
|
|
||||||
|
|
||||||
Chip
|
|
||||||
Memory Sel Use
|
|
||||||
--------------------- --- ---------------------------------
|
|
||||||
0xF0000000-0xF001FFFF n/a IMMR: dual port RAM, registers
|
|
||||||
|
|
||||||
DBAT1, IBAT1, cache inhibited:
|
|
||||||
|
|
@ -278,7 +278,7 @@ it with special cases.
|
|||||||
a 64-bit platform.
|
a 64-bit platform.
|
||||||
|
|
||||||
d) request and get assigned a platform number (see PLATFORM_*
|
d) request and get assigned a platform number (see PLATFORM_*
|
||||||
constants in include/asm-powerpc/processor.h
|
constants in arch/powerpc/include/asm/processor.h
|
||||||
|
|
||||||
32-bit embedded kernels:
|
32-bit embedded kernels:
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ the block to RAM before passing it to the kernel.
|
|||||||
---------
|
---------
|
||||||
|
|
||||||
The kernel is entered with r3 pointing to an area of memory that is
|
The kernel is entered with r3 pointing to an area of memory that is
|
||||||
roughly described in include/asm-powerpc/prom.h by the structure
|
roughly described in arch/powerpc/include/asm/prom.h by the structure
|
||||||
boot_param_header:
|
boot_param_header:
|
||||||
|
|
||||||
struct boot_param_header {
|
struct boot_param_header {
|
||||||
|
@ -7,6 +7,15 @@ Currently defined compatibles:
|
|||||||
- fsl,cpm2-scc-uart
|
- fsl,cpm2-scc-uart
|
||||||
- fsl,qe-uart
|
- fsl,qe-uart
|
||||||
|
|
||||||
|
Modem control lines connected to GPIO controllers are listed in the gpios
|
||||||
|
property as described in booting-without-of.txt, section IX.1 in the following
|
||||||
|
order:
|
||||||
|
|
||||||
|
CTS, RTS, DCD, DSR, DTR, and RI.
|
||||||
|
|
||||||
|
The gpios property is optional and can be left out when control lines are
|
||||||
|
not used.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
serial@11a00 {
|
serial@11a00 {
|
||||||
@ -18,4 +27,6 @@ Example:
|
|||||||
interrupt-parent = <&PIC>;
|
interrupt-parent = <&PIC>;
|
||||||
fsl,cpm-brg = <1>;
|
fsl,cpm-brg = <1>;
|
||||||
fsl,cpm-command = <00800000>;
|
fsl,cpm-command = <00800000>;
|
||||||
|
gpios = <&gpio_c 15 0
|
||||||
|
&gpio_d 29 0>;
|
||||||
};
|
};
|
||||||
|
@ -133,7 +133,7 @@ error. Given an arbitrary address, the routine
|
|||||||
pci_get_device_by_addr() will find the pci device associated
|
pci_get_device_by_addr() will find the pci device associated
|
||||||
with that address (if any).
|
with that address (if any).
|
||||||
|
|
||||||
The default include/asm-powerpc/io.h macros readb(), inb(), insb(),
|
The default arch/powerpc/include/asm/io.h macros readb(), inb(), insb(),
|
||||||
etc. include a check to see if the i/o read returned all-0xff's.
|
etc. include a check to see if the i/o read returned all-0xff's.
|
||||||
If so, these make a call to eeh_dn_check_failure(), which in turn
|
If so, these make a call to eeh_dn_check_failure(), which in turn
|
||||||
asks the firmware if the all-ff's value is the sign of a true EEH
|
asks the firmware if the all-ff's value is the sign of a true EEH
|
||||||
|
@ -390,9 +390,10 @@ rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft
|
|||||||
rfkill input line is active. Only if none of the rfkill input lines are
|
rfkill input line is active. Only if none of the rfkill input lines are
|
||||||
active, will it return RFKILL_STATE_UNBLOCKED.
|
active, will it return RFKILL_STATE_UNBLOCKED.
|
||||||
|
|
||||||
If it doesn't implement the get_state() hook, it must make sure that its calls
|
Since the device has a hardware rfkill line, it IS subject to state changes
|
||||||
to rfkill_force_state() are enough to keep the status always up-to-date, and it
|
external to rfkill. Therefore, the driver must make sure that it calls
|
||||||
must do a rfkill_force_state() on resume from sleep.
|
rfkill_force_state() to keep the status always up-to-date, and it must do a
|
||||||
|
rfkill_force_state() on resume from sleep.
|
||||||
|
|
||||||
Every time the driver gets a notification from the card that one of its rfkill
|
Every time the driver gets a notification from the card that one of its rfkill
|
||||||
lines changed state (polling might be needed on badly designed cards that don't
|
lines changed state (polling might be needed on badly designed cards that don't
|
||||||
@ -422,13 +423,24 @@ of the hardware is unknown), or read-write (where the hardware can be queried
|
|||||||
about its current state).
|
about its current state).
|
||||||
|
|
||||||
The rfkill class will call the get_state hook of a device every time it needs
|
The rfkill class will call the get_state hook of a device every time it needs
|
||||||
to know the *real* current state of the hardware. This can happen often.
|
to know the *real* current state of the hardware. This can happen often, but
|
||||||
|
it does not do any polling, so it is not enough on hardware that is subject
|
||||||
|
to state changes outside of the rfkill subsystem.
|
||||||
|
|
||||||
|
Therefore, calling rfkill_force_state() when a state change happens is
|
||||||
|
mandatory when the device has a hardware rfkill line, or when something else
|
||||||
|
like the firmware could cause its state to be changed without going through the
|
||||||
|
rfkill class.
|
||||||
|
|
||||||
Some hardware provides events when its status changes. In these cases, it is
|
Some hardware provides events when its status changes. In these cases, it is
|
||||||
best for the driver to not provide a get_state hook, and instead register the
|
best for the driver to not provide a get_state hook, and instead register the
|
||||||
rfkill class *already* with the correct status, and keep it updated using
|
rfkill class *already* with the correct status, and keep it updated using
|
||||||
rfkill_force_state() when it gets an event from the hardware.
|
rfkill_force_state() when it gets an event from the hardware.
|
||||||
|
|
||||||
|
rfkill_force_state() must be used on the device resume handlers to update the
|
||||||
|
rfkill status, should there be any chance of the device status changing during
|
||||||
|
the sleep.
|
||||||
|
|
||||||
There is no provision for a statically-allocated rfkill struct. You must
|
There is no provision for a statically-allocated rfkill struct. You must
|
||||||
use rfkill_allocate() to allocate one.
|
use rfkill_allocate() to allocate one.
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ Declaring PXA2xx Master Controllers
|
|||||||
-----------------------------------
|
-----------------------------------
|
||||||
Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a
|
Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a
|
||||||
"platform device". The master configuration is passed to the driver via a table
|
"platform device". The master configuration is passed to the driver via a table
|
||||||
found in include/asm-arm/arch-pxa/pxa2xx_spi.h:
|
found in arch/arm/mach-pxa/include/mach/pxa2xx_spi.h:
|
||||||
|
|
||||||
struct pxa2xx_spi_master {
|
struct pxa2xx_spi_master {
|
||||||
enum pxa_ssp_type ssp_type;
|
enum pxa_ssp_type ssp_type;
|
||||||
@ -94,7 +94,7 @@ using the "spi_board_info" structure found in "linux/spi/spi.h". See
|
|||||||
|
|
||||||
Each slave device attached to the PXA must provide slave specific configuration
|
Each slave device attached to the PXA must provide slave specific configuration
|
||||||
information via the structure "pxa2xx_spi_chip" found in
|
information via the structure "pxa2xx_spi_chip" found in
|
||||||
"include/asm-arm/arch-pxa/pxa2xx_spi.h". The pxa2xx_spi master controller driver
|
"arch/arm/mach-pxa/include/mach/pxa2xx_spi.h". The pxa2xx_spi master controller driver
|
||||||
will uses the configuration whenever the driver communicates with the slave
|
will uses the configuration whenever the driver communicates with the slave
|
||||||
device.
|
device.
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ board should normally be set up and registered.
|
|||||||
|
|
||||||
So for example arch/.../mach-*/board-*.c files might have code like:
|
So for example arch/.../mach-*/board-*.c files might have code like:
|
||||||
|
|
||||||
#include <asm/arch/spi.h> /* for mysoc_spi_data */
|
#include <mach/spi.h> /* for mysoc_spi_data */
|
||||||
|
|
||||||
/* if your mach-* infrastructure doesn't support kernels that can
|
/* if your mach-* infrastructure doesn't support kernels that can
|
||||||
* run on multiple boards, pdata wouldn't benefit from "__init".
|
* run on multiple boards, pdata wouldn't benefit from "__init".
|
||||||
@ -227,7 +227,7 @@ So for example arch/.../mach-*/board-*.c files might have code like:
|
|||||||
|
|
||||||
And SOC-specific utility code might look something like:
|
And SOC-specific utility code might look something like:
|
||||||
|
|
||||||
#include <asm/arch/spi.h>
|
#include <mach/spi.h>
|
||||||
|
|
||||||
static struct platform_device spi2 = { ... };
|
static struct platform_device spi2 = { ... };
|
||||||
|
|
||||||
|
@ -226,6 +226,7 @@ sonixj 0c45:6130 Sonix Pccam
|
|||||||
sonixj 0c45:6138 Sn9c120 Mo4000
|
sonixj 0c45:6138 Sn9c120 Mo4000
|
||||||
sonixj 0c45:613b Surfer SN-206
|
sonixj 0c45:613b Surfer SN-206
|
||||||
sonixj 0c45:613c Sonix Pccam168
|
sonixj 0c45:613c Sonix Pccam168
|
||||||
|
sonixj 0c45:6143 Sonix Pccam168
|
||||||
sunplus 0d64:0303 Sunplus FashionCam DXG
|
sunplus 0d64:0303 Sunplus FashionCam DXG
|
||||||
etoms 102c:6151 Qcam Sangha CIF
|
etoms 102c:6151 Qcam Sangha CIF
|
||||||
etoms 102c:6251 Qcam xxxxxx VGA
|
etoms 102c:6251 Qcam xxxxxx VGA
|
||||||
|
39
MAINTAINERS
39
MAINTAINERS
@ -502,6 +502,12 @@ L: openezx-devel@lists.openezx.org (subscribers-only)
|
|||||||
W: http://www.openezx.org/
|
W: http://www.openezx.org/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
|
||||||
|
P: Sascha Hauer
|
||||||
|
M: kernel@pengutronix.de
|
||||||
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
|
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
|
||||||
P: Lennert Buytenhek
|
P: Lennert Buytenhek
|
||||||
M: kernel@wantstofly.org
|
M: kernel@wantstofly.org
|
||||||
@ -588,6 +594,11 @@ M: kernel@wantstofly.org
|
|||||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ARM/MAGICIAN MACHINE SUPPORT
|
||||||
|
P: Philipp Zabel
|
||||||
|
M: philipp.zabel@gmail.com
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ARM/TOSA MACHINE SUPPORT
|
ARM/TOSA MACHINE SUPPORT
|
||||||
P: Dmitry Baryshkov
|
P: Dmitry Baryshkov
|
||||||
M: dbaryshkov@gmail.com
|
M: dbaryshkov@gmail.com
|
||||||
@ -714,6 +725,15 @@ L: linux-wireless@vger.kernel.org
|
|||||||
L: ath5k-devel@lists.ath5k.org
|
L: ath5k-devel@lists.ath5k.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ATHEROS ATH9K WIRELESS DRIVER
|
||||||
|
P: Luis R. Rodriguez
|
||||||
|
M: lrodriguez@atheros.com
|
||||||
|
P: Jouni Malinen
|
||||||
|
M: jmalinen@atheros.com
|
||||||
|
L: linux-wireless@vger.kernel.org
|
||||||
|
L: ath9k-devel@lists.ath9k.org
|
||||||
|
S: Supported
|
||||||
|
|
||||||
ATI_REMOTE2 DRIVER
|
ATI_REMOTE2 DRIVER
|
||||||
P: Ville Syrjala
|
P: Ville Syrjala
|
||||||
M: syrjala@sci.fi
|
M: syrjala@sci.fi
|
||||||
@ -1229,7 +1249,7 @@ S: Maintained
|
|||||||
CPU FREQUENCY DRIVERS
|
CPU FREQUENCY DRIVERS
|
||||||
P: Dave Jones
|
P: Dave Jones
|
||||||
M: davej@codemonkey.org.uk
|
M: davej@codemonkey.org.uk
|
||||||
L: cpufreq@lists.linux.org.uk
|
L: cpufreq@vger.kernel.org
|
||||||
W: http://www.codemonkey.org.uk/projects/cpufreq/
|
W: http://www.codemonkey.org.uk/projects/cpufreq/
|
||||||
T: git kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
|
T: git kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
@ -1878,13 +1898,9 @@ W: http://gigaset307x.sourceforge.net/
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
HARDWARE MONITORING
|
HARDWARE MONITORING
|
||||||
P: Mark M. Hoffman
|
|
||||||
M: mhoffman@lightlink.com
|
|
||||||
L: lm-sensors@lm-sensors.org
|
L: lm-sensors@lm-sensors.org
|
||||||
W: http://www.lm-sensors.org/
|
W: http://www.lm-sensors.org/
|
||||||
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git testing
|
S: Orphaned
|
||||||
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release
|
|
||||||
S: Maintained
|
|
||||||
|
|
||||||
HARDWARE RANDOM NUMBER GENERATOR CORE
|
HARDWARE RANDOM NUMBER GENERATOR CORE
|
||||||
S: Orphaned
|
S: Orphaned
|
||||||
@ -3968,7 +3984,7 @@ M: lethal@linux-sh.org
|
|||||||
L: linux-sh@vger.kernel.org
|
L: linux-sh@vger.kernel.org
|
||||||
W: http://www.linux-sh.org
|
W: http://www.linux-sh.org
|
||||||
T: git kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.git
|
T: git kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.git
|
||||||
S: Maintained
|
S: Supported
|
||||||
|
|
||||||
SUN3/3X
|
SUN3/3X
|
||||||
P: Sam Creasey
|
P: Sam Creasey
|
||||||
@ -4504,6 +4520,15 @@ M: kaber@trash.net
|
|||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
|
||||||
|
P: Liam Girdwood
|
||||||
|
M: lg@opensource.wolfsonmicro.com
|
||||||
|
P: Mark Brown
|
||||||
|
M: broonie@opensource.wolfsonmicro.com
|
||||||
|
W: http://opensource.wolfsonmicro.com/node/15
|
||||||
|
T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
|
||||||
|
S: Supported
|
||||||
|
|
||||||
VT1211 HARDWARE MONITOR DRIVER
|
VT1211 HARDWARE MONITOR DRIVER
|
||||||
P: Juerg Haefliger
|
P: Juerg Haefliger
|
||||||
M: juergh@gmail.com
|
M: juergh@gmail.com
|
||||||
|
10
Makefile
10
Makefile
@ -1,7 +1,7 @@
|
|||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 27
|
SUBLEVEL = 27
|
||||||
EXTRAVERSION = -rc1
|
EXTRAVERSION = -rc2
|
||||||
NAME = Rotary Wombat
|
NAME = Rotary Wombat
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
@ -929,10 +929,10 @@ ifneq ($(KBUILD_SRC),)
|
|||||||
echo " in the '$(srctree)' directory.";\
|
echo " in the '$(srctree)' directory.";\
|
||||||
/bin/false; \
|
/bin/false; \
|
||||||
fi;
|
fi;
|
||||||
$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
|
$(Q)if [ ! -d include2 ]; then \
|
||||||
$(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/system.h ]; then \
|
mkdir -p include2; \
|
||||||
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
|
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
|
||||||
fi
|
fi
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# prepare2 creates a makefile if using a separate output directory
|
# prepare2 creates a makefile if using a separate output directory
|
||||||
@ -1492,7 +1492,7 @@ quiet_cmd_cscope-file = FILELST cscope.files
|
|||||||
cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
|
cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
|
||||||
|
|
||||||
quiet_cmd_cscope = MAKE cscope.out
|
quiet_cmd_cscope = MAKE cscope.out
|
||||||
cmd_cscope = cscope -b
|
cmd_cscope = cscope -b -f cscope.out
|
||||||
|
|
||||||
cscope: FORCE
|
cscope: FORCE
|
||||||
$(call cmd,cscope-file)
|
$(call cmd,cscope-file)
|
||||||
|
@ -1225,6 +1225,8 @@ source "drivers/dma/Kconfig"
|
|||||||
|
|
||||||
source "drivers/dca/Kconfig"
|
source "drivers/dca/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/regulator/Kconfig"
|
||||||
|
|
||||||
source "drivers/uio/Kconfig"
|
source "drivers/uio/Kconfig"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -97,9 +97,7 @@ textofs-y := 0x00008000
|
|||||||
machine-$(CONFIG_ARCH_RPC) := rpc
|
machine-$(CONFIG_ARCH_RPC) := rpc
|
||||||
machine-$(CONFIG_ARCH_EBSA110) := ebsa110
|
machine-$(CONFIG_ARCH_EBSA110) := ebsa110
|
||||||
machine-$(CONFIG_ARCH_CLPS7500) := clps7500
|
machine-$(CONFIG_ARCH_CLPS7500) := clps7500
|
||||||
incdir-$(CONFIG_ARCH_CLPS7500) := cl7500
|
|
||||||
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
||||||
incdir-$(CONFIG_FOOTBRIDGE) := ebsa285
|
|
||||||
machine-$(CONFIG_ARCH_SHARK) := shark
|
machine-$(CONFIG_ARCH_SHARK) := shark
|
||||||
machine-$(CONFIG_ARCH_SA1100) := sa1100
|
machine-$(CONFIG_ARCH_SA1100) := sa1100
|
||||||
ifeq ($(CONFIG_ARCH_SA1100),y)
|
ifeq ($(CONFIG_ARCH_SA1100),y)
|
||||||
@ -114,13 +112,15 @@ endif
|
|||||||
machine-$(CONFIG_ARCH_IOP32X) := iop32x
|
machine-$(CONFIG_ARCH_IOP32X) := iop32x
|
||||||
machine-$(CONFIG_ARCH_IOP33X) := iop33x
|
machine-$(CONFIG_ARCH_IOP33X) := iop33x
|
||||||
machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
|
machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
|
||||||
|
plat-$(CONFIG_PLAT_IOP) := iop
|
||||||
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
|
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
|
||||||
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
|
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
|
||||||
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
|
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
|
||||||
machine-$(CONFIG_ARCH_OMAP1) := omap1
|
machine-$(CONFIG_ARCH_OMAP1) := omap1
|
||||||
machine-$(CONFIG_ARCH_OMAP2) := omap2
|
machine-$(CONFIG_ARCH_OMAP2) := omap2
|
||||||
incdir-$(CONFIG_ARCH_OMAP) := omap
|
plat-$(CONFIG_ARCH_OMAP) := omap
|
||||||
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
|
machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
|
||||||
|
plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx
|
||||||
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
|
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
|
||||||
machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
||||||
machine-$(CONFIG_ARCH_IMX) := imx
|
machine-$(CONFIG_ARCH_IMX) := imx
|
||||||
@ -135,10 +135,11 @@ endif
|
|||||||
machine-$(CONFIG_ARCH_DAVINCI) := davinci
|
machine-$(CONFIG_ARCH_DAVINCI) := davinci
|
||||||
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
|
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
|
||||||
machine-$(CONFIG_ARCH_KS8695) := ks8695
|
machine-$(CONFIG_ARCH_KS8695) := ks8695
|
||||||
incdir-$(CONFIG_ARCH_MXC) := mxc
|
plat-$(CONFIG_ARCH_MXC) := mxc
|
||||||
machine-$(CONFIG_ARCH_MX2) := mx2
|
machine-$(CONFIG_ARCH_MX2) := mx2
|
||||||
machine-$(CONFIG_ARCH_MX3) := mx3
|
machine-$(CONFIG_ARCH_MX3) := mx3
|
||||||
machine-$(CONFIG_ARCH_ORION5X) := orion5x
|
machine-$(CONFIG_ARCH_ORION5X) := orion5x
|
||||||
|
plat-$(CONFIG_PLAT_ORION) := orion
|
||||||
machine-$(CONFIG_ARCH_MSM7X00A) := msm
|
machine-$(CONFIG_ARCH_MSM7X00A) := msm
|
||||||
machine-$(CONFIG_ARCH_LOKI) := loki
|
machine-$(CONFIG_ARCH_LOKI) := loki
|
||||||
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
|
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
|
||||||
@ -153,17 +154,22 @@ endif
|
|||||||
# The byte offset of the kernel image in RAM from the start of RAM.
|
# The byte offset of the kernel image in RAM from the start of RAM.
|
||||||
TEXT_OFFSET := $(textofs-y)
|
TEXT_OFFSET := $(textofs-y)
|
||||||
|
|
||||||
ifeq ($(incdir-y),)
|
# The first directory contains additional information for the boot setup code
|
||||||
incdir-y := $(machine-y)
|
|
||||||
endif
|
|
||||||
INCDIR := arch-$(incdir-y)
|
|
||||||
|
|
||||||
ifneq ($(machine-y),)
|
ifneq ($(machine-y),)
|
||||||
MACHINE := arch/arm/mach-$(machine-y)/
|
MACHINE := arch/arm/mach-$(word 1,$(machine-y))/
|
||||||
else
|
else
|
||||||
MACHINE :=
|
MACHINE :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
|
||||||
|
platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
|
||||||
|
|
||||||
|
ifeq ($(KBUILD_SRC),)
|
||||||
|
KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
|
||||||
|
else
|
||||||
|
KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
|
||||||
|
endif
|
||||||
|
|
||||||
export TEXT_OFFSET GZFLAGS MMUEXT
|
export TEXT_OFFSET GZFLAGS MMUEXT
|
||||||
|
|
||||||
# Do we have FASTFPE?
|
# Do we have FASTFPE?
|
||||||
@ -174,23 +180,11 @@ endif
|
|||||||
|
|
||||||
# If we have a machine-specific directory, then include it in the build.
|
# If we have a machine-specific directory, then include it in the build.
|
||||||
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
|
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
|
||||||
core-y += $(MACHINE)
|
core-y += $(machdirs) $(platdirs)
|
||||||
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/
|
|
||||||
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/
|
|
||||||
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/
|
|
||||||
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2442/
|
|
||||||
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2443/
|
|
||||||
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
|
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
|
||||||
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
|
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
|
||||||
core-$(CONFIG_VFP) += arch/arm/vfp/
|
core-$(CONFIG_VFP) += arch/arm/vfp/
|
||||||
|
|
||||||
# If we have a common platform directory, then include it in the build.
|
|
||||||
core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/
|
|
||||||
core-$(CONFIG_PLAT_ORION) += arch/arm/plat-orion/
|
|
||||||
core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/
|
|
||||||
core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/
|
|
||||||
core-$(CONFIG_ARCH_MXC) += arch/arm/plat-mxc/
|
|
||||||
|
|
||||||
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
||||||
|
|
||||||
libs-y := arch/arm/lib/ $(libs-y)
|
libs-y := arch/arm/lib/ $(libs-y)
|
||||||
@ -210,20 +204,10 @@ boot := arch/arm/boot
|
|||||||
# them changed. We use .arch to indicate when they were updated
|
# them changed. We use .arch to indicate when they were updated
|
||||||
# last, otherwise make uses the target directory mtime.
|
# last, otherwise make uses the target directory mtime.
|
||||||
|
|
||||||
include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf
|
|
||||||
@echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)'
|
|
||||||
ifneq ($(KBUILD_SRC),)
|
|
||||||
$(Q)mkdir -p include/asm-arm
|
|
||||||
$(Q)ln -fsn $(srctree)/include/asm-arm/$(INCDIR) include/asm-arm/arch
|
|
||||||
else
|
|
||||||
$(Q)ln -fsn $(INCDIR) include/asm-arm/arch
|
|
||||||
endif
|
|
||||||
@touch $@
|
|
||||||
|
|
||||||
archprepare: maketools
|
archprepare: maketools
|
||||||
|
|
||||||
PHONY += maketools FORCE
|
PHONY += maketools FORCE
|
||||||
maketools: include/linux/version.h include/asm-arm/.arch FORCE
|
maketools: include/linux/version.h FORCE
|
||||||
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
|
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
|
||||||
|
|
||||||
# Convert bzImage to zImage
|
# Convert bzImage to zImage
|
||||||
|
@ -112,6 +112,3 @@ $(obj)/font.c: $(FONTC)
|
|||||||
|
|
||||||
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
|
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
|
||||||
@sed "$(SEDFLAGS)" < $< > $@
|
@sed "$(SEDFLAGS)" < $< > $@
|
||||||
|
|
||||||
$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c
|
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/mach-types.h>
|
|
||||||
|
|
||||||
.section ".start", "ax"
|
.section ".start", "ax"
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <asm/arch/debug-macro.S>
|
#include <mach/debug-macro.S>
|
||||||
|
|
||||||
.macro writeb, ch, rb
|
.macro writeb, ch, rb
|
||||||
senduart \ch, \rb
|
senduart \ch, \rb
|
||||||
|
@ -27,7 +27,7 @@ unsigned int __machine_arch_type;
|
|||||||
static void putstr(const char *ptr);
|
static void putstr(const char *ptr);
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <asm/arch/uncompress.h>
|
#include <mach/uncompress.h>
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_ICEDCC
|
#ifdef CONFIG_DEBUG_ICEDCC
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/mach/irq.h>
|
#include <asm/mach/irq.h>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
@ -26,13 +26,12 @@
|
|||||||
#include <linux/apm-emulation.h>
|
#include <linux/apm-emulation.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/mach-types.h>
|
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/arch/pm.h>
|
#include <mach/pm.h>
|
||||||
#include <asm/arch/pxa-regs.h>
|
#include <mach/pxa-regs.h>
|
||||||
#include <asm/arch/pxa2xx-regs.h>
|
#include <mach/pxa2xx-regs.h>
|
||||||
#include <asm/arch/sharpsl.h>
|
#include <mach/sharpsl.h>
|
||||||
#include <asm/hardware/sharpsl_pm.h>
|
#include <asm/hardware/sharpsl_pm.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/hardware/ioc.h>
|
#include <asm/hardware/ioc.h>
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <asm/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/arch/hardware.h>
|
|
||||||
#include <asm/hardware/uengine.h>
|
#include <asm/hardware/uengine.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ CONFIG_MACH_AT91CAP9ADK=y
|
|||||||
# AT91 Board Options
|
# AT91 Board Options
|
||||||
#
|
#
|
||||||
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
||||||
# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
|
# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# AT91 Feature Selections
|
# AT91 Feature Selections
|
||||||
@ -442,7 +442,7 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -176,7 +176,7 @@ CONFIG_MACH_AT91SAM9260EK=y
|
|||||||
# AT91 Board Options
|
# AT91 Board Options
|
||||||
#
|
#
|
||||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||||
# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
|
# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# AT91 Feature Selections
|
# AT91 Feature Selections
|
||||||
|
@ -169,7 +169,7 @@ CONFIG_MACH_AT91SAM9261EK=y
|
|||||||
# AT91 Board Options
|
# AT91 Board Options
|
||||||
#
|
#
|
||||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||||
# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
|
# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# AT91 Feature Selections
|
# AT91 Feature Selections
|
||||||
@ -433,7 +433,7 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -169,7 +169,7 @@ CONFIG_MACH_AT91SAM9263EK=y
|
|||||||
# AT91 Board Options
|
# AT91 Board Options
|
||||||
#
|
#
|
||||||
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
||||||
# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
|
# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# AT91 Feature Selections
|
# AT91 Feature Selections
|
||||||
@ -428,7 +428,7 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -168,7 +168,7 @@ CONFIG_MACH_AT91SAM9G20EK=y
|
|||||||
# AT91 Board Options
|
# AT91 Board Options
|
||||||
#
|
#
|
||||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||||
# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
|
# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# AT91 Feature Selections
|
# AT91 Feature Selections
|
||||||
@ -442,10 +442,10 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
|
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -392,7 +392,7 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ONENAND is not set
|
# CONFIG_MTD_ONENAND is not set
|
||||||
|
@ -466,10 +466,10 @@ CONFIG_MTD_NAND_VERIFY_WRITE=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_SOFT is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
|
||||||
CONFIG_MTD_NAND_AT91_ECC_HW=y
|
CONFIG_MTD_NAND_ATMEL_ECC_HW=y
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -458,10 +458,10 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
|
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -429,7 +429,7 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
CONFIG_MTD_NAND_PLATFORM=y
|
CONFIG_MTD_NAND_PLATFORM=y
|
||||||
# CONFIG_MTD_ONENAND is not set
|
# CONFIG_MTD_ONENAND is not set
|
||||||
|
@ -458,10 +458,10 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
|
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -450,10 +450,10 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
|
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
|
||||||
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
|
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
@ -421,7 +421,7 @@ CONFIG_MTD_NAND=y
|
|||||||
# CONFIG_MTD_NAND_ECC_SMC is not set
|
# CONFIG_MTD_NAND_ECC_SMC is not set
|
||||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||||
CONFIG_MTD_NAND_IDS=y
|
CONFIG_MTD_NAND_IDS=y
|
||||||
CONFIG_MTD_NAND_AT91=y
|
CONFIG_MTD_NAND_ATMEL=y
|
||||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||||
CONFIG_MTD_NAND_PLATFORM=y
|
CONFIG_MTD_NAND_PLATFORM=y
|
||||||
# CONFIG_MTD_ALAUDA is not set
|
# CONFIG_MTD_ALAUDA is not set
|
||||||
|
116
arch/arm/include/asm/assembler.h
Normal file
116
arch/arm/include/asm/assembler.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/assembler.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996-2000 Russell King
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This file contains arm architecture specific defines
|
||||||
|
* for the different processors.
|
||||||
|
*
|
||||||
|
* Do not include any C declarations in this file - it is included by
|
||||||
|
* assembler source.
|
||||||
|
*/
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
#error "Only include this from assembly code"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Endian independent macros for shifting bytes within registers.
|
||||||
|
*/
|
||||||
|
#ifndef __ARMEB__
|
||||||
|
#define pull lsr
|
||||||
|
#define push lsl
|
||||||
|
#define get_byte_0 lsl #0
|
||||||
|
#define get_byte_1 lsr #8
|
||||||
|
#define get_byte_2 lsr #16
|
||||||
|
#define get_byte_3 lsr #24
|
||||||
|
#define put_byte_0 lsl #0
|
||||||
|
#define put_byte_1 lsl #8
|
||||||
|
#define put_byte_2 lsl #16
|
||||||
|
#define put_byte_3 lsl #24
|
||||||
|
#else
|
||||||
|
#define pull lsl
|
||||||
|
#define push lsr
|
||||||
|
#define get_byte_0 lsr #24
|
||||||
|
#define get_byte_1 lsr #16
|
||||||
|
#define get_byte_2 lsr #8
|
||||||
|
#define get_byte_3 lsl #0
|
||||||
|
#define put_byte_0 lsl #24
|
||||||
|
#define put_byte_1 lsl #16
|
||||||
|
#define put_byte_2 lsl #8
|
||||||
|
#define put_byte_3 lsl #0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data preload for architectures that support it
|
||||||
|
*/
|
||||||
|
#if __LINUX_ARM_ARCH__ >= 5
|
||||||
|
#define PLD(code...) code
|
||||||
|
#else
|
||||||
|
#define PLD(code...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This can be used to enable code to cacheline align the destination
|
||||||
|
* pointer when bulk writing to memory. Experiments on StrongARM and
|
||||||
|
* XScale didn't show this a worthwhile thing to do when the cache is not
|
||||||
|
* set to write-allocate (this would need further testing on XScale when WA
|
||||||
|
* is used).
|
||||||
|
*
|
||||||
|
* On Feroceon there is much to gain however, regardless of cache mode.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_CPU_FEROCEON
|
||||||
|
#define CALGN(code...) code
|
||||||
|
#else
|
||||||
|
#define CALGN(code...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable and disable interrupts
|
||||||
|
*/
|
||||||
|
#if __LINUX_ARM_ARCH__ >= 6
|
||||||
|
.macro disable_irq
|
||||||
|
cpsid i
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro enable_irq
|
||||||
|
cpsie i
|
||||||
|
.endm
|
||||||
|
#else
|
||||||
|
.macro disable_irq
|
||||||
|
msr cpsr_c, #PSR_I_BIT | SVC_MODE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro enable_irq
|
||||||
|
msr cpsr_c, #SVC_MODE
|
||||||
|
.endm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the current IRQ state and disable IRQs. Note that this macro
|
||||||
|
* assumes FIQs are enabled, and that the processor is in SVC mode.
|
||||||
|
*/
|
||||||
|
.macro save_and_disable_irqs, oldcpsr
|
||||||
|
mrs \oldcpsr, cpsr
|
||||||
|
disable_irq
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore interrupt state previously stored in a register. We don't
|
||||||
|
* guarantee that this will preserve the flags.
|
||||||
|
*/
|
||||||
|
.macro restore_irqs, oldcpsr
|
||||||
|
msr cpsr_c, \oldcpsr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define USER(x...) \
|
||||||
|
9999: x; \
|
||||||
|
.section __ex_table,"a"; \
|
||||||
|
.align 3; \
|
||||||
|
.long 9999b,9001f; \
|
||||||
|
.previous
|
212
arch/arm/include/asm/atomic.h
Normal file
212
arch/arm/include/asm/atomic.h
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/atomic.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996 Russell King.
|
||||||
|
* Copyright (C) 2002 Deep Blue Solutions Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_ARM_ATOMIC_H
|
||||||
|
#define __ASM_ARM_ATOMIC_H
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
typedef struct { volatile int counter; } atomic_t;
|
||||||
|
|
||||||
|
#define ATOMIC_INIT(i) { (i) }
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
#define atomic_read(v) ((v)->counter)
|
||||||
|
|
||||||
|
#if __LINUX_ARM_ARCH__ >= 6
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ARMv6 UP and SMP safe atomic ops. We use load exclusive and
|
||||||
|
* store exclusive to ensure that these are atomic. We may loop
|
||||||
|
* to ensure that the update happens. Writing to 'v->counter'
|
||||||
|
* without using the following operations WILL break the atomic
|
||||||
|
* nature of these ops.
|
||||||
|
*/
|
||||||
|
static inline void atomic_set(atomic_t *v, int i)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic_set\n"
|
||||||
|
"1: ldrex %0, [%1]\n"
|
||||||
|
" strex %0, %2, [%1]\n"
|
||||||
|
" teq %0, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (i)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atomic_add_return(int i, atomic_t *v)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic_add_return\n"
|
||||||
|
"1: ldrex %0, [%2]\n"
|
||||||
|
" add %0, %0, %3\n"
|
||||||
|
" strex %1, %0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "Ir" (i)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atomic_sub_return(int i, atomic_t *v)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic_sub_return\n"
|
||||||
|
"1: ldrex %0, [%2]\n"
|
||||||
|
" sub %0, %0, %3\n"
|
||||||
|
" strex %1, %0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "Ir" (i)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
|
||||||
|
{
|
||||||
|
unsigned long oldval, res;
|
||||||
|
|
||||||
|
do {
|
||||||
|
__asm__ __volatile__("@ atomic_cmpxchg\n"
|
||||||
|
"ldrex %1, [%2]\n"
|
||||||
|
"mov %0, #0\n"
|
||||||
|
"teq %1, %3\n"
|
||||||
|
"strexeq %0, %4, [%2]\n"
|
||||||
|
: "=&r" (res), "=&r" (oldval)
|
||||||
|
: "r" (&ptr->counter), "Ir" (old), "r" (new)
|
||||||
|
: "cc");
|
||||||
|
} while (res);
|
||||||
|
|
||||||
|
return oldval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
|
||||||
|
{
|
||||||
|
unsigned long tmp, tmp2;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic_clear_mask\n"
|
||||||
|
"1: ldrex %0, [%2]\n"
|
||||||
|
" bic %0, %0, %3\n"
|
||||||
|
" strex %1, %0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (tmp), "=&r" (tmp2)
|
||||||
|
: "r" (addr), "Ir" (mask)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ARM_ARCH_6 */
|
||||||
|
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
#error SMP not supported on pre-ARMv6 CPUs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define atomic_set(v,i) (((v)->counter) = (i))
|
||||||
|
|
||||||
|
static inline int atomic_add_return(int i, atomic_t *v)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
raw_local_irq_save(flags);
|
||||||
|
val = v->counter;
|
||||||
|
v->counter = val += i;
|
||||||
|
raw_local_irq_restore(flags);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atomic_sub_return(int i, atomic_t *v)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
raw_local_irq_save(flags);
|
||||||
|
val = v->counter;
|
||||||
|
v->counter = val -= i;
|
||||||
|
raw_local_irq_restore(flags);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
raw_local_irq_save(flags);
|
||||||
|
ret = v->counter;
|
||||||
|
if (likely(ret == old))
|
||||||
|
v->counter = new;
|
||||||
|
raw_local_irq_restore(flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
raw_local_irq_save(flags);
|
||||||
|
*addr &= ~mask;
|
||||||
|
raw_local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __LINUX_ARM_ARCH__ */
|
||||||
|
|
||||||
|
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||||
|
|
||||||
|
static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
||||||
|
{
|
||||||
|
int c, old;
|
||||||
|
|
||||||
|
c = atomic_read(v);
|
||||||
|
while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
|
||||||
|
c = old;
|
||||||
|
return c != u;
|
||||||
|
}
|
||||||
|
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||||
|
|
||||||
|
#define atomic_add(i, v) (void) atomic_add_return(i, v)
|
||||||
|
#define atomic_inc(v) (void) atomic_add_return(1, v)
|
||||||
|
#define atomic_sub(i, v) (void) atomic_sub_return(i, v)
|
||||||
|
#define atomic_dec(v) (void) atomic_sub_return(1, v)
|
||||||
|
|
||||||
|
#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
|
||||||
|
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
|
||||||
|
#define atomic_inc_return(v) (atomic_add_return(1, v))
|
||||||
|
#define atomic_dec_return(v) (atomic_sub_return(1, v))
|
||||||
|
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
|
||||||
|
|
||||||
|
#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
|
||||||
|
|
||||||
|
/* Atomic operations are already serializing on ARM */
|
||||||
|
#define smp_mb__before_atomic_dec() barrier()
|
||||||
|
#define smp_mb__after_atomic_dec() barrier()
|
||||||
|
#define smp_mb__before_atomic_inc() barrier()
|
||||||
|
#define smp_mb__after_atomic_inc() barrier()
|
||||||
|
|
||||||
|
#include <asm-generic/atomic.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
21
arch/arm/include/asm/bugs.h
Normal file
21
arch/arm/include/asm/bugs.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/bugs.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995-2003 Russell King
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_BUGS_H
|
||||||
|
#define __ASM_BUGS_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
extern void check_writebuffer_bugs(void);
|
||||||
|
|
||||||
|
#define check_bugs() check_writebuffer_bugs()
|
||||||
|
#else
|
||||||
|
#define check_bugs() do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
58
arch/arm/include/asm/byteorder.h
Normal file
58
arch/arm/include/asm/byteorder.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/byteorder.h
|
||||||
|
*
|
||||||
|
* ARM Endian-ness. In little endian mode, the data bus is connected such
|
||||||
|
* that byte accesses appear as:
|
||||||
|
* 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
|
||||||
|
* and word accesses (data or instruction) appear as:
|
||||||
|
* d0...d31
|
||||||
|
*
|
||||||
|
* When in big endian mode, byte accesses appear as:
|
||||||
|
* 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7
|
||||||
|
* and word accesses (data or instruction) appear as:
|
||||||
|
* d0...d31
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_ARM_BYTEORDER_H
|
||||||
|
#define __ASM_ARM_BYTEORDER_H
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <asm/types.h>
|
||||||
|
|
||||||
|
static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
|
||||||
|
{
|
||||||
|
__u32 t;
|
||||||
|
|
||||||
|
#ifndef __thumb__
|
||||||
|
if (!__builtin_constant_p(x)) {
|
||||||
|
/*
|
||||||
|
* The compiler needs a bit of a hint here to always do the
|
||||||
|
* right thing and not screw it up to different degrees
|
||||||
|
* depending on the gcc version.
|
||||||
|
*/
|
||||||
|
asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */
|
||||||
|
|
||||||
|
x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */
|
||||||
|
t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */
|
||||||
|
x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __arch__swab32(x) ___arch__swab32(x)
|
||||||
|
|
||||||
|
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
||||||
|
# define __BYTEORDER_HAS_U64__
|
||||||
|
# define __SWAB_64_THRU_32__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
#include <linux/byteorder/big_endian.h>
|
||||||
|
#else
|
||||||
|
#include <linux/byteorder/little_endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
10
arch/arm/include/asm/cache.h
Normal file
10
arch/arm/include/asm/cache.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/cache.h
|
||||||
|
*/
|
||||||
|
#ifndef __ASMARM_CACHE_H
|
||||||
|
#define __ASMARM_CACHE_H
|
||||||
|
|
||||||
|
#define L1_CACHE_SHIFT 5
|
||||||
|
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
|
||||||
|
|
||||||
|
#endif
|
537
arch/arm/include/asm/cacheflush.h
Normal file
537
arch/arm/include/asm/cacheflush.h
Normal file
@ -0,0 +1,537 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/cacheflush.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2002 Russell King
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef _ASMARM_CACHEFLUSH_H
|
||||||
|
#define _ASMARM_CACHEFLUSH_H
|
||||||
|
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
|
||||||
|
#include <asm/glue.h>
|
||||||
|
#include <asm/shmparam.h>
|
||||||
|
|
||||||
|
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache Model
|
||||||
|
* ===========
|
||||||
|
*/
|
||||||
|
#undef _CACHE
|
||||||
|
#undef MULTI_CACHE
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_CACHE_V3)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE v3
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_CACHE_V4)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE v4
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
|
||||||
|
defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020)
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_ARM926T)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE arm926
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_ARM940T)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE arm940
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_ARM946E)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE arm946
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_CACHE_V4WB)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE v4wb
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_XSCALE)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE xscale
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_XSC3)
|
||||||
|
# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
# else
|
||||||
|
# define _CACHE xsc3
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_FEROCEON)
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_V6)
|
||||||
|
//# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
//# else
|
||||||
|
//# define _CACHE v6
|
||||||
|
//# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_V7)
|
||||||
|
//# ifdef _CACHE
|
||||||
|
# define MULTI_CACHE 1
|
||||||
|
//# else
|
||||||
|
//# define _CACHE v7
|
||||||
|
//# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_CACHE) && !defined(MULTI_CACHE)
|
||||||
|
#error Unknown cache maintainence model
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This flag is used to indicate that the page pointed to by a pte
|
||||||
|
* is dirty and requires cleaning before returning it to the user.
|
||||||
|
*/
|
||||||
|
#define PG_dcache_dirty PG_arch_1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MM Cache Management
|
||||||
|
* ===================
|
||||||
|
*
|
||||||
|
* The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
|
||||||
|
* implement these methods.
|
||||||
|
*
|
||||||
|
* Start addresses are inclusive and end addresses are exclusive;
|
||||||
|
* start addresses should be rounded down, end addresses up.
|
||||||
|
*
|
||||||
|
* See Documentation/cachetlb.txt for more information.
|
||||||
|
* Please note that the implementation of these, and the required
|
||||||
|
* effects are cache-type (VIVT/VIPT/PIPT) specific.
|
||||||
|
*
|
||||||
|
* flush_cache_kern_all()
|
||||||
|
*
|
||||||
|
* Unconditionally clean and invalidate the entire cache.
|
||||||
|
*
|
||||||
|
* flush_cache_user_mm(mm)
|
||||||
|
*
|
||||||
|
* Clean and invalidate all user space cache entries
|
||||||
|
* before a change of page tables.
|
||||||
|
*
|
||||||
|
* flush_cache_user_range(start, end, flags)
|
||||||
|
*
|
||||||
|
* Clean and invalidate a range of cache entries in the
|
||||||
|
* specified address space before a change of page tables.
|
||||||
|
* - start - user start address (inclusive, page aligned)
|
||||||
|
* - end - user end address (exclusive, page aligned)
|
||||||
|
* - flags - vma->vm_flags field
|
||||||
|
*
|
||||||
|
* coherent_kern_range(start, end)
|
||||||
|
*
|
||||||
|
* Ensure coherency between the Icache and the Dcache in the
|
||||||
|
* region described by start, end. If you have non-snooping
|
||||||
|
* Harvard caches, you need to implement this function.
|
||||||
|
* - start - virtual start address
|
||||||
|
* - end - virtual end address
|
||||||
|
*
|
||||||
|
* DMA Cache Coherency
|
||||||
|
* ===================
|
||||||
|
*
|
||||||
|
* dma_inv_range(start, end)
|
||||||
|
*
|
||||||
|
* Invalidate (discard) the specified virtual address range.
|
||||||
|
* May not write back any entries. If 'start' or 'end'
|
||||||
|
* are not cache line aligned, those lines must be written
|
||||||
|
* back.
|
||||||
|
* - start - virtual start address
|
||||||
|
* - end - virtual end address
|
||||||
|
*
|
||||||
|
* dma_clean_range(start, end)
|
||||||
|
*
|
||||||
|
* Clean (write back) the specified virtual address range.
|
||||||
|
* - start - virtual start address
|
||||||
|
* - end - virtual end address
|
||||||
|
*
|
||||||
|
* dma_flush_range(start, end)
|
||||||
|
*
|
||||||
|
* Clean and invalidate the specified virtual address range.
|
||||||
|
* - start - virtual start address
|
||||||
|
* - end - virtual end address
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct cpu_cache_fns {
|
||||||
|
void (*flush_kern_all)(void);
|
||||||
|
void (*flush_user_all)(void);
|
||||||
|
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
|
||||||
|
|
||||||
|
void (*coherent_kern_range)(unsigned long, unsigned long);
|
||||||
|
void (*coherent_user_range)(unsigned long, unsigned long);
|
||||||
|
void (*flush_kern_dcache_page)(void *);
|
||||||
|
|
||||||
|
void (*dma_inv_range)(const void *, const void *);
|
||||||
|
void (*dma_clean_range)(const void *, const void *);
|
||||||
|
void (*dma_flush_range)(const void *, const void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct outer_cache_fns {
|
||||||
|
void (*inv_range)(unsigned long, unsigned long);
|
||||||
|
void (*clean_range)(unsigned long, unsigned long);
|
||||||
|
void (*flush_range)(unsigned long, unsigned long);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select the calling method
|
||||||
|
*/
|
||||||
|
#ifdef MULTI_CACHE
|
||||||
|
|
||||||
|
extern struct cpu_cache_fns cpu_cache;
|
||||||
|
|
||||||
|
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
|
||||||
|
#define __cpuc_flush_user_all cpu_cache.flush_user_all
|
||||||
|
#define __cpuc_flush_user_range cpu_cache.flush_user_range
|
||||||
|
#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
|
||||||
|
#define __cpuc_coherent_user_range cpu_cache.coherent_user_range
|
||||||
|
#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are private to the dma-mapping API. Do not use directly.
|
||||||
|
* Their sole purpose is to ensure that data held in the cache
|
||||||
|
* is visible to DMA, or data written by DMA to system memory is
|
||||||
|
* visible to the CPU.
|
||||||
|
*/
|
||||||
|
#define dmac_inv_range cpu_cache.dma_inv_range
|
||||||
|
#define dmac_clean_range cpu_cache.dma_clean_range
|
||||||
|
#define dmac_flush_range cpu_cache.dma_flush_range
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
|
||||||
|
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
|
||||||
|
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
|
||||||
|
#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
|
||||||
|
#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
|
||||||
|
#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page)
|
||||||
|
|
||||||
|
extern void __cpuc_flush_kern_all(void);
|
||||||
|
extern void __cpuc_flush_user_all(void);
|
||||||
|
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
|
||||||
|
extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
|
||||||
|
extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
|
||||||
|
extern void __cpuc_flush_dcache_page(void *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are private to the dma-mapping API. Do not use directly.
|
||||||
|
* Their sole purpose is to ensure that data held in the cache
|
||||||
|
* is visible to DMA, or data written by DMA to system memory is
|
||||||
|
* visible to the CPU.
|
||||||
|
*/
|
||||||
|
#define dmac_inv_range __glue(_CACHE,_dma_inv_range)
|
||||||
|
#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
|
||||||
|
#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
|
||||||
|
|
||||||
|
extern void dmac_inv_range(const void *, const void *);
|
||||||
|
extern void dmac_clean_range(const void *, const void *);
|
||||||
|
extern void dmac_flush_range(const void *, const void *);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_OUTER_CACHE
|
||||||
|
|
||||||
|
extern struct outer_cache_fns outer_cache;
|
||||||
|
|
||||||
|
static inline void outer_inv_range(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
if (outer_cache.inv_range)
|
||||||
|
outer_cache.inv_range(start, end);
|
||||||
|
}
|
||||||
|
static inline void outer_clean_range(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
if (outer_cache.clean_range)
|
||||||
|
outer_cache.clean_range(start, end);
|
||||||
|
}
|
||||||
|
static inline void outer_flush_range(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
if (outer_cache.flush_range)
|
||||||
|
outer_cache.flush_range(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline void outer_inv_range(unsigned long start, unsigned long end)
|
||||||
|
{ }
|
||||||
|
static inline void outer_clean_range(unsigned long start, unsigned long end)
|
||||||
|
{ }
|
||||||
|
static inline void outer_flush_range(unsigned long start, unsigned long end)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush_cache_vmap() is used when creating mappings (eg, via vmap,
|
||||||
|
* vmalloc, ioremap etc) in kernel space for pages. Since the
|
||||||
|
* direct-mappings of these pages may contain cached data, we need
|
||||||
|
* to do a full cache flush to ensure that writebacks don't corrupt
|
||||||
|
* data placed into these pages via the new mappings.
|
||||||
|
*/
|
||||||
|
#define flush_cache_vmap(start, end) flush_cache_all()
|
||||||
|
#define flush_cache_vunmap(start, end) flush_cache_all()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy user data from/to a page which is mapped into a different
|
||||||
|
* processes address space. Really, we want to allow our "user
|
||||||
|
* space" model to handle this.
|
||||||
|
*/
|
||||||
|
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||||
|
do { \
|
||||||
|
memcpy(dst, src, len); \
|
||||||
|
flush_ptrace_access(vma, page, vaddr, dst, len, 1);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||||
|
do { \
|
||||||
|
memcpy(dst, src, len); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert calls to our calling convention.
|
||||||
|
*/
|
||||||
|
#define flush_cache_all() __cpuc_flush_kern_all()
|
||||||
|
#ifndef CONFIG_CPU_CACHE_VIPT
|
||||||
|
static inline void flush_cache_mm(struct mm_struct *mm)
|
||||||
|
{
|
||||||
|
if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
|
||||||
|
__cpuc_flush_user_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask))
|
||||||
|
__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
|
||||||
|
vma->vm_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
|
||||||
|
{
|
||||||
|
if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
|
||||||
|
unsigned long addr = user_addr & PAGE_MASK;
|
||||||
|
__cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
|
||||||
|
unsigned long uaddr, void *kaddr,
|
||||||
|
unsigned long len, int write)
|
||||||
|
{
|
||||||
|
if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
|
||||||
|
unsigned long addr = (unsigned long)kaddr;
|
||||||
|
__cpuc_coherent_kern_range(addr, addr + len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern void flush_cache_mm(struct mm_struct *mm);
|
||||||
|
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
|
||||||
|
extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
|
||||||
|
extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
|
||||||
|
unsigned long uaddr, void *kaddr,
|
||||||
|
unsigned long len, int write);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush_cache_user_range is used when we want to ensure that the
|
||||||
|
* Harvard caches are synchronised for the user space address range.
|
||||||
|
* This is used for the ARM private sys_cacheflush system call.
|
||||||
|
*/
|
||||||
|
#define flush_cache_user_range(vma,start,end) \
|
||||||
|
__cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform necessary cache operations to ensure that data previously
|
||||||
|
* stored within this range of addresses can be executed by the CPU.
|
||||||
|
*/
|
||||||
|
#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform necessary cache operations to ensure that the TLB will
|
||||||
|
* see data written in the specified area.
|
||||||
|
*/
|
||||||
|
#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush_dcache_page is used when the kernel has written to the page
|
||||||
|
* cache page at virtual address page->virtual.
|
||||||
|
*
|
||||||
|
* If this page isn't mapped (ie, page_mapping == NULL), or it might
|
||||||
|
* have userspace mappings, then we _must_ always clean + invalidate
|
||||||
|
* the dcache entries associated with the kernel mapping.
|
||||||
|
*
|
||||||
|
* Otherwise we can defer the operation, and clean the cache when we are
|
||||||
|
* about to change to user space. This is the same method as used on SPARC64.
|
||||||
|
* See update_mmu_cache for the user space part.
|
||||||
|
*/
|
||||||
|
extern void flush_dcache_page(struct page *);
|
||||||
|
|
||||||
|
extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
|
||||||
|
|
||||||
|
static inline void __flush_icache_all(void)
|
||||||
|
{
|
||||||
|
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
|
||||||
|
:
|
||||||
|
: "r" (0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ARCH_HAS_FLUSH_ANON_PAGE
|
||||||
|
static inline void flush_anon_page(struct vm_area_struct *vma,
|
||||||
|
struct page *page, unsigned long vmaddr)
|
||||||
|
{
|
||||||
|
extern void __flush_anon_page(struct vm_area_struct *vma,
|
||||||
|
struct page *, unsigned long);
|
||||||
|
if (PageAnon(page))
|
||||||
|
__flush_anon_page(vma, page, vmaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define flush_dcache_mmap_lock(mapping) \
|
||||||
|
spin_lock_irq(&(mapping)->tree_lock)
|
||||||
|
#define flush_dcache_mmap_unlock(mapping) \
|
||||||
|
spin_unlock_irq(&(mapping)->tree_lock)
|
||||||
|
|
||||||
|
#define flush_icache_user_range(vma,page,addr,len) \
|
||||||
|
flush_dcache_page(page)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't appear to need to do anything here. In fact, if we did, we'd
|
||||||
|
* duplicate cache flushing elsewhere performed by flush_dcache_page().
|
||||||
|
*/
|
||||||
|
#define flush_icache_page(vma,page) do { } while (0)
|
||||||
|
|
||||||
|
static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt,
|
||||||
|
unsigned offset, size_t size)
|
||||||
|
{
|
||||||
|
const void *start = (void __force *)virt + offset;
|
||||||
|
dmac_inv_range(start, start + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __cacheid_present(val) (val != read_cpuid(CPUID_ID))
|
||||||
|
#define __cacheid_type_v7(val) ((val & (7 << 29)) == (4 << 29))
|
||||||
|
|
||||||
|
#define __cacheid_vivt_prev7(val) ((val & (15 << 25)) != (14 << 25))
|
||||||
|
#define __cacheid_vipt_prev7(val) ((val & (15 << 25)) == (14 << 25))
|
||||||
|
#define __cacheid_vipt_nonaliasing_prev7(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25))
|
||||||
|
#define __cacheid_vipt_aliasing_prev7(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23))
|
||||||
|
|
||||||
|
#define __cacheid_vivt(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vivt_prev7(val))
|
||||||
|
#define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val))
|
||||||
|
#define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val))
|
||||||
|
#define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val))
|
||||||
|
#define __cacheid_vivt_asid_tagged_instr(val) (__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0)
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
|
||||||
|
/*
|
||||||
|
* VIVT caches only
|
||||||
|
*/
|
||||||
|
#define cache_is_vivt() 1
|
||||||
|
#define cache_is_vipt() 0
|
||||||
|
#define cache_is_vipt_nonaliasing() 0
|
||||||
|
#define cache_is_vipt_aliasing() 0
|
||||||
|
#define icache_is_vivt_asid_tagged() 0
|
||||||
|
|
||||||
|
#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT)
|
||||||
|
/*
|
||||||
|
* VIPT caches only
|
||||||
|
*/
|
||||||
|
#define cache_is_vivt() 0
|
||||||
|
#define cache_is_vipt() 1
|
||||||
|
#define cache_is_vipt_nonaliasing() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_vipt_nonaliasing(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define cache_is_vipt_aliasing() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_vipt_aliasing(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define icache_is_vivt_asid_tagged() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_vivt_asid_tagged_instr(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* VIVT or VIPT caches. Note that this is unreliable since ARM926
|
||||||
|
* and V6 CPUs satisfy the "(val & (15 << 25)) == (14 << 25)" test.
|
||||||
|
* There's no way to tell from the CacheType register what type (!)
|
||||||
|
* the cache is.
|
||||||
|
*/
|
||||||
|
#define cache_is_vivt() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
(!__cacheid_present(__val)) || __cacheid_vivt(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define cache_is_vipt() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_present(__val) && __cacheid_vipt(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define cache_is_vipt_nonaliasing() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_present(__val) && \
|
||||||
|
__cacheid_vipt_nonaliasing(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define cache_is_vipt_aliasing() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_present(__val) && \
|
||||||
|
__cacheid_vipt_aliasing(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define icache_is_vivt_asid_tagged() \
|
||||||
|
({ \
|
||||||
|
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
|
||||||
|
__cacheid_present(__val) && \
|
||||||
|
__cacheid_vivt_asid_tagged_instr(__val); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
139
arch/arm/include/asm/checksum.h
Normal file
139
arch/arm/include/asm/checksum.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/checksum.h
|
||||||
|
*
|
||||||
|
* IP checksum routines
|
||||||
|
*
|
||||||
|
* Copyright (C) Original authors of ../asm-i386/checksum.h
|
||||||
|
* Copyright (C) 1996-1999 Russell King
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_ARM_CHECKSUM_H
|
||||||
|
#define __ASM_ARM_CHECKSUM_H
|
||||||
|
|
||||||
|
#include <linux/in6.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* computes the checksum of a memory block at buff, length len,
|
||||||
|
* and adds in "sum" (32-bit)
|
||||||
|
*
|
||||||
|
* returns a 32-bit number suitable for feeding into itself
|
||||||
|
* or csum_tcpudp_magic
|
||||||
|
*
|
||||||
|
* this function must be called with even lengths, except
|
||||||
|
* for the last fragment, which may be odd
|
||||||
|
*
|
||||||
|
* it's best to have buff aligned on a 32-bit boundary
|
||||||
|
*/
|
||||||
|
__wsum csum_partial(const void *buff, int len, __wsum sum);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the same as csum_partial, but copies from src while it
|
||||||
|
* checksums, and handles user-space pointer exceptions correctly, when needed.
|
||||||
|
*
|
||||||
|
* here even more important to align src and dst on a 32-bit (or even
|
||||||
|
* better 64-bit) boundary
|
||||||
|
*/
|
||||||
|
|
||||||
|
__wsum
|
||||||
|
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
|
||||||
|
|
||||||
|
__wsum
|
||||||
|
csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fold a partial checksum without adding pseudo headers
|
||||||
|
*/
|
||||||
|
static inline __sum16 csum_fold(__wsum sum)
|
||||||
|
{
|
||||||
|
__asm__(
|
||||||
|
"add %0, %1, %1, ror #16 @ csum_fold"
|
||||||
|
: "=r" (sum)
|
||||||
|
: "r" (sum)
|
||||||
|
: "cc");
|
||||||
|
return (__force __sum16)(~(__force u32)sum >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||||
|
* which always checksum on 4 octet boundaries.
|
||||||
|
*/
|
||||||
|
static inline __sum16
|
||||||
|
ip_fast_csum(const void *iph, unsigned int ihl)
|
||||||
|
{
|
||||||
|
unsigned int tmp1;
|
||||||
|
__wsum sum;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"ldr %0, [%1], #4 @ ip_fast_csum \n\
|
||||||
|
ldr %3, [%1], #4 \n\
|
||||||
|
sub %2, %2, #5 \n\
|
||||||
|
adds %0, %0, %3 \n\
|
||||||
|
ldr %3, [%1], #4 \n\
|
||||||
|
adcs %0, %0, %3 \n\
|
||||||
|
ldr %3, [%1], #4 \n\
|
||||||
|
1: adcs %0, %0, %3 \n\
|
||||||
|
ldr %3, [%1], #4 \n\
|
||||||
|
tst %2, #15 @ do this carefully \n\
|
||||||
|
subne %2, %2, #1 @ without destroying \n\
|
||||||
|
bne 1b @ the carry flag \n\
|
||||||
|
adcs %0, %0, %3 \n\
|
||||||
|
adc %0, %0, #0"
|
||||||
|
: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
|
||||||
|
: "1" (iph), "2" (ihl)
|
||||||
|
: "cc", "memory");
|
||||||
|
return csum_fold(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __wsum
|
||||||
|
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
|
||||||
|
unsigned short proto, __wsum sum)
|
||||||
|
{
|
||||||
|
__asm__(
|
||||||
|
"adds %0, %1, %2 @ csum_tcpudp_nofold \n\
|
||||||
|
adcs %0, %0, %3 \n"
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
"adcs %0, %0, %4 \n"
|
||||||
|
#else
|
||||||
|
"adcs %0, %0, %4, lsl #8 \n"
|
||||||
|
#endif
|
||||||
|
"adcs %0, %0, %5 \n\
|
||||||
|
adc %0, %0, #0"
|
||||||
|
: "=&r"(sum)
|
||||||
|
: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))
|
||||||
|
: "cc");
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* computes the checksum of the TCP/UDP pseudo-header
|
||||||
|
* returns a 16-bit checksum, already complemented
|
||||||
|
*/
|
||||||
|
static inline __sum16
|
||||||
|
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
|
||||||
|
unsigned short proto, __wsum sum)
|
||||||
|
{
|
||||||
|
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this routine is used for miscellaneous IP-like checksums, mainly
|
||||||
|
* in icmp.c
|
||||||
|
*/
|
||||||
|
static inline __sum16
|
||||||
|
ip_compute_csum(const void *buff, int len)
|
||||||
|
{
|
||||||
|
return csum_fold(csum_partial(buff, len, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _HAVE_ARCH_IPV6_CSUM
|
||||||
|
extern __wsum
|
||||||
|
__csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len,
|
||||||
|
__be32 proto, __wsum sum);
|
||||||
|
|
||||||
|
static inline __sum16
|
||||||
|
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len,
|
||||||
|
unsigned short proto, __wsum sum)
|
||||||
|
{
|
||||||
|
return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
|
||||||
|
htonl(proto), sum));
|
||||||
|
}
|
||||||
|
#endif
|
69
arch/arm/include/asm/cpu-multi32.h
Normal file
69
arch/arm/include/asm/cpu-multi32.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/cpu-multi32.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000 Russell King
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
struct mm_struct;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't change this structure - ASM code
|
||||||
|
* relies on it.
|
||||||
|
*/
|
||||||
|
extern struct processor {
|
||||||
|
/* MISC
|
||||||
|
* get data abort address/flags
|
||||||
|
*/
|
||||||
|
void (*_data_abort)(unsigned long pc);
|
||||||
|
/*
|
||||||
|
* Retrieve prefetch fault address
|
||||||
|
*/
|
||||||
|
unsigned long (*_prefetch_abort)(unsigned long lr);
|
||||||
|
/*
|
||||||
|
* Set up any processor specifics
|
||||||
|
*/
|
||||||
|
void (*_proc_init)(void);
|
||||||
|
/*
|
||||||
|
* Disable any processor specifics
|
||||||
|
*/
|
||||||
|
void (*_proc_fin)(void);
|
||||||
|
/*
|
||||||
|
* Special stuff for a reset
|
||||||
|
*/
|
||||||
|
void (*reset)(unsigned long addr) __attribute__((noreturn));
|
||||||
|
/*
|
||||||
|
* Idle the processor
|
||||||
|
*/
|
||||||
|
int (*_do_idle)(void);
|
||||||
|
/*
|
||||||
|
* Processor architecture specific
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* clean a virtual address range from the
|
||||||
|
* D-cache without flushing the cache.
|
||||||
|
*/
|
||||||
|
void (*dcache_clean_area)(void *addr, int size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the page table
|
||||||
|
*/
|
||||||
|
void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
|
||||||
|
/*
|
||||||
|
* Set a possibly extended PTE. Non-extended PTEs should
|
||||||
|
* ignore 'ext'.
|
||||||
|
*/
|
||||||
|
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
|
||||||
|
} processor;
|
||||||
|
|
||||||
|
#define cpu_proc_init() processor._proc_init()
|
||||||
|
#define cpu_proc_fin() processor._proc_fin()
|
||||||
|
#define cpu_reset(addr) processor.reset(addr)
|
||||||
|
#define cpu_do_idle() processor._do_idle()
|
||||||
|
#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
|
||||||
|
#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
|
||||||
|
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
|
44
arch/arm/include/asm/cpu-single.h
Normal file
44
arch/arm/include/asm/cpu-single.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/cpu-single.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000 Russell King
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Single CPU
|
||||||
|
*/
|
||||||
|
#ifdef __STDC__
|
||||||
|
#define __catify_fn(name,x) name##x
|
||||||
|
#else
|
||||||
|
#define __catify_fn(name,x) name/**/x
|
||||||
|
#endif
|
||||||
|
#define __cpu_fn(name,x) __catify_fn(name,x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are supporting multiple CPUs, then we must use a table of
|
||||||
|
* function pointers for this lot. Otherwise, we can optimise the
|
||||||
|
* table away.
|
||||||
|
*/
|
||||||
|
#define cpu_proc_init __cpu_fn(CPU_NAME,_proc_init)
|
||||||
|
#define cpu_proc_fin __cpu_fn(CPU_NAME,_proc_fin)
|
||||||
|
#define cpu_reset __cpu_fn(CPU_NAME,_reset)
|
||||||
|
#define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle)
|
||||||
|
#define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area)
|
||||||
|
#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm)
|
||||||
|
#define cpu_set_pte_ext __cpu_fn(CPU_NAME,_set_pte_ext)
|
||||||
|
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
struct mm_struct;
|
||||||
|
|
||||||
|
/* declare all the functions as extern */
|
||||||
|
extern void cpu_proc_init(void);
|
||||||
|
extern void cpu_proc_fin(void);
|
||||||
|
extern int cpu_do_idle(void);
|
||||||
|
extern void cpu_dcache_clean_area(void *, int);
|
||||||
|
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
|
||||||
|
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
|
||||||
|
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
|
25
arch/arm/include/asm/cpu.h
Normal file
25
arch/arm/include/asm/cpu.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/cpu.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 ARM Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_ARM_CPU_H
|
||||||
|
#define __ASM_ARM_CPU_H
|
||||||
|
|
||||||
|
#include <linux/percpu.h>
|
||||||
|
|
||||||
|
struct cpuinfo_arm {
|
||||||
|
struct cpu cpu;
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
struct task_struct *idle;
|
||||||
|
unsigned int loops_per_jiffy;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data);
|
||||||
|
|
||||||
|
#endif
|
143
arch/arm/include/asm/dma.h
Normal file
143
arch/arm/include/asm/dma.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#ifndef __ASM_ARM_DMA_H
|
||||||
|
#define __ASM_ARM_DMA_H
|
||||||
|
|
||||||
|
typedef unsigned int dmach_t;
|
||||||
|
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/scatterlist.h>
|
||||||
|
#include <mach/dma.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the maximum virtual address which can be DMA'd from.
|
||||||
|
*/
|
||||||
|
#ifndef MAX_DMA_ADDRESS
|
||||||
|
#define MAX_DMA_ADDRESS 0xffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA modes
|
||||||
|
*/
|
||||||
|
typedef unsigned int dmamode_t;
|
||||||
|
|
||||||
|
#define DMA_MODE_MASK 3
|
||||||
|
|
||||||
|
#define DMA_MODE_READ 0
|
||||||
|
#define DMA_MODE_WRITE 1
|
||||||
|
#define DMA_MODE_CASCADE 2
|
||||||
|
#define DMA_AUTOINIT 4
|
||||||
|
|
||||||
|
extern spinlock_t dma_spin_lock;
|
||||||
|
|
||||||
|
static inline unsigned long claim_dma_lock(void)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
spin_lock_irqsave(&dma_spin_lock, flags);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void release_dma_lock(unsigned long flags)
|
||||||
|
{
|
||||||
|
spin_unlock_irqrestore(&dma_spin_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the 'DMA Pointer Flip Flop'.
|
||||||
|
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
|
||||||
|
*/
|
||||||
|
#define clear_dma_ff(channel)
|
||||||
|
|
||||||
|
/* Set only the page register bits of the transfer address.
|
||||||
|
*
|
||||||
|
* NOTE: This is an architecture specific function, and should
|
||||||
|
* be hidden from the drivers
|
||||||
|
*/
|
||||||
|
extern void set_dma_page(dmach_t channel, char pagenr);
|
||||||
|
|
||||||
|
/* Request a DMA channel
|
||||||
|
*
|
||||||
|
* Some architectures may need to do allocate an interrupt
|
||||||
|
*/
|
||||||
|
extern int request_dma(dmach_t channel, const char * device_id);
|
||||||
|
|
||||||
|
/* Free a DMA channel
|
||||||
|
*
|
||||||
|
* Some architectures may need to do free an interrupt
|
||||||
|
*/
|
||||||
|
extern void free_dma(dmach_t channel);
|
||||||
|
|
||||||
|
/* Enable DMA for this channel
|
||||||
|
*
|
||||||
|
* On some architectures, this may have other side effects like
|
||||||
|
* enabling an interrupt and setting the DMA registers.
|
||||||
|
*/
|
||||||
|
extern void enable_dma(dmach_t channel);
|
||||||
|
|
||||||
|
/* Disable DMA for this channel
|
||||||
|
*
|
||||||
|
* On some architectures, this may have other side effects like
|
||||||
|
* disabling an interrupt or whatever.
|
||||||
|
*/
|
||||||
|
extern void disable_dma(dmach_t channel);
|
||||||
|
|
||||||
|
/* Test whether the specified channel has an active DMA transfer
|
||||||
|
*/
|
||||||
|
extern int dma_channel_active(dmach_t channel);
|
||||||
|
|
||||||
|
/* Set the DMA scatter gather list for this channel
|
||||||
|
*
|
||||||
|
* This should not be called if a DMA channel is enabled,
|
||||||
|
* especially since some DMA architectures don't update the
|
||||||
|
* DMA address immediately, but defer it to the enable_dma().
|
||||||
|
*/
|
||||||
|
extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
|
||||||
|
|
||||||
|
/* Set the DMA address for this channel
|
||||||
|
*
|
||||||
|
* This should not be called if a DMA channel is enabled,
|
||||||
|
* especially since some DMA architectures don't update the
|
||||||
|
* DMA address immediately, but defer it to the enable_dma().
|
||||||
|
*/
|
||||||
|
extern void __set_dma_addr(dmach_t channel, void *addr);
|
||||||
|
#define set_dma_addr(channel, addr) \
|
||||||
|
__set_dma_addr(channel, bus_to_virt(addr))
|
||||||
|
|
||||||
|
/* Set the DMA byte count for this channel
|
||||||
|
*
|
||||||
|
* This should not be called if a DMA channel is enabled,
|
||||||
|
* especially since some DMA architectures don't update the
|
||||||
|
* DMA count immediately, but defer it to the enable_dma().
|
||||||
|
*/
|
||||||
|
extern void set_dma_count(dmach_t channel, unsigned long count);
|
||||||
|
|
||||||
|
/* Set the transfer direction for this channel
|
||||||
|
*
|
||||||
|
* This should not be called if a DMA channel is enabled,
|
||||||
|
* especially since some DMA architectures don't update the
|
||||||
|
* DMA transfer direction immediately, but defer it to the
|
||||||
|
* enable_dma().
|
||||||
|
*/
|
||||||
|
extern void set_dma_mode(dmach_t channel, dmamode_t mode);
|
||||||
|
|
||||||
|
/* Set the transfer speed for this channel
|
||||||
|
*/
|
||||||
|
extern void set_dma_speed(dmach_t channel, int cycle_ns);
|
||||||
|
|
||||||
|
/* Get DMA residue count. After a DMA transfer, this
|
||||||
|
* should return zero. Reading this while a DMA transfer is
|
||||||
|
* still in progress will return unpredictable results.
|
||||||
|
* If called before the channel has been used, it may return 1.
|
||||||
|
* Otherwise, it returns the number of _bytes_ left to transfer.
|
||||||
|
*/
|
||||||
|
extern int get_dma_residue(dmach_t channel);
|
||||||
|
|
||||||
|
#ifndef NO_DMA
|
||||||
|
#define NO_DMA 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
extern int isa_dma_bridge_buggy;
|
||||||
|
#else
|
||||||
|
#define isa_dma_bridge_buggy (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ARM_DMA_H */
|
78
arch/arm/include/asm/domain.h
Normal file
78
arch/arm/include/asm/domain.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/domain.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 Russell King.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_PROC_DOMAIN_H
|
||||||
|
#define __ASM_PROC_DOMAIN_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Domain numbers
|
||||||
|
*
|
||||||
|
* DOMAIN_IO - domain 2 includes all IO only
|
||||||
|
* DOMAIN_USER - domain 1 includes all user memory only
|
||||||
|
* DOMAIN_KERNEL - domain 0 includes all kernel memory only
|
||||||
|
*
|
||||||
|
* The domain numbering depends on whether we support 36 physical
|
||||||
|
* address for I/O or not. Addresses above the 32 bit boundary can
|
||||||
|
* only be mapped using supersections and supersections can only
|
||||||
|
* be set for domain 0. We could just default to DOMAIN_IO as zero,
|
||||||
|
* but there may be systems with supersection support and no 36-bit
|
||||||
|
* addressing. In such cases, we want to map system memory with
|
||||||
|
* supersections to reduce TLB misses and footprint.
|
||||||
|
*
|
||||||
|
* 36-bit addressing and supersections are only available on
|
||||||
|
* CPUs based on ARMv6+ or the Intel XSC3 core.
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_IO_36
|
||||||
|
#define DOMAIN_KERNEL 0
|
||||||
|
#define DOMAIN_TABLE 0
|
||||||
|
#define DOMAIN_USER 1
|
||||||
|
#define DOMAIN_IO 2
|
||||||
|
#else
|
||||||
|
#define DOMAIN_KERNEL 2
|
||||||
|
#define DOMAIN_TABLE 2
|
||||||
|
#define DOMAIN_USER 1
|
||||||
|
#define DOMAIN_IO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Domain types
|
||||||
|
*/
|
||||||
|
#define DOMAIN_NOACCESS 0
|
||||||
|
#define DOMAIN_CLIENT 1
|
||||||
|
#define DOMAIN_MANAGER 3
|
||||||
|
|
||||||
|
#define domain_val(dom,type) ((type) << (2*(dom)))
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
#define set_domain(x) \
|
||||||
|
do { \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"mcr p15, 0, %0, c3, c0 @ set domain" \
|
||||||
|
: : "r" (x)); \
|
||||||
|
isb(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define modify_domain(dom,type) \
|
||||||
|
do { \
|
||||||
|
struct thread_info *thread = current_thread_info(); \
|
||||||
|
unsigned int domain = thread->cpu_domain; \
|
||||||
|
domain &= ~domain_val(dom, DOMAIN_MANAGER); \
|
||||||
|
thread->cpu_domain = domain | domain_val(dom, type); \
|
||||||
|
set_domain(thread->cpu_domain); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define set_domain(x) do { } while (0)
|
||||||
|
#define modify_domain(dom,type) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
219
arch/arm/include/asm/ecard.h
Normal file
219
arch/arm/include/asm/ecard.h
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/ecard.h
|
||||||
|
*
|
||||||
|
* definitions for expansion cards
|
||||||
|
*
|
||||||
|
* This is a new system as from Linux 1.2.3
|
||||||
|
*
|
||||||
|
* Changelog:
|
||||||
|
* 11-12-1996 RMK Further minor improvements
|
||||||
|
* 12-09-1997 RMK Added interrupt enable/disable for card level
|
||||||
|
*
|
||||||
|
* Reference: Acorns Risc OS 3 Programmers Reference Manuals.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ECARD_H
|
||||||
|
#define __ASM_ECARD_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently understood cards (but not necessarily
|
||||||
|
* supported):
|
||||||
|
* Manufacturer Product ID
|
||||||
|
*/
|
||||||
|
#define MANU_ACORN 0x0000
|
||||||
|
#define PROD_ACORN_SCSI 0x0002
|
||||||
|
#define PROD_ACORN_ETHER1 0x0003
|
||||||
|
#define PROD_ACORN_MFM 0x000b
|
||||||
|
|
||||||
|
#define MANU_ANT2 0x0011
|
||||||
|
#define PROD_ANT_ETHER3 0x00a4
|
||||||
|
|
||||||
|
#define MANU_ATOMWIDE 0x0017
|
||||||
|
#define PROD_ATOMWIDE_3PSERIAL 0x0090
|
||||||
|
|
||||||
|
#define MANU_IRLAM_INSTRUMENTS 0x001f
|
||||||
|
#define MANU_IRLAM_INSTRUMENTS_ETHERN 0x5678
|
||||||
|
|
||||||
|
#define MANU_OAK 0x0021
|
||||||
|
#define PROD_OAK_SCSI 0x0058
|
||||||
|
|
||||||
|
#define MANU_MORLEY 0x002b
|
||||||
|
#define PROD_MORLEY_SCSI_UNCACHED 0x0067
|
||||||
|
|
||||||
|
#define MANU_CUMANA 0x003a
|
||||||
|
#define PROD_CUMANA_SCSI_2 0x003a
|
||||||
|
#define PROD_CUMANA_SCSI_1 0x00a0
|
||||||
|
|
||||||
|
#define MANU_ICS 0x003c
|
||||||
|
#define PROD_ICS_IDE 0x00ae
|
||||||
|
|
||||||
|
#define MANU_ICS2 0x003d
|
||||||
|
#define PROD_ICS2_IDE 0x00ae
|
||||||
|
|
||||||
|
#define MANU_SERPORT 0x003f
|
||||||
|
#define PROD_SERPORT_DSPORT 0x00b9
|
||||||
|
|
||||||
|
#define MANU_ARXE 0x0041
|
||||||
|
#define PROD_ARXE_SCSI 0x00be
|
||||||
|
|
||||||
|
#define MANU_I3 0x0046
|
||||||
|
#define PROD_I3_ETHERLAN500 0x00d4
|
||||||
|
#define PROD_I3_ETHERLAN600 0x00ec
|
||||||
|
#define PROD_I3_ETHERLAN600A 0x011e
|
||||||
|
|
||||||
|
#define MANU_ANT 0x0053
|
||||||
|
#define PROD_ANT_ETHERM 0x00d8
|
||||||
|
#define PROD_ANT_ETHERB 0x00e4
|
||||||
|
|
||||||
|
#define MANU_ALSYSTEMS 0x005b
|
||||||
|
#define PROD_ALSYS_SCSIATAPI 0x0107
|
||||||
|
|
||||||
|
#define MANU_MCS 0x0063
|
||||||
|
#define PROD_MCS_CONNECT32 0x0125
|
||||||
|
|
||||||
|
#define MANU_EESOX 0x0064
|
||||||
|
#define PROD_EESOX_SCSI2 0x008c
|
||||||
|
|
||||||
|
#define MANU_YELLOWSTONE 0x0096
|
||||||
|
#define PROD_YELLOWSTONE_RAPIDE32 0x0120
|
||||||
|
|
||||||
|
#ifdef ECARD_C
|
||||||
|
#define CONST
|
||||||
|
#else
|
||||||
|
#define CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_ECARDS 9
|
||||||
|
|
||||||
|
struct ecard_id { /* Card ID structure */
|
||||||
|
unsigned short manufacturer;
|
||||||
|
unsigned short product;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct in_ecid { /* Packed card ID information */
|
||||||
|
unsigned short product; /* Product code */
|
||||||
|
unsigned short manufacturer; /* Manufacturer code */
|
||||||
|
unsigned char id:4; /* Simple ID */
|
||||||
|
unsigned char cd:1; /* Chunk dir present */
|
||||||
|
unsigned char is:1; /* Interrupt status pointers */
|
||||||
|
unsigned char w:2; /* Width */
|
||||||
|
unsigned char country; /* Country */
|
||||||
|
unsigned char irqmask; /* IRQ mask */
|
||||||
|
unsigned char fiqmask; /* FIQ mask */
|
||||||
|
unsigned long irqoff; /* IRQ offset */
|
||||||
|
unsigned long fiqoff; /* FIQ offset */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct expansion_card ecard_t;
|
||||||
|
typedef unsigned long *loader_t;
|
||||||
|
|
||||||
|
typedef struct expansion_card_ops { /* Card handler routines */
|
||||||
|
void (*irqenable)(ecard_t *ec, int irqnr);
|
||||||
|
void (*irqdisable)(ecard_t *ec, int irqnr);
|
||||||
|
int (*irqpending)(ecard_t *ec);
|
||||||
|
void (*fiqenable)(ecard_t *ec, int fiqnr);
|
||||||
|
void (*fiqdisable)(ecard_t *ec, int fiqnr);
|
||||||
|
int (*fiqpending)(ecard_t *ec);
|
||||||
|
} expansioncard_ops_t;
|
||||||
|
|
||||||
|
#define ECARD_NUM_RESOURCES (6)
|
||||||
|
|
||||||
|
#define ECARD_RES_IOCSLOW (0)
|
||||||
|
#define ECARD_RES_IOCMEDIUM (1)
|
||||||
|
#define ECARD_RES_IOCFAST (2)
|
||||||
|
#define ECARD_RES_IOCSYNC (3)
|
||||||
|
#define ECARD_RES_MEMC (4)
|
||||||
|
#define ECARD_RES_EASI (5)
|
||||||
|
|
||||||
|
#define ecard_resource_start(ec,nr) ((ec)->resource[nr].start)
|
||||||
|
#define ecard_resource_end(ec,nr) ((ec)->resource[nr].end)
|
||||||
|
#define ecard_resource_len(ec,nr) ((ec)->resource[nr].end - \
|
||||||
|
(ec)->resource[nr].start + 1)
|
||||||
|
#define ecard_resource_flags(ec,nr) ((ec)->resource[nr].flags)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This contains all the info needed on an expansion card
|
||||||
|
*/
|
||||||
|
struct expansion_card {
|
||||||
|
struct expansion_card *next;
|
||||||
|
|
||||||
|
struct device dev;
|
||||||
|
struct resource resource[ECARD_NUM_RESOURCES];
|
||||||
|
|
||||||
|
/* Public data */
|
||||||
|
void __iomem *irqaddr; /* address of IRQ register */
|
||||||
|
void __iomem *fiqaddr; /* address of FIQ register */
|
||||||
|
unsigned char irqmask; /* IRQ mask */
|
||||||
|
unsigned char fiqmask; /* FIQ mask */
|
||||||
|
unsigned char claimed; /* Card claimed? */
|
||||||
|
unsigned char easi; /* EASI card */
|
||||||
|
|
||||||
|
void *irq_data; /* Data for use for IRQ by card */
|
||||||
|
void *fiq_data; /* Data for use for FIQ by card */
|
||||||
|
const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
|
||||||
|
|
||||||
|
CONST unsigned int slot_no; /* Slot number */
|
||||||
|
CONST unsigned int dma; /* DMA number (for request_dma) */
|
||||||
|
CONST unsigned int irq; /* IRQ number (for request_irq) */
|
||||||
|
CONST unsigned int fiq; /* FIQ number (for request_irq) */
|
||||||
|
CONST struct in_ecid cid; /* Card Identification */
|
||||||
|
|
||||||
|
/* Private internal data */
|
||||||
|
const char *card_desc; /* Card description */
|
||||||
|
CONST unsigned int podaddr; /* Base Linux address for card */
|
||||||
|
CONST loader_t loader; /* loader program */
|
||||||
|
u64 dma_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data);
|
||||||
|
|
||||||
|
struct in_chunk_dir {
|
||||||
|
unsigned int start_offset;
|
||||||
|
union {
|
||||||
|
unsigned char string[256];
|
||||||
|
unsigned char data[1];
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a chunk from an expansion card
|
||||||
|
* cd : where to put read data
|
||||||
|
* ec : expansion card info struct
|
||||||
|
* id : id number to find
|
||||||
|
* num: (n+1)'th id to find.
|
||||||
|
*/
|
||||||
|
extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request and release ecard resources
|
||||||
|
*/
|
||||||
|
extern int ecard_request_resources(struct expansion_card *ec);
|
||||||
|
extern void ecard_release_resources(struct expansion_card *ec);
|
||||||
|
|
||||||
|
void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
|
||||||
|
unsigned long offset, unsigned long maxsize);
|
||||||
|
#define ecardm_iounmap(__ec, __addr) devm_iounmap(&(__ec)->dev, __addr)
|
||||||
|
|
||||||
|
extern struct bus_type ecard_bus_type;
|
||||||
|
|
||||||
|
#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)
|
||||||
|
|
||||||
|
struct ecard_driver {
|
||||||
|
int (*probe)(struct expansion_card *, const struct ecard_id *id);
|
||||||
|
void (*remove)(struct expansion_card *);
|
||||||
|
void (*shutdown)(struct expansion_card *);
|
||||||
|
const struct ecard_id *id_table;
|
||||||
|
unsigned int id;
|
||||||
|
struct device_driver drv;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ECARD_DRV(_d) container_of((_d), struct ecard_driver, drv)
|
||||||
|
|
||||||
|
#define ecard_set_drvdata(ec,data) dev_set_drvdata(&(ec)->dev, (data))
|
||||||
|
#define ecard_get_drvdata(ec) dev_get_drvdata(&(ec)->dev)
|
||||||
|
|
||||||
|
int ecard_register_driver(struct ecard_driver *);
|
||||||
|
void ecard_remove_driver(struct ecard_driver *);
|
||||||
|
|
||||||
|
#endif
|
37
arch/arm/include/asm/fiq.h
Normal file
37
arch/arm/include/asm/fiq.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/fiq.h
|
||||||
|
*
|
||||||
|
* Support for FIQ on ARM architectures.
|
||||||
|
* Written by Philip Blundell <philb@gnu.org>, 1998
|
||||||
|
* Re-written by Russell King
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_FIQ_H
|
||||||
|
#define __ASM_FIQ_H
|
||||||
|
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
|
struct fiq_handler {
|
||||||
|
struct fiq_handler *next;
|
||||||
|
/* Name
|
||||||
|
*/
|
||||||
|
const char *name;
|
||||||
|
/* Called to ask driver to relinquish/
|
||||||
|
* reacquire FIQ
|
||||||
|
* return zero to accept, or -<errno>
|
||||||
|
*/
|
||||||
|
int (*fiq_op)(void *, int relinquish);
|
||||||
|
/* data for the relinquish/reacquire functions
|
||||||
|
*/
|
||||||
|
void *dev_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int claim_fiq(struct fiq_handler *f);
|
||||||
|
extern void release_fiq(struct fiq_handler *f);
|
||||||
|
extern void set_fiq_handler(void *start, unsigned int length);
|
||||||
|
extern void set_fiq_regs(struct pt_regs *regs);
|
||||||
|
extern void get_fiq_regs(struct pt_regs *regs);
|
||||||
|
extern void enable_fiq(int fiq);
|
||||||
|
extern void disable_fiq(int fiq);
|
||||||
|
|
||||||
|
#endif
|
19
arch/arm/include/asm/flat.h
Normal file
19
arch/arm/include/asm/flat.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/flat.h -- uClinux flat-format executables
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARM_FLAT_H__
|
||||||
|
#define __ARM_FLAT_H__
|
||||||
|
|
||||||
|
/* An odd number of words will be pushed after this alignment, so
|
||||||
|
deliberately misalign the value. */
|
||||||
|
#define flat_stack_align(sp) sp = (void *)(((unsigned long)(sp) - 4) | 4)
|
||||||
|
#define flat_argvp_envp_on_stack() 1
|
||||||
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
|
#define flat_get_addr_from_rp(rp, relval, flags, persistent) get_unaligned(rp)
|
||||||
|
#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp)
|
||||||
|
#define flat_get_relocate_addr(rel) (rel)
|
||||||
|
#define flat_set_persistent(relval, p) 0
|
||||||
|
|
||||||
|
#endif /* __ARM_FLAT_H__ */
|
148
arch/arm/include/asm/floppy.h
Normal file
148
arch/arm/include/asm/floppy.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/include/asm/floppy.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996-2000 Russell King
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_ARM_FLOPPY_H
|
||||||
|
#define __ASM_ARM_FLOPPY_H
|
||||||
|
#if 0
|
||||||
|
#include <mach/floppy.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define fd_outb(val,port) \
|
||||||
|
do { \
|
||||||
|
if ((port) == FD_DOR) \
|
||||||
|
fd_setdor((val)); \
|
||||||
|
else \
|
||||||
|
outb((val),(port)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define fd_inb(port) inb((port))
|
||||||
|
#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
|
||||||
|
IRQF_DISABLED,"floppy",NULL)
|
||||||
|
#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL)
|
||||||
|
#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK)
|
||||||
|
#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK)
|
||||||
|
|
||||||
|
static inline int fd_dma_setup(void *data, unsigned int length,
|
||||||
|
unsigned int mode, unsigned long addr)
|
||||||
|
{
|
||||||
|
set_dma_mode(DMA_FLOPPY, mode);
|
||||||
|
__set_dma_addr(DMA_FLOPPY, data);
|
||||||
|
set_dma_count(DMA_FLOPPY, length);
|
||||||
|
virtual_dma_port = addr;
|
||||||
|
enable_dma(DMA_FLOPPY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define fd_dma_setup fd_dma_setup
|
||||||
|
|
||||||
|
#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy")
|
||||||
|
#define fd_free_dma() free_dma(DMA_FLOPPY)
|
||||||
|
#define fd_disable_dma() disable_dma(DMA_FLOPPY)
|
||||||
|
|
||||||
|
/* need to clean up dma.h */
|
||||||
|
#define DMA_FLOPPYDISK DMA_FLOPPY
|
||||||
|
|
||||||
|
/* Floppy_selects is the list of DOR's to select drive fd
|
||||||
|
*
|
||||||
|
* On initialisation, the floppy list is scanned, and the drives allocated
|
||||||
|
* in the order that they are found. This is done by seeking the drive
|
||||||
|
* to a non-zero track, and then restoring it to track 0. If an error occurs,
|
||||||
|
* then there is no floppy drive present. [to be put back in again]
|
||||||
|
*/
|
||||||
|
static unsigned char floppy_selects[2][4] =
|
||||||
|
{
|
||||||
|
{ 0x10, 0x21, 0x23, 0x33 },
|
||||||
|
{ 0x10, 0x21, 0x23, 0x33 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define fd_setdor(dor) \
|
||||||
|
do { \
|
||||||
|
int new_dor = (dor); \
|
||||||
|
if (new_dor & 0xf0) \
|
||||||
|
new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3]; \
|
||||||
|
else \
|
||||||
|
new_dor &= 0x0c; \
|
||||||
|
outb(new_dor, FD_DOR); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Someday, we'll automatically detect which drives are present...
|
||||||
|
*/
|
||||||
|
static inline void fd_scandrives (void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int floppy, drive_count;
|
||||||
|
|
||||||
|
fd_disable_irq();
|
||||||
|
raw_cmd = &default_raw_cmd;
|
||||||
|
raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK;
|
||||||
|
raw_cmd->track = 0;
|
||||||
|
raw_cmd->rate = ?;
|
||||||
|
drive_count = 0;
|
||||||
|
for (floppy = 0; floppy < 4; floppy ++) {
|
||||||
|
current_drive = drive_count;
|
||||||
|
/*
|
||||||
|
* Turn on floppy motor
|
||||||
|
*/
|
||||||
|
if (start_motor(redo_fd_request))
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Set up FDC
|
||||||
|
*/
|
||||||
|
fdc_specify();
|
||||||
|
/*
|
||||||
|
* Tell FDC to recalibrate
|
||||||
|
*/
|
||||||
|
output_byte(FD_RECALIBRATE);
|
||||||
|
LAST_OUT(UNIT(floppy));
|
||||||
|
/* wait for command to complete */
|
||||||
|
if (!successful) {
|
||||||
|
int i;
|
||||||
|
for (i = drive_count; i < 3; i--)
|
||||||
|
floppy_selects[fdc][i] = floppy_selects[fdc][i + 1];
|
||||||
|
floppy_selects[fdc][3] = 0;
|
||||||
|
floppy -= 1;
|
||||||
|
} else
|
||||||
|
drive_count++;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
floppy_selects[0][0] = 0x10;
|
||||||
|
floppy_selects[0][1] = 0x21;
|
||||||
|
floppy_selects[0][2] = 0x23;
|
||||||
|
floppy_selects[0][3] = 0x33;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FDC1 (0x3f0)
|
||||||
|
|
||||||
|
#define FLOPPY0_TYPE 4
|
||||||
|
#define FLOPPY1_TYPE 4
|
||||||
|
|
||||||
|
#define N_FDC 1
|
||||||
|
#define N_DRIVE 4
|
||||||
|
|
||||||
|
#define CROSS_64KB(a,s) (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This allows people to reverse the order of
|
||||||
|
* fd0 and fd1, in case their hardware is
|
||||||
|
* strangely connected (as some RiscPCs
|
||||||
|
* and A5000s seem to be).
|
||||||
|
*/
|
||||||
|
static void driveswap(int *ints, int dummy, int dummy2)
|
||||||
|
{
|
||||||
|
floppy_selects[0][0] ^= floppy_selects[0][1];
|
||||||
|
floppy_selects[0][1] ^= floppy_selects[0][0];
|
||||||
|
floppy_selects[0][0] ^= floppy_selects[0][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user