Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: sysfs: fix off-by-one error in fill_read_buffer() kobject: two typo fixes UIO: add UIO documentation target to DocBook Makefile UIO: fix up the UIO documentation create /sys/.../power when CONFIG_PM is set allow LEGACY_PTYS to be set to 0
This commit is contained in:
commit
cae2f9c46d
@ -11,7 +11,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
|
||||
procfs-guide.xml writing_usb_driver.xml \
|
||||
kernel-api.xml filesystems.xml lsm.xml usb.xml \
|
||||
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
||||
genericirq.xml s390-drivers.xml
|
||||
genericirq.xml s390-drivers.xml uio-howto.xml
|
||||
|
||||
###
|
||||
# The build process is as follows (targets):
|
||||
|
@ -29,6 +29,12 @@
|
||||
</abstract>
|
||||
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>0.4</revnumber>
|
||||
<date>2007-11-26</date>
|
||||
<authorinitials>hjk</authorinitials>
|
||||
<revremark>Removed section about uio_dummy.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.3</revnumber>
|
||||
<date>2007-04-29</date>
|
||||
@ -94,6 +100,26 @@ interested in translating it, please email me
|
||||
user space. This simplifies development and reduces the risk of
|
||||
serious bugs within a kernel module.
|
||||
</para>
|
||||
<para>
|
||||
Please note that UIO is not an universal driver interface. Devices
|
||||
that are already handled well by other kernel subsystems (like
|
||||
networking or serial or USB) are no candidates for an UIO driver.
|
||||
Hardware that is ideally suited for an UIO driver fulfills all of
|
||||
the following:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>The device has memory that can be mapped. The device can be
|
||||
controlled completely by writing to this memory.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>The device usually generates interrupts.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>The device does not fit into one of the standard kernel
|
||||
subsystems.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="thanks">
|
||||
@ -174,8 +200,9 @@ interested in translating it, please email me
|
||||
For cards that don't generate interrupts but need to be
|
||||
polled, there is the possibility to set up a timer that
|
||||
triggers the interrupt handler at configurable time intervals.
|
||||
See <filename>drivers/uio/uio_dummy.c</filename> for an
|
||||
example of this technique.
|
||||
This interrupt simulation is done by calling
|
||||
<function>uio_event_notify()</function>
|
||||
from the timer's event handler.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -263,63 +290,11 @@ offset = N * getpagesize();
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
|
||||
<?dbhtml filename="using-uio_dummy.html"?>
|
||||
<title>Using uio_dummy</title>
|
||||
<para>
|
||||
Well, there is no real use for uio_dummy. Its only purpose is
|
||||
to test most parts of the UIO system (everything except
|
||||
hardware interrupts), and to serve as an example for the
|
||||
kernel module that you will have to write yourself.
|
||||
</para>
|
||||
|
||||
<sect1 id="what_uio_dummy_does">
|
||||
<title>What uio_dummy does</title>
|
||||
<para>
|
||||
The kernel module <filename>uio_dummy.ko</filename> creates a
|
||||
device that uses a timer to generate periodic interrupts. The
|
||||
interrupt handler does nothing but increment a counter. The
|
||||
driver adds two custom attributes, <varname>count</varname>
|
||||
and <varname>freq</varname>, that appear under
|
||||
<filename>/sys/devices/platform/uio_dummy/</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The attribute <varname>count</varname> can be read and
|
||||
written. The associated file
|
||||
<filename>/sys/devices/platform/uio_dummy/count</filename>
|
||||
appears as a normal text file and contains the total number of
|
||||
timer interrupts. If you look at it (e.g. using
|
||||
<function>cat</function>), you'll notice it is slowly counting
|
||||
up.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The attribute <varname>freq</varname> can be read and written.
|
||||
The content of
|
||||
<filename>/sys/devices/platform/uio_dummy/freq</filename>
|
||||
represents the number of system timer ticks between two timer
|
||||
interrupts. The default value of <varname>freq</varname> is
|
||||
the value of the kernel variable <varname>HZ</varname>, which
|
||||
gives you an interval of one second. Lower values will
|
||||
increase the frequency. Try the following:
|
||||
</para>
|
||||
<programlisting format="linespecific">
|
||||
cd /sys/devices/platform/uio_dummy/
|
||||
echo 100 > freq
|
||||
</programlisting>
|
||||
<para>
|
||||
Use <function>cat count</function> to see how the interrupt
|
||||
frequency changes.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
|
||||
<?dbhtml filename="custom_kernel_module.html"?>
|
||||
<title>Writing your own kernel module</title>
|
||||
<para>
|
||||
Please have a look at <filename>uio_dummy.c</filename> as an
|
||||
Please have a look at <filename>uio_cif.c</filename> as an
|
||||
example. The following paragraphs explain the different
|
||||
sections of this file.
|
||||
</para>
|
||||
@ -354,9 +329,8 @@ See the description below for details.
|
||||
interrupt, it's your modules task to determine the irq number during
|
||||
initialization. If you don't have a hardware generated interrupt but
|
||||
want to trigger the interrupt handler in some other way, set
|
||||
<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The
|
||||
uio_dummy module does this as it triggers the event mechanism in a timer
|
||||
routine. If you had no interrupt at all, you could set
|
||||
<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>.
|
||||
If you had no interrupt at all, you could set
|
||||
<varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
|
||||
rarely makes sense.
|
||||
</para></listitem>
|
||||
|
@ -770,9 +770,10 @@ int device_add(struct device *dev)
|
||||
error = device_add_attrs(dev);
|
||||
if (error)
|
||||
goto AttrsError;
|
||||
error = device_pm_add(dev);
|
||||
error = dpm_sysfs_add(dev);
|
||||
if (error)
|
||||
goto PMError;
|
||||
device_pm_add(dev);
|
||||
error = bus_add_device(dev);
|
||||
if (error)
|
||||
goto BusError;
|
||||
@ -797,6 +798,7 @@ int device_add(struct device *dev)
|
||||
return error;
|
||||
BusError:
|
||||
device_pm_remove(dev);
|
||||
dpm_sysfs_remove(dev);
|
||||
PMError:
|
||||
if (dev->bus)
|
||||
blocking_notifier_call_chain(&dev->bus->bus_notifier,
|
||||
|
@ -1,5 +1,6 @@
|
||||
obj-y := shutdown.o
|
||||
obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o
|
||||
obj-$(CONFIG_PM) += sysfs.o
|
||||
obj-$(CONFIG_PM_SLEEP) += main.o
|
||||
obj-$(CONFIG_PM_TRACE) += trace.o
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_DRIVER),y)
|
||||
|
@ -38,20 +38,14 @@ static DEFINE_MUTEX(dpm_list_mtx);
|
||||
int (*platform_enable_wakeup)(struct device *dev, int is_on);
|
||||
|
||||
|
||||
int device_pm_add(struct device *dev)
|
||||
void device_pm_add(struct device *dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
pr_debug("PM: Adding info for %s:%s\n",
|
||||
dev->bus ? dev->bus->name : "No Bus",
|
||||
kobject_name(&dev->kobj));
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
list_add_tail(&dev->power.entry, &dpm_active);
|
||||
error = dpm_sysfs_add(dev);
|
||||
if (error)
|
||||
list_del(&dev->power.entry);
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
return error;
|
||||
}
|
||||
|
||||
void device_pm_remove(struct device *dev)
|
||||
|
@ -13,14 +13,29 @@ extern void device_shutdown(void);
|
||||
|
||||
extern struct list_head dpm_active; /* The active device list */
|
||||
|
||||
static inline struct device * to_device(struct list_head * entry)
|
||||
static inline struct device *to_device(struct list_head *entry)
|
||||
{
|
||||
return container_of(entry, struct device, power.entry);
|
||||
}
|
||||
|
||||
extern int device_pm_add(struct device *);
|
||||
extern void device_pm_add(struct device *);
|
||||
extern void device_pm_remove(struct device *);
|
||||
|
||||
#else /* CONFIG_PM_SLEEP */
|
||||
|
||||
|
||||
static inline void device_pm_add(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void device_pm_remove(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
/*
|
||||
* sysfs.c
|
||||
*/
|
||||
@ -28,16 +43,15 @@ extern void device_pm_remove(struct device *);
|
||||
extern int dpm_sysfs_add(struct device *);
|
||||
extern void dpm_sysfs_remove(struct device *);
|
||||
|
||||
#else /* CONFIG_PM_SLEEP */
|
||||
#else /* CONFIG_PM */
|
||||
|
||||
|
||||
static inline int device_pm_add(struct device * dev)
|
||||
static inline int dpm_sysfs_add(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void device_pm_remove(struct device * dev)
|
||||
{
|
||||
|
||||
static inline void dpm_sysfs_remove(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -457,7 +457,7 @@ config LEGACY_PTYS
|
||||
config LEGACY_PTY_COUNT
|
||||
int "Maximum number of legacy PTY in use"
|
||||
depends on LEGACY_PTYS
|
||||
range 1 256
|
||||
range 0 256
|
||||
default "256"
|
||||
---help---
|
||||
The maximum number of legacy PTYs that can be used at any one time.
|
||||
|
@ -119,7 +119,11 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
|
||||
|
||||
sysfs_put_active_two(attr_sd);
|
||||
|
||||
BUG_ON(count > (ssize_t)PAGE_SIZE);
|
||||
/*
|
||||
* The code works fine with PAGE_SIZE return but it's likely to
|
||||
* indicate truncated result or overflow in normal use cases.
|
||||
*/
|
||||
BUG_ON(count >= (ssize_t)PAGE_SIZE);
|
||||
if (count >= 0) {
|
||||
buffer->needs_read_fill = 0;
|
||||
buffer->count = count;
|
||||
|
@ -313,8 +313,8 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
|
||||
struct kobject *temp_kobj;
|
||||
temp_kobj = kset_find_obj(kobj->kset, new_name);
|
||||
if (temp_kobj) {
|
||||
printk(KERN_WARNING "kobject '%s' can not be renamed "
|
||||
"to '%s' as '%s' is already in existance.\n",
|
||||
printk(KERN_WARNING "kobject '%s' cannot be renamed "
|
||||
"to '%s' as '%s' is already in existence.\n",
|
||||
kobject_name(kobj), new_name, new_name);
|
||||
kobject_put(temp_kobj);
|
||||
return -EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user