Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes

This commit is contained in:
Russell King 2008-08-07 09:55:03 +01:00 committed by Russell King
commit 4fb8af10d0
2827 changed files with 59247 additions and 34588 deletions

View File

@ -89,8 +89,6 @@ cciss.txt
- info, major/minor #'s for Compaq's SMART Array Controllers.
cdrom/
- directory with information on the CD-ROM drivers that Linux has.
cli-sti-removal.txt
- cli()/sti() removal guide.
computone.txt
- info on Computone Intelliport II/Plus Multiport Serial Driver.
connector/

View File

@ -0,0 +1,315 @@
What: /sys/class/regulator/.../state
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
state. This holds the regulator output state.
This will be one of the following strings:
'enabled'
'disabled'
'unknown'
'enabled' means the regulator output is ON and is supplying
power to the system.
'disabled' means the regulator output is OFF and is not
supplying power to the system..
'unknown' means software cannot determine the state.
NOTE: this field can be used in conjunction with microvolts
and microamps to determine regulator output levels.
What: /sys/class/regulator/.../type
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
type. This holds the regulator type.
This will be one of the following strings:
'voltage'
'current'
'unknown'
'voltage' means the regulator output voltage can be controlled
by software.
'current' means the regulator output current limit can be
controlled by software.
'unknown' means software cannot control either voltage or
current limit.
What: /sys/class/regulator/.../microvolts
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
microvolts. This holds the regulator output voltage setting
measured in microvolts (i.e. E-6 Volts).
NOTE: This value should not be used to determine the regulator
output voltage level as this value is the same regardless of
whether the regulator is enabled or disabled.
What: /sys/class/regulator/.../microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
microamps. This holds the regulator output current limit
setting measured in microamps (i.e. E-6 Amps).
NOTE: This value should not be used to determine the regulator
output current level as this value is the same regardless of
whether the regulator is enabled or disabled.
What: /sys/class/regulator/.../opmode
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
opmode. This holds the regulator operating mode setting.
The opmode value can be one of the following strings:
'fast'
'normal'
'idle'
'standby'
'unknown'
The modes are described in include/linux/regulator/regulator.h
NOTE: This value should not be used to determine the regulator
output operating mode as this value is the same regardless of
whether the regulator is enabled or disabled.
What: /sys/class/regulator/.../min_microvolts
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
min_microvolts. This holds the minimum safe working regulator
output voltage setting for this domain measured in microvolts.
NOTE: this will return the string 'constraint not defined' if
the power domain has no min microvolts constraint defined by
platform code.
What: /sys/class/regulator/.../max_microvolts
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
max_microvolts. This holds the maximum safe working regulator
output voltage setting for this domain measured in microvolts.
NOTE: this will return the string 'constraint not defined' if
the power domain has no max microvolts constraint defined by
platform code.
What: /sys/class/regulator/.../min_microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
min_microamps. This holds the minimum safe working regulator
output current limit setting for this domain measured in
microamps.
NOTE: this will return the string 'constraint not defined' if
the power domain has no min microamps constraint defined by
platform code.
What: /sys/class/regulator/.../max_microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
max_microamps. This holds the maximum safe working regulator
output current limit setting for this domain measured in
microamps.
NOTE: this will return the string 'constraint not defined' if
the power domain has no max microamps constraint defined by
platform code.
What: /sys/class/regulator/.../num_users
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
num_users. This holds the number of consumer devices that
have called regulator_enable() on this regulator.
What: /sys/class/regulator/.../requested_microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
requested_microamps. This holds the total requested load
current in microamps for this regulator from all its consumer
devices.
What: /sys/class/regulator/.../parent
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Some regulator directories will contain a link called parent.
This points to the parent or supply regulator if one exists.
What: /sys/class/regulator/.../suspend_mem_microvolts
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_mem_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when
the system is suspended to memory.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to memory voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_disk_microvolts
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_disk_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when
the system is suspended to disk.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to disk voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_standby_microvolts
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_standby_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when
the system is suspended to standby.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to standby voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_mem_mode
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_mem_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to
memory.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to memory mode defined by
platform code.
What: /sys/class/regulator/.../suspend_disk_mode
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_disk_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to disk.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to disk mode defined by
platform code.
What: /sys/class/regulator/.../suspend_standby_mode
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_standby_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to
standby.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to standby mode defined by
platform code.
What: /sys/class/regulator/.../suspend_mem_state
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_mem_state. This holds the regulator operating state
when suspended to memory.
This will be one of the following strings:
'enabled'
'disabled'
'not defined'
What: /sys/class/regulator/.../suspend_disk_state
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_disk_state. This holds the regulator operating state
when suspended to disk.
This will be one of the following strings:
'enabled'
'disabled'
'not defined'
What: /sys/class/regulator/.../suspend_standby_state
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_standby_state. This holds the regulator operating
state when suspended to standby.
This will be one of the following strings:
'enabled'
'disabled'
'not defined'

View File

@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.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):

View File

@ -98,6 +98,24 @@
"Kernel debugging" select "KGDB: kernel debugging with remote gdb".
</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
host and debugged target. Early boot debugging requires a KGDB
I/O driver that supports early debugging and the driver must be

View File

@ -100,7 +100,7 @@
the hardware structures represented here, please consult the Principles
of Operation.
</para>
!Iinclude/asm-s390/cio.h
!Iarch/s390/include/asm/cio.h
</sect1>
<sect1 id="ccwdev">
<title>ccw devices</title>
@ -114,7 +114,7 @@
ccw device structure. Device drivers must not bypass those functions
or strange side effects may happen.
</para>
!Iinclude/asm-s390/ccwdev.h
!Iarch/s390/include/asm/ccwdev.h
!Edrivers/s390/cio/device.c
!Edrivers/s390/cio/device_ops.c
</sect1>
@ -125,7 +125,7 @@
measurement data which is made available by the channel subsystem
for each channel attached device.
</para>
!Iinclude/asm-s390/cmb.h
!Iarch/s390/include/asm/cmb.h
!Edrivers/s390/cio/cmf.c
</sect1>
</chapter>
@ -142,7 +142,7 @@
</para>
<sect1 id="ccwgroupdevices">
<title>ccw group devices</title>
!Iinclude/asm-s390/ccwgroup.h
!Iarch/s390/include/asm/ccwgroup.h
!Edrivers/s390/cio/ccwgroup.c
</sect1>
</chapter>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="sh-drivers">
<bookinfo>
<title>SuperH Interfaces Guide</title>
<authorgroup>
<author>
<firstname>Paul</firstname>
<surname>Mundt</surname>
<affiliation>
<address>
<email>lethal@linux-sh.org</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2008</year>
<holder>Paul Mundt</holder>
</copyright>
<copyright>
<year>2008</year>
<holder>Renesas Technology Corp.</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="mm">
<title>Memory Management</title>
<sect1 id="sh4">
<title>SH-4</title>
<sect2 id="sq">
<title>Store Queue API</title>
!Earch/sh/kernel/cpu/sh4/sq.c
</sect2>
</sect1>
<sect1 id="sh5">
<title>SH-5</title>
<sect2 id="tlb">
<title>TLB Interfaces</title>
!Iarch/sh/mm/tlb-sh5.c
!Iarch/sh/include/asm/tlb_64.h
</sect2>
</sect1>
</chapter>
<chapter id="clk">
<title>Clock Framework Extensions</title>
!Iarch/sh/include/asm/clock.h
</chapter>
<chapter id="mach">
<title>Machine Specific Interfaces</title>
<sect1 id="dreamcast">
<title>mach-dreamcast</title>
!Iarch/sh/boards/mach-dreamcast/rtc.c
</sect1>
<sect1 id="x3proto">
<title>mach-x3proto</title>
!Earch/sh/boards/mach-x3proto/ilsel.c
</sect1>
</chapter>
<chapter id="busses">
<title>Busses</title>
<sect1 id="superhyway">
<title>SuperHyway</title>
!Edrivers/sh/superhyway/superhyway.c
</sect1>
<sect1 id="maple">
<title>Maple</title>
!Edrivers/sh/maple/maple.c
</sect1>
</chapter>
</book>

View File

@ -528,7 +528,33 @@ See more details on the proper patch format in the following
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

View File

@ -1,133 +0,0 @@
#### cli()/sti() removal guide, started by Ingo Molnar <mingo@redhat.com>
as of 2.5.28, five popular macros have been removed on SMP, and
are being phased out on UP:
cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags)
until now it was possible to protect driver code against interrupt
handlers via a cli(), but from now on other, more lightweight methods
have to be used for synchronization, such as spinlocks or semaphores.
for example, driver code that used to do something like:
struct driver_data;
irq_handler (...)
{
....
driver_data.finish = 1;
driver_data.new_work = 0;
....
}
...
ioctl_func (...)
{
...
cli();
...
driver_data.finish = 0;
driver_data.new_work = 2;
...
sti();
...
}
was SMP-correct because the cli() function ensured that no
interrupt handler (amongst them the above irq_handler()) function
would execute while the cli()-ed section is executing.
but from now on a more direct method of locking has to be used:
DEFINE_SPINLOCK(driver_lock);
struct driver_data;
irq_handler (...)
{
unsigned long flags;
....
spin_lock_irqsave(&driver_lock, flags);
....
driver_data.finish = 1;
driver_data.new_work = 0;
....
spin_unlock_irqrestore(&driver_lock, flags);
....
}
...
ioctl_func (...)
{
...
spin_lock_irq(&driver_lock);
...
driver_data.finish = 0;
driver_data.new_work = 2;
...
spin_unlock_irq(&driver_lock);
...
}
the above code has a number of advantages:
- the locking relation is easier to understand - actual lock usage
pinpoints the critical sections. cli() usage is too opaque.
Easier to understand means it's easier to debug.
- it's faster, because spinlocks are faster to acquire than the
potentially heavily-used IRQ lock. Furthermore, your driver does
not have to wait eg. for a big heavy SCSI interrupt to finish,
because the driver_lock spinlock is only used by your driver.
cli() on the other hand was used by many drivers, and extended
the critical section to the whole IRQ handler function - creating
serious lock contention.
to make the transition easier, we've still kept the cli(), sti(),
save_flags(), save_flags_cli() and restore_flags() macros defined
on UP systems - but their usage will be phased out until 2.6 is
released.
drivers that want to disable local interrupts (interrupts on the
current CPU), can use the following five macros:
local_irq_disable(), local_irq_enable(), local_save_flags(flags),
local_irq_save(flags), local_irq_restore(flags)
but beware, their meaning and semantics are much simpler, far from
that of the old cli(), sti(), save_flags(flags) and restore_flags(flags)
SMP meaning:
local_irq_disable() => turn local IRQs off
local_irq_enable() => turn local IRQs on
local_save_flags(flags) => save the current IRQ state into flags. The
state can be on or off. (on some
architectures there's even more bits in it.)
local_irq_save(flags) => save the current IRQ state into flags and
disable interrupts.
local_irq_restore(flags) => restore the IRQ state from flags.
(local_irq_save can save both irqs on and irqs off state, and
local_irq_restore can restore into both irqs on and irqs off state.)
another related change is that synchronize_irq() now takes a parameter:
synchronize_irq(irq). This change too has the purpose of making SMP
synchronization more lightweight - this way you can wait for your own
interrupt handler to finish, no need to wait for other IRQ sources.
why were these changes done? The main reason was the architectural burden
of maintaining the cli()/sti() interface - it became a real problem. The
new interrupt system is much more streamlined, easier to understand, debug,
and it's also a bit faster - the same happened to it that will happen to
cli()/sti() using drivers once they convert to spinlocks :-)

View File

@ -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])
When: November 2005
Files: drivers/pcmcia/: pcmcia_ioctl.c

View File

@ -311,9 +311,20 @@ the subsystem must be ready for it.
[An Example]
The best example of these basic concepts is the simple_children
subsystem/group and the simple_child item in configfs_example.c It
shows a trivial object displaying and storing an attribute, and a simple
group creating and destroying these children.
subsystem/group and the simple_child item in configfs_example_explicit.c
and configfs_example_macros.c. It shows a trivial object displaying and
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]

View File

@ -1,8 +1,10 @@
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example.c - This file is a demonstration module containing
* a number of configfs subsystems.
* 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
@ -281,7 +283,6 @@ static struct config_item *simple_children_make_item(struct config_group *group,
if (!simple_child)
return ERR_PTR(-ENOMEM);
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
@ -302,8 +303,8 @@ static struct configfs_attribute *simple_children_attrs[] = {
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
@ -318,7 +319,7 @@ static void simple_children_release(struct config_item *item)
}
static struct configfs_item_operations simple_children_item_ops = {
.release = simple_children_release,
.release = simple_children_release,
.show_attribute = simple_children_attr_show,
};
@ -368,7 +369,6 @@ static struct config_group *group_children_make_group(struct config_group *group
if (!simple_children)
return ERR_PTR(-ENOMEM);
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
@ -387,8 +387,8 @@ static struct configfs_attribute *group_children_attrs[] = {
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"

View File

@ -0,0 +1,448 @@
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example_macros.c - This file is a demonstration module
* containing a number of configfs subsystems. It uses the helper
* macros defined by configfs.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA.
*
* Based on sysfs:
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
*
* configfs Copyright (C) 2005 Oracle. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/configfs.h>
/*
* 01-childless
*
* This first example is a childless subsystem. It cannot create
* any config_items. It just has attributes.
*
* Note that we are enclosing the configfs_subsystem inside a container.
* This is not necessary if a subsystem has no attributes directly
* on the subsystem. See the next example, 02-simple-children, for
* such a subsystem.
*/
struct childless {
struct configfs_subsystem subsys;
int showme;
int storeme;
};
static inline struct childless *to_childless(struct config_item *item)
{
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
}
CONFIGFS_ATTR_STRUCT(childless);
#define CHILDLESS_ATTR(_name, _mode, _show, _store) \
struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
#define CHILDLESS_ATTR_RO(_name, _show) \
struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show);
static ssize_t childless_showme_read(struct childless *childless,
char *page)
{
ssize_t pos;
pos = sprintf(page, "%d\n", childless->showme);
childless->showme++;
return pos;
}
static ssize_t childless_storeme_read(struct childless *childless,
char *page)
{
return sprintf(page, "%d\n", childless->storeme);
}
static ssize_t childless_storeme_write(struct childless *childless,
const char *page,
size_t count)
{
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
childless->storeme = tmp;
return count;
}
static ssize_t childless_description_read(struct childless *childless,
char *page)
{
return sprintf(page,
"[01-childless]\n"
"\n"
"The childless subsystem is the simplest possible subsystem in\n"
"configfs. It does not support the creation of child config_items.\n"
"It only has a few attributes. In fact, it isn't much different\n"
"than a directory in /proc.\n");
}
CHILDLESS_ATTR_RO(showme, childless_showme_read);
CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read,
childless_storeme_write);
CHILDLESS_ATTR_RO(description, childless_description_read);
static struct configfs_attribute *childless_attrs[] = {
&childless_attr_showme.attr,
&childless_attr_storeme.attr,
&childless_attr_description.attr,
NULL,
};
CONFIGFS_ATTR_OPS(childless);
static struct configfs_item_operations childless_item_ops = {
.show_attribute = childless_attr_show,
.store_attribute = childless_attr_store,
};
static struct config_item_type childless_type = {
.ct_item_ops = &childless_item_ops,
.ct_attrs = childless_attrs,
.ct_owner = THIS_MODULE,
};
static struct childless childless_subsys = {
.subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "01-childless",
.ci_type = &childless_type,
},
},
},
};
/* ----------------------------------------------------------------- */
/*
* 02-simple-children
*
* This example merely has a simple one-attribute child. Note that
* there is no extra attribute structure, as the child's attribute is
* known from the get-go. Also, there is no container for the
* subsystem, as it has no attributes of its own.
*/
struct simple_child {
struct config_item item;
int storeme;
};
static inline struct simple_child *to_simple_child(struct config_item *item)
{
return item ? container_of(item, struct simple_child, item) : NULL;
}
static struct configfs_attribute simple_child_attr_storeme = {
.ca_owner = THIS_MODULE,
.ca_name = "storeme",
.ca_mode = S_IRUGO | S_IWUSR,
};
static struct configfs_attribute *simple_child_attrs[] = {
&simple_child_attr_storeme,
NULL,
};
static ssize_t simple_child_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
ssize_t count;
struct simple_child *simple_child = to_simple_child(item);
count = sprintf(page, "%d\n", simple_child->storeme);
return count;
}
static ssize_t simple_child_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct simple_child *simple_child = to_simple_child(item);
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
simple_child->storeme = tmp;
return count;
}
static void simple_child_release(struct config_item *item)
{
kfree(to_simple_child(item));
}
static struct configfs_item_operations simple_child_item_ops = {
.release = simple_child_release,
.show_attribute = simple_child_attr_show,
.store_attribute = simple_child_attr_store,
};
static struct config_item_type simple_child_type = {
.ct_item_ops = &simple_child_item_ops,
.ct_attrs = simple_child_attrs,
.ct_owner = THIS_MODULE,
};
struct simple_children {
struct config_group group;
};
static inline struct simple_children *to_simple_children(struct config_item *item)
{
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
}
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
{
struct simple_child *simple_child;
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child)
return ERR_PTR(-ENOMEM);
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
simple_child->storeme = 0;
return &simple_child->item;
}
static struct configfs_attribute simple_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *simple_children_attrs[] = {
&simple_children_attr_description,
NULL,
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
"\n"
"This subsystem allows the creation of child config_items. These\n"
"items have only one attribute that is readable and writeable.\n");
}
static void simple_children_release(struct config_item *item)
{
kfree(to_simple_children(item));
}
static struct configfs_item_operations simple_children_item_ops = {
.release = simple_children_release,
.show_attribute = simple_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations simple_children_group_ops = {
.make_item = simple_children_make_item,
};
static struct config_item_type simple_children_type = {
.ct_item_ops = &simple_children_item_ops,
.ct_group_ops = &simple_children_group_ops,
.ct_attrs = simple_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem simple_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "02-simple-children",
.ci_type = &simple_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* 03-group-children
*
* This example reuses the simple_children group from above. However,
* the simple_children group is not the subsystem itself, it is a
* child of the subsystem. Creation of a group in the subsystem creates
* a new simple_children group. That group can then have simple_child
* children of its own.
*/
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
{
struct simple_children *simple_children;
simple_children = kzalloc(sizeof(struct simple_children),
GFP_KERNEL);
if (!simple_children)
return ERR_PTR(-ENOMEM);
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
return &simple_children->group;
}
static struct configfs_attribute group_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *group_children_attrs[] = {
&group_children_attr_description,
NULL,
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"
"\n"
"This subsystem allows the creation of child config_groups. These\n"
"groups are like the subsystem simple-children.\n");
}
static struct configfs_item_operations group_children_item_ops = {
.show_attribute = group_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations group_children_group_ops = {
.make_group = group_children_make_group,
};
static struct config_item_type group_children_type = {
.ct_item_ops = &group_children_item_ops,
.ct_group_ops = &group_children_group_ops,
.ct_attrs = group_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem group_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "03-group-children",
.ci_type = &group_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* We're now done with our subsystem definitions.
* For convenience in this module, here's a list of them all. It
* allows the init function to easily register them. Most modules
* will only have one subsystem, and will only call register_subsystem
* on it directly.
*/
static struct configfs_subsystem *example_subsys[] = {
&childless_subsys.subsys,
&simple_children_subsys,
&group_children_subsys,
NULL,
};
static int __init configfs_example_init(void)
{
int ret;
int i;
struct configfs_subsystem *subsys;
for (i = 0; example_subsys[i]; i++) {
subsys = example_subsys[i];
config_group_init(&subsys->su_group);
mutex_init(&subsys->su_mutex);
ret = configfs_register_subsystem(subsys);
if (ret) {
printk(KERN_ERR "Error %d while registering subsystem %s\n",
ret,
subsys->su_group.cg_item.ci_namebuf);
goto out_unregister;
}
}
return 0;
out_unregister:
for (; i >= 0; i--) {
configfs_unregister_subsystem(example_subsys[i]);
}
return ret;
}
static void __exit configfs_example_exit(void)
{
int i;
for (i = 0; example_subsys[i]; i++) {
configfs_unregister_subsystem(example_subsys[i]);
}
}
module_init(configfs_example_init);
module_exit(configfs_example_exit);
MODULE_LICENSE("GPL");

View File

@ -4,6 +4,7 @@
Copyright 2008 Red Hat Inc.
Author: Steven Rostedt <srostedt@redhat.com>
License: The GNU Free Documentation License, Version 1.2
(dual licensed under the GPL v2)
Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton,
John Kacur, and David Teigland.

View File

@ -22,6 +22,10 @@ Module Parameters
and PWM output control functions. Using this parameter
shouldn't be required since the BIOS usually takes care
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
complaining. The driver will say so if it is necessary.

View File

@ -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
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
from National (AN-1260) with some additional information about the LM85.
The Analog Devices datasheet is very detailed and describes a procedure for
@ -206,13 +201,15 @@ Configuration choices:
The National LM85's have two vendor specific configuration
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 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
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
and THERM asserted counts. Automatic Tmin control acts to adjust the

View File

@ -0,0 +1,281 @@
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,
};

View File

@ -65,26 +65,26 @@ Install kexec-tools
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
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/
This is a symlink to the latest version.
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
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:
tar xvpzf kexec-tools-testing.tar.gz
tar xvpzf kexec-tools.tar.gz
4) Change to the kexec-tools directory, as follows:
cd kexec-tools-testing-VERSION
cd kexec-tools-VERSION
5) Configure the package, as follows:

View File

@ -36,11 +36,13 @@
#include <sched.h>
#include <limits.h>
#include <stddef.h>
#include <signal.h>
#include "linux/lguest_launcher.h"
#include "linux/virtio_config.h"
#include "linux/virtio_net.h"
#include "linux/virtio_blk.h"
#include "linux/virtio_console.h"
#include "linux/virtio_rng.h"
#include "linux/virtio_ring.h"
#include "asm-x86/bootparam.h"
/*L:110 We can ignore the 39 include files we need for this program, but I do
@ -64,8 +66,8 @@ typedef uint8_t u8;
#endif
/* We can have up to 256 pages for devices. */
#define DEVICE_PAGES 256
/* This will occupy 2 pages: it must be a power of 2. */
#define VIRTQUEUE_NUM 128
/* This will occupy 3 pages: it must be a power of 2. */
#define VIRTQUEUE_NUM 256
/*L:120 verbose is both a global flag and a macro. The C preprocessor allows
* this, and although I wouldn't recommend it, it works quite nicely here. */
@ -74,12 +76,19 @@ static bool verbose;
do { if (verbose) printf(args); } while(0)
/*:*/
/* The pipe to send commands to the waker process */
static int waker_fd;
/* File descriptors for the Waker. */
struct {
int pipe[2];
int lguest_fd;
} waker_fds;
/* The pointer to the start of guest memory. */
static void *guest_base;
/* The maximum guest physical address allowed, and maximum possible. */
static unsigned long guest_limit, guest_max;
/* The pipe for signal hander to write to. */
static int timeoutpipe[2];
static unsigned int timeout_usec = 500;
/* a per-cpu variable indicating whose vcpu is currently running */
static unsigned int __thread cpu_id;
@ -155,11 +164,14 @@ struct virtqueue
/* Last available index we saw. */
u16 last_avail_idx;
/* The routine to call when the Guest pings us. */
void (*handle_output)(int fd, struct virtqueue *me);
/* The routine to call when the Guest pings us, or timeout. */
void (*handle_output)(int fd, struct virtqueue *me, bool timeout);
/* Outstanding buffers */
unsigned int inflight;
/* Is this blocked awaiting a timer? */
bool blocked;
};
/* Remember the arguments to the program so we can "reboot" */
@ -190,6 +202,9 @@ static void *_convert(struct iovec *iov, size_t size, size_t align,
return iov->iov_base;
}
/* Wrapper for the last available index. Makes it easier to change. */
#define lg_last_avail(vq) ((vq)->last_avail_idx)
/* The virtio configuration space is defined to be little-endian. x86 is
* little-endian too, but it's nice to be explicit so we have these helpers. */
#define cpu_to_le16(v16) (v16)
@ -199,6 +214,33 @@ static void *_convert(struct iovec *iov, size_t size, size_t align,
#define le32_to_cpu(v32) (v32)
#define le64_to_cpu(v64) (v64)
/* Is this iovec empty? */
static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
{
unsigned int i;
for (i = 0; i < num_iov; i++)
if (iov[i].iov_len)
return false;
return true;
}
/* Take len bytes from the front of this iovec. */
static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len)
{
unsigned int i;
for (i = 0; i < num_iov; i++) {
unsigned int used;
used = iov[i].iov_len < len ? iov[i].iov_len : len;
iov[i].iov_base += used;
iov[i].iov_len -= used;
len -= used;
}
assert(len == 0);
}
/* The device virtqueue descriptors are followed by feature bitmasks. */
static u8 *get_feature_bits(struct device *dev)
{
@ -254,6 +296,7 @@ static void *map_zeroed_pages(unsigned int num)
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED)
err(1, "Mmaping %u pages of /dev/zero", num);
close(fd);
return addr;
}
@ -540,69 +583,64 @@ static void add_device_fd(int fd)
* watch, but handing a file descriptor mask through to the kernel is fairly
* icky.
*
* Instead, we fork off a process which watches the file descriptors and writes
* Instead, we clone off a thread which watches the file descriptors and writes
* the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host
* stop running the Guest. This causes the Launcher to return from the
* /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset
* the LHREQ_BREAK and wake us up again.
*
* This, of course, is merely a different *kind* of icky.
*
* Given my well-known antipathy to threads, I'd prefer to use processes. But
* it's easier to share Guest memory with threads, and trivial to share the
* devices.infds as the Launcher changes it.
*/
static void wake_parent(int pipefd, int lguest_fd)
static int waker(void *unused)
{
/* Add the pipe from the Launcher to the fdset in the device_list, so
* we watch it, too. */
add_device_fd(pipefd);
/* Close the write end of the pipe: only the Launcher has it open. */
close(waker_fds.pipe[1]);
for (;;) {
fd_set rfds = devices.infds;
unsigned long args[] = { LHREQ_BREAK, 1 };
unsigned int maxfd = devices.max_infd;
/* We also listen to the pipe from the Launcher. */
FD_SET(waker_fds.pipe[0], &rfds);
if (waker_fds.pipe[0] > maxfd)
maxfd = waker_fds.pipe[0];
/* Wait until input is ready from one of the devices. */
select(devices.max_infd+1, &rfds, NULL, NULL, NULL);
/* Is it a message from the Launcher? */
if (FD_ISSET(pipefd, &rfds)) {
int fd;
/* If read() returns 0, it means the Launcher has
* exited. We silently follow. */
if (read(pipefd, &fd, sizeof(fd)) == 0)
exit(0);
/* Otherwise it's telling us to change what file
* descriptors we're to listen to. Positive means
* listen to a new one, negative means stop
* listening. */
if (fd >= 0)
FD_SET(fd, &devices.infds);
else
FD_CLR(-fd - 1, &devices.infds);
} else /* Send LHREQ_BREAK command. */
pwrite(lguest_fd, args, sizeof(args), cpu_id);
select(maxfd+1, &rfds, NULL, NULL, NULL);
/* Message from Launcher? */
if (FD_ISSET(waker_fds.pipe[0], &rfds)) {
char c;
/* If this fails, then assume Launcher has exited.
* Don't do anything on exit: we're just a thread! */
if (read(waker_fds.pipe[0], &c, 1) != 1)
_exit(0);
continue;
}
/* Send LHREQ_BREAK command to snap the Launcher out of it. */
pwrite(waker_fds.lguest_fd, args, sizeof(args), cpu_id);
}
return 0;
}
/* This routine just sets up a pipe to the Waker process. */
static int setup_waker(int lguest_fd)
static void setup_waker(int lguest_fd)
{
int pipefd[2], child;
/* This pipe is closed when Launcher dies, telling Waker. */
if (pipe(waker_fds.pipe) != 0)
err(1, "Creating pipe for Waker");
/* We create a pipe to talk to the Waker, and also so it knows when the
* Launcher dies (and closes pipe). */
pipe(pipefd);
child = fork();
if (child == -1)
err(1, "forking");
/* Waker also needs to know the lguest fd */
waker_fds.lguest_fd = lguest_fd;
if (child == 0) {
/* We are the Waker: close the "writing" end of our copy of the
* pipe and start waiting for input. */
close(pipefd[1]);
wake_parent(pipefd[0], lguest_fd);
}
/* Close the reading end of our copy of the pipe. */
close(pipefd[0]);
/* Here is the fd used to talk to the waker. */
return pipefd[1];
if (clone(waker, malloc(4096) + 4096, CLONE_VM | SIGCHLD, NULL) == -1)
err(1, "Creating Waker");
}
/*
@ -661,19 +699,22 @@ static unsigned get_vq_desc(struct virtqueue *vq,
unsigned int *out_num, unsigned int *in_num)
{
unsigned int i, head;
u16 last_avail;
/* Check it isn't doing very strange things with descriptor numbers. */
if ((u16)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num)
last_avail = lg_last_avail(vq);
if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num)
errx(1, "Guest moved used index from %u to %u",
vq->last_avail_idx, vq->vring.avail->idx);
last_avail, vq->vring.avail->idx);
/* If there's nothing new since last we looked, return invalid. */
if (vq->vring.avail->idx == vq->last_avail_idx)
if (vq->vring.avail->idx == last_avail)
return vq->vring.num;
/* Grab the next descriptor number they're advertising, and increment
* the index we've seen. */
head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
head = vq->vring.avail->ring[last_avail % vq->vring.num];
lg_last_avail(vq)++;
/* If their number is silly, that's a fatal mistake. */
if (head >= vq->vring.num)
@ -821,8 +862,8 @@ static bool handle_console_input(int fd, struct device *dev)
unsigned long args[] = { LHREQ_BREAK, 0 };
/* Close the fd so Waker will know it has to
* exit. */
close(waker_fd);
/* Just in case waker is blocked in BREAK, send
close(waker_fds.pipe[1]);
/* Just in case Waker is blocked in BREAK, send
* unbreak now. */
write(fd, args, sizeof(args));
exit(2);
@ -839,7 +880,7 @@ static bool handle_console_input(int fd, struct device *dev)
/* Handling output for console is simple: we just get all the output buffers
* and write them to stdout. */
static void handle_console_output(int fd, struct virtqueue *vq)
static void handle_console_output(int fd, struct virtqueue *vq, bool timeout)
{
unsigned int head, out, in;
int len;
@ -854,6 +895,21 @@ static void handle_console_output(int fd, struct virtqueue *vq)
}
}
static void block_vq(struct virtqueue *vq)
{
struct itimerval itm;
vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
vq->blocked = true;
itm.it_interval.tv_sec = 0;
itm.it_interval.tv_usec = 0;
itm.it_value.tv_sec = 0;
itm.it_value.tv_usec = timeout_usec;
setitimer(ITIMER_REAL, &itm, NULL);
}
/*
* The Network
*
@ -861,22 +917,34 @@ static void handle_console_output(int fd, struct virtqueue *vq)
* and write them (ignoring the first element) to this device's file descriptor
* (/dev/net/tun).
*/
static void handle_net_output(int fd, struct virtqueue *vq)
static void handle_net_output(int fd, struct virtqueue *vq, bool timeout)
{
unsigned int head, out, in;
unsigned int head, out, in, num = 0;
int len;
struct iovec iov[vq->vring.num];
static int last_timeout_num;
/* Keep getting output buffers from the Guest until we run out. */
while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
if (in)
errx(1, "Input buffers in output queue?");
/* Check header, but otherwise ignore it (we told the Guest we
* supported no features, so it shouldn't have anything
* interesting). */
(void)convert(&iov[0], struct virtio_net_hdr);
len = writev(vq->dev->fd, iov+1, out-1);
len = writev(vq->dev->fd, iov, out);
if (len < 0)
err(1, "Writing network packet to tun");
add_used_and_trigger(fd, vq, head, len);
num++;
}
/* Block further kicks and set up a timer if we saw anything. */
if (!timeout && num)
block_vq(vq);
if (timeout) {
if (num < last_timeout_num)
timeout_usec += 10;
else if (timeout_usec > 1)
timeout_usec--;
last_timeout_num = num;
}
}
@ -887,7 +955,6 @@ static bool handle_tun_input(int fd, struct device *dev)
unsigned int head, in_num, out_num;
int len;
struct iovec iov[dev->vq->vring.num];
struct virtio_net_hdr *hdr;
/* First we need a network buffer from the Guests's recv virtqueue. */
head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
@ -896,25 +963,23 @@ static bool handle_tun_input(int fd, struct device *dev)
* early, the Guest won't be ready yet. Wait until the device
* status says it's ready. */
/* FIXME: Actually want DRIVER_ACTIVE here. */
if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK)
warn("network: no dma buffer!");
/* Now tell it we want to know if new things appear. */
dev->vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
wmb();
/* We'll turn this back on if input buffers are registered. */
return false;
} else if (out_num)
errx(1, "Output buffers in network recv queue?");
/* First element is the header: we set it to 0 (no features). */
hdr = convert(&iov[0], struct virtio_net_hdr);
hdr->flags = 0;
hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
/* Read the packet from the device directly into the Guest's buffer. */
len = readv(dev->fd, iov+1, in_num-1);
len = readv(dev->fd, iov, in_num);
if (len <= 0)
err(1, "reading network");
/* Tell the Guest about the new packet. */
add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len);
add_used_and_trigger(fd, dev->vq, head, len);
verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
@ -927,11 +992,18 @@ static bool handle_tun_input(int fd, struct device *dev)
/*L:215 This is the callback attached to the network and console input
* virtqueues: it ensures we try again, in case we stopped console or net
* delivery because Guest didn't have any buffers. */
static void enable_fd(int fd, struct virtqueue *vq)
static void enable_fd(int fd, struct virtqueue *vq, bool timeout)
{
add_device_fd(vq->dev->fd);
/* Tell waker to listen to it again */
write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
/* Snap the Waker out of its select loop. */
write(waker_fds.pipe[1], "", 1);
}
static void net_enable_fd(int fd, struct virtqueue *vq, bool timeout)
{
/* We don't need to know again when Guest refills receive buffer. */
vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
enable_fd(fd, vq, timeout);
}
/* When the Guest tells us they updated the status field, we handle it. */
@ -951,7 +1023,7 @@ static void update_device_status(struct device *dev)
for (vq = dev->vq; vq; vq = vq->next) {
memset(vq->vring.desc, 0,
vring_size(vq->config.num, getpagesize()));
vq->last_avail_idx = 0;
lg_last_avail(vq) = 0;
}
} else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) {
warnx("Device %s configuration FAILED", dev->name);
@ -960,10 +1032,10 @@ static void update_device_status(struct device *dev)
verbose("Device %s OK: offered", dev->name);
for (i = 0; i < dev->desc->feature_len; i++)
verbose(" %08x", get_feature_bits(dev)[i]);
verbose(" %02x", get_feature_bits(dev)[i]);
verbose(", accepted");
for (i = 0; i < dev->desc->feature_len; i++)
verbose(" %08x", get_feature_bits(dev)
verbose(" %02x", get_feature_bits(dev)
[dev->desc->feature_len+i]);
if (dev->ready)
@ -1000,7 +1072,7 @@ static void handle_output(int fd, unsigned long addr)
if (strcmp(vq->dev->name, "console") != 0)
verbose("Output to %s\n", vq->dev->name);
if (vq->handle_output)
vq->handle_output(fd, vq);
vq->handle_output(fd, vq, false);
return;
}
}
@ -1014,6 +1086,29 @@ static void handle_output(int fd, unsigned long addr)
strnlen(from_guest_phys(addr), guest_limit - addr));
}
static void handle_timeout(int fd)
{
char buf[32];
struct device *i;
struct virtqueue *vq;
/* Clear the pipe */
read(timeoutpipe[0], buf, sizeof(buf));
/* Check each device and virtqueue: flush blocked ones. */
for (i = devices.dev; i; i = i->next) {
for (vq = i->vq; vq; vq = vq->next) {
if (!vq->blocked)
continue;
vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
vq->blocked = false;
if (vq->handle_output)
vq->handle_output(fd, vq, true);
}
}
}
/* This is called when the Waker wakes us up: check for incoming file
* descriptors. */
static void handle_input(int fd)
@ -1024,16 +1119,20 @@ static void handle_input(int fd)
for (;;) {
struct device *i;
fd_set fds = devices.infds;
int num;
num = select(devices.max_infd+1, &fds, NULL, NULL, &poll);
/* Could get interrupted */
if (num < 0)
continue;
/* If nothing is ready, we're done. */
if (select(devices.max_infd+1, &fds, NULL, NULL, &poll) == 0)
if (num == 0)
break;
/* Otherwise, call the device(s) which have readable file
* descriptors and a method of handling them. */
for (i = devices.dev; i; i = i->next) {
if (i->handle_input && FD_ISSET(i->fd, &fds)) {
int dev_fd;
if (i->handle_input(fd, i))
continue;
@ -1043,13 +1142,12 @@ static void handle_input(int fd)
* buffers to deliver into. Console also uses
* it when it discovers that stdin is closed. */
FD_CLR(i->fd, &devices.infds);
/* Tell waker to ignore it too, by sending a
* negative fd number (-1, since 0 is a valid
* FD number). */
dev_fd = -i->fd - 1;
write(waker_fd, &dev_fd, sizeof(dev_fd));
}
}
/* Is this the timeout fd? */
if (FD_ISSET(timeoutpipe[0], &fds))
handle_timeout(fd);
}
}
@ -1098,7 +1196,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type)
/* Each device descriptor is followed by the description of its virtqueues. We
* specify how many descriptors the virtqueue is to have. */
static void add_virtqueue(struct device *dev, unsigned int num_descs,
void (*handle_output)(int fd, struct virtqueue *me))
void (*handle_output)(int, struct virtqueue *, bool))
{
unsigned int pages;
struct virtqueue **i, *vq = malloc(sizeof(*vq));
@ -1114,6 +1212,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
vq->last_avail_idx = 0;
vq->dev = dev;
vq->inflight = 0;
vq->blocked = false;
/* Initialize the configuration. */
vq->config.num = num_descs;
@ -1246,6 +1345,24 @@ static void setup_console(void)
}
/*:*/
static void timeout_alarm(int sig)
{
write(timeoutpipe[1], "", 1);
}
static void setup_timeout(void)
{
if (pipe(timeoutpipe) != 0)
err(1, "Creating timeout pipe");
if (fcntl(timeoutpipe[1], F_SETFL,
fcntl(timeoutpipe[1], F_GETFL) | O_NONBLOCK) != 0)
err(1, "Making timeout pipe nonblocking");
add_device_fd(timeoutpipe[0]);
signal(SIGALRM, timeout_alarm);
}
/*M:010 Inter-guest networking is an interesting area. Simplest is to have a
* --sharenet=<name> option which opens or creates a named pipe. This can be
* used to send packets to another guest in a 1:1 manner.
@ -1264,10 +1381,25 @@ static void setup_console(void)
static u32 str2ip(const char *ipaddr)
{
unsigned int byte[4];
unsigned int b[4];
sscanf(ipaddr, "%u.%u.%u.%u", &byte[0], &byte[1], &byte[2], &byte[3]);
return (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4)
errx(1, "Failed to parse IP address '%s'", ipaddr);
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
}
static void str2mac(const char *macaddr, unsigned char mac[6])
{
unsigned int m[6];
if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
&m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6)
errx(1, "Failed to parse mac address '%s'", macaddr);
mac[0] = m[0];
mac[1] = m[1];
mac[2] = m[2];
mac[3] = m[3];
mac[4] = m[4];
mac[5] = m[5];
}
/* This code is "adapted" from libbridge: it attaches the Host end of the
@ -1288,6 +1420,7 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name)
errx(1, "interface %s does not exist!", if_name);
strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
ifr.ifr_ifindex = ifidx;
if (ioctl(fd, SIOCBRADDIF, &ifr) < 0)
err(1, "can't add %s to bridge %s", if_name, br_name);
@ -1296,64 +1429,90 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name)
/* This sets up the Host end of the network device with an IP address, brings
* it up so packets will flow, the copies the MAC address into the hwaddr
* pointer. */
static void configure_device(int fd, const char *devname, u32 ipaddr,
unsigned char hwaddr[6])
static void configure_device(int fd, const char *tapif, u32 ipaddr)
{
struct ifreq ifr;
struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
/* Don't read these incantations. Just cut & paste them like I did! */
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, devname);
strcpy(ifr.ifr_name, tapif);
/* Don't read these incantations. Just cut & paste them like I did! */
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = htonl(ipaddr);
if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
err(1, "Setting %s interface address", devname);
err(1, "Setting %s interface address", tapif);
ifr.ifr_flags = IFF_UP;
if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
err(1, "Bringing interface %s up", devname);
err(1, "Bringing interface %s up", tapif);
}
static void get_mac(int fd, const char *tapif, unsigned char hwaddr[6])
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, tapif);
/* SIOC stands for Socket I/O Control. G means Get (vs S for Set
* above). IF means Interface, and HWADDR is hardware address.
* Simple! */
if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0)
err(1, "getting hw address for %s", devname);
err(1, "getting hw address for %s", tapif);
memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
}
/*L:195 Our network is a Host<->Guest network. This can either use bridging or
* routing, but the principle is the same: it uses the "tun" device to inject
* packets into the Host as if they came in from a normal network card. We
* just shunt packets between the Guest and the tun device. */
static void setup_tun_net(const char *arg)
static int get_tun_device(char tapif[IFNAMSIZ])
{
struct device *dev;
struct ifreq ifr;
int netfd, ipfd;
u32 ip;
const char *br_name = NULL;
struct virtio_net_config conf;
int netfd;
/* Start with this zeroed. Messy but sure. */
memset(&ifr, 0, sizeof(ifr));
/* We open the /dev/net/tun device and tell it we want a tap device. A
* tap device is like a tun device, only somehow different. To tell
* the truth, I completely blundered my way through this code, but it
* works now! */
netfd = open_or_die("/dev/net/tun", O_RDWR);
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
strcpy(ifr.ifr_name, "tap%d");
if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
err(1, "configuring /dev/net/tun");
if (ioctl(netfd, TUNSETOFFLOAD,
TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0)
err(1, "Could not set features for tun device");
/* We don't need checksums calculated for packets coming in this
* device: trust us! */
ioctl(netfd, TUNSETNOCSUM, 1);
memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
return netfd;
}
/*L:195 Our network is a Host<->Guest network. This can either use bridging or
* routing, but the principle is the same: it uses the "tun" device to inject
* packets into the Host as if they came in from a normal network card. We
* just shunt packets between the Guest and the tun device. */
static void setup_tun_net(char *arg)
{
struct device *dev;
int netfd, ipfd;
u32 ip = INADDR_ANY;
bool bridging = false;
char tapif[IFNAMSIZ], *p;
struct virtio_net_config conf;
netfd = get_tun_device(tapif);
/* First we create a new network device. */
dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input);
/* Network devices need a receive and a send queue, just like
* console. */
add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
add_virtqueue(dev, VIRTQUEUE_NUM, net_enable_fd);
add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output);
/* We need a socket to perform the magic network ioctls to bring up the
@ -1364,28 +1523,56 @@ static void setup_tun_net(const char *arg)
/* If the command line was --tunnet=bridge:<name> do bridging. */
if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) {
ip = INADDR_ANY;
br_name = arg + strlen(BRIDGE_PFX);
add_to_bridge(ipfd, ifr.ifr_name, br_name);
} else /* It is an IP address to set up the device with */
arg += strlen(BRIDGE_PFX);
bridging = true;
}
/* A mac address may follow the bridge name or IP address */
p = strchr(arg, ':');
if (p) {
str2mac(p+1, conf.mac);
*p = '\0';
} else {
p = arg + strlen(arg);
/* None supplied; query the randomly assigned mac. */
get_mac(ipfd, tapif, conf.mac);
}
/* arg is now either an IP address or a bridge name */
if (bridging)
add_to_bridge(ipfd, tapif, arg);
else
ip = str2ip(arg);
/* Set up the tun device, and get the mac address for the interface. */
configure_device(ipfd, ifr.ifr_name, ip, conf.mac);
/* Set up the tun device. */
configure_device(ipfd, tapif, ip);
/* Tell Guest what MAC address to use. */
add_feature(dev, VIRTIO_NET_F_MAC);
add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
/* Expect Guest to handle everything except UFO */
add_feature(dev, VIRTIO_NET_F_CSUM);
add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
add_feature(dev, VIRTIO_NET_F_MAC);
add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
add_feature(dev, VIRTIO_NET_F_HOST_ECN);
set_config(dev, sizeof(conf), &conf);
/* We don't need the socket any more; setup is done. */
close(ipfd);
verbose("device %u: tun net %u.%u.%u.%u\n",
devices.device_num++,
(u8)(ip>>24),(u8)(ip>>16),(u8)(ip>>8),(u8)ip);
if (br_name)
verbose("attached to bridge: %s\n", br_name);
devices.device_num++;
if (bridging)
verbose("device %u: tun %s attached to bridge: %s\n",
devices.device_num, tapif, arg);
else
verbose("device %u: tun %s: %s\n",
devices.device_num, tapif, arg);
}
/* Our block (disk) device should be really simple: the Guest asks for a block
@ -1550,7 +1737,7 @@ static bool handle_io_finish(int fd, struct device *dev)
}
/* When the Guest submits some I/O, we just need to wake the I/O thread. */
static void handle_virtblk_output(int fd, struct virtqueue *vq)
static void handle_virtblk_output(int fd, struct virtqueue *vq, bool timeout)
{
struct vblk_info *vblk = vq->dev->priv;
char c = 0;
@ -1621,6 +1808,64 @@ static void setup_block_file(const char *filename)
verbose("device %u: virtblock %llu sectors\n",
devices.device_num, le64_to_cpu(conf.capacity));
}
/* Our random number generator device reads from /dev/random into the Guest's
* input buffers. The usual case is that the Guest doesn't want random numbers
* and so has no buffers although /dev/random is still readable, whereas
* console is the reverse.
*
* The same logic applies, however. */
static bool handle_rng_input(int fd, struct device *dev)
{
int len;
unsigned int head, in_num, out_num, totlen = 0;
struct iovec iov[dev->vq->vring.num];
/* First we need a buffer from the Guests's virtqueue. */
head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
/* If they're not ready for input, stop listening to this file
* descriptor. We'll start again once they add an input buffer. */
if (head == dev->vq->vring.num)
return false;
if (out_num)
errx(1, "Output buffers in rng?");
/* This is why we convert to iovecs: the readv() call uses them, and so
* it reads straight into the Guest's buffer. We loop to make sure we
* fill it. */
while (!iov_empty(iov, in_num)) {
len = readv(dev->fd, iov, in_num);
if (len <= 0)
err(1, "Read from /dev/random gave %i", len);
iov_consume(iov, in_num, len);
totlen += len;
}
/* Tell the Guest about the new input. */
add_used_and_trigger(fd, dev->vq, head, totlen);
/* Everything went OK! */
return true;
}
/* And this creates a "hardware" random number device for the Guest. */
static void setup_rng(void)
{
struct device *dev;
int fd;
fd = open_or_die("/dev/random", O_RDONLY);
/* The device responds to return from I/O thread. */
dev = new_device("rng", VIRTIO_ID_RNG, fd, handle_rng_input);
/* The device has one virtqueue, where the Guest places inbufs. */
add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
verbose("device %u: rng\n", devices.device_num++);
}
/* That's the end of device setup. */
/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */
@ -1628,11 +1873,12 @@ static void __attribute__((noreturn)) restart_guest(void)
{
unsigned int i;
/* Closing pipes causes the Waker thread and io_threads to die, and
* closing /dev/lguest cleans up the Guest. Since we don't track all
* open fds, we simply close everything beyond stderr. */
/* Since we don't track all open fds, we simply close everything beyond
* stderr. */
for (i = 3; i < FD_SETSIZE; i++)
close(i);
/* The exec automatically gets rid of the I/O and Waker threads. */
execv(main_args[0], main_args);
err(1, "Could not exec %s", main_args[0]);
}
@ -1663,7 +1909,7 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
/* ERESTART means that we need to reboot the guest */
} else if (errno == ERESTART) {
restart_guest();
/* EAGAIN means the Waker wanted us to look at some input.
/* EAGAIN means a signal (timeout).
* Anything else means a bug or incompatible change. */
} else if (errno != EAGAIN)
err(1, "Running guest failed");
@ -1691,13 +1937,14 @@ static struct option opts[] = {
{ "verbose", 0, NULL, 'v' },
{ "tunnet", 1, NULL, 't' },
{ "block", 1, NULL, 'b' },
{ "rng", 0, NULL, 'r' },
{ "initrd", 1, NULL, 'i' },
{ NULL },
};
static void usage(void)
{
errx(1, "Usage: lguest [--verbose] "
"[--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
"[--tunnet=(<ipaddr>:<macaddr>|bridge:<bridgename>:<macaddr>)\n"
"|--block=<filename>|--initrd=<filename>]...\n"
"<mem-in-mb> vmlinux [args...]");
}
@ -1765,6 +2012,9 @@ int main(int argc, char *argv[])
case 'b':
setup_block_file(optarg);
break;
case 'r':
setup_rng();
break;
case 'i':
initrd_name = optarg;
break;
@ -1783,6 +2033,9 @@ int main(int argc, char *argv[])
/* We always have a console device */
setup_console();
/* We can timeout waiting for Guest network transmit. */
setup_timeout();
/* Now we load the kernel */
start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));
@ -1826,10 +2079,10 @@ int main(int argc, char *argv[])
* /dev/lguest file descriptor. */
lguest_fd = tell_kernel(pgdir, start);
/* We fork off a child process, which wakes the Launcher whenever one
* of the input file descriptors needs attention. We call this the
* Waker, and we'll cover it in a moment. */
waker_fd = setup_waker(lguest_fd);
/* We clone off a thread, which wakes the Launcher whenever one of the
* input file descriptors needs attention. We call this the Waker, and
* we'll cover it in a moment. */
setup_waker(lguest_fd);
/* Finally, run the Guest. This doesn't return. */
run_guest(lguest_fd);

View File

@ -1,4 +1,4 @@
PM quality of Service interface.
PM Quality Of Service Interface.
This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
@ -7,6 +7,11 @@ one of the parameters.
Currently we have {cpu_dma_latency, network_latency, network_throughput} as the
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
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

View File

@ -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,
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.
CAPACITY - capacity in percents.

View File

@ -0,0 +1,182 @@
Regulator Consumer Driver Interface
===================================
This text describes the regulator interface for consumer device drivers.
Please see overview.txt for a description of the terms used in this text.
1. Consumer Regulator Access (static & dynamic drivers)
=======================================================
A consumer driver can get access to it's supply regulator by calling :-
regulator = regulator_get(dev, "Vcc");
The consumer passes in it's struct device pointer and power supply ID. The core
then finds the correct regulator by consulting a machine specific lookup table.
If the lookup is successful then this call will return a pointer to the struct
regulator that supplies this consumer.
To release the regulator the consumer driver should call :-
regulator_put(regulator);
Consumers can be supplied by more than one regulator e.g. codec consumer with
analog and digital supplies :-
digital = regulator_get(dev, "Vcc"); /* digital core */
analog = regulator_get(dev, "Avdd"); /* analog */
The regulator access functions regulator_get() and regulator_put() will
usually be called in your device drivers probe() and remove() respectively.
2. Regulator Output Enable & Disable (static & dynamic drivers)
====================================================================
A consumer can enable it's power supply by calling:-
int regulator_enable(regulator);
NOTE: The supply may already be enabled before regulator_enabled() is called.
This may happen if the consumer shares the regulator or the regulator has been
previously enabled by bootloader or kernel board initialization code.
A consumer can determine if a regulator is enabled by calling :-
int regulator_is_enabled(regulator);
This will return > zero when the regulator is enabled.
A consumer can disable it's supply when no longer needed by calling :-
int regulator_disable(regulator);
NOTE: This may not disable the supply if it's shared with other consumers. The
regulator will only be disabled when the enabled reference count is zero.
Finally, a regulator can be forcefully disabled in the case of an emergency :-
int regulator_force_disable(regulator);
NOTE: this will immediately and forcefully shutdown the regulator output. All
consumers will be powered off.
3. Regulator Voltage Control & Status (dynamic drivers)
======================================================
Some consumer drivers need to be able to dynamically change their supply
voltage to match system operating points. e.g. CPUfreq drivers can scale
voltage along with frequency to save power, SD drivers may need to select the
correct card voltage, etc.
Consumers can control their supply voltage by calling :-
int regulator_set_voltage(regulator, min_uV, max_uV);
Where min_uV and max_uV are the minimum and maximum acceptable voltages in
microvolts.
NOTE: this can be called when the regulator is enabled or disabled. If called
when enabled, then the voltage changes instantly, otherwise the voltage
configuration changes and the voltage is physically set when the regulator is
next enabled.
The regulators configured voltage output can be found by calling :-
int regulator_get_voltage(regulator);
NOTE: get_voltage() will return the configured output voltage whether the
regulator is enabled or disabled and should NOT be used to determine regulator
output state. However this can be used in conjunction with is_enabled() to
determine the regulator physical output voltage.
4. Regulator Current Limit Control & Status (dynamic drivers)
===========================================================
Some consumer drivers need to be able to dynamically change their supply
current limit to match system operating points. e.g. LCD backlight driver can
change the current limit to vary the backlight brightness, USB drivers may want
to set the limit to 500mA when supplying power.
Consumers can control their supply current limit by calling :-
int regulator_set_current_limit(regulator, min_uV, max_uV);
Where min_uA and max_uA are the minimum and maximum acceptable current limit in
microamps.
NOTE: this can be called when the regulator is enabled or disabled. If called
when enabled, then the current limit changes instantly, otherwise the current
limit configuration changes and the current limit is physically set when the
regulator is next enabled.
A regulators current limit can be found by calling :-
int regulator_get_current_limit(regulator);
NOTE: get_current_limit() will return the current limit whether the regulator
is enabled or disabled and should not be used to determine regulator current
load.
5. Regulator Operating Mode Control & Status (dynamic drivers)
=============================================================
Some consumers can further save system power by changing the operating mode of
their supply regulator to be more efficient when the consumers operating state
changes. e.g. consumer driver is idle and subsequently draws less current
Regulator operating mode can be changed indirectly or directly.
Indirect operating mode control.
--------------------------------
Consumer drivers can request a change in their supply regulator operating mode
by calling :-
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
This will cause the core to recalculate the total load on the regulator (based
on all it's consumers) and change operating mode (if necessary and permitted)
to best match the current operating load.
The load_uA value can be determined from the consumers datasheet. e.g.most
datasheets have tables showing the max current consumed in certain situations.
Most consumers will use indirect operating mode control since they have no
knowledge of the regulator or whether the regulator is shared with other
consumers.
Direct operating mode control.
------------------------------
Bespoke or tightly coupled drivers may want to directly control regulator
operating mode depending on their operating point. This can be achieved by
calling :-
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
unsigned int regulator_get_mode(struct regulator *regulator);
Direct mode will only be used by consumers that *know* about the regulator and
are not sharing the regulator with other consumers.
6. Regulator Events
===================
Regulators can notify consumers of external events. Events could be received by
consumers under regulator stress or failure conditions.
Consumers can register interest in regulator events by calling :-
int regulator_register_notifier(struct regulator *regulator,
struct notifier_block *nb);
Consumers can uregister interest by calling :-
int regulator_unregister_notifier(struct regulator *regulator,
struct notifier_block *nb);
Regulators use the kernel notifier framework to send event to thier interested
consumers.

View File

@ -0,0 +1,101 @@
Regulator Machine Driver Interface
===================================
The regulator machine driver interface is intended for board/machine specific
initialisation code to configure the regulator subsystem. Typical things that
machine drivers would do are :-
1. Regulator -> Device mapping.
2. Regulator supply configuration.
3. Power Domain constraint setting.
1. Regulator -> device mapping
==============================
Consider the following machine :-
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
+-> [Consumer B @ 3.3V]
The drivers for consumers A & B must be mapped to the correct regulator in
order to control their power supply. This mapping can be achieved in machine
initialisation code by calling :-
int regulator_set_device_supply(const char *regulator, struct device *dev,
const char *supply);
and is shown with the following code :-
regulator_set_device_supply("Regulator-1", devB, "Vcc");
regulator_set_device_supply("Regulator-2", devA, "Vcc");
This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2
to the 'Vcc' supply for Consumer A.
2. Regulator supply configuration.
==================================
Consider the following machine (again) :-
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
+-> [Consumer B @ 3.3V]
Regulator-1 supplies power to Regulator-2. This relationship must be registered
with the core so that Regulator-1 is also enabled when Consumer A enables it's
supply (Regulator-2).
This relationship can be register with the core via :-
int regulator_set_supply(const char *regulator, const char *regulator_supply);
In this example we would use the following code :-
regulator_set_supply("Regulator-2", "Regulator-1");
Relationships can be queried by calling :-
const char *regulator_get_supply(const char *regulator);
3. Power Domain constraint setting.
===================================
Each power domain within a system has physical constraints on voltage and
current. This must be defined in software so that the power domain is always
operated within specifications.
Consider the following machine (again) :-
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
+-> [Consumer B @ 3.3V]
This gives us two regulators and two power domains:
Domain 1: Regulator-2, Consumer B.
Domain 2: Consumer A.
Constraints can be registered by calling :-
int regulator_set_platform_constraints(const char *regulator,
struct regulation_constraints *constraints);
The example is defined as follows :-
struct regulation_constraints domain_1 = {
.min_uV = 3300000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
};
struct regulation_constraints domain_2 = {
.min_uV = 1800000,
.max_uV = 2000000,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
};
regulator_set_platform_constraints("Regulator-1", &domain_1);
regulator_set_platform_constraints("Regulator-2", &domain_2);

View File

@ -0,0 +1,171 @@
Linux voltage and current regulator framework
=============================================
About
=====
This framework is designed to provide a standard kernel interface to control
voltage and current regulators.
The intention is to allow systems to dynamically control regulator power output
in order to save power and prolong battery life. This applies to both voltage
regulators (where voltage output is controllable) and current sinks (where
current limit is controllable).
(C) 2008 Wolfson Microelectronics PLC.
Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Nomenclature
============
Some terms used in this document:-
o Regulator - Electronic device that supplies power to other devices.
Most regulators can enable and disable their output whilst
some can control their output voltage and or current.
Input Voltage -> Regulator -> Output Voltage
o PMIC - Power Management IC. An IC that contains numerous regulators
and often contains other susbsystems.
o Consumer - Electronic device that is supplied power by a regulator.
Consumers can be classified into two types:-
Static: consumer does not change it's supply voltage or
current limit. It only needs to enable or disable it's
power supply. It's supply voltage is set by the hardware,
bootloader, firmware or kernel board initialisation code.
Dynamic: consumer needs to change it's supply voltage or
current limit to meet operation demands.
o Power Domain - Electronic circuit that is supplied it's input power by the
output power of a regulator, switch or by another power
domain.
The supply regulator may be behind a switch(s). i.e.
Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A]
| |
| +-> [Consumer B], [Consumer C]
|
+-> [Consumer D], [Consumer E]
That is one regulator and three power domains:
Domain 1: Switch-1, Consumers D & E.
Domain 2: Switch-2, Consumers B & C.
Domain 3: Consumer A.
and this represents a "supplies" relationship:
Domain-1 --> Domain-2 --> Domain-3.
A power domain may have regulators that are supplied power
by other regulators. i.e.
Regulator-1 -+-> Regulator-2 -+-> [Consumer A]
|
+-> [Consumer B]
This gives us two regulators and two power domains:
Domain 1: Regulator-2, Consumer B.
Domain 2: Consumer A.
and a "supplies" relationship:
Domain-1 --> Domain-2
o Constraints - Constraints are used to define power levels for performance
and hardware protection. Constraints exist at three levels:
Regulator Level: This is defined by the regulator hardware
operating parameters and is specified in the regulator
datasheet. i.e.
- voltage output is in the range 800mV -> 3500mV.
- regulator current output limit is 20mA @ 5V but is
10mA @ 10V.
Power Domain Level: This is defined in software by kernel
level board initialisation code. It is used to constrain a
power domain to a particular power range. i.e.
- Domain-1 voltage is 3300mV
- Domain-2 voltage is 1400mV -> 1600mV
- Domain-3 current limit is 0mA -> 20mA.
Consumer Level: This is defined by consumer drivers
dynamically setting voltage or current limit levels.
e.g. a consumer backlight driver asks for a current increase
from 5mA to 10mA to increase LCD illumination. This passes
to through the levels as follows :-
Consumer: need to increase LCD brightness. Lookup and
request next current mA value in brightness table (the
consumer driver could be used on several different
personalities based upon the same reference device).
Power Domain: is the new current limit within the domain
operating limits for this domain and system state (e.g.
battery power, USB power)
Regulator Domains: is the new current limit within the
regulator operating parameters for input/ouput voltage.
If the regulator request passes all the constraint tests
then the new regulator value is applied.
Design
======
The framework is designed and targeted at SoC based devices but may also be
relevant to non SoC devices and is split into the following four interfaces:-
1. Consumer driver interface.
This uses a similar API to the kernel clock interface in that consumer
drivers can get and put a regulator (like they can with clocks atm) and
get/set voltage, current limit, mode, enable and disable. This should
allow consumers complete control over their supply voltage and current
limit. This also compiles out if not in use so drivers can be reused in
systems with no regulator based power control.
See Documentation/power/regulator/consumer.txt
2. Regulator driver interface.
This allows regulator drivers to register their regulators and provide
operations to the core. It also has a notifier call chain for propagating
regulator events to clients.
See Documentation/power/regulator/regulator.txt
3. Machine interface.
This interface is for machine specific code and allows the creation of
voltage/current domains (with constraints) for each regulator. It can
provide regulator constraints that will prevent device damage through
overvoltage or over current caused by buggy client drivers. It also
allows the creation of a regulator tree whereby some regulators are
supplied by others (similar to a clock tree).
See Documentation/power/regulator/machine.txt
4. Userspace ABI.
The framework also exports a lot of useful voltage/current/opmode data to
userspace via sysfs. This could be used to help monitor device power
consumption and status.
See Documentation/ABI/testing/regulator-sysfs.txt

View File

@ -0,0 +1,30 @@
Regulator Driver Interface
==========================
The regulator driver interface is relatively simple and designed to allow
regulator drivers to register their services with the core framework.
Registration
============
Drivers can register a regulator by calling :-
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
void *reg_data);
This will register the regulators capabilities and operations the regulator
core. The core does not touch reg_data (private to regulator driver).
Regulators can be unregistered by calling :-
void regulator_unregister(struct regulator_dev *rdev);
Regulator Events
================
Regulators can send events (e.g. over temp, under voltage, etc) to consumer
drivers by calling :-
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data);

View File

@ -20,8 +20,6 @@ mpc52xx-device-tree-bindings.txt
- MPC5200 Device Tree Bindings
ppc_htab.txt
- info about the Linux/PPC /proc/ppc_htab entry
SBC8260_memory_mapping.txt
- EST SBC8260 board info
smp.txt
- use and state info about Linux/PPC on MP machines
sound.txt

View File

@ -1,197 +0,0 @@
Please mail me (Jon Diekema, diekema_jon@si.com or diekema@cideas.com)
if you have questions, comments or corrections.
* EST SBC8260 Linux memory mapping rules
http://www.estc.com/
http://www.estc.com/products/boards/SBC8260-8240_ds.html
Initial conditions:
-------------------
Tasks that need to be perform by the boot ROM before control is
transferred to zImage (compressed Linux kernel):
- Define the IMMR to 0xf0000000
- Initialize the memory controller so that RAM is available at
physical address 0x00000000. On the SBC8260 is this 16M (64M)
SDRAM.
- The boot ROM should only clear the RAM that it is using.
The reason for doing this is to enhances the chances of a
successful post mortem on a Linux panic. One of the first
items to examine is the 16k (LOG_BUF_LEN) circular console
buffer called log_buf which is defined in kernel/printk.c.
- To enhance boot ROM performance, the I-cache can be enabled.
Date: Mon, 22 May 2000 14:21:10 -0700
From: Neil Russell <caret@c-side.com>
LiMon (LInux MONitor) runs with and starts Linux with MMU
off, I-cache enabled, D-cache disabled. The I-cache doesn't
need hints from the MMU to work correctly as the D-cache
does. No D-cache means no special code to handle devices in
the presence of cache (no snooping, etc). The use of the
I-cache means that the monitor can run acceptably fast
directly from ROM, rather than having to copy it to RAM.
- Build the board information structure (see
include/asm-ppc/est8260.h for its definition)
- The compressed Linux kernel (zImage) contains a bootstrap loader
that is position independent; you can load it into any RAM,
ROM or FLASH memory address >= 0x00500000 (above 5 MB), or
at its link address of 0x00400000 (4 MB).
Note: If zImage is loaded at its link address of 0x00400000 (4 MB),
then zImage will skip the step of moving itself to
its link address.
- Load R3 with the address of the board information structure
- Transfer control to zImage
- The Linux console port is SMC1, and the baud rate is controlled
from the bi_baudrate field of the board information structure.
On thing to keep in mind when picking the baud rate, is that
there is no flow control on the SMC ports. I would stick
with something safe and standard like 19200.
On the EST SBC8260, the SMC1 port is on the COM1 connector of
the board.
EST SBC8260 defaults:
---------------------
Chip
Memory Sel Bus Use
--------------------- --- --- ----------------------------------
0x00000000-0x03FFFFFF CS2 60x (16M or 64M)/64M SDRAM
0x04000000-0x04FFFFFF CS4 local 4M/16M SDRAM (soldered to the board)
0x21000000-0x21000000 CS7 60x 1B/64K Flash present detect (from the flash SIMM)
0x21000001-0x21000001 CS7 60x 1B/64K Switches (read) and LEDs (write)
0x22000000-0x2200FFFF CS5 60x 8K/64K EEPROM
0xFC000000-0xFCFFFFFF CS6 60x 2M/16M flash (8 bits wide, soldered to the board)
0xFE000000-0xFFFFFFFF CS0 60x 4M/16M flash (SIMM)
Notes:
------
- The chip selects can map 32K blocks and up (powers of 2)
- The SDRAM machine can handled up to 128Mbytes per chip select
- Linux uses the 60x bus memory (the SDRAM DIMM) for the
communications buffers.
- BATs can map 128K-256Mbytes each. There are four data BATs and
four instruction BATs. Generally the data and instruction BATs
are mapped the same.
- The IMMR must be set above the kernel virtual memory addresses,
which start at 0xC0000000. Otherwise, the kernel may crash as
soon as you start any threads or processes due to VM collisions
in the kernel or user process space.
Details from Dan Malek <dan_malek@mvista.com> on 10/29/1999:
The user application virtual space consumes the first 2 Gbytes
(0x00000000 to 0x7FFFFFFF). The kernel virtual text starts at
0xC0000000, with data following. There is a "protection hole"
between the end of kernel data and the start of the kernel
dynamically allocated space, but this space is still within
0xCxxxxxxx.
Obviously the kernel can't map any physical addresses 1:1 in
these ranges.
Details from Dan Malek <dan_malek@mvista.com> on 5/19/2000:
During the early kernel initialization, the kernel virtual
memory allocator is not operational. Prior to this KVM
initialization, we choose to map virtual to physical addresses
1:1. That is, the kernel virtual address exactly matches the
physical address on the bus. These mappings are typically done
in arch/ppc/kernel/head.S, or arch/ppc/mm/init.c. Only
absolutely necessary mappings should be done at this time, for
example board control registers or a serial uart. Normal device
driver initialization should map resources later when necessary.
Although platform dependent, and certainly the case for embedded
8xx, traditionally memory is mapped at physical address zero,
and I/O devices above physical address 0x80000000. The lowest
and highest (above 0xf0000000) I/O addresses are traditionally
used for devices or registers we need to map during kernel
initialization and prior to KVM operation. For this reason,
and since it followed prior PowerPC platform examples, I chose
to map the embedded 8xx kernel to the 0xc0000000 virtual address.
This way, we can enable the MMU to map the kernel for proper
operation, and still map a few windows before the KVM is operational.
On some systems, you could possibly run the kernel at the
0x80000000 or any other virtual address. It just depends upon
mapping that must be done prior to KVM operational. You can never
map devices or kernel spaces that overlap with the user virtual
space. This is why default IMMR mapping used by most BDM tools
won't work. They put the IMMR at something like 0x10000000 or
0x02000000 for example. You simply can't map these addresses early
in the kernel, and continue proper system operation.
The embedded 8xx/82xx kernel is mature enough that all you should
need to do is map the IMMR someplace at or above 0xf0000000 and it
should boot far enough to get serial console messages and KGDB
connected on any platform. There are lots of other subtle memory
management design features that you simply don't need to worry
about. If you are changing functions related to MMU initialization,
you are likely breaking things that are known to work and are
heading down a path of disaster and frustration. Your changes
should be to make the flexibility of the processor fit Linux,
not force arbitrary and non-workable memory mappings into Linux.
- You don't want to change KERNELLOAD or KERNELBASE, otherwise the
virtual memory and MMU code will get confused.
arch/ppc/Makefile:KERNELLOAD = 0xc0000000
include/asm-ppc/page.h:#define PAGE_OFFSET 0xc0000000
include/asm-ppc/page.h:#define KERNELBASE PAGE_OFFSET
- RAM is at physical address 0x00000000, and gets mapped to
virtual address 0xC0000000 for the kernel.
Physical addresses used by the Linux kernel:
--------------------------------------------
0x00000000-0x3FFFFFFF 1GB reserved for RAM
0xF0000000-0xF001FFFF 128K IMMR 64K used for dual port memory,
64K for 8260 registers
Logical addresses used by the Linux kernel:
-------------------------------------------
0xF0000000-0xFFFFFFFF 256M BAT0 (IMMR: dual port RAM, registers)
0xE0000000-0xEFFFFFFF 256M BAT1 (I/O space for custom boards)
0xC0000000-0xCFFFFFFF 256M BAT2 (RAM)
0xD0000000-0xDFFFFFFF 256M BAT3 (if RAM > 256MByte)
EST SBC8260 Linux mapping:
--------------------------
DBAT0, IBAT0, cache inhibited:
Chip
Memory Sel Use
--------------------- --- ---------------------------------
0xF0000000-0xF001FFFF n/a IMMR: dual port RAM, registers
DBAT1, IBAT1, cache inhibited:

View File

@ -278,7 +278,7 @@ it with special cases.
a 64-bit 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:
@ -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
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:
struct boot_param_header {

View File

@ -7,6 +7,15 @@ Currently defined compatibles:
- fsl,cpm2-scc-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:
serial@11a00 {
@ -18,4 +27,6 @@ Example:
interrupt-parent = <&PIC>;
fsl,cpm-brg = <1>;
fsl,cpm-command = <00800000>;
gpios = <&gpio_c 15 0
&gpio_d 29 0>;
};

View File

@ -133,7 +133,7 @@ error. Given an arbitrary address, the routine
pci_get_device_by_addr() will find the pci device associated
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.
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

View File

@ -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
active, will it return RFKILL_STATE_UNBLOCKED.
If it doesn't implement the get_state() hook, it must make sure that its calls
to rfkill_force_state() are enough to keep the status always up-to-date, and it
must do a rfkill_force_state() on resume from sleep.
Since the device has a hardware rfkill line, it IS subject to state changes
external to rfkill. Therefore, the driver must make sure that it calls
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
lines changed state (polling might be needed on badly designed cards that don't
@ -422,13 +423,24 @@ of the hardware is unknown), or read-write (where the hardware can be queried
about its current state).
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
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_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
use rfkill_allocate() to allocate one.

View File

@ -2,3 +2,4 @@
1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]

View File

@ -1,11 +1,11 @@
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]
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
5 -> MSI VOX USB 2.0 (em2820/em2840)
6 -> Terratec Cinergy 200 USB (em2800)
7 -> Leadtek Winfast USB II (em2800)
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
@ -14,7 +14,46 @@
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
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]
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
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]

View File

@ -1,4 +1,4 @@
List of the webcams know by gspca.
List of the webcams known by gspca.
The modules are:
gspca_main main driver

View File

@ -1884,13 +1884,9 @@ W: http://gigaset307x.sourceforge.net/
S: Maintained
HARDWARE MONITORING
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git testing
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release
S: Maintained
S: Orphaned
HARDWARE RANDOM NUMBER GENERATOR CORE
S: Orphaned
@ -3802,6 +3798,12 @@ P: Ben Nizette
M: bn@niasdigital.com
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
P: Ingo Molnar
M: mingo@redhat.com
@ -3968,7 +3970,7 @@ M: lethal@linux-sh.org
L: linux-sh@vger.kernel.org
W: http://www.linux-sh.org
T: git kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.git
S: Maintained
S: Supported
SUN3/3X
P: Sam Creasey
@ -4504,6 +4506,15 @@ M: kaber@trash.net
L: netdev@vger.kernel.org
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
P: Juerg Haefliger
M: juergh@gmail.com

View File

@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 26
EXTRAVERSION =
SUBLEVEL = 27
EXTRAVERSION = -rc2
NAME = Rotary Wombat
# *DOCUMENTATION*
@ -206,7 +206,11 @@ ifeq ($(ARCH),x86_64)
endif
# Where to locate arch specific headers
hdr-arch := $(SRCARCH)
ifeq ($(ARCH),sparc64)
hdr-arch := sparc
else
hdr-arch := $(SRCARCH)
endif
KCONFIG_CONFIG ?= .config
@ -925,10 +929,10 @@ ifneq ($(KBUILD_SRC),)
echo " in the '$(srctree)' directory.";\
/bin/false; \
fi;
$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
$(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/system.h ]; then \
$(Q)if [ ! -d include2 ]; then \
mkdir -p include2; \
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
fi
fi
endif
# prepare2 creates a makefile if using a separate output directory
@ -1488,7 +1492,7 @@ quiet_cmd_cscope-file = FILELST cscope.files
cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
quiet_cmd_cscope = MAKE cscope.out
cmd_cscope = cscope -b
cmd_cscope = cscope -b -f cscope.out
cscope: FORCE
$(call cmd,cscope-file)

View File

@ -17,6 +17,7 @@ config ARM
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FTRACE if (!XIP_KERNEL)
select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE)
select HAVE_GENERIC_DMA_COHERENT
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@ -234,6 +235,7 @@ config ARCH_VERSATILE
config ARCH_AT91
bool "Atmel AT91"
select GENERIC_GPIO
select HAVE_CLK
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
@ -267,7 +269,6 @@ config ARCH_EP93XX
select ARM_VIC
select GENERIC_GPIO
select HAVE_CLK
select HAVE_CLK
select ARCH_REQUIRE_GPIOLIB
help
This enables support for the Cirrus EP93xx series of CPUs.
@ -1224,6 +1225,8 @@ source "drivers/dma/Kconfig"
source "drivers/dca/Kconfig"
source "drivers/regulator/Kconfig"
source "drivers/uio/Kconfig"
endmenu

View File

@ -170,7 +170,7 @@ CONFIG_MACH_AT91CAP9ADK=y
# AT91 Board Options
#
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
@ -442,7 +442,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# 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_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -176,7 +176,7 @@ CONFIG_MACH_AT91SAM9260EK=y
# AT91 Board Options
#
# 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

View File

@ -169,7 +169,7 @@ CONFIG_MACH_AT91SAM9261EK=y
# AT91 Board Options
#
# 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
@ -433,7 +433,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# 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_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -169,7 +169,7 @@ CONFIG_MACH_AT91SAM9263EK=y
# AT91 Board Options
#
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
@ -428,7 +428,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# 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_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -168,7 +168,7 @@ CONFIG_MACH_AT91SAM9G20EK=y
# AT91 Board Options
#
# 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
@ -442,10 +442,10 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
CONFIG_MTD_NAND_AT91=y
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -392,7 +392,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# 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_PLATFORM is not set
# CONFIG_MTD_ONENAND is not set

View File

@ -466,10 +466,10 @@ CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
CONFIG_MTD_NAND_AT91=y
# CONFIG_MTD_NAND_AT91_ECC_SOFT is not set
CONFIG_MTD_NAND_AT91_ECC_HW=y
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
CONFIG_MTD_NAND_ATMEL=y
# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
CONFIG_MTD_NAND_ATMEL_ECC_HW=y
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -458,10 +458,10 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
CONFIG_MTD_NAND_AT91=y
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -429,7 +429,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# 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_PLATFORM=y
# CONFIG_MTD_ONENAND is not set

View File

@ -458,10 +458,10 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
CONFIG_MTD_NAND_AT91=y
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -450,10 +450,10 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
CONFIG_MTD_NAND_AT91=y
CONFIG_MTD_NAND_AT91_ECC_SOFT=y
# CONFIG_MTD_NAND_AT91_ECC_HW is not set
# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set

View File

@ -421,7 +421,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
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_PLATFORM=y
# CONFIG_MTD_ALAUDA is not set

View File

@ -7,6 +7,8 @@
#include <linux/scatterlist.h>
#include <asm-generic/dma-coherent.h>
/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA

View File

@ -297,7 +297,7 @@ config MTD_AT91_DATAFLASH_CARD
help
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"
depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK)
help

View File

@ -376,7 +376,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* 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;
#define NAND_BASE AT91_CHIPSELECT_3

View File

@ -368,7 +368,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* 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;
#define NAND_BASE AT91_CHIPSELECT_3

View File

@ -283,7 +283,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* 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;
#define NAND_BASE AT91_CHIPSELECT_3

View File

@ -198,7 +198,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* 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;
#define NAND_BASE AT91_CHIPSELECT_3

View File

@ -352,7 +352,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* 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;
#define NAND_BASE AT91_CHIPSELECT_3

View File

@ -194,7 +194,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
* 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;
#define NAND_BASE AT91_CHIPSELECT_3

View File

@ -188,7 +188,7 @@ static struct atmel_nand_data __initdata cap9adk_nand_data = {
// .rdy_pin = ... not connected
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -147,7 +147,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -148,7 +148,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -185,7 +185,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -190,7 +190,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC15,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -194,7 +194,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -149,7 +149,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -121,7 +121,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -134,7 +134,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15,
.partition_info = nand_partitions,
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,

View File

@ -18,6 +18,7 @@
#include <linux/timer.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
@ -69,6 +70,8 @@ static struct platform_device rd88f6281_nand_flash = {
static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
.phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static struct mv_sata_platform_data rd88f6281_sata_data = {

View File

@ -15,6 +15,7 @@
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/leds.h>
@ -88,6 +89,8 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
.phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static void __init rd88f5181l_fxo_init(void)

View File

@ -15,6 +15,7 @@
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
@ -89,6 +90,8 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
.phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {

View File

@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
@ -92,6 +93,8 @@ static struct platform_device wnr854t_nor_flash = {
static struct mv643xx_eth_platform_data wnr854t_eth_data = {
.phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static void __init wnr854t_init(void)

View File

@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
@ -100,6 +101,8 @@ static struct platform_device wrt350n_v2_nor_flash = {
static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
.phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static void __init wrt350n_v2_init(void)

View File

@ -22,7 +22,6 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/ide.h>
#include <linux/i2c.h>
#include <linux/pwm_backlight.h>

View File

@ -274,6 +274,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
void *
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()) {
void *virt;
@ -362,6 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
WARN_ON(irqs_disabled());
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
return;
if (arch_is_coherent()) {
kfree(cpu_addr);
return;

View File

@ -641,6 +641,7 @@ config PCI
bool
depends on ETRAX_CARDBUS
default y
select HAVE_GENERIC_DMA_COHERENT
config ETRAX_IOP_FW_LOAD
tristate "IO-processor hotplug firmware loading support"

View File

@ -15,35 +15,16 @@
#include <linux/pci.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,
dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
int order = get_order(size);
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
if (mem) {
int page = bitmap_find_free_region(mem->bitmap, mem->size,
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 (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
return ret;
if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
gfp |= GFP_DMA;
@ -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 *vaddr, dma_addr_t dma_handle)
{
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
int order = get_order(size);
if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
bitmap_release_region(mem->bitmap, page, order);
} else
if (!dma_release_from_coherent(dev, order, vaddr))
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);

View File

@ -1519,6 +1519,11 @@ sys_call_table:
.long sys_fallocate
.long sys_timerfd_settime /* 325 */
.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)

View File

@ -1,6 +1,4 @@
/*
* asm-ia64/acpi.h
*
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>

View File

@ -1,6 +1,5 @@
/*
* include/asm-ia64/cputime.h:
* Definitions for measuring cputime on ia64 machines.
* Definitions for measuring cputime on ia64 machines.
*
* Based on <asm-powerpc/cputime.h>.
*

Some files were not shown because too many files have changed in this diff Show More