Commit f0deb97a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'driver-core-next' of...

Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6

* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6:
  updated Documentation/ja_JP/SubmittingPatches
  debugfs: add documentation for debugfs_create_x64
  uio: uio_pdrv_genirq: Add OF support
  firmware: gsmi: remove sysfs entries when unload the module
  Documentation/zh_CN: Fix messy code file email-clients.txt
  driver core: add more help description for "path to uevent helper"
  driver-core: modify FIRMWARE_IN_KERNEL help message
  driver-core: Kconfig grammar corrections in firmware configuration
  DOCUMENTATION: Replace create_device() with device_create().
  DOCUMENTATION: Update overview.txt in Doc/driver-model.
  pti: pti_tty_install documentation mispelling.
parents 18447502 21d541aa
...@@ -104,4 +104,4 @@ Then in the module init function is would do: ...@@ -104,4 +104,4 @@ Then in the module init function is would do:
And assuming 'dev' is the struct device passed into the probe hook, the driver And assuming 'dev' is the struct device passed into the probe hook, the driver
probe function would do something like: probe function would do something like:
create_device(&mydriver_class, dev, chrdev, &private_data, "my_name"); device_create(&mydriver_class, dev, chrdev, &private_data, "my_name");
...@@ -30,7 +30,7 @@ management, and hot plug. In particular, the model dictated by Intel and ...@@ -30,7 +30,7 @@ management, and hot plug. In particular, the model dictated by Intel and
Microsoft (namely ACPI) ensures that almost every device on almost any bus Microsoft (namely ACPI) ensures that almost every device on almost any bus
on an x86-compatible system can work within this paradigm. Of course, on an x86-compatible system can work within this paradigm. Of course,
not every bus is able to support all such operations, although most not every bus is able to support all such operations, although most
buses support a most of those operations. buses support most of those operations.
Downstream Access Downstream Access
...@@ -46,25 +46,29 @@ struct pci_dev now looks like this: ...@@ -46,25 +46,29 @@ struct pci_dev now looks like this:
struct pci_dev { struct pci_dev {
... ...
struct device dev; struct device dev; /* Generic device interface */
...
}; };
Note first that it is statically allocated. This means only one allocation on Note first that the struct device dev within the struct pci_dev is
device discovery. Note also that it is at the _end_ of struct pci_dev. This is statically allocated. This means only one allocation on device discovery.
to make people think about what they're doing when switching between the bus
driver and the global driver; and to prevent against mindless casts between Note also that that struct device dev is not necessarily defined at the
the two. front of the pci_dev structure. This is to make people think about what
they're doing when switching between the bus driver and the global driver,
and to discourage meaningless and incorrect casts between the two.
The PCI bus layer freely accesses the fields of struct device. It knows about The PCI bus layer freely accesses the fields of struct device. It knows about
the structure of struct pci_dev, and it should know the structure of struct the structure of struct pci_dev, and it should know the structure of struct
device. Individual PCI device drivers that have been converted to the current device. Individual PCI device drivers that have been converted to the current
driver model generally do not and should not touch the fields of struct device, driver model generally do not and should not touch the fields of struct device,
unless there is a strong compelling reason to do so. unless there is a compelling reason to do so.
This abstraction is prevention of unnecessary pain during transitional phases. The above abstraction prevents unnecessary pain during transitional phases.
If the name of the field changes or is removed, then every downstream driver If it were not done this way, then when a field was renamed or removed, every
will break. On the other hand, if only the bus layer (and not the device downstream driver would break. On the other hand, if only the bus layer
layer) accesses struct device, it is only that layer that needs to change. (and not the device layer) accesses the struct device, it is only the bus
layer that needs to change.
User Interface User Interface
...@@ -73,15 +77,27 @@ User Interface ...@@ -73,15 +77,27 @@ User Interface
By virtue of having a complete hierarchical view of all the devices in the By virtue of having a complete hierarchical view of all the devices in the
system, exporting a complete hierarchical view to userspace becomes relatively system, exporting a complete hierarchical view to userspace becomes relatively
easy. This has been accomplished by implementing a special purpose virtual easy. This has been accomplished by implementing a special purpose virtual
file system named sysfs. It is hence possible for the user to mount the file system named sysfs.
whole sysfs filesystem anywhere in userspace.
Almost all mainstream Linux distros mount this filesystem automatically; you
can see some variation of the following in the output of the "mount" command:
$ mount
...
none on /sys type sysfs (rw,noexec,nosuid,nodev)
...
$
The auto-mounting of sysfs is typically accomplished by an entry similar to
the following in the /etc/fstab file:
none /sys sysfs defaults 0 0
This can be done permanently by providing the following entry into the or something similar in the /lib/init/fstab file on Debian-based systems:
/etc/fstab (under the provision that the mount point does exist, of course):
none /sys sysfs defaults 0 0 none /sys sysfs nodev,noexec,nosuid 0 0
Or by hand on the command line: If sysfs is not automatically mounted, you can always do it manually with:
# mount -t sysfs sysfs /sys # mount -t sysfs sysfs /sys
......
...@@ -73,8 +73,8 @@ the following functions can be used instead: ...@@ -73,8 +73,8 @@ the following functions can be used instead:
struct dentry *parent, u16 *value); struct dentry *parent, u16 *value);
struct dentry *debugfs_create_x32(const char *name, mode_t mode, struct dentry *debugfs_create_x32(const char *name, mode_t mode,
struct dentry *parent, u32 *value); struct dentry *parent, u32 *value);
struct dentry *debugfs_create_x64(const char *name, mode_t mode,
Note that there is no debugfs_create_x64(). struct dentry *parent, u64 *value);
These functions are useful as long as the developer knows the size of the These functions are useful as long as the developer knows the size of the
value to be exported. Some types can have different widths on different value to be exported. Some types can have different widths on different
......
This diff is collapsed.
This diff is collapsed.
...@@ -16,6 +16,11 @@ config UEVENT_HELPER_PATH ...@@ -16,6 +16,11 @@ config UEVENT_HELPER_PATH
that it creates a high system load, or on smaller systems that it creates a high system load, or on smaller systems
it is known to create out-of-memory situations during bootup. it is known to create out-of-memory situations during bootup.
To disable user space helper program execution at early boot
time specify an empty string here. This setting can be altered
via /proc/sys/kernel/hotplug or via /sys/kernel/uevent_helper
later at runtime.
config DEVTMPFS config DEVTMPFS
bool "Maintain a devtmpfs filesystem to mount at /dev" bool "Maintain a devtmpfs filesystem to mount at /dev"
depends on HOTPLUG depends on HOTPLUG
...@@ -65,17 +70,17 @@ config PREVENT_FIRMWARE_BUILD ...@@ -65,17 +70,17 @@ config PREVENT_FIRMWARE_BUILD
default y default y
help help
Say yes to avoid building firmware. Firmware is usually shipped Say yes to avoid building firmware. Firmware is usually shipped
with the driver, and only when updating the firmware a rebuild with the driver and only when updating the firmware should a
should be made. rebuild be made.
If unsure say Y here. If unsure, say Y here.
config FW_LOADER config FW_LOADER
tristate "Userspace firmware loading support" if EXPERT tristate "Userspace firmware loading support" if EXPERT
default y default y
---help--- ---help---
This option is provided for the case where no in-kernel-tree modules This option is provided for the case where none of the in-tree modules
require userspace firmware loading support, but a module built outside require userspace firmware loading support, but a module built
the kernel tree does. out-of-tree does.
config FIRMWARE_IN_KERNEL config FIRMWARE_IN_KERNEL
bool "Include in-kernel firmware blobs in kernel binary" bool "Include in-kernel firmware blobs in kernel binary"
...@@ -83,22 +88,22 @@ config FIRMWARE_IN_KERNEL ...@@ -83,22 +88,22 @@ config FIRMWARE_IN_KERNEL
default y default y
help help
The kernel source tree includes a number of firmware 'blobs' The kernel source tree includes a number of firmware 'blobs'
which are used by various drivers. The recommended way to that are used by various drivers. The recommended way to
use these is to run "make firmware_install" and to copy the use these is to run "make firmware_install", which, after
resulting binary files created in usr/lib/firmware directory converting ihex files to binary, copies all of the needed
of the kernel tree to the /lib/firmware on your system so binary files in firmware/ to /lib/firmware/ on your system so
that they can be loaded by userspace helpers on request. that they can be loaded by userspace helpers on request.
Enabling this option will build each required firmware blob Enabling this option will build each required firmware blob
into the kernel directly, where request_firmware() will find into the kernel directly, where request_firmware() will find
them without having to call out to userspace. This may be them without having to call out to userspace. This may be
useful if your root file system requires a device which uses useful if your root file system requires a device that uses
such firmware, and do not wish to use an initrd. such firmware and do not wish to use an initrd.
This single option controls the inclusion of firmware for This single option controls the inclusion of firmware for
every driver which uses request_firmware() and ships its every driver that uses request_firmware() and ships its
firmware in the kernel source tree, to avoid a proliferation firmware in the kernel source tree, which avoids a
of 'Include firmware for xxx device' options. proliferation of 'Include firmware for xxx device' options.
Say 'N' and let firmware be loaded from userspace. Say 'N' and let firmware be loaded from userspace.
...@@ -106,27 +111,27 @@ config EXTRA_FIRMWARE ...@@ -106,27 +111,27 @@ config EXTRA_FIRMWARE
string "External firmware blobs to build into the kernel binary" string "External firmware blobs to build into the kernel binary"
depends on FW_LOADER depends on FW_LOADER
help help
This option allows firmware to be built into the kernel, for the This option allows firmware to be built into the kernel for the case
cases where the user either cannot or doesn't want to provide it from where the user either cannot or doesn't want to provide it from
userspace at runtime (for example, when the firmware in question is userspace at runtime (for example, when the firmware in question is
required for accessing the boot device, and the user doesn't want to required for accessing the boot device, and the user doesn't want to
use an initrd). use an initrd).
This option is a string, and takes the (space-separated) names of the This option is a string and takes the (space-separated) names of the
firmware files -- the same names which appear in MODULE_FIRMWARE() firmware files -- the same names that appear in MODULE_FIRMWARE()
and request_firmware() in the source. These files should exist under and request_firmware() in the source. These files should exist under
the directory specified by the EXTRA_FIRMWARE_DIR option, which is the directory specified by the EXTRA_FIRMWARE_DIR option, which is
by default the firmware/ subdirectory of the kernel source tree. by default the firmware subdirectory of the kernel source tree.
So, for example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin", For example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin", copy
copy the usb8388.bin file into the firmware/ directory, and build the the usb8388.bin file into the firmware directory, and build the kernel.
kernel. Then any request_firmware("usb8388.bin") will be Then any request_firmware("usb8388.bin") will be satisfied internally
satisfied internally without needing to call out to userspace. without needing to call out to userspace.
WARNING: If you include additional firmware files into your binary WARNING: If you include additional firmware files into your binary
kernel image which are not available under the terms of the GPL, kernel image that are not available under the terms of the GPL,
then it may be a violation of the GPL to distribute the resulting then it may be a violation of the GPL to distribute the resulting
image -- since it combines both GPL and non-GPL work. You should image since it combines both GPL and non-GPL work. You should
consult a lawyer of your own before distributing such an image. consult a lawyer of your own before distributing such an image.
config EXTRA_FIRMWARE_DIR config EXTRA_FIRMWARE_DIR
...@@ -136,10 +141,9 @@ config EXTRA_FIRMWARE_DIR ...@@ -136,10 +141,9 @@ config EXTRA_FIRMWARE_DIR
help help
This option controls the directory in which the kernel build system This option controls the directory in which the kernel build system
looks for the firmware files listed in the EXTRA_FIRMWARE option. looks for the firmware files listed in the EXTRA_FIRMWARE option.
The default is the firmware/ directory in the kernel source tree, The default is firmware/ in the kernel source tree, but by changing
but by changing this option you can point it elsewhere, such as this option you can point it elsewhere, such as /lib/firmware/ or
the /lib/firmware/ directory or another separate directory some other directory containing the firmware files.
containing firmware files.
config DEBUG_DRIVER config DEBUG_DRIVER
bool "Driver Core verbose debug messages" bool "Driver Core verbose debug messages"
......
...@@ -869,8 +869,6 @@ static __init int gsmi_init(void) ...@@ -869,8 +869,6 @@ static __init int gsmi_init(void)
goto out_err; goto out_err;
} }
printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
/* Register in the firmware directory */ /* Register in the firmware directory */
ret = -ENOMEM; ret = -ENOMEM;
gsmi_kobj = kobject_create_and_add("gsmi", firmware_kobj); gsmi_kobj = kobject_create_and_add("gsmi", firmware_kobj);
...@@ -890,12 +888,13 @@ static __init int gsmi_init(void) ...@@ -890,12 +888,13 @@ static __init int gsmi_init(void)
ret = sysfs_create_files(gsmi_kobj, gsmi_attrs); ret = sysfs_create_files(gsmi_kobj, gsmi_attrs);
if (ret) { if (ret) {
printk(KERN_INFO "gsmi: Failed to add attrs"); printk(KERN_INFO "gsmi: Failed to add attrs");
goto out_err; goto out_remove_bin_file;
} }
if (register_efivars(&efivars, &efivar_ops, gsmi_kobj)) { ret = register_efivars(&efivars, &efivar_ops, gsmi_kobj);
if (ret) {
printk(KERN_INFO "gsmi: Failed to register efivars\n"); printk(KERN_INFO "gsmi: Failed to register efivars\n");
goto out_err; goto out_remove_sysfs_files;
} }
register_reboot_notifier(&gsmi_reboot_notifier); register_reboot_notifier(&gsmi_reboot_notifier);
...@@ -903,9 +902,15 @@ static __init int gsmi_init(void) ...@@ -903,9 +902,15 @@ static __init int gsmi_init(void)
atomic_notifier_chain_register(&panic_notifier_list, atomic_notifier_chain_register(&panic_notifier_list,
&gsmi_panic_notifier); &gsmi_panic_notifier);
printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
return 0; return 0;
out_err: out_remove_sysfs_files:
sysfs_remove_files(gsmi_kobj, gsmi_attrs);
out_remove_bin_file:
sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
out_err:
kobject_put(gsmi_kobj); kobject_put(gsmi_kobj);
gsmi_buf_free(gsmi_dev.param_buf); gsmi_buf_free(gsmi_dev.param_buf);
gsmi_buf_free(gsmi_dev.data_buf); gsmi_buf_free(gsmi_dev.data_buf);
...@@ -925,6 +930,8 @@ static void __exit gsmi_exit(void) ...@@ -925,6 +930,8 @@ static void __exit gsmi_exit(void)
&gsmi_panic_notifier); &gsmi_panic_notifier);
unregister_efivars(&efivars); unregister_efivars(&efivars);
sysfs_remove_files(gsmi_kobj, gsmi_attrs);
sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
kobject_put(gsmi_kobj); kobject_put(gsmi_kobj);
gsmi_buf_free(gsmi_dev.param_buf); gsmi_buf_free(gsmi_dev.param_buf);
gsmi_buf_free(gsmi_dev.data_buf); gsmi_buf_free(gsmi_dev.data_buf);
......
...@@ -445,9 +445,9 @@ static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) ...@@ -445,9 +445,9 @@ static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
} }
/** /**
* pti_tty_intstall()- Used to set up specific master-channels * pti_tty_install()- Used to set up specific master-channels
* to tty ports for organizational purposes when * to tty ports for organizational purposes when
* tracing viewed from debuging tools. * tracing viewed from debuging tools.
* *
* @driver: tty driver information. * @driver: tty driver information.
* @tty: tty struct containing pti information. * @tty: tty struct containing pti information.
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#define DRIVER_NAME "uio_pdrv_genirq" #define DRIVER_NAME "uio_pdrv_genirq"
struct uio_pdrv_genirq_platdata { struct uio_pdrv_genirq_platdata {
...@@ -97,6 +101,27 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) ...@@ -97,6 +101,27 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
int ret = -EINVAL; int ret = -EINVAL;
int i; int i;
if (!uioinfo) {
int irq;
/* alloc uioinfo for one device */
uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL);
if (!uioinfo) {
ret = -ENOMEM;
dev_err(&pdev->dev, "unable to kmalloc\n");
goto bad2;
}
uioinfo->name = pdev->dev.of_node->name;
uioinfo->version = "devicetree";
/* Multiple IRQs are not supported */
irq = platform_get_irq(pdev, 0);
if (irq == -ENXIO)
uioinfo->irq = UIO_IRQ_NONE;
else
uioinfo->irq = irq;
}
if (!uioinfo || !uioinfo->name || !uioinfo->version) { if (!uioinfo || !uioinfo->name || !uioinfo->version) {
dev_err(&pdev->dev, "missing platform_data\n"); dev_err(&pdev->dev, "missing platform_data\n");
goto bad0; goto bad0;
...@@ -180,6 +205,10 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) ...@@ -180,6 +205,10 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
kfree(priv); kfree(priv);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
bad0: bad0:
/* kfree uioinfo for OF */
if (pdev->dev.of_node)
kfree(uioinfo);
bad2:
return ret; return ret;
} }
...@@ -193,6 +222,10 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev) ...@@ -193,6 +222,10 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev)
priv->uioinfo->handler = NULL; priv->uioinfo->handler = NULL;
priv->uioinfo->irqcontrol = NULL; priv->uioinfo->irqcontrol = NULL;
/* kfree uioinfo for OF */
if (pdev->dev.of_node)
kfree(priv->uioinfo);
kfree(priv); kfree(priv);
return 0; return 0;
} }
...@@ -219,6 +252,15 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { ...@@ -219,6 +252,15 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
.runtime_resume = uio_pdrv_genirq_runtime_nop, .runtime_resume = uio_pdrv_genirq_runtime_nop,
}; };
#ifdef CONFIG_OF
static const struct of_device_id __devinitconst uio_of_genirq_match[] = {
{ /* empty for now */ },
};
MODULE_DEVICE_TABLE(of, uio_of_genirq_match);
#else
# define uio_of_genirq_match NULL
#endif
static struct platform_driver uio_pdrv_genirq = { static struct platform_driver uio_pdrv_genirq = {
.probe = uio_pdrv_genirq_probe, .probe = uio_pdrv_genirq_probe,
.remove = uio_pdrv_genirq_remove, .remove = uio_pdrv_genirq_remove,
...@@ -226,6 +268,7 @@ static struct platform_driver uio_pdrv_genirq = { ...@@ -226,6 +268,7 @@ static struct platform_driver uio_pdrv_genirq = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &uio_pdrv_genirq_dev_pm_ops, .pm = &uio_pdrv_genirq_dev_pm_ops,
.of_match_table = uio_of_genirq_match,
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment