提交 b9da0571 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (31 commits)
  driver core: Display error codes when class suspend fails
  Driver core: Add section count to memory_block struct
  Driver core: Add mutex for adding/removing memory blocks
  Driver core: Move find_memory_block routine
  hpilo: Despecificate driver from iLO generation
  driver core: Convert link_mem_sections to use find_memory_block_hinted.
  driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted.
  kobject: Introduce kset_find_obj_hinted.
  driver core: fix build for CONFIG_BLOCK not enabled
  driver-core: base: change to new flag variable
  sysfs: only access bin file vm_ops with the active lock
  sysfs: Fail bin file mmap if vma close is implemented.
  FW_LOADER: fix kconfig dependency warning on HOTPLUG
  uio: Statically allocate uio_class and use class .dev_attrs.
  uio: Support 2^MINOR_BITS minors
  uio: Cleanup irq handling.
  uio: Don't clear driver data
  uio: Fix lack of locking in init_uio_class
  SYSFS: Allow boot time switching between deprecated and modern sysfs layout
  driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices
  ...
What: /sys/module/pch_phub/drivers/.../pch_mac
Date: August 2010
KernelVersion: 2.6.35
Contact: masa-korg@dsn.okisemi.com
Description: Write/read GbE MAC address.
What: /sys/module/pch_phub/drivers/.../pch_firmware
Date: August 2010
KernelVersion: 2.6.35
Contact: masa-korg@dsn.okisemi.com
Description: Write/read Option ROM data.
......@@ -24,7 +24,7 @@ Dynamic debug has even more useful features:
read to display the complete list of known debug statements, to help guide you
Controlling dynamic debug Behaviour
===============================
===================================
The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
......@@ -212,6 +212,26 @@ Note the regexp ^[-+=][scp]+$ matches a flags specification.
Note also that there is no convenient syntax to remove all
the flags at once, you need to use "-psc".
Debug messages during boot process
==================================
To be able to activate debug messages during the boot process,
even before userspace and debugfs exists, use the boot parameter:
ddebug_query="QUERY"
QUERY follows the syntax described above, but must not exceed 1023
characters. The enablement of debug messages is done as an arch_initcall.
Thus you can enable debug messages in all code processed after this
arch_initcall via this boot parameter.
On an x86 system for example ACPI enablement is a subsys_initcall and
ddebug_query="file ec.c +p"
will show early Embedded Controller transactions during ACPI setup if
your machine (typically a laptop) has an Embedded Controller.
PCI (or other devices) initialization also is a hot candidate for using
this boot parameter for debugging purposes.
Examples
========
......
......@@ -43,10 +43,11 @@ parameter is applicable:
AVR32 AVR32 architecture is enabled.
AX25 Appropriate AX.25 support is enabled.
BLACKFIN Blackfin architecture is enabled.
DRM Direct Rendering Management support is enabled.
EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
EFI EFI Partitioning (GPT) is enabled
EIDE EIDE/ATAPI support is enabled.
DRM Direct Rendering Management support is enabled.
DYNAMIC_DEBUG Build in debug messages and enable them at runtime
FB The frame buffer device is enabled.
GCOV GCOV profiling is enabled.
HW Appropriate hardware is enabled.
......@@ -570,6 +571,10 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <port#>,<type>
See also Documentation/input/joystick-parport.txt
ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
time. See Documentation/dynamic-debug-howto.txt for
details.
debug [KNL] Enable kernel debugging (events log level).
debug_locks_verbose=
......@@ -2370,6 +2375,15 @@ and is between 256 and 4096 characters. It is defined in the file
switches= [HW,M68k]
sysfs.deprecated=0|1 [KNL]
Enable/disable old style sysfs layout for old udev
on older distributions. When this option is enabled
very new udev will not work anymore. When this option
is disabled (or CONFIG_SYSFS_DEPRECATED not compiled)
in older udev will not work anymore.
Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in
the kernel configuration.
sysrq_always_enabled
[KNL]
Ignore sysrq setting - this boot parameter will
......
......@@ -2064,14 +2064,16 @@ F: drivers/block/drbd/
F: lib/lru_cache.c
F: Documentation/blockdev/drbd/
DRIVER CORE, KOBJECTS, AND SYSFS
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
M: Greg Kroah-Hartman <gregkh@suse.de>
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
F: Documentation/kobject.txt
F: drivers/base/
F: fs/sysfs/
F: fs/debugfs/
F: include/linux/kobj*
F: include/linux/debugfs.h
F: lib/kobj*
DRM DRIVERS
......
......@@ -22,9 +22,7 @@
#include "blk.h"
static DEFINE_MUTEX(block_class_lock);
#ifndef CONFIG_SYSFS_DEPRECATED
struct kobject *block_depr;
#endif
/* for extended dynamic devt allocation, currently only one major is used */
#define MAX_EXT_DEVT (1 << MINORBITS)
......@@ -810,10 +808,9 @@ static int __init genhd_device_init(void)
register_blkdev(BLOCK_EXT_MAJOR, "blkext");
#ifndef CONFIG_SYSFS_DEPRECATED
/* create top-level block dir */
block_depr = kobject_create_and_add("block", NULL);
#endif
if (!sysfs_deprecated)
block_depr = kobject_create_and_add("block", NULL);
return 0;
}
......
......@@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD
config FW_LOADER
tristate "Userspace firmware loading support" if EMBEDDED
depends on HOTPLUG
default y
---help---
This option is provided for the case where no in-kernel-tree modules
......
......@@ -19,7 +19,5 @@ obj-$(CONFIG_MODULES) += module.o
endif
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
ifeq ($(CONFIG_DEBUG_DRIVER),y)
EXTRA_CFLAGS += -DDEBUG
endif
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
......@@ -440,22 +440,6 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev)
}
}
#ifdef CONFIG_SYSFS_DEPRECATED
static int make_deprecated_bus_links(struct device *dev)
{
return sysfs_create_link(&dev->kobj,
&dev->bus->p->subsys.kobj, "bus");
}
static void remove_deprecated_bus_links(struct device *dev)
{
sysfs_remove_link(&dev->kobj, "bus");
}
#else
static inline int make_deprecated_bus_links(struct device *dev) { return 0; }
static inline void remove_deprecated_bus_links(struct device *dev) { }
#endif
/**
* bus_add_device - add device to bus
* @dev: device being added
......@@ -482,15 +466,10 @@ int bus_add_device(struct device *dev)
&dev->bus->p->subsys.kobj, "subsystem");
if (error)
goto out_subsys;
error = make_deprecated_bus_links(dev);
if (error)
goto out_deprecated;
klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
}
return 0;
out_deprecated:
sysfs_remove_link(&dev->kobj, "subsystem");
out_subsys:
sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
out_id:
......@@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev)
{
if (dev->bus) {
sysfs_remove_link(&dev->kobj, "subsystem");
remove_deprecated_bus_links(dev);
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
......
......@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
if (!cls->dev_kobj)
cls->dev_kobj = sysfs_dev_char_kobj;
#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
#if defined(CONFIG_BLOCK)
/* let the block class directory show up in the root of sysfs */
if (cls != &block_class)
if (!sysfs_deprecated || cls != &block_class)
cp->class_subsys.kobj.kset = class_kset;
#else
cp->class_subsys.kobj.kset = class_kset;
......@@ -276,25 +276,6 @@ void class_destroy(struct class *cls)
class_unregister(cls);
}
#ifdef CONFIG_SYSFS_DEPRECATED
char *make_class_name(const char *name, struct kobject *kobj)
{
char *class_name;
int size;
size = strlen(name) + strlen(kobject_name(kobj)) + 2;
class_name = kmalloc(size, GFP_KERNEL);
if (!class_name)
return NULL;
strcpy(class_name, name);
strcat(class_name, ":");
strcat(class_name, kobject_name(kobj));
return class_name;
}
#endif
/**
* class_dev_iter_init - initialize class device iterator
* @iter: class iterator to initialize
......
......@@ -26,6 +26,19 @@
#include "base.h"
#include "power/power.h"
#ifdef CONFIG_SYSFS_DEPRECATED
#ifdef CONFIG_SYSFS_DEPRECATED_V2
long sysfs_deprecated = 1;
#else
long sysfs_deprecated = 0;
#endif
static __init int sysfs_deprecated_setup(char *arg)
{
return strict_strtol(arg, 10, &sysfs_deprecated);
}
early_param("sysfs.deprecated", sysfs_deprecated_setup);
#endif
int (*platform_notify)(struct device *dev) = NULL;
int (*platform_notify_remove)(struct device *dev) = NULL;
static struct kobject *dev_kobj;
......@@ -203,37 +216,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (dev->driver)
add_uevent_var(env, "DRIVER=%s", dev->driver->name);
#ifdef CONFIG_SYSFS_DEPRECATED
if (dev->class) {
struct device *parent = dev->parent;
/* find first bus device in parent chain */
while (parent && !parent->bus)
parent = parent->parent;
if (parent && parent->bus) {
const char *path;
path = kobject_get_path(&parent->kobj, GFP_KERNEL);
if (path) {
add_uevent_var(env, "PHYSDEVPATH=%s", path);
kfree(path);
}
add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
if (parent->driver)
add_uevent_var(env, "PHYSDEVDRIVER=%s",
parent->driver->name);
}
} else if (dev->bus) {
add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
if (dev->driver)
add_uevent_var(env, "PHYSDEVDRIVER=%s",
dev->driver->name);
}
#endif
/* have the bus specific function add its stuff */
if (dev->bus && dev->bus->uevent) {
retval = dev->bus->uevent(dev, env);
......@@ -578,24 +560,6 @@ void device_initialize(struct device *dev)
set_dev_node(dev, -1);
}
#ifdef CONFIG_SYSFS_DEPRECATED
static struct kobject *get_device_parent(struct device *dev,
struct device *parent)
{
/* class devices without a parent live in /sys/class/<classname>/ */
if (dev->class && (!parent || parent->class != dev->class))
return &dev->class->p->class_subsys.kobj;
/* all other devices keep their parent */
else if (parent)
return &parent->kobj;
return NULL;
}
static inline void cleanup_device_parent(struct device *dev) {}
static inline void cleanup_glue_dir(struct device *dev,
struct kobject *glue_dir) {}
#else
static struct kobject *virtual_device_parent(struct device *dev)
{
static struct kobject *virtual_dir = NULL;
......@@ -666,6 +630,15 @@ static struct kobject *get_device_parent(struct device *dev,
struct kobject *parent_kobj;
struct kobject *k;
#ifdef CONFIG_BLOCK
/* block disks show up in /sys/block */
if (sysfs_deprecated && dev->class == &block_class) {
if (parent && parent->class == &block_class)
return &parent->kobj;
return &block_class.p->class_subsys.kobj;
}
#endif
/*
* If we have no parent, we live in "virtual".
* Class-devices with a non class-device as parent, live
......@@ -719,7 +692,6 @@ static void cleanup_device_parent(struct device *dev)
{
cleanup_glue_dir(dev, dev->kobj.parent);
}
#endif
static void setup_parent(struct device *dev, struct device *parent)
{
......@@ -742,70 +714,29 @@ static int device_add_class_symlinks(struct device *dev)
if (error)
goto out;
#ifdef CONFIG_SYSFS_DEPRECATED
/* stacked class devices need a symlink in the class directory */
if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
device_is_not_partition(dev)) {
error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, dev_name(dev));
if (error)
goto out_subsys;
}
if (dev->parent && device_is_not_partition(dev)) {
struct device *parent = dev->parent;
char *class_name;
/*
* stacked class devices have the 'device' link
* pointing to the bus device instead of the parent
*/
while (parent->class && !parent->bus && parent->parent)
parent = parent->parent;
error = sysfs_create_link(&dev->kobj,
&parent->kobj,
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
"device");
if (error)
goto out_busid;
class_name = make_class_name(dev->class->name,
&dev->kobj);
if (class_name)
error = sysfs_create_link(&dev->parent->kobj,
&dev->kobj, class_name);
kfree(class_name);
if (error)
goto out_device;
goto out_subsys;
}
return 0;
out_device:
if (dev->parent && device_is_not_partition(dev))
sysfs_remove_link(&dev->kobj, "device");
out_busid:
if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
device_is_not_partition(dev))
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
dev_name(dev));
#else
#ifdef CONFIG_BLOCK
/* /sys/block has directories and does not need symlinks */
if (sysfs_deprecated && dev->class == &block_class)
return 0;
#endif
/* link in the class directory pointing to the device */
error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, dev_name(dev));
if (error)
goto out_subsys;
goto out_device;
if (dev->parent && device_is_not_partition(dev)) {
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
"device");
if (error)
goto out_busid;
}
return 0;
out_busid:
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
#endif
out_device:
sysfs_remove_link(&dev->kobj, "device");
out_subsys:
sysfs_remove_link(&dev->kobj, "subsystem");
......@@ -818,30 +749,14 @@ static void device_remove_class_symlinks(struct device *dev)
if (!dev->class)
return;
#ifdef CONFIG_SYSFS_DEPRECATED
if (dev->parent && device_is_not_partition(dev)) {
char *class_name;
class_name = make_class_name(dev->class->name, &dev->kobj);
if (class_name) {
sysfs_remove_link(&dev->parent->kobj, class_name);
kfree(class_name);
}
sysfs_remove_link(&dev->kobj, "device");
}
if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
device_is_not_partition(dev))
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
dev_name(dev));
#else
if (dev->parent && device_is_not_partition(dev))
sysfs_remove_link(&dev->kobj, "device");
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
#endif
sysfs_remove_link(&dev->kobj, "subsystem");
#ifdef CONFIG_BLOCK
if (sysfs_deprecated && dev->class == &block_class)
return;
#endif
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
}
/**
......@@ -1613,41 +1528,23 @@ int device_rename(struct device *dev, const char *new_name)
pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev),
__func__, new_name);
#ifdef CONFIG_SYSFS_DEPRECATED
if ((dev->class) && (dev->parent))
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif
old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
#ifndef CONFIG_SYSFS_DEPRECATED
if (dev->class) {
error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, old_device_name, new_name);
if (error)
goto out;
}
#endif
error = kobject_rename(&dev->kobj, new_name);
if (error)
goto out;
#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
new_class_name = make_class_name(dev->class->name, &dev->kobj);
if (new_class_name) {
error = sysfs_rename_link(&dev->parent->kobj,
&dev->kobj,
old_class_name,
new_class_name);
}
}
#endif
out:
put_device(dev);
......@@ -1664,40 +1561,13 @@ static int device_move_class_links(struct device *dev,
struct device *new_parent)
{
int error = 0;
#ifdef CONFIG_SYSFS_DEPRECATED
char *class_name;
class_name = make_class_name(dev->class->name, &dev->kobj);
if (!class_name) {
error = -ENOMEM;
goto out;
}
if (old_parent) {
sysfs_remove_link(&dev->kobj, "device");
sysfs_remove_link(&old_parent->kobj, class_name);
}
if (new_parent) {
error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
"device");
if (error)
goto out;
error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
class_name);
if (error)
sysfs_remove_link(&dev->kobj, "device");
} else
error = 0;
out:
kfree(class_name);
return error;
#else
if (old_parent)
sysfs_remove_link(&dev->kobj, "device");
if (new_parent)
error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
"device");
return error;
#endif
}
/**
......
......@@ -27,6 +27,8 @@
#include <asm/atomic.h>
#include <asm/uaccess.h>
static DEFINE_MUTEX(mem_sysfs_mutex);
#define MEMORY_CLASS_NAME "memory"
static struct sysdev_class memory_sysdev_class = {
......@@ -435,6 +437,45 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
return 0;
}
struct memory_block *find_memory_block_hinted(struct mem_section *section,
struct memory_block *hint)
{
struct kobject *kobj;
struct sys_device *sysdev;
struct memory_block *mem;
char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
kobj = hint ? &hint->sysdev.kobj : NULL;
/*
* This only works because we know that section == sysdev->id
* slightly redundant with sysdev_register()
*/
sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj);
if (!kobj)
return NULL;
sysdev = container_of(kobj, struct sys_device, kobj);
mem = container_of(sysdev, struct memory_block, sysdev);
return mem;
}
/*
* For now, we have a linear search to go find the appropriate
* memory_block corresponding to a particular phys_index. If
* this gets to be a real problem, we can always use a radix
* tree or something here.
*
* This could be made generic for all sysdev classes.
*/
struct memory_block *find_memory_block(struct mem_section *section)
{
return find_memory_block_hinted(section, NULL);
}
static int add_memory_block(int nid, struct mem_section *section,
unsigned long state, enum mem_add_context context)
{
......@@ -445,8 +486,11 @@ static int add_memory_block(int nid, struct mem_section *section,
if (!mem)
return -ENOMEM;
mutex_lock(&mem_sysfs_mutex);
mem->phys_index = __section_nr(section);
mem->state = state;
mem->section_count++;
mutex_init(&mem->state_mutex);
start_pfn = section_nr_to_pfn(mem->phys_index);
mem->phys_device = arch_get_memory_phys_device(start_pfn);
......@@ -465,53 +509,29 @@ static int add_memory_block(int nid, struct mem_section *section,
ret = register_mem_sect_under_node(mem, nid);
}
mutex_unlock(&mem_sysfs_mutex);
return ret;
}
/*
* For now, we have a linear search to go find the appropriate
* memory_block corresponding to a particular phys_index. If
* this gets to be a real problem, we can always use a radix
* tree or something here.
*
* This could be made generic for all sysdev classes.
*/
struct memory_block *find_memory_block(struct mem_section *section)
{
struct kobject *kobj;
struct sys_device *sysdev;
struct memory_block *mem;
char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
/*
* This only works because we know that section == sysdev->id
* slightly redundant with sysdev_register()
*/
sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
kobj = kset_find_obj(&memory_sysdev_class.kset, name);
if (!kobj)
return NULL;
sysdev = container_of(kobj, struct sys_device, kobj);
mem = container_of(sysdev, struct memory_block, sysdev);
return mem;
}
int remove_memory_block(unsigned long node_id, struct mem_section *section,
int phys_device)
{
struct memory_block *mem;
mutex_lock(&mem_sysfs_mutex);
mem = find_memory_block(section);
unregister_mem_sect_under_nodes(mem);
mem_remove_simple_file(mem, phys_index);
mem_remove_simple_file(mem, state);
mem_remove_simple_file(mem, phys_device);
mem_remove_simple_file(mem, removable);
unregister_memory(mem, section);
mem->section_count--;
if (mem->section_count == 0) {
unregister_mem_sect_under_nodes(mem);
mem_remove_simple_file(mem, phys_index);
mem_remove_simple_file(mem, state);
mem_remove_simple_file(mem, phys_device);
mem_remove_simple_file(mem, removable);
unregister_memory(mem, section);
}
mutex_unlock(&mem_sysfs_mutex);
return 0;
}
......
......@@ -409,25 +409,27 @@ static int link_mem_sections(int nid)
unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
unsigned long pfn;
struct memory_block *mem_blk = NULL;
int err = 0;
for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
unsigned long section_nr = pfn_to_section_nr(pfn);
struct mem_section *mem_sect;
struct memory_block *mem_blk;
int ret;
if (!present_section_nr(section_nr))
continue;
mem_sect = __nr_to_section(section_nr);
mem_blk = find_memory_block(mem_sect);
mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
ret = register_mem_sect_under_node(mem_blk, nid);
if (!err)
err = ret;
/* discard ref obtained in find_memory_block() */
kobject_put(&mem_blk->sysdev.kobj);
}
if (mem_blk)
kobject_put(&mem_blk->sysdev.kobj);
return err;
}
......
......@@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev,
{
struct resource *r;
if (!res)
return 0;
r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
if (r) {
pdev->resource = r;
......@@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
int platform_device_add_data(struct platform_device *pdev, const void *data,
size_t size)
{
void *d = kmemdup(data, size, GFP_KERNEL);
void *d;
if (!data)
return 0;
d = kmemdup(data, size, GFP_KERNEL);
if (d) {
pdev->dev.platform_data = d;
return 0;
......@@ -373,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata(
pdev->dev.parent = parent;
if (res) {
ret = platform_device_add_resources(pdev, res, num);
if (ret)
goto err;
}
ret = platform_device_add_resources(pdev, res, num);
if (ret)
goto err;
if (data) {
ret = platform_device_add_data(pdev, data, size);
if (ret)
goto err;
}
ret = platform_device_add_data(pdev, data, size);
if (ret)
goto err;
ret = platform_device_add(pdev);
if (ret) {
......@@ -488,12 +491,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
* if the probe was successful, and make sure any forced probes of
* new devices fail.
*/
spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
drv->probe = NULL;
if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
retval = -ENODEV;
drv->driver.probe = platform_drv_probe_fail;
spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
if (code != retval)
platform_driver_unregister(drv);
......@@ -530,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle(
goto err_out;
}
if (res) {
error = platform_device_add_resources(pdev, res, n_res);
if (error)
goto err_pdev_put;
}
error = platform_device_add_resources(pdev, res, n_res);
if (error)
goto err_pdev_put;
if (data) {
error = platform_device_add_data(pdev, data, size);
if (error)
goto err_pdev_put;
}
error = platform_device_add_data(pdev, data, size);
if (error)
goto err_pdev_put;
error = platform_device_add(pdev);
if (error)
......@@ -976,6 +975,41 @@ struct bus_type platform_bus_type = {
};
EXPORT_SYMBOL_GPL(platform_bus_type);
/**
* platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
*
* This function can be used by platform code to get the current
* set of dev_pm_ops functions used by the platform_bus_type.
*/
const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
{
return platform_bus_type.pm;
}
/**
* platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
*
* @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
*
* Platform code can override the dev_pm_ops methods of
* platform_bus_type by using this function. It is expected that
* platform code will first do a platform_bus_get_pm_ops(), then
* kmemdup it, then customize selected methods and pass a pointer to
* the new struct dev_pm_ops to this function.
*
* Since platform-specific code is customizing methods for *all*
* devices (not just platform-specific devices) it is expected that
* any custom overrides of these functions will keep existing behavior
* and simply extend it. For example, any customization of the
* runtime PM methods should continue to call the pm_generic_*
* functions as the default ones do in addition to the
* platform-specific behavior.
*/
void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
{
platform_bus_type.pm = pm;
}
int __init platform_bus_init(void)
{
int error;
......
......@@ -432,13 +432,13 @@ int sysdev_suspend(pm_message_t state)
/* resume current sysdev */
cls_driver:
drv = NULL;
printk(KERN_ERR "Class suspend failed for %s\n",
kobject_name(&sysdev->kobj));
printk(KERN_ERR "Class suspend failed for %s: %d\n",
kobject_name(&sysdev->kobj), ret);
aux_driver:
if (drv)
printk(KERN_ERR "Class driver suspend failed for %s\n",
kobject_name(&sysdev->kobj));
printk(KERN_ERR "Class driver suspend failed for %s: %d\n",
kobject_name(&sysdev->kobj), ret);
list_for_each_entry(err_drv, &cls->drivers, entry) {
if (err_drv == drv)
break;
......
......@@ -248,15 +248,15 @@ config CS5535_CLOCK_EVENT_SRC
generic PIT, and are suitable for use as high-res timers.
config HP_ILO
tristate "Channel interface driver for HP iLO/iLO2 processor"
tristate "Channel interface driver for the HP iLO processor"
depends on PCI
default n
help
The channel interface driver allows applications to communicate
with iLO/iLO2 management processors present on HP ProLiant
servers. Upon loading, the driver creates /dev/hpilo/dXccbN files,
which can be used to gather data from the management processor,
via read and write system calls.
with iLO management processors present on HP ProLiant servers.
Upon loading, the driver creates /dev/hpilo/dXccbN files, which
can be used to gather data from the management processor, via
read and write system calls.
To compile this driver as a module, choose M here: the
module will be called hpilo.
......@@ -390,6 +390,18 @@ config BMP085
To compile this driver as a module, choose M here: the
module will be called bmp085.
config PCH_PHUB
tristate "PCH Packet Hub of Intel Topcliff"
depends on PCI
help
This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded
processor. The Topcliff has MAC address and Option ROM data in SROM.
This driver can access MAC address and Option ROM data in SROM.
To compile this driver as a module, choose M here: the module will
be called pch_phub.
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
......
......@@ -35,3 +35,4 @@ obj-y += eeprom/
obj-y += cb710/
obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
obj-$(CONFIG_PCH_PHUB) += pch_phub.o
/*
* Driver for HP iLO/iLO2 management processor.
* Driver for the HP iLO management processor.
*
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* David Altobelli <david.altobelli@hp.com>
......
此差异已折叠。
......@@ -412,9 +412,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
device_initialize(&shost->shost_gendev);
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
#ifndef CONFIG_SYSFS_DEPRECATED
shost->shost_gendev.bus = &scsi_bus_type;
#endif
shost->shost_gendev.type = &scsi_host_type;
device_initialize(&shost->shost_dev);
......
......@@ -417,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
starget->reap_ref = 1;
dev->parent = get_device(parent);
dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
#ifndef CONFIG_SYSFS_DEPRECATED
dev->bus = &scsi_bus_type;
#endif
dev->type = &scsi_target_type;
starget->id = id;
starget->channel = channel;
......
......@@ -23,9 +23,10 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/kobject.h>
#include <linux/cdev.h>
#include <linux/uio_driver.h>
#define UIO_MAX_DEVICES 255
#define UIO_MAX_DEVICES (1U << MINORBITS)
struct uio_device {
struct module *owner;
......@@ -41,15 +42,10 @@ struct uio_device {
};
static int uio_major;
static struct cdev *uio_cdev;
static DEFINE_IDR(uio_idr);
static const struct file_operations uio_fops;
/* UIO class infrastructure */
static struct uio_class {
struct kref kref;
struct class *class;
} *uio_class;
/* Protect idr accesses */
static DEFINE_MUTEX(minor_lock);
......@@ -232,45 +228,34 @@ static ssize_t show_name(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct uio_device *idev = dev_get_drvdata(dev);
if (idev)
return sprintf(buf, "%s\n", idev->info->name);
else
return -ENODEV;
return sprintf(buf, "%s\n", idev->info->name);
}
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static ssize_t show_version(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct uio_device *idev = dev_get_drvdata(dev);
if (idev)
return sprintf(buf, "%s\n", idev->info->version);
else
return -ENODEV;
return sprintf(buf, "%s\n", idev->info->version);
}
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
static ssize_t show_event(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct uio_device *idev = dev_get_drvdata(dev);
if (idev)
return sprintf(buf, "%u\n",
(unsigned int)atomic_read(&idev->event));
else
return -ENODEV;
return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
}
static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
static struct attribute *uio_attrs[] = {
&dev_attr_name.attr,
&dev_attr_version.attr,
&dev_attr_event.attr,
NULL,
static struct device_attribute uio_class_attributes[] = {
__ATTR(name, S_IRUGO, show_name, NULL),
__ATTR(version, S_IRUGO, show_version, NULL),
__ATTR(event, S_IRUGO, show_event, NULL),
{}
};
static struct attribute_group uio_attr_grp = {
.attrs = uio_attrs,
/* UIO class infrastructure */
static struct class uio_class = {
.name = "uio",
.dev_attrs = uio_class_attributes,
};
/*
......@@ -287,10 +272,6 @@ static int uio_dev_add_attributes(struct uio_device *idev)
struct uio_port *port;
struct uio_portio *portio;
ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
if (ret)
goto err_group;
for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
mem = &idev->info->mem[mi];
if (mem->size == 0)
......@@ -358,8 +339,6 @@ static int uio_dev_add_attributes(struct uio_device *idev)
kobject_put(&map->kobj);
}
kobject_put(idev->map_dir);
sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
err_group:
dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
return ret;
}
......@@ -385,8 +364,6 @@ static void uio_dev_del_attributes(struct uio_device *idev)
kobject_put(&port->portio->kobj);
}
kobject_put(idev->portio_dir);
sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
}
static int uio_get_minor(struct uio_device *idev)
......@@ -525,7 +502,7 @@ static unsigned int uio_poll(struct file *filep, poll_table *wait)
struct uio_listener *listener = filep->private_data;
struct uio_device *idev = listener->dev;
if (idev->info->irq == UIO_IRQ_NONE)
if (!idev->info->irq)
return -EIO;
poll_wait(filep, &idev->wait, wait);
......@@ -543,7 +520,7 @@ static ssize_t uio_read(struct file *filep, char __user *buf,
ssize_t retval;
s32 event_count;
if (idev->info->irq == UIO_IRQ_NONE)
if (!idev->info->irq)
return -EIO;
if (count != sizeof(s32))
......@@ -591,7 +568,7 @@ static ssize_t uio_write(struct file *filep, const char __user *buf,
ssize_t retval;
s32 irq_on;
if (idev->info->irq == UIO_IRQ_NONE)
if (!idev->info->irq)
return -EIO;
if (count != sizeof(s32))
......@@ -745,68 +722,72 @@ static const struct file_operations uio_fops = {
static int uio_major_init(void)
{
uio_major = register_chrdev(0, "uio", &uio_fops);
if (uio_major < 0)
return uio_major;
return 0;
static const char name[] = "uio";
struct cdev *cdev = NULL;
dev_t uio_dev = 0;
int result;
result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name);
if (result)
goto out;
result = -ENOMEM;
cdev = cdev_alloc();
if (!cdev)
goto out_unregister;
cdev->owner = THIS_MODULE;
cdev->ops = &uio_fops;
kobject_set_name(&cdev->kobj, "%s", name);
result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES);
if (result)
goto out_put;
uio_major = MAJOR(uio_dev);
uio_cdev = cdev;
result = 0;
out:
return result;
out_put:
kobject_put(&cdev->kobj);
out_unregister:
unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
goto out;
}
static void uio_major_cleanup(void)
{
unregister_chrdev(uio_major, "uio");
unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES);
cdev_del(uio_cdev);
}
static int init_uio_class(void)
{
int ret = 0;
if (uio_class != NULL) {
kref_get(&uio_class->kref);
goto exit;
}
int ret;
/* This is the first time in here, set everything up properly */
ret = uio_major_init();
if (ret)
goto exit;
uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
if (!uio_class) {
ret = -ENOMEM;
goto err_kzalloc;
}
kref_init(&uio_class->kref);
uio_class->class = class_create(THIS_MODULE, "uio");
if (IS_ERR(uio_class->class)) {
ret = IS_ERR(uio_class->class);
printk(KERN_ERR "class_create failed for uio\n");
goto err_class_create;
ret = class_register(&uio_class);
if (ret) {
printk(KERN_ERR "class_register failed for uio\n");
goto err_class_register;
}
return 0;
err_class_create:
kfree(uio_class);
uio_class = NULL;
err_kzalloc:
err_class_register:
uio_major_cleanup();
exit:
return ret;
}
static void release_uio_class(struct kref *kref)
static void release_uio_class(void)
{
/* Ok, we cheat as we know we only have one uio_class */
class_destroy(uio_class->class);
kfree(uio_class);
class_unregister(&uio_class);
uio_major_cleanup();
uio_class = NULL;
}
static void uio_class_destroy(void)
{
if (uio_class)
kref_put(&uio_class->kref, release_uio_class);
}
/**
......@@ -829,10 +810,6 @@ int __uio_register_device(struct module *owner,
info->uio_dev = NULL;
ret = init_uio_class();
if (ret)
return ret;
idev = kzalloc(sizeof(*idev), GFP_KERNEL);
if (!idev) {
ret = -ENOMEM;
......@@ -848,7 +825,7 @@ int __uio_register_device(struct module *owner,
if (ret)
goto err_get_minor;
idev->dev = device_create(uio_class->class, parent,
idev->dev = device_create(&uio_class, parent,
MKDEV(uio_major, idev->minor), idev,
"uio%d", idev->minor);
if (IS_ERR(idev->dev)) {
......@@ -863,9 +840,9 @@ int __uio_register_device(struct module *owner,
info->uio_dev = idev;
if (idev->info->irq >= 0) {
ret = request_irq(idev->info->irq, uio_interrupt,
idev->info->irq_flags, idev->info->name, idev);
if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
ret = request_irq(info->irq, uio_interrupt,
info->irq_flags, info->name, idev);
if (ret)
goto err_request_irq;
}
......@@ -875,13 +852,12 @@ int __uio_register_device(struct module *owner,
err_request_irq:
uio_dev_del_attributes(idev);
err_uio_dev_add_attributes:
device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
err_device_create:
uio_free_minor(idev);
err_get_minor:
kfree(idev);
err_kzalloc:
uio_class_destroy();
return ret;
}
EXPORT_SYMBOL_GPL(__uio_register_device);
......@@ -902,15 +878,13 @@ void uio_unregister_device(struct uio_info *info)
uio_free_minor(idev);
if (info->irq >= 0)
if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
free_irq(info->irq, idev);
uio_dev_del_attributes(idev);
dev_set_drvdata(idev->dev, NULL);
device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
kfree(idev);
uio_class_destroy();
return;
}
......@@ -918,11 +892,12 @@ EXPORT_SYMBOL_GPL(uio_unregister_device);
static int __init uio_init(void)
{
return 0;
return init_uio_class();
}
static void __exit uio_exit(void)
{
release_uio_class();
}
module_init(uio_init)
......
......@@ -128,12 +128,6 @@ static int __devinit probe(struct pci_dev *pdev,
struct uio_pci_generic_dev *gdev;
int err;
if (!pdev->irq) {
dev_warn(&pdev->dev, "No IRQ assigned to device: "
"no support for interrupts?\n");
return -ENODEV;
}
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
......@@ -141,6 +135,13 @@ static int __devinit probe(struct pci_dev *pdev,
return err;
}
if (!pdev->irq) {
dev_warn(&pdev->dev, "No IRQ assigned to device: "
"no support for interrupts?\n");
pci_disable_device(pdev);
return -ENODEV;
}
err = verify_pci_2_3(pdev);
if (err)
goto err_verify;
......
......@@ -537,14 +537,14 @@ void register_disk(struct gendisk *disk)
if (device_add(ddev))
return;
#ifndef CONFIG_SYSFS_DEPRECATED
err = sysfs_create_link(block_depr, &ddev->kobj,
kobject_name(&ddev->kobj));
if (err) {
device_del(ddev);
return;
if (!sysfs_deprecated) {
err = sysfs_create_link(block_depr, &ddev->kobj,
kobject_name(&ddev->kobj));
if (err) {
device_del(ddev);
return;
}
}
#endif
disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
......@@ -766,8 +766,7 @@ void del_gendisk(struct gendisk *disk)
kobject_put(disk->part0.holder_dir);
kobject_put(disk->slave_dir);
disk->driverfs_dev = NULL;
#ifndef CONFIG_SYSFS_DEPRECATED
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
#endif
if (!sysfs_deprecated)
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
device_del(disk_to_dev(disk));
}
......@@ -179,30 +179,14 @@ static void bin_vma_open(struct vm_area_struct *vma)
struct bin_buffer *bb = file->private_data;
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
if (!bb->vm_ops || !bb->vm_ops->open)
return;
if (!sysfs_get_active(attr_sd))
return;
bb->vm_ops->open(vma);
sysfs_put_active(attr_sd);
}
static void bin_vma_close(struct vm_area_struct *vma)
{
struct file *file = vma->vm_file;
struct bin_buffer *bb = file->private_data;
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
if (!bb->vm_ops || !bb->vm_ops->close)
if (!bb->vm_ops)
return;
if (!sysfs_get_active(attr_sd))
return;
bb->vm_ops->close(vma);
if (bb->vm_ops->open)
bb->vm_ops->open(vma);
sysfs_put_active(attr_sd);
}
......@@ -214,13 +198,15 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret;
if (!bb->vm_ops || !bb->vm_ops->fault)
if (!bb->vm_ops)
return VM_FAULT_SIGBUS;
if (!sysfs_get_active(attr_sd))
return VM_FAULT_SIGBUS;
ret = bb->vm_ops->fault(vma, vmf);
ret = VM_FAULT_SIGBUS;
if (bb->vm_ops->fault)
ret = bb->vm_ops->fault(vma, vmf);
sysfs_put_active(attr_sd);
return ret;
......@@ -236,13 +222,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
if (!bb->vm_ops)
return VM_FAULT_SIGBUS;
if (!bb->vm_ops->page_mkwrite)
return 0;
if (!sysfs_get_active(attr_sd))
return VM_FAULT_SIGBUS;
ret = bb->vm_ops->page_mkwrite(vma, vmf);
ret = 0;
if (bb->vm_ops->page_mkwrite)
ret = bb->vm_ops->page_mkwrite(vma, vmf);
sysfs_put_active(attr_sd);
return ret;
......@@ -256,13 +241,15 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret;
if (!bb->vm_ops || !bb->vm_ops->access)
if (!bb->vm_ops)
return -EINVAL;
if (!sysfs_get_active(attr_sd))
return -EINVAL;
ret = bb->vm_ops->access(vma, addr, buf, len, write);
ret = -EINVAL;
if (bb->vm_ops->access)
ret = bb->vm_ops->access(vma, addr, buf, len, write);
sysfs_put_active(attr_sd);
return ret;
......@@ -276,13 +263,15 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret;
if (!bb->vm_ops || !bb->vm_ops->set_policy)
if (!bb->vm_ops)
return 0;
if (!sysfs_get_active(attr_sd))
return -EINVAL;
ret = bb->vm_ops->set_policy(vma, new);
ret = 0;
if (bb->vm_ops->set_policy)
ret = bb->vm_ops->set_policy(vma, new);
sysfs_put_active(attr_sd);
return ret;
......@@ -296,13 +285,15 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct mempolicy *pol;
if (!bb->vm_ops || !bb->vm_ops->get_policy)
if (!bb->vm_ops)
return vma->vm_policy;
if (!sysfs_get_active(attr_sd))
return vma->vm_policy;
pol = bb->vm_ops->get_policy(vma, addr);
pol = vma->vm_policy;
if (bb->vm_ops->get_policy)
pol = bb->vm_ops->get_policy(vma, addr);
sysfs_put_active(attr_sd);
return pol;
......@@ -316,13 +307,15 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret;
if (!bb->vm_ops || !bb->vm_ops->migrate)
if (!bb->vm_ops)
return 0;
if (!sysfs_get_active(attr_sd))
return 0;
ret = bb->vm_ops->migrate(vma, from, to, flags);
ret = 0;
if (bb->vm_ops->migrate)
ret = bb->vm_ops->migrate(vma, from, to, flags);
sysfs_put_active(attr_sd);
return ret;
......@@ -331,7 +324,6 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
static const struct vm_operations_struct bin_vm_ops = {
.open = bin_vma_open,
.close = bin_vma_close,
.fault = bin_fault,
.page_mkwrite = bin_page_mkwrite,
.access = bin_access,
......@@ -377,6 +369,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
if (bb->mmapped && bb->vm_ops != vma->vm_ops)
goto out_put;
/*
* It is not possible to successfully wrap close.
* So error if someone is trying to use close.
*/
rc = -EINVAL;
if (vma->vm_ops && vma->vm_ops->close)
goto out_put;
rc = 0;
bb->mmapped = 1;
bb->vm_ops = vma->vm_ops;
......
......@@ -751,4 +751,11 @@ do { \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
#define MODULE_ALIAS_CHARDEV_MAJOR(major) \
MODULE_ALIAS("char-major-" __stringify(major) "-*")
#ifdef CONFIG_SYSFS_DEPRECATED
extern long sysfs_deprecated;
#else
#define sysfs_deprecated 0
#endif
#endif /* _DEVICE_H_ */
......@@ -191,6 +191,8 @@ static inline struct kobj_type *get_ktype(struct kobject *kobj)
}
extern struct kobject *kset_find_obj(struct kset *, const char *);
extern struct kobject *kset_find_obj_hinted(struct kset *, const char *,
struct kobject *);
/* The global /sys/kernel/ kobject for people to chain off of */
extern struct kobject *kernel_kobj;
......
......@@ -23,6 +23,8 @@
struct memory_block {
unsigned long phys_index;
unsigned long state;
int section_count;
/*
* This serializes all state change requests. It isn't
* held during creation because the control files are
......@@ -113,6 +115,8 @@ extern int memory_dev_init(void);
extern int remove_memory_block(unsigned long, struct mem_section *, int);
extern int memory_notify(unsigned long val, void *v);
extern int memory_isolate_notify(unsigned long val, void *v);
extern struct memory_block *find_memory_block_hinted(struct mem_section *,
struct memory_block *);
extern struct memory_block *find_memory_block(struct mem_section *);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
enum mem_add_context { BOOT, HOTPLUG };
......
......@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
struct resource *res, unsigned int n_res,
const void *data, size_t size);
extern const struct dev_pm_ops * platform_bus_get_pm_ops(void);
extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm);
/* early platform driver interface */
struct early_platform_driver {
const char *class_str;
......
......@@ -108,7 +108,7 @@ extern void uio_event_notify(struct uio_info *info);
/* defines for uio_info->irq */
#define UIO_IRQ_CUSTOM -1
#define UIO_IRQ_NONE -2
#define UIO_IRQ_NONE 0
/* defines for uio_mem->memtype */
#define UIO_MEM_NONE 0
......
......@@ -133,9 +133,7 @@ struct snd_card {
int free_on_last_close; /* free in context of file_release */
wait_queue_head_t shutdown_sleep;
struct device *dev; /* device assigned to this card */
#ifndef CONFIG_SYSFS_DEPRECATED
struct device *card_dev; /* cardX object for sysfs */
#endif
#ifdef CONFIG_PM
unsigned int power_state; /* power state */
......@@ -196,11 +194,7 @@ struct snd_minor {
/* return a device pointer linked to each sound device as a parent */
static inline struct device *snd_card_get_device_link(struct snd_card *card)
{
#ifdef CONFIG_SYSFS_DEPRECATED
return card ? card->dev : NULL;
#else
return card ? card->card_dev : NULL;
#endif
}
/* sound.c */
......
......@@ -686,40 +686,42 @@ config MM_OWNER
bool
config SYSFS_DEPRECATED
bool
config SYSFS_DEPRECATED_V2
bool "enable deprecated sysfs features to support old userspace tools"
depends on SYSFS
default n
select SYSFS_DEPRECATED
help
This option switches the layout of sysfs to the deprecated
version. Do not use it on recent distributions.
The current sysfs layout features a unified device tree at
/sys/devices/, which is able to express a hierarchy between
class devices. If the deprecated option is set to Y, the
unified device tree is split into a bus device tree at
/sys/devices/ and several individual class device trees at
/sys/class/. The class and bus devices will be connected by
"<subsystem>:<name>" and the "device" links. The "block"
class devices, will not show up in /sys/class/block/. Some
subsystems will suppress the creation of some devices which
depend on the unified device tree.
This option is not a pure compatibility option that can
be safely enabled on newer distributions. It will change the
layout of sysfs to the non-extensible deprecated version,
and disable some features, which can not be exported without
confusing older userspace tools. Since 2007/2008 all major
distributions do not enable this option, and ship no tools which
depend on the deprecated layout or this option.
If you are using a new kernel on an older distribution, or use
older userspace tools, you might need to say Y here. Do not say Y,
if the original kernel, that came with your distribution, has
this option set to N.
help
This option adds code that switches the layout of the "block" class
devices, to not show up in /sys/class/block/, but only in
/sys/block/.
This switch is only active when the sysfs.deprecated=1 boot option is
passed or the SYSFS_DEPRECATED_V2 option is set.
This option allows new kernels to run on old distributions and tools,
which might get confused by /sys/class/block/. Since 2007/2008 all
major distributions and tools handle this just fine.
Recent distributions and userspace tools after 2009/2010 depend on
the existence of /sys/class/block/, and will not work with this
option enabled.
Only if you are using a new kernel on an old distribution, you might
need to say Y here.
config SYSFS_DEPRECATED_V2
bool "enabled deprecated sysfs features by default"
default n
depends on SYSFS
depends on SYSFS_DEPRECATED
help
Enable deprecated sysfs by default.
See the CONFIG_SYSFS_DEPRECATED option for more details about this
option.
Only if you are using a new kernel on an old distribution, you might
need to say Y here. Even then, odds are you would not need it
enabled, you can always pass the boot option if absolutely necessary.
config RELAY
bool "Kernel->user space relay support (formerly relayfs)"
......
......@@ -393,6 +393,40 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
return 0;
}
static int ddebug_exec_query(char *query_string)
{
unsigned int flags = 0, mask = 0;
struct ddebug_query query;
#define MAXWORDS 9
int nwords;
char *words[MAXWORDS];
nwords = ddebug_tokenize(query_string, words, MAXWORDS);
if (nwords <= 0)
return -EINVAL;
if (ddebug_parse_query(words, nwords-1, &query))
return -EINVAL;
if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
return -EINVAL;
/* actually go and implement the change */
ddebug_change(&query, flags, mask);
return 0;
}
static __initdata char ddebug_setup_string[1024];
static __init int ddebug_setup_query(char *str)
{
if (strlen(str) >= 1024) {
pr_warning("ddebug boot param string too large\n");
return 0;
}
strcpy(ddebug_setup_string, str);
return 1;
}
__setup("ddebug_query=", ddebug_setup_query);
/*
* File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
* command text from userspace, parses and executes it.
......@@ -400,12 +434,8 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
unsigned int flags = 0, mask = 0;
struct ddebug_query query;
#define MAXWORDS 9
int nwords;
char *words[MAXWORDS];
char tmpbuf[256];
int ret;
if (len == 0)
return 0;
......@@ -419,16 +449,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
printk(KERN_INFO "%s: read %d bytes from userspace\n",
__func__, (int)len);
nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS);
if (nwords <= 0)
return -EINVAL;
if (ddebug_parse_query(words, nwords-1, &query))
return -EINVAL;
if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
return -EINVAL;
/* actually go and implement the change */
ddebug_change(&query, flags, mask);
ret = ddebug_exec_query(tmpbuf);
if (ret)
return ret;
*offp += len;
return len;
......@@ -689,13 +712,14 @@ static void ddebug_remove_all_tables(void)
mutex_unlock(&ddebug_lock);
}
static int __init dynamic_debug_init(void)
static __initdata int ddebug_init_success;
static int __init dynamic_debug_init_debugfs(void)
{
struct dentry *dir, *file;
struct _ddebug *iter, *iter_start;
const char *modname = NULL;
int ret = 0;
int n = 0;
if (!ddebug_init_success)
return -ENODEV;
dir = debugfs_create_dir("dynamic_debug", NULL);
if (!dir)
......@@ -706,6 +730,16 @@ static int __init dynamic_debug_init(void)
debugfs_remove(dir);
return -ENOMEM;
}
return 0;
}
static int __init dynamic_debug_init(void)
{
struct _ddebug *iter, *iter_start;
const char *modname = NULL;
int ret = 0;
int n = 0;
if (__start___verbose != __stop___verbose) {
iter = __start___verbose;
modname = iter->modname;
......@@ -723,12 +757,26 @@ static int __init dynamic_debug_init(void)
}
ret = ddebug_add_module(iter_start, n, modname);
}
/* ddebug_query boot param got passed -> set it up */
if (ddebug_setup_string[0] != '\0') {
ret = ddebug_exec_query(ddebug_setup_string);
if (ret)
pr_warning("Invalid ddebug boot param %s",
ddebug_setup_string);
else
pr_info("ddebug initialized with string %s",
ddebug_setup_string);
}
out_free:
if (ret) {
if (ret)
ddebug_remove_all_tables();
debugfs_remove(dir);
debugfs_remove(file);
}
else
ddebug_init_success = 1;
return 0;
}
module_init(dynamic_debug_init);
/* Allow early initialization for boot messages via boot param */
arch_initcall(dynamic_debug_init);
/* Debugfs setup must be done later */
module_init(dynamic_debug_init_debugfs);
......@@ -745,18 +745,57 @@ void kset_unregister(struct kset *k)
* take a reference and return the object.
*/
struct kobject *kset_find_obj(struct kset *kset, const char *name)
{
return kset_find_obj_hinted(kset, name, NULL);
}
/**
* kset_find_obj_hinted - search for object in kset given a predecessor hint.
* @kset: kset we're looking in.
* @name: object's name.
* @hint: hint to possible object's predecessor.
*
* Check the hint's next object and if it is a match return it directly,
* otherwise, fall back to the behavior of kset_find_obj(). Either way
* a reference for the returned object is held and the reference on the
* hinted object is released.
*/
struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
struct kobject *hint)
{
struct kobject *k;
struct kobject *ret = NULL;
spin_lock(&kset->list_lock);
if (!hint)
goto slow_search;
/* end of list detection */
if (hint->entry.next == kset->list.next)
goto slow_search;
k = container_of(hint->entry.next, struct kobject, entry);
if (!kobject_name(k) || strcmp(kobject_name(k), name))
goto slow_search;
ret = kobject_get(k);
goto unlock_exit;
slow_search:
list_for_each_entry(k, &kset->list, entry) {
if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
ret = kobject_get(k);
break;
}
}
unlock_exit:
spin_unlock(&kset->list_lock);
if (hint)
kobject_put(hint);
return ret;
}
......
......@@ -395,12 +395,10 @@ int snd_card_disconnect(struct snd_card *card)
snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
snd_info_card_disconnect(card);
#ifndef CONFIG_SYSFS_DEPRECATED
if (card->card_dev) {
device_unregister(card->card_dev);
card->card_dev = NULL;
}
#endif
#ifdef CONFIG_PM
wake_up(&card->power_sleep);
#endif
......@@ -573,7 +571,6 @@ void snd_card_set_id(struct snd_card *card, const char *nid)
}
EXPORT_SYMBOL(snd_card_set_id);
#ifndef CONFIG_SYSFS_DEPRECATED
static ssize_t
card_id_show_attr(struct device *dev,
struct device_attribute *attr, char *buf)
......@@ -630,7 +627,6 @@ card_number_show_attr(struct device *dev,
static struct device_attribute card_number_attrs =
__ATTR(number, S_IRUGO, card_number_show_attr, NULL);
#endif /* CONFIG_SYSFS_DEPRECATED */
/**
* snd_card_register - register the soundcard
......@@ -649,7 +645,7 @@ int snd_card_register(struct snd_card *card)
if (snd_BUG_ON(!card))
return -EINVAL;
#ifndef CONFIG_SYSFS_DEPRECATED
if (!card->card_dev) {
card->card_dev = device_create(sound_class, card->dev,
MKDEV(0, 0), card,
......@@ -657,7 +653,7 @@ int snd_card_register(struct snd_card *card)
if (IS_ERR(card->card_dev))
card->card_dev = NULL;
}
#endif
if ((err = snd_device_register_all(card)) < 0)
return err;
mutex_lock(&snd_card_mutex);
......@@ -674,7 +670,6 @@ int snd_card_register(struct snd_card *card)
if (snd_mixer_oss_notify_callback)
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
#endif
#ifndef CONFIG_SYSFS_DEPRECATED
if (card->card_dev) {
err = device_create_file(card->card_dev, &card_id_attrs);
if (err < 0)
......@@ -683,7 +678,7 @@ int snd_card_register(struct snd_card *card)
if (err < 0)
return err;
}
#endif
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册