mirror of https://gitee.com/openkylin/linux.git
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 ...
This commit is contained in:
commit
b9da057105
|
@ -0,0 +1,12 @@
|
|||
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,
|
||||
"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;
|
||||
}
|
||||
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
|
||||
/* 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;
|
||||
|
||||
if (dev->parent && device_is_not_partition(dev)) {
|
||||
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
|
||||
"device");
|
||||
if (error)
|
||||
goto out_busid;
|
||||
goto out_subsys;
|
||||
}
|
||||
|
||||
#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_device;
|
||||
|
||||
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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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>
|
||||
|
|
|
@ -0,0 +1,717 @@
|
|||
/*
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#define PHUB_STATUS 0x00 /* Status Register offset */
|
||||
#define PHUB_CONTROL 0x04 /* Control Register offset */
|
||||
#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
|
||||
#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
|
||||
#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
|
||||
#define PCH_PHUB_ROM_START_ADDR 0x14 /* ROM data area start address offset */
|
||||
|
||||
/* MAX number of INT_REDUCE_CONTROL registers */
|
||||
#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
|
||||
#define PCI_DEVICE_ID_PCH1_PHUB 0x8801
|
||||
#define PCH_MINOR_NOS 1
|
||||
#define CLKCFG_CAN_50MHZ 0x12000000
|
||||
#define CLKCFG_CANCLK_MASK 0xFF000000
|
||||
|
||||
/* SROM ACCESS Macro */
|
||||
#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
|
||||
|
||||
/* Registers address offset */
|
||||
#define PCH_PHUB_ID_REG 0x0000
|
||||
#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004
|
||||
#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008
|
||||
#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C
|
||||
#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010
|
||||
#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014
|
||||
#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018
|
||||
#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020
|
||||
#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024
|
||||
#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028
|
||||
#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C
|
||||
#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040
|
||||
#define CLKCFG_REG_OFFSET 0x500
|
||||
|
||||
#define PCH_PHUB_OROM_SIZE 15360
|
||||
|
||||
/**
|
||||
* struct pch_phub_reg - PHUB register structure
|
||||
* @phub_id_reg: PHUB_ID register val
|
||||
* @q_pri_val_reg: QUEUE_PRI_VAL register val
|
||||
* @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val
|
||||
* @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val
|
||||
* @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val
|
||||
* @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val
|
||||
* @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val
|
||||
* @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val
|
||||
* @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val
|
||||
* @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val
|
||||
* @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val
|
||||
* @int_reduce_control_reg: INT_REDUCE_CONTROL registers val
|
||||
* @clkcfg_reg: CLK CFG register val
|
||||
* @pch_phub_base_address: Register base address
|
||||
* @pch_phub_extrom_base_address: external rom base address
|
||||
*/
|
||||
struct pch_phub_reg {
|
||||
u32 phub_id_reg;
|
||||
u32 q_pri_val_reg;
|
||||
u32 rc_q_maxsize_reg;
|
||||
u32 bri_q_maxsize_reg;
|
||||
u32 comp_resp_timeout_reg;
|
||||
u32 bus_slave_control_reg;
|
||||
u32 deadlock_avoid_type_reg;
|
||||
u32 intpin_reg_wpermit_reg0;
|
||||
u32 intpin_reg_wpermit_reg1;
|
||||
u32 intpin_reg_wpermit_reg2;
|
||||
u32 intpin_reg_wpermit_reg3;
|
||||
u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
|
||||
u32 clkcfg_reg;
|
||||
void __iomem *pch_phub_base_address;
|
||||
void __iomem *pch_phub_extrom_base_address;
|
||||
};
|
||||
|
||||
/* SROM SPEC for MAC address assignment offset */
|
||||
static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa};
|
||||
|
||||
static DEFINE_MUTEX(pch_phub_mutex);
|
||||
|
||||
/**
|
||||
* pch_phub_read_modify_write_reg() - Reading modifying and writing register
|
||||
* @reg_addr_offset: Register offset address value.
|
||||
* @data: Writing value.
|
||||
* @mask: Mask value.
|
||||
*/
|
||||
static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip,
|
||||
unsigned int reg_addr_offset,
|
||||
unsigned int data, unsigned int mask)
|
||||
{
|
||||
void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset;
|
||||
iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
|
||||
}
|
||||
|
||||
/* pch_phub_save_reg_conf - saves register configuration */
|
||||
static void pch_phub_save_reg_conf(struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int i;
|
||||
struct pch_phub_reg *chip = pci_get_drvdata(pdev);
|
||||
|
||||
void __iomem *p = chip->pch_phub_base_address;
|
||||
|
||||
chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG);
|
||||
chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
|
||||
chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
|
||||
chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
|
||||
chip->comp_resp_timeout_reg =
|
||||
ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
|
||||
chip->bus_slave_control_reg =
|
||||
ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
|
||||
chip->deadlock_avoid_type_reg =
|
||||
ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
|
||||
chip->intpin_reg_wpermit_reg0 =
|
||||
ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
|
||||
chip->intpin_reg_wpermit_reg1 =
|
||||
ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
|
||||
chip->intpin_reg_wpermit_reg2 =
|
||||
ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
|
||||
chip->intpin_reg_wpermit_reg3 =
|
||||
ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"chip->phub_id_reg=%x, "
|
||||
"chip->q_pri_val_reg=%x, "
|
||||
"chip->rc_q_maxsize_reg=%x, "
|
||||
"chip->bri_q_maxsize_reg=%x, "
|
||||
"chip->comp_resp_timeout_reg=%x, "
|
||||
"chip->bus_slave_control_reg=%x, "
|
||||
"chip->deadlock_avoid_type_reg=%x, "
|
||||
"chip->intpin_reg_wpermit_reg0=%x, "
|
||||
"chip->intpin_reg_wpermit_reg1=%x, "
|
||||
"chip->intpin_reg_wpermit_reg2=%x, "
|
||||
"chip->intpin_reg_wpermit_reg3=%x\n", __func__,
|
||||
chip->phub_id_reg,
|
||||
chip->q_pri_val_reg,
|
||||
chip->rc_q_maxsize_reg,
|
||||
chip->bri_q_maxsize_reg,
|
||||
chip->comp_resp_timeout_reg,
|
||||
chip->bus_slave_control_reg,
|
||||
chip->deadlock_avoid_type_reg,
|
||||
chip->intpin_reg_wpermit_reg0,
|
||||
chip->intpin_reg_wpermit_reg1,
|
||||
chip->intpin_reg_wpermit_reg2,
|
||||
chip->intpin_reg_wpermit_reg3);
|
||||
for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
|
||||
chip->int_reduce_control_reg[i] =
|
||||
ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"chip->int_reduce_control_reg[%d]=%x\n",
|
||||
__func__, i, chip->int_reduce_control_reg[i]);
|
||||
}
|
||||
chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
|
||||
}
|
||||
|
||||
/* pch_phub_restore_reg_conf - restore register configuration */
|
||||
static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int i;
|
||||
struct pch_phub_reg *chip = pci_get_drvdata(pdev);
|
||||
void __iomem *p;
|
||||
p = chip->pch_phub_base_address;
|
||||
|
||||
iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG);
|
||||
iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
|
||||
iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
|
||||
iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
|
||||
iowrite32(chip->comp_resp_timeout_reg,
|
||||
p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
|
||||
iowrite32(chip->bus_slave_control_reg,
|
||||
p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
|
||||
iowrite32(chip->deadlock_avoid_type_reg,
|
||||
p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
|
||||
iowrite32(chip->intpin_reg_wpermit_reg0,
|
||||
p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
|
||||
iowrite32(chip->intpin_reg_wpermit_reg1,
|
||||
p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
|
||||
iowrite32(chip->intpin_reg_wpermit_reg2,
|
||||
p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
|
||||
iowrite32(chip->intpin_reg_wpermit_reg3,
|
||||
p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"chip->phub_id_reg=%x, "
|
||||
"chip->q_pri_val_reg=%x, "
|
||||
"chip->rc_q_maxsize_reg=%x, "
|
||||
"chip->bri_q_maxsize_reg=%x, "
|
||||
"chip->comp_resp_timeout_reg=%x, "
|
||||
"chip->bus_slave_control_reg=%x, "
|
||||
"chip->deadlock_avoid_type_reg=%x, "
|
||||
"chip->intpin_reg_wpermit_reg0=%x, "
|
||||
"chip->intpin_reg_wpermit_reg1=%x, "
|
||||
"chip->intpin_reg_wpermit_reg2=%x, "
|
||||
"chip->intpin_reg_wpermit_reg3=%x\n", __func__,
|
||||
chip->phub_id_reg,
|
||||
chip->q_pri_val_reg,
|
||||
chip->rc_q_maxsize_reg,
|
||||
chip->bri_q_maxsize_reg,
|
||||
chip->comp_resp_timeout_reg,
|
||||
chip->bus_slave_control_reg,
|
||||
chip->deadlock_avoid_type_reg,
|
||||
chip->intpin_reg_wpermit_reg0,
|
||||
chip->intpin_reg_wpermit_reg1,
|
||||
chip->intpin_reg_wpermit_reg2,
|
||||
chip->intpin_reg_wpermit_reg3);
|
||||
for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
|
||||
iowrite32(chip->int_reduce_control_reg[i],
|
||||
p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"chip->int_reduce_control_reg[%d]=%x\n",
|
||||
__func__, i, chip->int_reduce_control_reg[i]);
|
||||
}
|
||||
|
||||
iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_read_serial_rom() - Reading Serial ROM
|
||||
* @offset_address: Serial ROM offset address to read.
|
||||
* @data: Read buffer for specified Serial ROM value.
|
||||
*/
|
||||
static void pch_phub_read_serial_rom(struct pch_phub_reg *chip,
|
||||
unsigned int offset_address, u8 *data)
|
||||
{
|
||||
void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
|
||||
offset_address;
|
||||
|
||||
*data = ioread8(mem_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_write_serial_rom() - Writing Serial ROM
|
||||
* @offset_address: Serial ROM offset address.
|
||||
* @data: Serial ROM value to write.
|
||||
*/
|
||||
static int pch_phub_write_serial_rom(struct pch_phub_reg *chip,
|
||||
unsigned int offset_address, u8 data)
|
||||
{
|
||||
void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
|
||||
(offset_address & PCH_WORD_ADDR_MASK);
|
||||
int i;
|
||||
unsigned int word_data;
|
||||
unsigned int pos;
|
||||
unsigned int mask;
|
||||
pos = (offset_address % 4) * 8;
|
||||
mask = ~(0xFF << pos);
|
||||
|
||||
iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
|
||||
chip->pch_phub_extrom_base_address + PHUB_CONTROL);
|
||||
|
||||
word_data = ioread32(mem_addr);
|
||||
iowrite32((word_data & mask) | (u32)data << pos, mem_addr);
|
||||
|
||||
i = 0;
|
||||
while (ioread8(chip->pch_phub_extrom_base_address +
|
||||
PHUB_STATUS) != 0x00) {
|
||||
msleep(1);
|
||||
if (i == PHUB_TIMEOUT)
|
||||
return -ETIMEDOUT;
|
||||
i++;
|
||||
}
|
||||
|
||||
iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
|
||||
chip->pch_phub_extrom_base_address + PHUB_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_read_serial_rom_val() - Read Serial ROM value
|
||||
* @offset_address: Serial ROM address offset value.
|
||||
* @data: Serial ROM value to read.
|
||||
*/
|
||||
static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
|
||||
unsigned int offset_address, u8 *data)
|
||||
{
|
||||
unsigned int mem_addr;
|
||||
|
||||
mem_addr = PCH_PHUB_ROM_START_ADDR +
|
||||
pch_phub_mac_offset[offset_address];
|
||||
|
||||
pch_phub_read_serial_rom(chip, mem_addr, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_write_serial_rom_val() - writing Serial ROM value
|
||||
* @offset_address: Serial ROM address offset value.
|
||||
* @data: Serial ROM value.
|
||||
*/
|
||||
static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
|
||||
unsigned int offset_address, u8 data)
|
||||
{
|
||||
int retval;
|
||||
unsigned int mem_addr;
|
||||
|
||||
mem_addr = PCH_PHUB_ROM_START_ADDR +
|
||||
pch_phub_mac_offset[offset_address];
|
||||
|
||||
retval = pch_phub_write_serial_rom(chip, mem_addr, data);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
|
||||
* for Gigabit Ethernet MAC address
|
||||
*/
|
||||
static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
|
||||
* @offset_address: Gigabit Ethernet MAC address offset value.
|
||||
* @data: Buffer of the Gigabit Ethernet MAC address value.
|
||||
*/
|
||||
static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
pch_phub_read_serial_rom_val(chip, i, &data[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_write_gbe_mac_addr() - Write MAC address
|
||||
* @offset_address: Gigabit Ethernet MAC address offset value.
|
||||
* @data: Gigabit Ethernet MAC address value.
|
||||
*/
|
||||
static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
|
||||
{
|
||||
int retval;
|
||||
int i;
|
||||
|
||||
retval = pch_phub_gbe_serial_rom_conf(chip);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
retval = pch_phub_write_serial_rom_val(chip, i, data[i]);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
unsigned int rom_signature;
|
||||
unsigned char rom_length;
|
||||
unsigned int tmp;
|
||||
unsigned int addr_offset;
|
||||
unsigned int orom_size;
|
||||
int ret;
|
||||
int err;
|
||||
|
||||
struct pch_phub_reg *chip =
|
||||
dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
|
||||
ret = mutex_lock_interruptible(&pch_phub_mutex);
|
||||
if (ret) {
|
||||
err = -ERESTARTSYS;
|
||||
goto return_err_nomutex;
|
||||
}
|
||||
|
||||
/* Get Rom signature */
|
||||
pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature);
|
||||
rom_signature &= 0xff;
|
||||
pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp);
|
||||
rom_signature |= (tmp & 0xff) << 8;
|
||||
if (rom_signature == 0xAA55) {
|
||||
pch_phub_read_serial_rom(chip, 0x82, &rom_length);
|
||||
orom_size = rom_length * 512;
|
||||
if (orom_size < off) {
|
||||
addr_offset = 0;
|
||||
goto return_ok;
|
||||
}
|
||||
if (orom_size < count) {
|
||||
addr_offset = 0;
|
||||
goto return_ok;
|
||||
}
|
||||
|
||||
for (addr_offset = 0; addr_offset < count; addr_offset++) {
|
||||
pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off,
|
||||
&buf[addr_offset]);
|
||||
}
|
||||
} else {
|
||||
err = -ENODATA;
|
||||
goto return_err;
|
||||
}
|
||||
return_ok:
|
||||
mutex_unlock(&pch_phub_mutex);
|
||||
return addr_offset;
|
||||
|
||||
return_err:
|
||||
mutex_unlock(&pch_phub_mutex);
|
||||
return_err_nomutex:
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
int err;
|
||||
unsigned int addr_offset;
|
||||
int ret;
|
||||
struct pch_phub_reg *chip =
|
||||
dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
|
||||
ret = mutex_lock_interruptible(&pch_phub_mutex);
|
||||
if (ret)
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (off > PCH_PHUB_OROM_SIZE) {
|
||||
addr_offset = 0;
|
||||
goto return_ok;
|
||||
}
|
||||
if (count > PCH_PHUB_OROM_SIZE) {
|
||||
addr_offset = 0;
|
||||
goto return_ok;
|
||||
}
|
||||
|
||||
for (addr_offset = 0; addr_offset < count; addr_offset++) {
|
||||
if (PCH_PHUB_OROM_SIZE < off + addr_offset)
|
||||
goto return_ok;
|
||||
|
||||
ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off,
|
||||
buf[addr_offset]);
|
||||
if (ret) {
|
||||
err = ret;
|
||||
goto return_err;
|
||||
}
|
||||
}
|
||||
|
||||
return_ok:
|
||||
mutex_unlock(&pch_phub_mutex);
|
||||
return addr_offset;
|
||||
|
||||
return_err:
|
||||
mutex_unlock(&pch_phub_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
u8 mac[8];
|
||||
struct pch_phub_reg *chip = dev_get_drvdata(dev);
|
||||
|
||||
pch_phub_read_gbe_mac_addr(chip, mac);
|
||||
|
||||
return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
u8 mac[6];
|
||||
struct pch_phub_reg *chip = dev_get_drvdata(dev);
|
||||
|
||||
if (count != 18)
|
||||
return -EINVAL;
|
||||
|
||||
sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
|
||||
(u32 *)&mac[4], (u32 *)&mac[5]);
|
||||
|
||||
pch_phub_write_gbe_mac_addr(chip, mac);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac);
|
||||
|
||||
static struct bin_attribute pch_bin_attr = {
|
||||
.attr = {
|
||||
.name = "pch_firmware",
|
||||
.mode = S_IRUGO | S_IWUSR,
|
||||
},
|
||||
.size = PCH_PHUB_OROM_SIZE + 1,
|
||||
.read = pch_phub_bin_read,
|
||||
.write = pch_phub_bin_write,
|
||||
};
|
||||
|
||||
static int __devinit pch_phub_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
int retval;
|
||||
|
||||
int ret;
|
||||
ssize_t rom_size;
|
||||
struct pch_phub_reg *chip;
|
||||
|
||||
chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
|
||||
if (chip == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s : pci_enable_device FAILED(ret=%d)", __func__, ret);
|
||||
goto err_pci_enable_dev;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__,
|
||||
ret);
|
||||
|
||||
ret = pci_request_regions(pdev, KBUILD_MODNAME);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s : pci_request_regions FAILED(ret=%d)", __func__, ret);
|
||||
goto err_req_regions;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"pci_request_regions returns %d\n", __func__, ret);
|
||||
|
||||
chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
|
||||
|
||||
|
||||
if (chip->pch_phub_base_address == 0) {
|
||||
dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_pci_iomap;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
|
||||
"in pch_phub_base_address variable is %p\n", __func__,
|
||||
chip->pch_phub_base_address);
|
||||
chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
|
||||
|
||||
if (chip->pch_phub_extrom_base_address == 0) {
|
||||
dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_pci_map;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"pci_map_rom SUCCESS and value in "
|
||||
"pch_phub_extrom_base_address variable is %p\n", __func__,
|
||||
chip->pch_phub_extrom_base_address);
|
||||
|
||||
pci_set_drvdata(pdev, chip);
|
||||
|
||||
retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
|
||||
if (retval)
|
||||
goto err_sysfs_create;
|
||||
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
|
||||
if (retval)
|
||||
goto exit_bin_attr;
|
||||
|
||||
pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET,
|
||||
CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK);
|
||||
|
||||
/* set the prefech value */
|
||||
iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
|
||||
/* set the interrupt delay value */
|
||||
iowrite32(0x25, chip->pch_phub_base_address + 0x44);
|
||||
|
||||
return 0;
|
||||
exit_bin_attr:
|
||||
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
|
||||
|
||||
err_sysfs_create:
|
||||
pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
|
||||
err_pci_map:
|
||||
pci_iounmap(pdev, chip->pch_phub_base_address);
|
||||
err_pci_iomap:
|
||||
pci_release_regions(pdev);
|
||||
err_req_regions:
|
||||
pci_disable_device(pdev);
|
||||
err_pci_enable_dev:
|
||||
kfree(chip);
|
||||
dev_err(&pdev->dev, "%s returns %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __devexit pch_phub_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct pch_phub_reg *chip = pci_get_drvdata(pdev);
|
||||
|
||||
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
|
||||
pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
|
||||
pci_iounmap(pdev, chip->pch_phub_base_address);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pch_phub_save_reg_conf(pdev);
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
" %s -pci_save_state returns %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch_phub_resume(struct pci_dev *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s-pci_enable_device failed(ret=%d) ", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pch_phub_restore_reg_conf(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define pch_phub_suspend NULL
|
||||
#define pch_phub_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_device_id pch_phub_pcidev_id[] = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)},
|
||||
{0,}
|
||||
};
|
||||
|
||||
static struct pci_driver pch_phub_driver = {
|
||||
.name = "pch_phub",
|
||||
.id_table = pch_phub_pcidev_id,
|
||||
.probe = pch_phub_probe,
|
||||
.remove = __devexit_p(pch_phub_remove),
|
||||
.suspend = pch_phub_suspend,
|
||||
.resume = pch_phub_resume
|
||||
};
|
||||
|
||||
static int __init pch_phub_pci_init(void)
|
||||
{
|
||||
return pci_register_driver(&pch_phub_driver);
|
||||
}
|
||||
|
||||
static void __exit pch_phub_pci_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&pch_phub_driver);
|
||||
}
|
||||
|
||||
module_init(pch_phub_pci_init);
|
||||
module_exit(pch_phub_pci_exit);
|
||||
|
||||
MODULE_DESCRIPTION("PCH Packet Hub PCI Driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -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)
|
||||
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;
|
||||
|
||||
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 */
|
||||
|
|
56
init/Kconfig
56
init/Kconfig
|
@ -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.
|
||||
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/.
|
||||
|
||||
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 switch is only active when the sysfs.deprecated=1 boot option is
|
||||
passed or the SYSFS_DEPRECATED_V2 option is set.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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);
|
||||
}
|
||||
out_free:
|
||||
if (ret) {
|
||||
ddebug_remove_all_tables();
|
||||
debugfs_remove(dir);
|
||||
debugfs_remove(file);
|
||||
|
||||
/* 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)
|
||||
ddebug_remove_all_tables();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue