Commit b9da0571 authored by Linus Torvalds's avatar 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
  ...
parents f8cae0f0 5abd9356
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: ...@@ -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 read to display the complete list of known debug statements, to help guide you
Controlling dynamic debug Behaviour Controlling dynamic debug Behaviour
=============================== ===================================
The behaviour of pr_debug()/dev_debug()s are controlled via writing to a 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 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. ...@@ -212,6 +212,26 @@ Note the regexp ^[-+=][scp]+$ matches a flags specification.
Note also that there is no convenient syntax to remove all Note also that there is no convenient syntax to remove all
the flags at once, you need to use "-psc". 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 Examples
======== ========
......
...@@ -43,10 +43,11 @@ parameter is applicable: ...@@ -43,10 +43,11 @@ parameter is applicable:
AVR32 AVR32 architecture is enabled. AVR32 AVR32 architecture is enabled.
AX25 Appropriate AX.25 support is enabled. AX25 Appropriate AX.25 support is enabled.
BLACKFIN Blackfin architecture is enabled. BLACKFIN Blackfin architecture is enabled.
DRM Direct Rendering Management support is enabled.
EDD BIOS Enhanced Disk Drive Services (EDD) is enabled EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
EFI EFI Partitioning (GPT) is enabled EFI EFI Partitioning (GPT) is enabled
EIDE EIDE/ATAPI support 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. FB The frame buffer device is enabled.
GCOV GCOV profiling is enabled. GCOV GCOV profiling is enabled.
HW Appropriate hardware is enabled. HW Appropriate hardware is enabled.
...@@ -570,6 +571,10 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -570,6 +571,10 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <port#>,<type> Format: <port#>,<type>
See also Documentation/input/joystick-parport.txt 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 [KNL] Enable kernel debugging (events log level).
debug_locks_verbose= debug_locks_verbose=
...@@ -2370,6 +2375,15 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2370,6 +2375,15 @@ and is between 256 and 4096 characters. It is defined in the file
switches= [HW,M68k] 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 sysrq_always_enabled
[KNL] [KNL]
Ignore sysrq setting - this boot parameter will Ignore sysrq setting - this boot parameter will
......
...@@ -2064,14 +2064,16 @@ F: drivers/block/drbd/ ...@@ -2064,14 +2064,16 @@ F: drivers/block/drbd/
F: lib/lru_cache.c F: lib/lru_cache.c
F: Documentation/blockdev/drbd/ F: Documentation/blockdev/drbd/
DRIVER CORE, KOBJECTS, AND SYSFS DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
M: Greg Kroah-Hartman <gregkh@suse.de> M: Greg Kroah-Hartman <gregkh@suse.de>
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported S: Supported
F: Documentation/kobject.txt F: Documentation/kobject.txt
F: drivers/base/ F: drivers/base/
F: fs/sysfs/ F: fs/sysfs/
F: fs/debugfs/
F: include/linux/kobj* F: include/linux/kobj*
F: include/linux/debugfs.h
F: lib/kobj* F: lib/kobj*
DRM DRIVERS DRM DRIVERS
......
...@@ -22,9 +22,7 @@ ...@@ -22,9 +22,7 @@
#include "blk.h" #include "blk.h"
static DEFINE_MUTEX(block_class_lock); static DEFINE_MUTEX(block_class_lock);
#ifndef CONFIG_SYSFS_DEPRECATED
struct kobject *block_depr; struct kobject *block_depr;
#endif
/* for extended dynamic devt allocation, currently only one major is used */ /* for extended dynamic devt allocation, currently only one major is used */
#define MAX_EXT_DEVT (1 << MINORBITS) #define MAX_EXT_DEVT (1 << MINORBITS)
...@@ -810,10 +808,9 @@ static int __init genhd_device_init(void) ...@@ -810,10 +808,9 @@ static int __init genhd_device_init(void)
register_blkdev(BLOCK_EXT_MAJOR, "blkext"); register_blkdev(BLOCK_EXT_MAJOR, "blkext");
#ifndef CONFIG_SYSFS_DEPRECATED
/* create top-level block dir */ /* create top-level block dir */
block_depr = kobject_create_and_add("block", NULL); if (!sysfs_deprecated)
#endif block_depr = kobject_create_and_add("block", NULL);
return 0; return 0;
} }
......
...@@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD ...@@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD
config FW_LOADER config FW_LOADER
tristate "Userspace firmware loading support" if EMBEDDED tristate "Userspace firmware loading support" if EMBEDDED
depends on HOTPLUG
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 no in-kernel-tree modules
......
...@@ -19,7 +19,5 @@ obj-$(CONFIG_MODULES) += module.o ...@@ -19,7 +19,5 @@ obj-$(CONFIG_MODULES) += module.o
endif endif
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
ifeq ($(CONFIG_DEBUG_DRIVER),y) ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
EXTRA_CFLAGS += -DDEBUG
endif
...@@ -440,22 +440,6 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev) ...@@ -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 * bus_add_device - add device to bus
* @dev: device being added * @dev: device being added
...@@ -482,15 +466,10 @@ int bus_add_device(struct device *dev) ...@@ -482,15 +466,10 @@ int bus_add_device(struct device *dev)
&dev->bus->p->subsys.kobj, "subsystem"); &dev->bus->p->subsys.kobj, "subsystem");
if (error) if (error)
goto out_subsys; 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); klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
} }
return 0; return 0;
out_deprecated:
sysfs_remove_link(&dev->kobj, "subsystem");
out_subsys: out_subsys:
sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
out_id: out_id:
...@@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev) ...@@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev)
{ {
if (dev->bus) { if (dev->bus) {
sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->kobj, "subsystem");
remove_deprecated_bus_links(dev);
sysfs_remove_link(&dev->bus->p->devices_kset->kobj, sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev)); dev_name(dev));
device_remove_attrs(dev->bus, dev); device_remove_attrs(dev->bus, dev);
......
...@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key) ...@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
if (!cls->dev_kobj) if (!cls->dev_kobj)
cls->dev_kobj = sysfs_dev_char_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 */ /* 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; cp->class_subsys.kobj.kset = class_kset;
#else #else
cp->class_subsys.kobj.kset = class_kset; cp->class_subsys.kobj.kset = class_kset;
...@@ -276,25 +276,6 @@ void class_destroy(struct class *cls) ...@@ -276,25 +276,6 @@ void class_destroy(struct class *cls)
class_unregister(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 * class_dev_iter_init - initialize class device iterator
* @iter: class iterator to initialize * @iter: class iterator to initialize
......
...@@ -26,6 +26,19 @@ ...@@ -26,6 +26,19 @@
#include "base.h" #include "base.h"
#include "power/power.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)(struct device *dev) = NULL;
int (*platform_notify_remove)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL;
static struct kobject *dev_kobj; static struct kobject *dev_kobj;
...@@ -203,37 +216,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, ...@@ -203,37 +216,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (dev->driver) if (dev->driver)
add_uevent_var(env, "DRIVER=%s", dev->driver->name); 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 */ /* have the bus specific function add its stuff */
if (dev->bus && dev->bus->uevent) { if (dev->bus && dev->bus->uevent) {
retval = dev->bus->uevent(dev, env); retval = dev->bus->uevent(dev, env);
...@@ -578,24 +560,6 @@ void device_initialize(struct device *dev) ...@@ -578,24 +560,6 @@ void device_initialize(struct device *dev)
set_dev_node(dev, -1); 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_device_parent(struct device *dev)
{ {
static struct kobject *virtual_dir = NULL; static struct kobject *virtual_dir = NULL;
...@@ -666,6 +630,15 @@ static struct kobject *get_device_parent(struct device *dev, ...@@ -666,6 +630,15 @@ static struct kobject *get_device_parent(struct device *dev,
struct kobject *parent_kobj; struct kobject *parent_kobj;
struct kobject *k; 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". * If we have no parent, we live in "virtual".
* Class-devices with a non class-device as parent, live * Class-devices with a non class-device as parent, live
...@@ -719,7 +692,6 @@ static void cleanup_device_parent(struct device *dev) ...@@ -719,7 +692,6 @@ static void cleanup_device_parent(struct device *dev)
{ {
cleanup_glue_dir(dev, dev->kobj.parent); cleanup_glue_dir(dev, dev->kobj.parent);
} }
#endif
static void setup_parent(struct device *dev, struct device *parent) static void setup_parent(struct device *dev, struct device *parent)
{ {
...@@ -742,70 +714,29 @@ static int device_add_class_symlinks(struct device *dev) ...@@ -742,70 +714,29 @@ static int device_add_class_symlinks(struct device *dev)
if (error) if (error)
goto out; 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)) { if (dev->parent && device_is_not_partition(dev)) {
struct device *parent = dev->parent; error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
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,
"device"); "device");
if (error) if (error)
goto out_busid; goto out_subsys;
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;
} }
return 0;
out_device: #ifdef CONFIG_BLOCK
if (dev->parent && device_is_not_partition(dev)) /* /sys/block has directories and does not need symlinks */
sysfs_remove_link(&dev->kobj, "device"); if (sysfs_deprecated && dev->class == &block_class)
out_busid: return 0;
if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && #endif
device_is_not_partition(dev))
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
dev_name(dev));
#else
/* link in the class directory pointing to the device */ /* link in the class directory pointing to the device */
error = sysfs_create_link(&dev->class->p->class_subsys.kobj, error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, dev_name(dev)); &dev->kobj, dev_name(dev));
if (error) 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; return 0;
out_busid: out_device:
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); sysfs_remove_link(&dev->kobj, "device");
#endif
out_subsys: out_subsys:
sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->kobj, "subsystem");
...@@ -818,30 +749,14 @@ static void device_remove_class_symlinks(struct device *dev) ...@@ -818,30 +749,14 @@ static void device_remove_class_symlinks(struct device *dev)
if (!dev->class) if (!dev->class)
return; 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)) if (dev->parent && device_is_not_partition(dev))
sysfs_remove_link(&dev->kobj, "device"); 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"); 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) ...@@ -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), pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev),
__func__, new_name); __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); old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) { if (!old_device_name) {
error = -ENOMEM; error = -ENOMEM;
goto out; goto out;
} }
#ifndef CONFIG_SYSFS_DEPRECATED
if (dev->class) { if (dev->class) {
error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, old_device_name, new_name); &dev->kobj, old_device_name, new_name);
if (error) if (error)
goto out; goto out;
} }
#endif
error = kobject_rename(&dev->kobj, new_name); error = kobject_rename(&dev->kobj, new_name);
if (error) if (error)
goto out; 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: out:
put_device(dev); put_device(dev);
...@@ -1664,40 +1561,13 @@ static int device_move_class_links(struct device *dev, ...@@ -1664,40 +1561,13 @@ static int device_move_class_links(struct device *dev,
struct device *new_parent) struct device *new_parent)
{ {
int error = 0; 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) if (old_parent)
sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "device");
if (new_parent) if (new_parent)
error = sysfs_create_link(&dev->kobj, &new_parent->kobj, error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
"device"); "device");
return error; return error;
#endif
} }
/** /**
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
static DEFINE_MUTEX(mem_sysfs_mutex);
#define MEMORY_CLASS_NAME "memory" #define MEMORY_CLASS_NAME "memory"
static struct sysdev_class memory_sysdev_class = { static struct sysdev_class memory_sysdev_class = {
...@@ -435,6 +437,45 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn) ...@@ -435,6 +437,45 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
return 0; 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, static int add_memory_block(int nid, struct mem_section *section,
unsigned long state, enum mem_add_context context) unsigned long state, enum mem_add_context context)
{ {
...@@ -445,8 +486,11 @@ static int add_memory_block(int nid, struct mem_section *section, ...@@ -445,8 +486,11 @@ static int add_memory_block(int nid, struct mem_section *section,
if (!mem) if (!mem)
return -ENOMEM; return -ENOMEM;
mutex_lock(&mem_sysfs_mutex);
mem->phys_index = __section_nr(section); mem->phys_index = __section_nr(section);
mem->state = state; mem->state = state;
mem->section_count++;
mutex_init(&mem->state_mutex); mutex_init(&mem->state_mutex);
start_pfn = section_nr_to_pfn(mem->phys_index); start_pfn = section_nr_to_pfn(mem->phys_index);
mem->phys_device = arch_get_memory_phys_device(start_pfn); 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, ...@@ -465,53 +509,29 @@ static int add_memory_block(int nid, struct mem_section *section,
ret = register_mem_sect_under_node(mem, nid); ret = register_mem_sect_under_node(mem, nid);
} }
mutex_unlock(&mem_sysfs_mutex);
return ret; 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 remove_memory_block(unsigned long node_id, struct mem_section *section,
int phys_device) int phys_device)
{ {
struct memory_block *mem; struct memory_block *mem;
mutex_lock(&mem_sysfs_mutex);
mem = find_memory_block(section); 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; return 0;
} }
......
...@@ -409,25 +409,27 @@ static int link_mem_sections(int nid) ...@@ -409,25 +409,27 @@ static int link_mem_sections(int nid)
unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
unsigned long pfn; unsigned long pfn;
struct memory_block *mem_blk = NULL;
int err = 0; int err = 0;
for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
unsigned long section_nr = pfn_to_section_nr(pfn); unsigned long section_nr = pfn_to_section_nr(pfn);
struct mem_section *mem_sect; struct mem_section *mem_sect;
struct memory_block *mem_blk;
int ret; int ret;
if (!present_section_nr(section_nr)) if (!present_section_nr(section_nr))
continue; continue;
mem_sect = __nr_to_section(section_nr); 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); ret = register_mem_sect_under_node(mem_blk, nid);
if (!err) if (!err)
err = ret; err = ret;
/* discard ref obtained in find_memory_block() */ /* discard ref obtained in find_memory_block() */
kobject_put(&mem_blk->sysdev.kobj);
} }
if (mem_blk)
kobject_put(&mem_blk->sysdev.kobj);
return err; return err;
} }
......
...@@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev, ...@@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev,
{ {
struct resource *r; struct resource *r;
if (!res)
return 0;
r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
if (r) { if (r) {
pdev->resource = r; pdev->resource = r;
...@@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources); ...@@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
int platform_device_add_data(struct platform_device *pdev, const void *data, int platform_device_add_data(struct platform_device *pdev, const void *data,
size_t size) size_t size)
{ {
void *d = kmemdup(data, size, GFP_KERNEL); void *d;
if (!data)
return 0;
d = kmemdup(data, size, GFP_KERNEL);
if (d) { if (d) {
pdev->dev.platform_data = d; pdev->dev.platform_data = d;
return 0; return 0;
...@@ -373,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata( ...@@ -373,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata(
pdev->dev.parent = parent; pdev->dev.parent = parent;
if (res) { ret = platform_device_add_resources(pdev, res, num);
ret = platform_device_add_resources(pdev, res, num); if (ret)
if (ret) goto err;
goto err;
}
if (data) { ret = platform_device_add_data(pdev, data, size);
ret = platform_device_add_data(pdev, data, size); if (ret)
if (ret) goto err;
goto err;
}
ret = platform_device_add(pdev); ret = platform_device_add(pdev);
if (ret) { if (ret) {
...@@ -488,12 +491,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, ...@@ -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 * if the probe was successful, and make sure any forced probes of
* new devices fail. * 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; drv->probe = NULL;
if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
retval = -ENODEV; retval = -ENODEV;
drv->driver.probe = platform_drv_probe_fail; 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) if (code != retval)
platform_driver_unregister(drv); platform_driver_unregister(drv);
...@@ -530,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle( ...@@ -530,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle(
goto err_out; goto err_out;
} }
if (res) { error = platform_device_add_resources(pdev, res, n_res);
error = platform_device_add_resources(pdev, res, n_res); if (error)
if (error) goto err_pdev_put;
goto err_pdev_put;
}
if (data) { error = platform_device_add_data(pdev, data, size);
error = platform_device_add_data(pdev, data, size); if (error)
if (error) goto err_pdev_put;
goto err_pdev_put;
}
error = platform_device_add(pdev); error = platform_device_add(pdev);
if (error) if (error)
...@@ -976,6 +975,41 @@ struct bus_type platform_bus_type = { ...@@ -976,6 +975,41 @@ struct bus_type platform_bus_type = {
}; };
EXPORT_SYMBOL_GPL(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 __init platform_bus_init(void)
{ {
int error; int error;
......
...@@ -432,13 +432,13 @@ int sysdev_suspend(pm_message_t state) ...@@ -432,13 +432,13 @@ int sysdev_suspend(pm_message_t state)
/* resume current sysdev */ /* resume current sysdev */
cls_driver: cls_driver:
drv = NULL; drv = NULL;
printk(KERN_ERR "Class suspend failed for %s\n", printk(KERN_ERR "Class suspend failed for %s: %d\n",
kobject_name(&sysdev->kobj)); kobject_name(&sysdev->kobj), ret);
aux_driver: aux_driver:
if (drv) if (drv)
printk(KERN_ERR "Class driver suspend failed for %s\n", printk(KERN_ERR "Class driver suspend failed for %s: %d\n",
kobject_name(&sysdev->kobj)); kobject_name(&sysdev->kobj), ret);
list_for_each_entry(err_drv, &cls->drivers, entry) { list_for_each_entry(err_drv, &cls->drivers, entry) {
if (err_drv == drv) if (err_drv == drv)
break; break;
......
...@@ -248,15 +248,15 @@ config CS5535_CLOCK_EVENT_SRC ...@@ -248,15 +248,15 @@ config CS5535_CLOCK_EVENT_SRC
generic PIT, and are suitable for use as high-res timers. generic PIT, and are suitable for use as high-res timers.
config HP_ILO config HP_ILO
tristate "Channel interface driver for HP iLO/iLO2 processor" tristate "Channel interface driver for the HP iLO processor"
depends on PCI depends on PCI
default n default n
help help
The channel interface driver allows applications to communicate The channel interface driver allows applications to communicate
with iLO/iLO2 management processors present on HP ProLiant with iLO management processors present on HP ProLiant servers.
servers. Upon loading, the driver creates /dev/hpilo/dXccbN files, Upon loading, the driver creates /dev/hpilo/dXccbN files, which
which can be used to gather data from the management processor, can be used to gather data from the management processor, via
via read and write system calls. read and write system calls.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called hpilo. module will be called hpilo.
...@@ -390,6 +390,18 @@ config BMP085 ...@@ -390,6 +390,18 @@ config BMP085
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called bmp085. 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/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig" source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig" source "drivers/misc/cb710/Kconfig"
......
...@@ -35,3 +35,4 @@ obj-y += eeprom/ ...@@ -35,3 +35,4 @@ obj-y += eeprom/
obj-y += cb710/ obj-y += cb710/
obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.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. * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* David Altobelli <david.altobelli@hp.com> * David Altobelli <david.altobelli@hp.com>
......
This diff is collapsed.
...@@ -412,9 +412,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) ...@@ -412,9 +412,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
device_initialize(&shost->shost_gendev); device_initialize(&shost->shost_gendev);
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
#ifndef CONFIG_SYSFS_DEPRECATED
shost->shost_gendev.bus = &scsi_bus_type; shost->shost_gendev.bus = &scsi_bus_type;
#endif
shost->shost_gendev.type = &scsi_host_type; shost->shost_gendev.type = &scsi_host_type;
device_initialize(&shost->shost_dev); device_initialize(&shost->shost_dev);
......
...@@ -417,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, ...@@ -417,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
starget->reap_ref = 1; starget->reap_ref = 1;
dev->parent = get_device(parent); dev->parent = get_device(parent);
dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id); dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
#ifndef CONFIG_SYSFS_DEPRECATED
dev->bus = &scsi_bus_type; dev->bus = &scsi_bus_type;
#endif
dev->type = &scsi_target_type; dev->type = &scsi_target_type;
starget->id = id; starget->id = id;
starget->channel = channel; starget->channel = channel;
......
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/cdev.h>
#include <linux/uio_driver.h> #include <linux/uio_driver.h>
#define UIO_MAX_DEVICES 255 #define UIO_MAX_DEVICES (1U << MINORBITS)
struct uio_device { struct uio_device {
struct module *owner; struct module *owner;
...@@ -41,15 +42,10 @@ struct uio_device { ...@@ -41,15 +42,10 @@ struct uio_device {
}; };
static int uio_major; static int uio_major;
static struct cdev *uio_cdev;
static DEFINE_IDR(uio_idr); static DEFINE_IDR(uio_idr);
static const struct file_operations uio_fops; 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 */ /* Protect idr accesses */
static DEFINE_MUTEX(minor_lock); static DEFINE_MUTEX(minor_lock);
...@@ -232,45 +228,34 @@ static ssize_t show_name(struct device *dev, ...@@ -232,45 +228,34 @@ static ssize_t show_name(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct uio_device *idev = dev_get_drvdata(dev); struct uio_device *idev = dev_get_drvdata(dev);
if (idev) return sprintf(buf, "%s\n", idev->info->name);
return sprintf(buf, "%s\n", idev->info->name);
else
return -ENODEV;
} }
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static ssize_t show_version(struct device *dev, static ssize_t show_version(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct uio_device *idev = dev_get_drvdata(dev); struct uio_device *idev = dev_get_drvdata(dev);
if (idev) return sprintf(buf, "%s\n", idev->info->version);
return sprintf(buf, "%s\n", idev->info->version);
else
return -ENODEV;
} }
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
static ssize_t show_event(struct device *dev, static ssize_t show_event(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct uio_device *idev = dev_get_drvdata(dev); struct uio_device *idev = dev_get_drvdata(dev);
if (idev) return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
return sprintf(buf, "%u\n",
(unsigned int)atomic_read(&idev->event));
else
return -ENODEV;
} }
static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
static struct attribute *uio_attrs[] = { static struct device_attribute uio_class_attributes[] = {
&dev_attr_name.attr, __ATTR(name, S_IRUGO, show_name, NULL),
&dev_attr_version.attr, __ATTR(version, S_IRUGO, show_version, NULL),
&dev_attr_event.attr, __ATTR(event, S_IRUGO, show_event, NULL),
NULL, {}
}; };
static struct attribute_group uio_attr_grp = { /* UIO class infrastructure */
.attrs = uio_attrs, 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) ...@@ -287,10 +272,6 @@ static int uio_dev_add_attributes(struct uio_device *idev)
struct uio_port *port; struct uio_port *port;
struct uio_portio *portio; 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++) { for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
mem = &idev->info->mem[mi]; mem = &idev->info->mem[mi];
if (mem->size == 0) if (mem->size == 0)
...@@ -358,8 +339,6 @@ static int uio_dev_add_attributes(struct uio_device *idev) ...@@ -358,8 +339,6 @@ static int uio_dev_add_attributes(struct uio_device *idev)
kobject_put(&map->kobj); kobject_put(&map->kobj);
} }
kobject_put(idev->map_dir); 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); dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
return ret; return ret;
} }
...@@ -385,8 +364,6 @@ static void uio_dev_del_attributes(struct uio_device *idev) ...@@ -385,8 +364,6 @@ static void uio_dev_del_attributes(struct uio_device *idev)
kobject_put(&port->portio->kobj); kobject_put(&port->portio->kobj);
} }
kobject_put(idev->portio_dir); kobject_put(idev->portio_dir);
sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
} }
static int uio_get_minor(struct uio_device *idev) static int uio_get_minor(struct uio_device *idev)
...@@ -525,7 +502,7 @@ static unsigned int uio_poll(struct file *filep, poll_table *wait) ...@@ -525,7 +502,7 @@ static unsigned int uio_poll(struct file *filep, poll_table *wait)
struct uio_listener *listener = filep->private_data; struct uio_listener *listener = filep->private_data;
struct uio_device *idev = listener->dev; struct uio_device *idev = listener->dev;
if (idev->info->irq == UIO_IRQ_NONE) if (!idev->info->irq)
return -EIO; return -EIO;
poll_wait(filep, &idev->wait, wait); poll_wait(filep, &idev->wait, wait);
...@@ -543,7 +520,7 @@ static ssize_t uio_read(struct file *filep, char __user *buf, ...@@ -543,7 +520,7 @@ static ssize_t uio_read(struct file *filep, char __user *buf,
ssize_t retval; ssize_t retval;
s32 event_count; s32 event_count;
if (idev->info->irq == UIO_IRQ_NONE) if (!idev->info->irq)
return -EIO; return -EIO;
if (count != sizeof(s32)) if (count != sizeof(s32))
...@@ -591,7 +568,7 @@ static ssize_t uio_write(struct file *filep, const char __user *buf, ...@@ -591,7 +568,7 @@ static ssize_t uio_write(struct file *filep, const char __user *buf,
ssize_t retval; ssize_t retval;
s32 irq_on; s32 irq_on;
if (idev->info->irq == UIO_IRQ_NONE) if (!idev->info->irq)
return -EIO; return -EIO;
if (count != sizeof(s32)) if (count != sizeof(s32))
...@@ -745,68 +722,72 @@ static const struct file_operations uio_fops = { ...@@ -745,68 +722,72 @@ static const struct file_operations uio_fops = {
static int uio_major_init(void) static int uio_major_init(void)
{ {
uio_major = register_chrdev(0, "uio", &uio_fops); static const char name[] = "uio";
if (uio_major < 0) struct cdev *cdev = NULL;
return uio_major; dev_t uio_dev = 0;
return 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) 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) static int init_uio_class(void)
{ {
int ret = 0; int ret;
if (uio_class != NULL) {
kref_get(&uio_class->kref);
goto exit;
}
/* This is the first time in here, set everything up properly */ /* This is the first time in here, set everything up properly */
ret = uio_major_init(); ret = uio_major_init();
if (ret) if (ret)
goto exit; goto exit;
uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL); ret = class_register(&uio_class);
if (!uio_class) { if (ret) {
ret = -ENOMEM; printk(KERN_ERR "class_register failed for uio\n");
goto err_kzalloc; goto err_class_register;
}
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;
} }
return 0; return 0;
err_class_create: err_class_register:
kfree(uio_class);
uio_class = NULL;
err_kzalloc:
uio_major_cleanup(); uio_major_cleanup();
exit: exit:
return ret; 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_unregister(&uio_class);
class_destroy(uio_class->class);
kfree(uio_class);
uio_major_cleanup(); 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, ...@@ -829,10 +810,6 @@ int __uio_register_device(struct module *owner,
info->uio_dev = NULL; info->uio_dev = NULL;
ret = init_uio_class();
if (ret)
return ret;
idev = kzalloc(sizeof(*idev), GFP_KERNEL); idev = kzalloc(sizeof(*idev), GFP_KERNEL);
if (!idev) { if (!idev) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -848,7 +825,7 @@ int __uio_register_device(struct module *owner, ...@@ -848,7 +825,7 @@ int __uio_register_device(struct module *owner,
if (ret) if (ret)
goto err_get_minor; 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, MKDEV(uio_major, idev->minor), idev,
"uio%d", idev->minor); "uio%d", idev->minor);
if (IS_ERR(idev->dev)) { if (IS_ERR(idev->dev)) {
...@@ -863,9 +840,9 @@ int __uio_register_device(struct module *owner, ...@@ -863,9 +840,9 @@ int __uio_register_device(struct module *owner,
info->uio_dev = idev; info->uio_dev = idev;
if (idev->info->irq >= 0) { if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
ret = request_irq(idev->info->irq, uio_interrupt, ret = request_irq(info->irq, uio_interrupt,
idev->info->irq_flags, idev->info->name, idev); info->irq_flags, info->name, idev);
if (ret) if (ret)
goto err_request_irq; goto err_request_irq;
} }
...@@ -875,13 +852,12 @@ int __uio_register_device(struct module *owner, ...@@ -875,13 +852,12 @@ int __uio_register_device(struct module *owner,
err_request_irq: err_request_irq:
uio_dev_del_attributes(idev); uio_dev_del_attributes(idev);
err_uio_dev_add_attributes: 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: err_device_create:
uio_free_minor(idev); uio_free_minor(idev);
err_get_minor: err_get_minor:
kfree(idev); kfree(idev);
err_kzalloc: err_kzalloc:
uio_class_destroy();
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(__uio_register_device); EXPORT_SYMBOL_GPL(__uio_register_device);
...@@ -902,15 +878,13 @@ void uio_unregister_device(struct uio_info *info) ...@@ -902,15 +878,13 @@ void uio_unregister_device(struct uio_info *info)
uio_free_minor(idev); uio_free_minor(idev);
if (info->irq >= 0) if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
free_irq(info->irq, idev); free_irq(info->irq, idev);
uio_dev_del_attributes(idev); uio_dev_del_attributes(idev);
dev_set_drvdata(idev->dev, NULL); device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
kfree(idev); kfree(idev);
uio_class_destroy();
return; return;
} }
...@@ -918,11 +892,12 @@ EXPORT_SYMBOL_GPL(uio_unregister_device); ...@@ -918,11 +892,12 @@ EXPORT_SYMBOL_GPL(uio_unregister_device);
static int __init uio_init(void) static int __init uio_init(void)
{ {
return 0; return init_uio_class();
} }
static void __exit uio_exit(void) static void __exit uio_exit(void)
{ {
release_uio_class();
} }
module_init(uio_init) module_init(uio_init)
......
...@@ -128,12 +128,6 @@ static int __devinit probe(struct pci_dev *pdev, ...@@ -128,12 +128,6 @@ static int __devinit probe(struct pci_dev *pdev,
struct uio_pci_generic_dev *gdev; struct uio_pci_generic_dev *gdev;
int err; 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); err = pci_enable_device(pdev);
if (err) { if (err) {
dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n", dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
...@@ -141,6 +135,13 @@ static int __devinit probe(struct pci_dev *pdev, ...@@ -141,6 +135,13 @@ static int __devinit probe(struct pci_dev *pdev,
return err; 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); err = verify_pci_2_3(pdev);
if (err) if (err)
goto err_verify; goto err_verify;
......
...@@ -537,14 +537,14 @@ void register_disk(struct gendisk *disk) ...@@ -537,14 +537,14 @@ void register_disk(struct gendisk *disk)
if (device_add(ddev)) if (device_add(ddev))
return; return;
#ifndef CONFIG_SYSFS_DEPRECATED if (!sysfs_deprecated) {
err = sysfs_create_link(block_depr, &ddev->kobj, err = sysfs_create_link(block_depr, &ddev->kobj,
kobject_name(&ddev->kobj)); kobject_name(&ddev->kobj));
if (err) { if (err) {
device_del(ddev); device_del(ddev);
return; return;
}
} }
#endif
disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
...@@ -766,8 +766,7 @@ void del_gendisk(struct gendisk *disk) ...@@ -766,8 +766,7 @@ void del_gendisk(struct gendisk *disk)
kobject_put(disk->part0.holder_dir); kobject_put(disk->part0.holder_dir);
kobject_put(disk->slave_dir); kobject_put(disk->slave_dir);
disk->driverfs_dev = NULL; disk->driverfs_dev = NULL;
#ifndef CONFIG_SYSFS_DEPRECATED if (!sysfs_deprecated)
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
#endif
device_del(disk_to_dev(disk)); device_del(disk_to_dev(disk));
} }
...@@ -179,30 +179,14 @@ static void bin_vma_open(struct vm_area_struct *vma) ...@@ -179,30 +179,14 @@ static void bin_vma_open(struct vm_area_struct *vma)
struct bin_buffer *bb = file->private_data; struct bin_buffer *bb = file->private_data;
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
if (!bb->vm_ops || !bb->vm_ops->open) if (!bb->vm_ops)
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)
return; return;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return; return;
bb->vm_ops->close(vma); if (bb->vm_ops->open)
bb->vm_ops->open(vma);
sysfs_put_active(attr_sd); sysfs_put_active(attr_sd);
} }
...@@ -214,13 +198,15 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -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; struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret; int ret;
if (!bb->vm_ops || !bb->vm_ops->fault) if (!bb->vm_ops)
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return VM_FAULT_SIGBUS; 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); sysfs_put_active(attr_sd);
return ret; return ret;
...@@ -236,13 +222,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -236,13 +222,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
if (!bb->vm_ops) if (!bb->vm_ops)
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
if (!bb->vm_ops->page_mkwrite)
return 0;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return VM_FAULT_SIGBUS; 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); sysfs_put_active(attr_sd);
return ret; return ret;
...@@ -256,13 +241,15 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr, ...@@ -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; struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret; int ret;
if (!bb->vm_ops || !bb->vm_ops->access) if (!bb->vm_ops)
return -EINVAL; return -EINVAL;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return -EINVAL; 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); sysfs_put_active(attr_sd);
return ret; return ret;
...@@ -276,13 +263,15 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new) ...@@ -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; struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret; int ret;
if (!bb->vm_ops || !bb->vm_ops->set_policy) if (!bb->vm_ops)
return 0; return 0;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return -EINVAL; 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); sysfs_put_active(attr_sd);
return ret; return ret;
...@@ -296,13 +285,15 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma, ...@@ -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 sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct mempolicy *pol; struct mempolicy *pol;
if (!bb->vm_ops || !bb->vm_ops->get_policy) if (!bb->vm_ops)
return vma->vm_policy; return vma->vm_policy;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return vma->vm_policy; 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); sysfs_put_active(attr_sd);
return pol; return pol;
...@@ -316,13 +307,15 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from, ...@@ -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; struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret; int ret;
if (!bb->vm_ops || !bb->vm_ops->migrate) if (!bb->vm_ops)
return 0; return 0;
if (!sysfs_get_active(attr_sd)) if (!sysfs_get_active(attr_sd))
return 0; 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); sysfs_put_active(attr_sd);
return ret; return ret;
...@@ -331,7 +324,6 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from, ...@@ -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 = { static const struct vm_operations_struct bin_vm_ops = {
.open = bin_vma_open, .open = bin_vma_open,
.close = bin_vma_close,
.fault = bin_fault, .fault = bin_fault,
.page_mkwrite = bin_page_mkwrite, .page_mkwrite = bin_page_mkwrite,
.access = bin_access, .access = bin_access,
...@@ -377,6 +369,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma) ...@@ -377,6 +369,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
if (bb->mmapped && bb->vm_ops != vma->vm_ops) if (bb->mmapped && bb->vm_ops != vma->vm_ops)
goto out_put; 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; rc = 0;
bb->mmapped = 1; bb->mmapped = 1;
bb->vm_ops = vma->vm_ops; bb->vm_ops = vma->vm_ops;
......
...@@ -751,4 +751,11 @@ do { \ ...@@ -751,4 +751,11 @@ do { \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
#define MODULE_ALIAS_CHARDEV_MAJOR(major) \ #define MODULE_ALIAS_CHARDEV_MAJOR(major) \
MODULE_ALIAS("char-major-" __stringify(major) "-*") MODULE_ALIAS("char-major-" __stringify(major) "-*")
#ifdef CONFIG_SYSFS_DEPRECATED
extern long sysfs_deprecated;
#else
#define sysfs_deprecated 0
#endif
#endif /* _DEVICE_H_ */ #endif /* _DEVICE_H_ */
...@@ -191,6 +191,8 @@ static inline struct kobj_type *get_ktype(struct kobject *kobj) ...@@ -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(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 */ /* The global /sys/kernel/ kobject for people to chain off of */
extern struct kobject *kernel_kobj; extern struct kobject *kernel_kobj;
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
struct memory_block { struct memory_block {
unsigned long phys_index; unsigned long phys_index;
unsigned long state; unsigned long state;
int section_count;
/* /*
* This serializes all state change requests. It isn't * This serializes all state change requests. It isn't
* held during creation because the control files are * held during creation because the control files are
...@@ -113,6 +115,8 @@ extern int memory_dev_init(void); ...@@ -113,6 +115,8 @@ extern int memory_dev_init(void);
extern int remove_memory_block(unsigned long, struct mem_section *, int); extern int remove_memory_block(unsigned long, struct mem_section *, int);
extern int memory_notify(unsigned long val, void *v); extern int memory_notify(unsigned long val, void *v);
extern int memory_isolate_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 *); extern struct memory_block *find_memory_block(struct mem_section *);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
enum mem_add_context { BOOT, HOTPLUG }; enum mem_add_context { BOOT, HOTPLUG };
......
...@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr ...@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
struct resource *res, unsigned int n_res, struct resource *res, unsigned int n_res,
const void *data, size_t size); 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 */ /* early platform driver interface */
struct early_platform_driver { struct early_platform_driver {
const char *class_str; const char *class_str;
......
...@@ -108,7 +108,7 @@ extern void uio_event_notify(struct uio_info *info); ...@@ -108,7 +108,7 @@ extern void uio_event_notify(struct uio_info *info);
/* defines for uio_info->irq */ /* defines for uio_info->irq */
#define UIO_IRQ_CUSTOM -1 #define UIO_IRQ_CUSTOM -1
#define UIO_IRQ_NONE -2 #define UIO_IRQ_NONE 0
/* defines for uio_mem->memtype */ /* defines for uio_mem->memtype */
#define UIO_MEM_NONE 0 #define UIO_MEM_NONE 0
......
...@@ -133,9 +133,7 @@ struct snd_card { ...@@ -133,9 +133,7 @@ struct snd_card {
int free_on_last_close; /* free in context of file_release */ int free_on_last_close; /* free in context of file_release */
wait_queue_head_t shutdown_sleep; wait_queue_head_t shutdown_sleep;
struct device *dev; /* device assigned to this card */ struct device *dev; /* device assigned to this card */
#ifndef CONFIG_SYSFS_DEPRECATED
struct device *card_dev; /* cardX object for sysfs */ struct device *card_dev; /* cardX object for sysfs */
#endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
unsigned int power_state; /* power state */ unsigned int power_state; /* power state */
...@@ -196,11 +194,7 @@ struct snd_minor { ...@@ -196,11 +194,7 @@ struct snd_minor {
/* return a device pointer linked to each sound device as a parent */ /* 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) 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; return card ? card->card_dev : NULL;
#endif
} }
/* sound.c */ /* sound.c */
......
...@@ -686,40 +686,42 @@ config MM_OWNER ...@@ -686,40 +686,42 @@ config MM_OWNER
bool bool
config SYSFS_DEPRECATED config SYSFS_DEPRECATED
bool
config SYSFS_DEPRECATED_V2
bool "enable deprecated sysfs features to support old userspace tools" bool "enable deprecated sysfs features to support old userspace tools"
depends on SYSFS depends on SYSFS
default n default n
select SYSFS_DEPRECATED help
help This option adds code that switches the layout of the "block" class
This option switches the layout of sysfs to the deprecated devices, to not show up in /sys/class/block/, but only in
version. Do not use it on recent distributions. /sys/block/.
The current sysfs layout features a unified device tree at This switch is only active when the sysfs.deprecated=1 boot option is
/sys/devices/, which is able to express a hierarchy between passed or the SYSFS_DEPRECATED_V2 option is set.
class devices. If the deprecated option is set to Y, the
unified device tree is split into a bus device tree at This option allows new kernels to run on old distributions and tools,
/sys/devices/ and several individual class device trees at which might get confused by /sys/class/block/. Since 2007/2008 all
/sys/class/. The class and bus devices will be connected by major distributions and tools handle this just fine.
"<subsystem>:<name>" and the "device" links. The "block"
class devices, will not show up in /sys/class/block/. Some Recent distributions and userspace tools after 2009/2010 depend on
subsystems will suppress the creation of some devices which the existence of /sys/class/block/, and will not work with this
depend on the unified device tree. option enabled.
This option is not a pure compatibility option that can Only if you are using a new kernel on an old distribution, you might
be safely enabled on newer distributions. It will change the need to say Y here.
layout of sysfs to the non-extensible deprecated version,
and disable some features, which can not be exported without config SYSFS_DEPRECATED_V2
confusing older userspace tools. Since 2007/2008 all major bool "enabled deprecated sysfs features by default"
distributions do not enable this option, and ship no tools which default n
depend on the deprecated layout or this option. depends on SYSFS
depends on SYSFS_DEPRECATED
If you are using a new kernel on an older distribution, or use help
older userspace tools, you might need to say Y here. Do not say Y, Enable deprecated sysfs by default.
if the original kernel, that came with your distribution, has
this option set to N. 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 config RELAY
bool "Kernel->user space relay support (formerly relayfs)" bool "Kernel->user space relay support (formerly relayfs)"
......
...@@ -393,6 +393,40 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, ...@@ -393,6 +393,40 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
return 0; 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 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
* command text from userspace, parses and executes it. * command text from userspace, parses and executes it.
...@@ -400,12 +434,8 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, ...@@ -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, static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp) 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]; char tmpbuf[256];
int ret;
if (len == 0) if (len == 0)
return 0; return 0;
...@@ -419,16 +449,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, ...@@ -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", printk(KERN_INFO "%s: read %d bytes from userspace\n",
__func__, (int)len); __func__, (int)len);
nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS); ret = ddebug_exec_query(tmpbuf);
if (nwords <= 0) if (ret)
return -EINVAL; return ret;
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);
*offp += len; *offp += len;
return len; return len;
...@@ -689,13 +712,14 @@ static void ddebug_remove_all_tables(void) ...@@ -689,13 +712,14 @@ static void ddebug_remove_all_tables(void)
mutex_unlock(&ddebug_lock); 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 dentry *dir, *file;
struct _ddebug *iter, *iter_start;
const char *modname = NULL; if (!ddebug_init_success)
int ret = 0; return -ENODEV;
int n = 0;
dir = debugfs_create_dir("dynamic_debug", NULL); dir = debugfs_create_dir("dynamic_debug", NULL);
if (!dir) if (!dir)
...@@ -706,6 +730,16 @@ static int __init dynamic_debug_init(void) ...@@ -706,6 +730,16 @@ static int __init dynamic_debug_init(void)
debugfs_remove(dir); debugfs_remove(dir);
return -ENOMEM; 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) { if (__start___verbose != __stop___verbose) {
iter = __start___verbose; iter = __start___verbose;
modname = iter->modname; modname = iter->modname;
...@@ -723,12 +757,26 @@ static int __init dynamic_debug_init(void) ...@@ -723,12 +757,26 @@ static int __init dynamic_debug_init(void)
} }
ret = ddebug_add_module(iter_start, n, modname); 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: out_free:
if (ret) { if (ret)
ddebug_remove_all_tables(); ddebug_remove_all_tables();
debugfs_remove(dir); else
debugfs_remove(file); ddebug_init_success = 1;
}
return 0; 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) ...@@ -745,18 +745,57 @@ void kset_unregister(struct kset *k)
* take a reference and return the object. * take a reference and return the object.
*/ */
struct kobject *kset_find_obj(struct kset *kset, const char *name) 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 *k;
struct kobject *ret = NULL; struct kobject *ret = NULL;
spin_lock(&kset->list_lock); 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) { list_for_each_entry(k, &kset->list, entry) {
if (kobject_name(k) && !strcmp(kobject_name(k), name)) { if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
ret = kobject_get(k); ret = kobject_get(k);
break; break;
} }
} }
unlock_exit:
spin_unlock(&kset->list_lock); spin_unlock(&kset->list_lock);
if (hint)
kobject_put(hint);
return ret; return ret;
} }
......
...@@ -395,12 +395,10 @@ int snd_card_disconnect(struct snd_card *card) ...@@ -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_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
snd_info_card_disconnect(card); snd_info_card_disconnect(card);
#ifndef CONFIG_SYSFS_DEPRECATED
if (card->card_dev) { if (card->card_dev) {
device_unregister(card->card_dev); device_unregister(card->card_dev);
card->card_dev = NULL; card->card_dev = NULL;
} }
#endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
wake_up(&card->power_sleep); wake_up(&card->power_sleep);
#endif #endif
...@@ -573,7 +571,6 @@ void snd_card_set_id(struct snd_card *card, const char *nid) ...@@ -573,7 +571,6 @@ void snd_card_set_id(struct snd_card *card, const char *nid)
} }
EXPORT_SYMBOL(snd_card_set_id); EXPORT_SYMBOL(snd_card_set_id);
#ifndef CONFIG_SYSFS_DEPRECATED
static ssize_t static ssize_t
card_id_show_attr(struct device *dev, card_id_show_attr(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
...@@ -630,7 +627,6 @@ card_number_show_attr(struct device *dev, ...@@ -630,7 +627,6 @@ card_number_show_attr(struct device *dev,
static struct device_attribute card_number_attrs = static struct device_attribute card_number_attrs =
__ATTR(number, S_IRUGO, card_number_show_attr, NULL); __ATTR(number, S_IRUGO, card_number_show_attr, NULL);
#endif /* CONFIG_SYSFS_DEPRECATED */
/** /**
* snd_card_register - register the soundcard * snd_card_register - register the soundcard
...@@ -649,7 +645,7 @@ int snd_card_register(struct snd_card *card) ...@@ -649,7 +645,7 @@ int snd_card_register(struct snd_card *card)
if (snd_BUG_ON(!card)) if (snd_BUG_ON(!card))
return -EINVAL; return -EINVAL;
#ifndef CONFIG_SYSFS_DEPRECATED
if (!card->card_dev) { if (!card->card_dev) {
card->card_dev = device_create(sound_class, card->dev, card->card_dev = device_create(sound_class, card->dev,
MKDEV(0, 0), card, MKDEV(0, 0), card,
...@@ -657,7 +653,7 @@ int snd_card_register(struct snd_card *card) ...@@ -657,7 +653,7 @@ int snd_card_register(struct snd_card *card)
if (IS_ERR(card->card_dev)) if (IS_ERR(card->card_dev))
card->card_dev = NULL; card->card_dev = NULL;
} }
#endif
if ((err = snd_device_register_all(card)) < 0) if ((err = snd_device_register_all(card)) < 0)
return err; return err;
mutex_lock(&snd_card_mutex); mutex_lock(&snd_card_mutex);
...@@ -674,7 +670,6 @@ int snd_card_register(struct snd_card *card) ...@@ -674,7 +670,6 @@ int snd_card_register(struct snd_card *card)
if (snd_mixer_oss_notify_callback) if (snd_mixer_oss_notify_callback)
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
#endif #endif
#ifndef CONFIG_SYSFS_DEPRECATED
if (card->card_dev) { if (card->card_dev) {
err = device_create_file(card->card_dev, &card_id_attrs); err = device_create_file(card->card_dev, &card_id_attrs);
if (err < 0) if (err < 0)
...@@ -683,7 +678,7 @@ int snd_card_register(struct snd_card *card) ...@@ -683,7 +678,7 @@ int snd_card_register(struct snd_card *card)
if (err < 0) if (err < 0)
return err; return err;
} }
#endif
return 0; return 0;
} }
......
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