提交 4fb8af10 编写于 作者: R Russell King 提交者: Russell King

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -89,8 +89,6 @@ cciss.txt ...@@ -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/
......
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 \ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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>
......
<?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>
...@@ -528,7 +528,33 @@ See more details on the proper patch format in the following ...@@ -528,7 +528,33 @@ See more details on the proper patch format in the following
references. references.
16) Sending "git pull" requests (from Linus emails)
Please write the git repo address and branch name alone on the same line
so that I can't even by mistake pull from the wrong branch, and so
that a triple-click just selects the whole thing.
So the proper format is something along the lines of:
"Please pull from
git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus
to get these changes:"
so that I don't have to hunt-and-peck for the address and inevitably
get it wrong (actually, I've only gotten it wrong a few times, and
checking against the diffstat tells me when I get it wrong, but I'm
just a lot more comfortable when I don't have to "look for" the right
thing to pull, and double-check that I have the right branch-name).
Please use "git diff -M --stat --summary" to generate the diffstat:
the -M enables rename detection, and the summary enables a summary of
new/deleted or renamed files.
With rename detection, the statistics are rather different [...]
because git will notice that a fair number of the changes are renames.
----------------------------------- -----------------------------------
SECTION 2 - HINTS, TIPS, AND TRICKS SECTION 2 - HINTS, TIPS, AND TRICKS
......
#### 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 :-)
...@@ -47,6 +47,30 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org> ...@@ -47,6 +47,30 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
--------------------------- ---------------------------
What: old tuner-3036 i2c driver
When: 2.6.28
Why: This driver is for VERY old i2c-over-parallel port teletext receiver
boxes. Rather then spending effort on converting this driver to V4L2,
and since it is extremely unlikely that anyone still uses one of these
devices, it was decided to drop it.
Who: Hans Verkuil <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: V4L2 dpc7146 driver
When: 2.6.28
Why: Old driver for the dpc7146 demonstration board that is no longer
relevant. The last time this was tested on actual hardware was
probably around 2002. Since this is a driver for a demonstration
board the decision was made to remove it rather than spending a
lot of effort continually updating this driver to stay in sync
with the latest internal V4L2 or I2C API.
Who: Hans Verkuil <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
When: November 2005 When: November 2005
Files: drivers/pcmcia/: pcmcia_ioctl.c Files: drivers/pcmcia/: pcmcia_ioctl.c
......
...@@ -311,9 +311,20 @@ the subsystem must be ready for it. ...@@ -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]
......
/*
* 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");
/*
* 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");
/*
* 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 @@ ...@@ -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.
......
...@@ -22,6 +22,10 @@ Module Parameters ...@@ -22,6 +22,10 @@ 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
when probing for ISA devices. This is required for the
following boards:
- VIA EPIA SN18000
Note that there is no need to use this parameter if the driver loads without Note that there is no need to use this parameter if the driver loads without
complaining. The driver will say so if it is necessary. complaining. The driver will say so if it is necessary.
......
...@@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has ...@@ -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: ...@@ -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
......
Upgrading I2C Drivers to the new 2.6 Driver Model
=================================================
Ben Dooks <ben-linux@fluff.org>
Introduction
------------
This guide outlines how to alter existing Linux 2.6 client drivers from
the old to the new new binding methods.
Example old-style driver
------------------------
struct example_state {
struct i2c_client client;
....
};
static struct i2c_driver example_driver;
static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
static int example_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct example_state *state;
struct device *dev = &adap->dev; /* to use for dev_ reports */
int ret;
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
if (state == NULL) {
dev_err(dev, "failed to create our state\n");
return -ENOMEM;
}
example->client.addr = addr;
example->client.flags = 0;
example->client.adapter = adap;
i2c_set_clientdata(&state->i2c_client, state);
strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
ret = i2c_attach_client(&state->i2c_client);
if (ret < 0) {
dev_err(dev, "failed to attach client\n");
kfree(state);
return ret;
}
dev = &state->i2c_client.dev;
/* rest of the initialisation goes here. */
dev_info(dev, "example client created\n");
return 0;
}
static int __devexit example_detach(struct i2c_client *client)
{
struct example_state *state = i2c_get_clientdata(client);
i2c_detach_client(client);
kfree(state);
return 0;
}
static int example_attach_adapter(struct i2c_adapter *adap)
{
return i2c_probe(adap, &addr_data, example_attach);
}
static struct i2c_driver example_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "example",
},
.attach_adapter = example_attach_adapter,
.detach_client = __devexit_p(example_detach),
.suspend = example_suspend,
.resume = example_resume,
};
Updating the client
-------------------
The new style binding model will check against a list of supported
devices and their associated address supplied by the code registering
the busses. This means that the driver .attach_adapter and
.detach_adapter methods can be removed, along with the addr_data,
as follows:
- static struct i2c_driver example_driver;
- static unsigned short ignore[] = { I2C_CLIENT_END };
- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
- I2C_CLIENT_INSMOD;
- static int example_attach_adapter(struct i2c_adapter *adap)
- {
- return i2c_probe(adap, &addr_data, example_attach);
- }
static struct i2c_driver example_driver = {
- .attach_adapter = example_attach_adapter,
- .detach_client = __devexit_p(example_detach),
}
Add the probe and remove methods to the i2c_driver, as so:
static struct i2c_driver example_driver = {
+ .probe = example_probe,
+ .remove = __devexit_p(example_remove),
}
Change the example_attach method to accept the new parameters
which include the i2c_client that it will be working with:
- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
+ static int example_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
Change the name of example_attach to example_probe to align it with the
i2c_driver entry names. The rest of the probe routine will now need to be
changed as the i2c_client has already been setup for use.
The necessary client fields have already been setup before
the probe function is called, so the following client setup
can be removed:
- example->client.addr = addr;
- example->client.flags = 0;
- example->client.adapter = adap;
-
- strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
The i2c_set_clientdata is now:
- i2c_set_clientdata(&state->client, state);
+ i2c_set_clientdata(client, state);
The call to i2c_attach_client is no longer needed, if the probe
routine exits successfully, then the driver will be automatically
attached by the core. Change the probe routine as so:
- ret = i2c_attach_client(&state->i2c_client);
- if (ret < 0) {
- dev_err(dev, "failed to attach client\n");
- kfree(state);
- return ret;
- }
Remove the storage of 'struct i2c_client' from the 'struct example_state'
as we are provided with the i2c_client in our example_probe. Instead we
store a pointer to it for when it is needed.
struct example_state {
- struct i2c_client client;
+ struct i2c_client *client;
the new i2c client as so:
- struct device *dev = &adap->dev; /* to use for dev_ reports */
+ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */
And remove the change after our client is attached, as the driver no
longer needs to register a new client structure with the core:
- dev = &state->i2c_client.dev;
In the probe routine, ensure that the new state has the client stored
in it:
static int example_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct example_state *state;
struct device *dev = &i2c_client->dev;
int ret;
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
if (state == NULL) {
dev_err(dev, "failed to create our state\n");
return -ENOMEM;
}
+ state->client = i2c_client;
Update the detach method, by changing the name to _remove and
to delete the i2c_detach_client call. It is possible that you
can also remove the ret variable as it is not not needed for
any of the core functions.
- static int __devexit example_detach(struct i2c_client *client)
+ static int __devexit example_remove(struct i2c_client *client)
{
struct example_state *state = i2c_get_clientdata(client);
- i2c_detach_client(client);
And finally ensure that we have the correct ID table for the i2c-core
and other utilities:
+ struct i2c_device_id example_idtable[] = {
+ { "example", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, example_idtable);
static struct i2c_driver example_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "example",
},
+ .id_table = example_ids,
Our driver should now look like this:
struct example_state {
struct i2c_client *client;
....
};
static int example_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct example_state *state;
struct device *dev = &client->dev;
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
if (state == NULL) {
dev_err(dev, "failed to create our state\n");
return -ENOMEM;
}
state->client = client;
i2c_set_clientdata(client, state);
/* rest of the initialisation goes here. */
dev_info(dev, "example client created\n");
return 0;
}
static int __devexit example_remove(struct i2c_client *client)
{
struct example_state *state = i2c_get_clientdata(client);
kfree(state);
return 0;
}
static struct i2c_device_id example_idtable[] = {
{ "example", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, example_idtable);
static struct i2c_driver example_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "example",
},
.id_table = example_idtable,
.probe = example_probe,
.remove = __devexit_p(example_remove),
.suspend = example_suspend,
.resume = example_resume,
};
...@@ -65,26 +65,26 @@ Install kexec-tools ...@@ -65,26 +65,26 @@ Install kexec-tools
2) Download the kexec-tools user-space package from the following URL: 2) Download the kexec-tools user-space package from the following URL:
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-testing.tar.gz http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools.tar.gz
This is a symlink to the latest version, which at the time of writing is This is a symlink to the latest version.
20061214, the only release of kexec-tools-testing so far. As other versions
are released, the older ones will remain available at
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
Note: Latest kexec-tools-testing git tree is available at The latest kexec-tools git tree is available at:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools-testing.git git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools.git
or or
http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools-testing.git;a=summary http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools.git
More information about kexec-tools can be found at
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/README.html
3) Unpack the tarball with the tar command, as follows: 3) Unpack the tarball with the tar command, as follows:
tar xvpzf kexec-tools-testing.tar.gz tar xvpzf kexec-tools.tar.gz
4) Change to the kexec-tools directory, as follows: 4) Change to the kexec-tools directory, as follows:
cd kexec-tools-testing-VERSION cd kexec-tools-VERSION
5) Configure the package, as follows: 5) Configure the package, as follows:
......
此差异已折叠。
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. ...@@ -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 ...@@ -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.
......
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.
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);
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
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 ...@@ -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
......
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. ...@@ -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. ...@@ -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: ...@@ -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: ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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.
......
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
2 -> Hauppauge HVR850 (au0828) [2040:7240] 2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
5 -> MSI VOX USB 2.0 (em2820/em2840) 5 -> MSI VOX USB 2.0 (em2820/em2840)
6 -> Terratec Cinergy 200 USB (em2800) 6 -> Terratec Cinergy 200 USB (em2800)
7 -> Leadtek Winfast USB II (em2800) 7 -> Leadtek Winfast USB II (em2800) [0413:6023]
8 -> Kworld USB2800 (em2800) 8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
...@@ -14,7 +14,46 @@ ...@@ -14,7 +14,46 @@
13 -> Terratec Prodigy XS (em2880) [0ccd:0047] 13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
15 -> V-Gear PocketTV (em2800) 15 -> V-Gear PocketTV (em2800)
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f]
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
19 -> PointNix Intra-Oral Camera (em2860) 19 -> PointNix Intra-Oral Camera (em2860)
20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002]
21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801]
22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751]
23 -> Huaqi DLCW-130 (em2750)
24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112]
25 -> Gadmei UTV310 (em2820/em2840)
26 -> Hercules Smart TV USB 2.0 (em2820/em2840)
27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840)
28 -> Leadtek Winfast USB II Deluxe (em2820/em2840)
29 -> Pinnacle Dazzle DVC 100 (em2820/em2840)
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
31 -> Usbgear VD204v9 (em2821)
32 -> Supercomp USB 2.0 TV (em2821)
33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821)
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
35 -> Typhoon DVD Maker (em2860)
36 -> NetGMBH Cam (em2860)
37 -> Gadmei UTV330 (em2860)
38 -> Yakumo MovieMixer (em2861)
39 -> KWorld PVRTV 300U (em2861) [eb1a:e300]
40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005]
41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350]
42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357]
43 -> Terratec Cinergy T XS (em2870) [0ccd:0043]
44 -> Terratec Cinergy T XS (MT2060) (em2870)
45 -> Pinnacle PCTV DVB-T (em2870)
46 -> Compro, VideoMate U3 (em2870) [185b:2870]
47 -> KWorld DVB-T 305U (em2880) [eb1a:e305]
48 -> KWorld DVB-T 310U (em2880)
49 -> MSI DigiVox A/D (em2880) [eb1a:e310]
50 -> MSI DigiVox A/D II (em2880) [eb1a:e320]
51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c]
52 -> DNT DA2 Hybrid (em2881)
53 -> Pinnacle Hybrid Pro (em2881)
54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323]
55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e]
56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
List of the webcams know by gspca. List of the webcams known by gspca.
The modules are: The modules are:
gspca_main main driver gspca_main main driver
......
...@@ -1884,13 +1884,9 @@ W: http://gigaset307x.sourceforge.net/ ...@@ -1884,13 +1884,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
...@@ -3802,6 +3798,12 @@ P: Ben Nizette ...@@ -3802,6 +3798,12 @@ P: Ben Nizette
M: bn@niasdigital.com M: bn@niasdigital.com
S: Maintained S: Maintained
SOC-CAMERA V4L2 SUBSYSTEM
P: Guennadi Liakhovetski
M: g.liakhovetski@gmx.de
L: video4linux-list@redhat.com
S: Maintained
SOFTWARE RAID (Multiple Disks) SUPPORT SOFTWARE RAID (Multiple Disks) SUPPORT
P: Ingo Molnar P: Ingo Molnar
M: mingo@redhat.com M: mingo@redhat.com
...@@ -3968,7 +3970,7 @@ M: lethal@linux-sh.org ...@@ -3968,7 +3970,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 +4506,15 @@ M: kaber@trash.net ...@@ -4504,6 +4506,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
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 26 SUBLEVEL = 27
EXTRAVERSION = EXTRAVERSION = -rc2
NAME = Rotary Wombat NAME = Rotary Wombat
# *DOCUMENTATION* # *DOCUMENTATION*
...@@ -206,7 +206,11 @@ ifeq ($(ARCH),x86_64) ...@@ -206,7 +206,11 @@ ifeq ($(ARCH),x86_64)
endif endif
# Where to locate arch specific headers # Where to locate arch specific headers
hdr-arch := $(SRCARCH) ifeq ($(ARCH),sparc64)
hdr-arch := sparc
else
hdr-arch := $(SRCARCH)
endif
KCONFIG_CONFIG ?= .config KCONFIG_CONFIG ?= .config
...@@ -925,10 +929,10 @@ ifneq ($(KBUILD_SRC),) ...@@ -925,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
...@@ -1488,7 +1492,7 @@ quiet_cmd_cscope-file = FILELST cscope.files ...@@ -1488,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)
......
...@@ -17,6 +17,7 @@ config ARM ...@@ -17,6 +17,7 @@ config ARM
select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FTRACE if (!XIP_KERNEL) select HAVE_FTRACE if (!XIP_KERNEL)
select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE) select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE)
select HAVE_GENERIC_DMA_COHERENT
help help
The ARM series is a line of low-power-consumption RISC chip designs The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and licensed by ARM Ltd and targeted at embedded applications and
...@@ -234,6 +235,7 @@ config ARCH_VERSATILE ...@@ -234,6 +235,7 @@ config ARCH_VERSATILE
config ARCH_AT91 config ARCH_AT91
bool "Atmel AT91" bool "Atmel AT91"
select GENERIC_GPIO select GENERIC_GPIO
select HAVE_CLK
help help
This enables support for systems based on the Atmel AT91RM9200, This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors. AT91SAM9 and AT91CAP9 processors.
...@@ -267,7 +269,6 @@ config ARCH_EP93XX ...@@ -267,7 +269,6 @@ config ARCH_EP93XX
select ARM_VIC select ARM_VIC
select GENERIC_GPIO select GENERIC_GPIO
select HAVE_CLK select HAVE_CLK
select HAVE_CLK
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
help help
This enables support for the Cirrus EP93xx series of CPUs. This enables support for the Cirrus EP93xx series of CPUs.
...@@ -1224,6 +1225,8 @@ source "drivers/dma/Kconfig" ...@@ -1224,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
......
...@@ -170,7 +170,7 @@ CONFIG_MACH_AT91CAP9ADK=y ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <asm-generic/dma-coherent.h>
/* /*
* DMA-consistent mapping functions. These allocate/free a region of * DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA * uncached, unwrite-buffered mapped memory space for use with DMA
......
...@@ -297,7 +297,7 @@ config MTD_AT91_DATAFLASH_CARD ...@@ -297,7 +297,7 @@ config MTD_AT91_DATAFLASH_CARD
help help
Enable support for the DataFlash card. Enable support for the DataFlash card.
config MTD_NAND_AT91_BUSWIDTH_16 config MTD_NAND_ATMEL_BUSWIDTH_16
bool "Enable 16-bit data bus interface to NAND flash" bool "Enable 16-bit data bus interface to NAND flash"
depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK) depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK)
help help
......
...@@ -376,7 +376,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} ...@@ -376,7 +376,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* NAND / SmartMedia * NAND / SmartMedia
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
static struct atmel_nand_data nand_data; static struct atmel_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3 #define NAND_BASE AT91_CHIPSELECT_3
......
...@@ -368,7 +368,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} ...@@ -368,7 +368,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* NAND / SmartMedia * NAND / SmartMedia
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
static struct atmel_nand_data nand_data; static struct atmel_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3 #define NAND_BASE AT91_CHIPSELECT_3
......
...@@ -283,7 +283,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} ...@@ -283,7 +283,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* NAND / SmartMedia * NAND / SmartMedia
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
static struct atmel_nand_data nand_data; static struct atmel_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3 #define NAND_BASE AT91_CHIPSELECT_3
......
...@@ -198,7 +198,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} ...@@ -198,7 +198,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* NAND / SmartMedia * NAND / SmartMedia
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
static struct atmel_nand_data nand_data; static struct atmel_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3 #define NAND_BASE AT91_CHIPSELECT_3
......
...@@ -352,7 +352,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} ...@@ -352,7 +352,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* NAND / SmartMedia * NAND / SmartMedia
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
static struct atmel_nand_data nand_data; static struct atmel_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3 #define NAND_BASE AT91_CHIPSELECT_3
......
...@@ -194,7 +194,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} ...@@ -194,7 +194,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* NAND / SmartMedia * NAND / SmartMedia
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
static struct atmel_nand_data nand_data; static struct atmel_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3 #define NAND_BASE AT91_CHIPSELECT_3
......
...@@ -188,7 +188,7 @@ static struct atmel_nand_data __initdata cap9adk_nand_data = { ...@@ -188,7 +188,7 @@ static struct atmel_nand_data __initdata cap9adk_nand_data = {
// .rdy_pin = ... not connected // .rdy_pin = ... not connected
.enable_pin = AT91_PIN_PD15, .enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -147,7 +147,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -147,7 +147,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -148,7 +148,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -148,7 +148,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -185,7 +185,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -185,7 +185,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -190,7 +190,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -190,7 +190,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC15, .rdy_pin = AT91_PIN_PC15,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -194,7 +194,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -194,7 +194,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PA22, .rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15, .enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -149,7 +149,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -149,7 +149,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -121,7 +121,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -121,7 +121,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -134,7 +134,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -134,7 +134,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PA22, .rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15, .enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions, .partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1, .bus_width_16 = 1,
#else #else
.bus_width_16 = 0, .bus_width_16 = 0,
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/ata_platform.h> #include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/pci.h> #include <asm/mach/pci.h>
...@@ -69,6 +70,8 @@ static struct platform_device rd88f6281_nand_flash = { ...@@ -69,6 +70,8 @@ static struct platform_device rd88f6281_nand_flash = {
static struct mv643xx_eth_platform_data rd88f6281_ge00_data = { static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
.phy_addr = -1, .phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
}; };
static struct mv_sata_platform_data rd88f6281_sata_data = { static struct mv_sata_platform_data rd88f6281_sata_data = {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/gpio.h> #include <asm/gpio.h>
#include <asm/leds.h> #include <asm/leds.h>
...@@ -88,6 +89,8 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = { ...@@ -88,6 +89,8 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = { static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
.phy_addr = -1, .phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
}; };
static void __init rd88f5181l_fxo_init(void) static void __init rd88f5181l_fxo_init(void)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/gpio.h> #include <asm/gpio.h>
...@@ -89,6 +90,8 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = { ...@@ -89,6 +90,8 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = { static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
.phy_addr = -1, .phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
}; };
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = { static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/gpio.h> #include <asm/gpio.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -92,6 +93,8 @@ static struct platform_device wnr854t_nor_flash = { ...@@ -92,6 +93,8 @@ static struct platform_device wnr854t_nor_flash = {
static struct mv643xx_eth_platform_data wnr854t_eth_data = { static struct mv643xx_eth_platform_data wnr854t_eth_data = {
.phy_addr = -1, .phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
}; };
static void __init wnr854t_init(void) static void __init wnr854t_init(void)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/gpio.h> #include <asm/gpio.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -100,6 +101,8 @@ static struct platform_device wrt350n_v2_nor_flash = { ...@@ -100,6 +101,8 @@ static struct platform_device wrt350n_v2_nor_flash = {
static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = { static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
.phy_addr = -1, .phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
}; };
static void __init wrt350n_v2_init(void) static void __init wrt350n_v2_init(void)
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/ide.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/pwm_backlight.h> #include <linux/pwm_backlight.h>
......
...@@ -274,6 +274,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, ...@@ -274,6 +274,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
void * void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{ {
void *memory;
if (dma_alloc_from_coherent(dev, size, handle, &memory))
return memory;
if (arch_is_coherent()) { if (arch_is_coherent()) {
void *virt; void *virt;
...@@ -362,6 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr ...@@ -362,6 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
WARN_ON(irqs_disabled()); WARN_ON(irqs_disabled());
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
return;
if (arch_is_coherent()) { if (arch_is_coherent()) {
kfree(cpu_addr); kfree(cpu_addr);
return; return;
......
...@@ -641,6 +641,7 @@ config PCI ...@@ -641,6 +641,7 @@ config PCI
bool bool
depends on ETRAX_CARDBUS depends on ETRAX_CARDBUS
default y default y
select HAVE_GENERIC_DMA_COHERENT
config ETRAX_IOP_FW_LOAD config ETRAX_IOP_FW_LOAD
tristate "IO-processor hotplug firmware loading support" tristate "IO-processor hotplug firmware loading support"
......
...@@ -15,35 +15,16 @@ ...@@ -15,35 +15,16 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/io.h> #include <asm/io.h>
struct dma_coherent_mem {
void *virt_base;
u32 device_base;
int size;
int flags;
unsigned long *bitmap;
};
void *dma_alloc_coherent(struct device *dev, size_t size, void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp) dma_addr_t *dma_handle, gfp_t gfp)
{ {
void *ret; void *ret;
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
int order = get_order(size); int order = get_order(size);
/* ignore region specifiers */ /* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
if (mem) { if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
int page = bitmap_find_free_region(mem->bitmap, mem->size, return ret;
order);
if (page >= 0) {
*dma_handle = mem->device_base + (page << PAGE_SHIFT);
ret = mem->virt_base + (page << PAGE_SHIFT);
memset(ret, 0, size);
return ret;
}
if (mem->flags & DMA_MEMORY_EXCLUSIVE)
return NULL;
}
if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
gfp |= GFP_DMA; gfp |= GFP_DMA;
...@@ -60,90 +41,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size, ...@@ -60,90 +41,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
void dma_free_coherent(struct device *dev, size_t size, void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle) void *vaddr, dma_addr_t dma_handle)
{ {
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
int order = get_order(size); int order = get_order(size);
if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { if (!dma_release_from_coherent(dev, order, vaddr))
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
bitmap_release_region(mem->bitmap, page, order);
} else
free_pages((unsigned long)vaddr, order); free_pages((unsigned long)vaddr, order);
} }
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
dma_addr_t device_addr, size_t size, int flags)
{
void __iomem *mem_base;
int pages = size >> PAGE_SHIFT;
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
goto out;
if (!size)
goto out;
if (dev->dma_mem)
goto out;
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
mem_base = ioremap(bus_addr, size);
if (!mem_base)
goto out;
dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
if (!dev->dma_mem)
goto iounmap_out;
dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!dev->dma_mem->bitmap)
goto free1_out;
dev->dma_mem->virt_base = mem_base;
dev->dma_mem->device_base = device_addr;
dev->dma_mem->size = pages;
dev->dma_mem->flags = flags;
if (flags & DMA_MEMORY_MAP)
return DMA_MEMORY_MAP;
return DMA_MEMORY_IO;
free1_out:
kfree(dev->dma_mem);
iounmap_out:
iounmap(mem_base);
out:
return 0;
}
EXPORT_SYMBOL(dma_declare_coherent_memory);
void dma_release_declared_memory(struct device *dev)
{
struct dma_coherent_mem *mem = dev->dma_mem;
if(!mem)
return;
dev->dma_mem = NULL;
iounmap(mem->virt_base);
kfree(mem->bitmap);
kfree(mem);
}
EXPORT_SYMBOL(dma_release_declared_memory);
void *dma_mark_declared_memory_occupied(struct device *dev,
dma_addr_t device_addr, size_t size)
{
struct dma_coherent_mem *mem = dev->dma_mem;
int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
int pos, err;
if (!mem)
return ERR_PTR(-EINVAL);
pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
if (err != 0)
return ERR_PTR(err);
return mem->virt_base + (pos << PAGE_SHIFT);
}
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
...@@ -1519,6 +1519,11 @@ sys_call_table: ...@@ -1519,6 +1519,11 @@ sys_call_table:
.long sys_fallocate .long sys_fallocate
.long sys_timerfd_settime /* 325 */ .long sys_timerfd_settime /* 325 */
.long sys_timerfd_gettime .long sys_timerfd_gettime
.long sys_signalfd4
.long sys_eventfd2
.long sys_epoll_create1
.long sys_dup3 /* 330 */
.long sys_pipe2
.long sys_inotify_init1
syscall_table_size = (. - sys_call_table) syscall_table_size = (. - sys_call_table)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册