diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 22:36:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 22:36:42 -0400 |
| commit | b9da0571050c09863e59f94d0b8594a290d61b88 (patch) | |
| tree | 3632c4fee768db9a27a5c872bd42133692e2f3d0 | |
| parent | f8cae0f03f75adb54b1d48ddbc90f84a1f5de186 (diff) | |
| parent | 5abd935661e01289ba143c3b2c1ba300c65bcc5f (diff) | |
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
...
34 files changed, 1238 insertions, 516 deletions
diff --git a/Documentation/ABI/testing/sysfs-module b/Documentation/ABI/testing/sysfs-module new file mode 100644 index 000000000000..cfcec3bffc0a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-module | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | What: /sys/module/pch_phub/drivers/.../pch_mac | ||
| 2 | Date: August 2010 | ||
| 3 | KernelVersion: 2.6.35 | ||
| 4 | Contact: masa-korg@dsn.okisemi.com | ||
| 5 | Description: Write/read GbE MAC address. | ||
| 6 | |||
| 7 | What: /sys/module/pch_phub/drivers/.../pch_firmware | ||
| 8 | Date: August 2010 | ||
| 9 | KernelVersion: 2.6.35 | ||
| 10 | Contact: masa-korg@dsn.okisemi.com | ||
| 11 | Description: Write/read Option ROM data. | ||
| 12 | |||
diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt index 674c5663d346..58ea64a96165 100644 --- a/Documentation/dynamic-debug-howto.txt +++ b/Documentation/dynamic-debug-howto.txt | |||
| @@ -24,7 +24,7 @@ Dynamic debug has even more useful features: | |||
| 24 | read to display the complete list of known debug statements, to help guide you | 24 | read to display the complete list of known debug statements, to help guide you |
| 25 | 25 | ||
| 26 | Controlling dynamic debug Behaviour | 26 | Controlling dynamic debug Behaviour |
| 27 | =============================== | 27 | =================================== |
| 28 | 28 | ||
| 29 | The behaviour of pr_debug()/dev_debug()s are controlled via writing to a | 29 | The behaviour of pr_debug()/dev_debug()s are controlled via writing to a |
| 30 | control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs | 30 | 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 | Note also that there is no convenient syntax to remove all | 212 | Note also that there is no convenient syntax to remove all |
| 213 | the flags at once, you need to use "-psc". | 213 | the flags at once, you need to use "-psc". |
| 214 | 214 | ||
| 215 | |||
| 216 | Debug messages during boot process | ||
| 217 | ================================== | ||
| 218 | |||
| 219 | To be able to activate debug messages during the boot process, | ||
| 220 | even before userspace and debugfs exists, use the boot parameter: | ||
| 221 | ddebug_query="QUERY" | ||
| 222 | |||
| 223 | QUERY follows the syntax described above, but must not exceed 1023 | ||
| 224 | characters. The enablement of debug messages is done as an arch_initcall. | ||
| 225 | Thus you can enable debug messages in all code processed after this | ||
| 226 | arch_initcall via this boot parameter. | ||
| 227 | On an x86 system for example ACPI enablement is a subsys_initcall and | ||
| 228 | ddebug_query="file ec.c +p" | ||
| 229 | will show early Embedded Controller transactions during ACPI setup if | ||
| 230 | your machine (typically a laptop) has an Embedded Controller. | ||
| 231 | PCI (or other devices) initialization also is a hot candidate for using | ||
| 232 | this boot parameter for debugging purposes. | ||
| 233 | |||
| 234 | |||
| 215 | Examples | 235 | Examples |
| 216 | ======== | 236 | ======== |
| 217 | 237 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 02f21d9220ce..4cd8b86e00ea 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -43,10 +43,11 @@ parameter is applicable: | |||
| 43 | AVR32 AVR32 architecture is enabled. | 43 | AVR32 AVR32 architecture is enabled. |
| 44 | AX25 Appropriate AX.25 support is enabled. | 44 | AX25 Appropriate AX.25 support is enabled. |
| 45 | BLACKFIN Blackfin architecture is enabled. | 45 | BLACKFIN Blackfin architecture is enabled. |
| 46 | DRM Direct Rendering Management support is enabled. | ||
| 47 | EDD BIOS Enhanced Disk Drive Services (EDD) is enabled | 46 | EDD BIOS Enhanced Disk Drive Services (EDD) is enabled |
| 48 | EFI EFI Partitioning (GPT) is enabled | 47 | EFI EFI Partitioning (GPT) is enabled |
| 49 | EIDE EIDE/ATAPI support is enabled. | 48 | EIDE EIDE/ATAPI support is enabled. |
| 49 | DRM Direct Rendering Management support is enabled. | ||
| 50 | DYNAMIC_DEBUG Build in debug messages and enable them at runtime | ||
| 50 | FB The frame buffer device is enabled. | 51 | FB The frame buffer device is enabled. |
| 51 | GCOV GCOV profiling is enabled. | 52 | GCOV GCOV profiling is enabled. |
| 52 | HW Appropriate hardware is enabled. | 53 | HW Appropriate hardware is enabled. |
| @@ -570,6 +571,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 570 | Format: <port#>,<type> | 571 | Format: <port#>,<type> |
| 571 | See also Documentation/input/joystick-parport.txt | 572 | See also Documentation/input/joystick-parport.txt |
| 572 | 573 | ||
| 574 | ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot | ||
| 575 | time. See Documentation/dynamic-debug-howto.txt for | ||
| 576 | details. | ||
| 577 | |||
| 573 | debug [KNL] Enable kernel debugging (events log level). | 578 | debug [KNL] Enable kernel debugging (events log level). |
| 574 | 579 | ||
| 575 | debug_locks_verbose= | 580 | debug_locks_verbose= |
| @@ -2370,6 +2375,15 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 2370 | 2375 | ||
| 2371 | switches= [HW,M68k] | 2376 | switches= [HW,M68k] |
| 2372 | 2377 | ||
| 2378 | sysfs.deprecated=0|1 [KNL] | ||
| 2379 | Enable/disable old style sysfs layout for old udev | ||
| 2380 | on older distributions. When this option is enabled | ||
| 2381 | very new udev will not work anymore. When this option | ||
| 2382 | is disabled (or CONFIG_SYSFS_DEPRECATED not compiled) | ||
| 2383 | in older udev will not work anymore. | ||
| 2384 | Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in | ||
| 2385 | the kernel configuration. | ||
| 2386 | |||
| 2373 | sysrq_always_enabled | 2387 | sysrq_always_enabled |
| 2374 | [KNL] | 2388 | [KNL] |
| 2375 | Ignore sysrq setting - this boot parameter will | 2389 | Ignore sysrq setting - this boot parameter will |
diff --git a/MAINTAINERS b/MAINTAINERS index b618b1e86c46..fd19b544a1b1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2064,14 +2064,16 @@ F: drivers/block/drbd/ | |||
| 2064 | F: lib/lru_cache.c | 2064 | F: lib/lru_cache.c |
| 2065 | F: Documentation/blockdev/drbd/ | 2065 | F: Documentation/blockdev/drbd/ |
| 2066 | 2066 | ||
| 2067 | DRIVER CORE, KOBJECTS, AND SYSFS | 2067 | DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS |
| 2068 | M: Greg Kroah-Hartman <gregkh@suse.de> | 2068 | M: Greg Kroah-Hartman <gregkh@suse.de> |
| 2069 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 2069 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
| 2070 | S: Supported | 2070 | S: Supported |
| 2071 | F: Documentation/kobject.txt | 2071 | F: Documentation/kobject.txt |
| 2072 | F: drivers/base/ | 2072 | F: drivers/base/ |
| 2073 | F: fs/sysfs/ | 2073 | F: fs/sysfs/ |
| 2074 | F: fs/debugfs/ | ||
| 2074 | F: include/linux/kobj* | 2075 | F: include/linux/kobj* |
| 2076 | F: include/linux/debugfs.h | ||
| 2075 | F: lib/kobj* | 2077 | F: lib/kobj* |
| 2076 | 2078 | ||
| 2077 | DRM DRIVERS | 2079 | DRM DRIVERS |
diff --git a/block/genhd.c b/block/genhd.c index 8313834596db..a8adf96a4b41 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -22,9 +22,7 @@ | |||
| 22 | #include "blk.h" | 22 | #include "blk.h" |
| 23 | 23 | ||
| 24 | static DEFINE_MUTEX(block_class_lock); | 24 | static DEFINE_MUTEX(block_class_lock); |
| 25 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 26 | struct kobject *block_depr; | 25 | struct kobject *block_depr; |
| 27 | #endif | ||
| 28 | 26 | ||
| 29 | /* for extended dynamic devt allocation, currently only one major is used */ | 27 | /* for extended dynamic devt allocation, currently only one major is used */ |
| 30 | #define MAX_EXT_DEVT (1 << MINORBITS) | 28 | #define MAX_EXT_DEVT (1 << MINORBITS) |
| @@ -810,10 +808,9 @@ static int __init genhd_device_init(void) | |||
| 810 | 808 | ||
| 811 | register_blkdev(BLOCK_EXT_MAJOR, "blkext"); | 809 | register_blkdev(BLOCK_EXT_MAJOR, "blkext"); |
| 812 | 810 | ||
| 813 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 814 | /* create top-level block dir */ | 811 | /* create top-level block dir */ |
| 815 | block_depr = kobject_create_and_add("block", NULL); | 812 | if (!sysfs_deprecated) |
| 816 | #endif | 813 | block_depr = kobject_create_and_add("block", NULL); |
| 817 | return 0; | 814 | return 0; |
| 818 | } | 815 | } |
| 819 | 816 | ||
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index ef38aff737eb..fd96345bc35c 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
| @@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD | |||
| 71 | 71 | ||
| 72 | config FW_LOADER | 72 | config FW_LOADER |
| 73 | tristate "Userspace firmware loading support" if EMBEDDED | 73 | tristate "Userspace firmware loading support" if EMBEDDED |
| 74 | depends on HOTPLUG | ||
| 75 | default y | 74 | default y |
| 76 | ---help--- | 75 | ---help--- |
| 77 | This option is provided for the case where no in-kernel-tree modules | 76 | This option is provided for the case where no in-kernel-tree modules |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index c12c7f2f2a6f..5f51c3b4451e 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
| @@ -19,7 +19,5 @@ obj-$(CONFIG_MODULES) += module.o | |||
| 19 | endif | 19 | endif |
| 20 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o | 20 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o |
| 21 | 21 | ||
| 22 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 22 | ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG |
| 23 | EXTRA_CFLAGS += -DDEBUG | ||
| 24 | endif | ||
| 25 | 23 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index eb1b7fa20dce..33c270a64db7 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
| @@ -440,22 +440,6 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev) | |||
| 440 | } | 440 | } |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 444 | static int make_deprecated_bus_links(struct device *dev) | ||
| 445 | { | ||
| 446 | return sysfs_create_link(&dev->kobj, | ||
| 447 | &dev->bus->p->subsys.kobj, "bus"); | ||
| 448 | } | ||
| 449 | |||
| 450 | static void remove_deprecated_bus_links(struct device *dev) | ||
| 451 | { | ||
| 452 | sysfs_remove_link(&dev->kobj, "bus"); | ||
| 453 | } | ||
| 454 | #else | ||
| 455 | static inline int make_deprecated_bus_links(struct device *dev) { return 0; } | ||
| 456 | static inline void remove_deprecated_bus_links(struct device *dev) { } | ||
| 457 | #endif | ||
| 458 | |||
| 459 | /** | 443 | /** |
| 460 | * bus_add_device - add device to bus | 444 | * bus_add_device - add device to bus |
| 461 | * @dev: device being added | 445 | * @dev: device being added |
| @@ -482,15 +466,10 @@ int bus_add_device(struct device *dev) | |||
| 482 | &dev->bus->p->subsys.kobj, "subsystem"); | 466 | &dev->bus->p->subsys.kobj, "subsystem"); |
| 483 | if (error) | 467 | if (error) |
| 484 | goto out_subsys; | 468 | goto out_subsys; |
| 485 | error = make_deprecated_bus_links(dev); | ||
| 486 | if (error) | ||
| 487 | goto out_deprecated; | ||
| 488 | klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); | 469 | klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); |
| 489 | } | 470 | } |
| 490 | return 0; | 471 | return 0; |
| 491 | 472 | ||
| 492 | out_deprecated: | ||
| 493 | sysfs_remove_link(&dev->kobj, "subsystem"); | ||
| 494 | out_subsys: | 473 | out_subsys: |
| 495 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); | 474 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); |
| 496 | out_id: | 475 | out_id: |
| @@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev) | |||
| 530 | { | 509 | { |
| 531 | if (dev->bus) { | 510 | if (dev->bus) { |
| 532 | sysfs_remove_link(&dev->kobj, "subsystem"); | 511 | sysfs_remove_link(&dev->kobj, "subsystem"); |
| 533 | remove_deprecated_bus_links(dev); | ||
| 534 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 512 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
| 535 | dev_name(dev)); | 513 | dev_name(dev)); |
| 536 | device_remove_attrs(dev->bus, dev); | 514 | device_remove_attrs(dev->bus, dev); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 8e231d05b400..9c63a5687d69 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
| @@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key) | |||
| 184 | if (!cls->dev_kobj) | 184 | if (!cls->dev_kobj) |
| 185 | cls->dev_kobj = sysfs_dev_char_kobj; | 185 | cls->dev_kobj = sysfs_dev_char_kobj; |
| 186 | 186 | ||
| 187 | #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) | 187 | #if defined(CONFIG_BLOCK) |
| 188 | /* let the block class directory show up in the root of sysfs */ | 188 | /* let the block class directory show up in the root of sysfs */ |
| 189 | if (cls != &block_class) | 189 | if (!sysfs_deprecated || cls != &block_class) |
| 190 | cp->class_subsys.kobj.kset = class_kset; | 190 | cp->class_subsys.kobj.kset = class_kset; |
| 191 | #else | 191 | #else |
| 192 | cp->class_subsys.kobj.kset = class_kset; | 192 | cp->class_subsys.kobj.kset = class_kset; |
| @@ -276,25 +276,6 @@ void class_destroy(struct class *cls) | |||
| 276 | class_unregister(cls); | 276 | class_unregister(cls); |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 280 | char *make_class_name(const char *name, struct kobject *kobj) | ||
| 281 | { | ||
| 282 | char *class_name; | ||
| 283 | int size; | ||
| 284 | |||
| 285 | size = strlen(name) + strlen(kobject_name(kobj)) + 2; | ||
| 286 | |||
| 287 | class_name = kmalloc(size, GFP_KERNEL); | ||
| 288 | if (!class_name) | ||
| 289 | return NULL; | ||
| 290 | |||
| 291 | strcpy(class_name, name); | ||
| 292 | strcat(class_name, ":"); | ||
| 293 | strcat(class_name, kobject_name(kobj)); | ||
| 294 | return class_name; | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | |||
| 298 | /** | 279 | /** |
| 299 | * class_dev_iter_init - initialize class device iterator | 280 | * class_dev_iter_init - initialize class device iterator |
| 300 | * @iter: class iterator to initialize | 281 | * @iter: class iterator to initialize |
diff --git a/drivers/base/core.c b/drivers/base/core.c index d1b2c9adc271..2cb49a93b1e6 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
| @@ -26,6 +26,19 @@ | |||
| 26 | #include "base.h" | 26 | #include "base.h" |
| 27 | #include "power/power.h" | 27 | #include "power/power.h" |
| 28 | 28 | ||
| 29 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 30 | #ifdef CONFIG_SYSFS_DEPRECATED_V2 | ||
| 31 | long sysfs_deprecated = 1; | ||
| 32 | #else | ||
| 33 | long sysfs_deprecated = 0; | ||
| 34 | #endif | ||
| 35 | static __init int sysfs_deprecated_setup(char *arg) | ||
| 36 | { | ||
| 37 | return strict_strtol(arg, 10, &sysfs_deprecated); | ||
| 38 | } | ||
| 39 | early_param("sysfs.deprecated", sysfs_deprecated_setup); | ||
| 40 | #endif | ||
| 41 | |||
| 29 | int (*platform_notify)(struct device *dev) = NULL; | 42 | int (*platform_notify)(struct device *dev) = NULL; |
| 30 | int (*platform_notify_remove)(struct device *dev) = NULL; | 43 | int (*platform_notify_remove)(struct device *dev) = NULL; |
| 31 | static struct kobject *dev_kobj; | 44 | static struct kobject *dev_kobj; |
| @@ -203,37 +216,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
| 203 | if (dev->driver) | 216 | if (dev->driver) |
| 204 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); | 217 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); |
| 205 | 218 | ||
| 206 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 207 | if (dev->class) { | ||
| 208 | struct device *parent = dev->parent; | ||
| 209 | |||
| 210 | /* find first bus device in parent chain */ | ||
| 211 | while (parent && !parent->bus) | ||
| 212 | parent = parent->parent; | ||
| 213 | if (parent && parent->bus) { | ||
| 214 | const char *path; | ||
| 215 | |||
| 216 | path = kobject_get_path(&parent->kobj, GFP_KERNEL); | ||
| 217 | if (path) { | ||
| 218 | add_uevent_var(env, "PHYSDEVPATH=%s", path); | ||
| 219 | kfree(path); | ||
| 220 | } | ||
| 221 | |||
| 222 | add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name); | ||
| 223 | |||
| 224 | if (parent->driver) | ||
| 225 | add_uevent_var(env, "PHYSDEVDRIVER=%s", | ||
| 226 | parent->driver->name); | ||
| 227 | } | ||
| 228 | } else if (dev->bus) { | ||
| 229 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); | ||
| 230 | |||
| 231 | if (dev->driver) | ||
| 232 | add_uevent_var(env, "PHYSDEVDRIVER=%s", | ||
| 233 | dev->driver->name); | ||
| 234 | } | ||
| 235 | #endif | ||
| 236 | |||
| 237 | /* have the bus specific function add its stuff */ | 219 | /* have the bus specific function add its stuff */ |
| 238 | if (dev->bus && dev->bus->uevent) { | 220 | if (dev->bus && dev->bus->uevent) { |
| 239 | retval = dev->bus->uevent(dev, env); | 221 | retval = dev->bus->uevent(dev, env); |
| @@ -578,24 +560,6 @@ void device_initialize(struct device *dev) | |||
| 578 | set_dev_node(dev, -1); | 560 | set_dev_node(dev, -1); |
| 579 | } | 561 | } |
| 580 | 562 | ||
| 581 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 582 | static struct kobject *get_device_parent(struct device *dev, | ||
| 583 | struct device *parent) | ||
| 584 | { | ||
| 585 | /* class devices without a parent live in /sys/class/<classname>/ */ | ||
| 586 | if (dev->class && (!parent || parent->class != dev->class)) | ||
| 587 | return &dev->class->p->class_subsys.kobj; | ||
| 588 | /* all other devices keep their parent */ | ||
| 589 | else if (parent) | ||
| 590 | return &parent->kobj; | ||
| 591 | |||
| 592 | return NULL; | ||
| 593 | } | ||
| 594 | |||
| 595 | static inline void cleanup_device_parent(struct device *dev) {} | ||
| 596 | static inline void cleanup_glue_dir(struct device *dev, | ||
| 597 | struct kobject *glue_dir) {} | ||
| 598 | #else | ||
| 599 | static struct kobject *virtual_device_parent(struct device *dev) | 563 | static struct kobject *virtual_device_parent(struct device *dev) |
| 600 | { | 564 | { |
| 601 | static struct kobject *virtual_dir = NULL; | 565 | static struct kobject *virtual_dir = NULL; |
| @@ -666,6 +630,15 @@ static struct kobject *get_device_parent(struct device *dev, | |||
| 666 | struct kobject *parent_kobj; | 630 | struct kobject *parent_kobj; |
| 667 | struct kobject *k; | 631 | struct kobject *k; |
| 668 | 632 | ||
| 633 | #ifdef CONFIG_BLOCK | ||
| 634 | /* block disks show up in /sys/block */ | ||
| 635 | if (sysfs_deprecated && dev->class == &block_class) { | ||
| 636 | if (parent && parent->class == &block_class) | ||
| 637 | return &parent->kobj; | ||
| 638 | return &block_class.p->class_subsys.kobj; | ||
| 639 | } | ||
| 640 | #endif | ||
| 641 | |||
| 669 | /* | 642 | /* |
| 670 | * If we have no parent, we live in "virtual". | 643 | * If we have no parent, we live in "virtual". |
| 671 | * Class-devices with a non class-device as parent, live | 644 | * Class-devices with a non class-device as parent, live |
| @@ -719,7 +692,6 @@ static void cleanup_device_parent(struct device *dev) | |||
| 719 | { | 692 | { |
| 720 | cleanup_glue_dir(dev, dev->kobj.parent); | 693 | cleanup_glue_dir(dev, dev->kobj.parent); |
| 721 | } | 694 | } |
| 722 | #endif | ||
| 723 | 695 | ||
| 724 | static void setup_parent(struct device *dev, struct device *parent) | 696 | static void setup_parent(struct device *dev, struct device *parent) |
| 725 | { | 697 | { |
| @@ -742,70 +714,29 @@ static int device_add_class_symlinks(struct device *dev) | |||
| 742 | if (error) | 714 | if (error) |
| 743 | goto out; | 715 | goto out; |
| 744 | 716 | ||
| 745 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 746 | /* stacked class devices need a symlink in the class directory */ | ||
| 747 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && | ||
| 748 | device_is_not_partition(dev)) { | ||
| 749 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | ||
| 750 | &dev->kobj, dev_name(dev)); | ||
| 751 | if (error) | ||
| 752 | goto out_subsys; | ||
| 753 | } | ||
| 754 | |||
| 755 | if (dev->parent && device_is_not_partition(dev)) { | 717 | if (dev->parent && device_is_not_partition(dev)) { |
| 756 | struct device *parent = dev->parent; | 718 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, |
| 757 | char *class_name; | ||
| 758 | |||
| 759 | /* | ||
| 760 | * stacked class devices have the 'device' link | ||
| 761 | * pointing to the bus device instead of the parent | ||
| 762 | */ | ||
| 763 | while (parent->class && !parent->bus && parent->parent) | ||
| 764 | parent = parent->parent; | ||
| 765 | |||
| 766 | error = sysfs_create_link(&dev->kobj, | ||
| 767 | &parent->kobj, | ||
| 768 | "device"); | 719 | "device"); |
| 769 | if (error) | 720 | if (error) |
| 770 | goto out_busid; | 721 | goto out_subsys; |
| 771 | |||
| 772 | class_name = make_class_name(dev->class->name, | ||
| 773 | &dev->kobj); | ||
| 774 | if (class_name) | ||
| 775 | error = sysfs_create_link(&dev->parent->kobj, | ||
| 776 | &dev->kobj, class_name); | ||
| 777 | kfree(class_name); | ||
| 778 | if (error) | ||
| 779 | goto out_device; | ||
| 780 | } | 722 | } |
| 781 | return 0; | ||
| 782 | 723 | ||
| 783 | out_device: | 724 | #ifdef CONFIG_BLOCK |
| 784 | if (dev->parent && device_is_not_partition(dev)) | 725 | /* /sys/block has directories and does not need symlinks */ |
| 785 | sysfs_remove_link(&dev->kobj, "device"); | 726 | if (sysfs_deprecated && dev->class == &block_class) |
| 786 | out_busid: | 727 | return 0; |
| 787 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && | 728 | #endif |
| 788 | device_is_not_partition(dev)) | 729 | |
| 789 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, | ||
| 790 | dev_name(dev)); | ||
| 791 | #else | ||
| 792 | /* link in the class directory pointing to the device */ | 730 | /* link in the class directory pointing to the device */ |
| 793 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | 731 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, |
| 794 | &dev->kobj, dev_name(dev)); | 732 | &dev->kobj, dev_name(dev)); |
| 795 | if (error) | 733 | if (error) |
| 796 | goto out_subsys; | 734 | goto out_device; |
| 797 | 735 | ||
| 798 | if (dev->parent && device_is_not_partition(dev)) { | ||
| 799 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, | ||
| 800 | "device"); | ||
| 801 | if (error) | ||
| 802 | goto out_busid; | ||
| 803 | } | ||
| 804 | return 0; | 736 | return 0; |
| 805 | 737 | ||
| 806 | out_busid: | 738 | out_device: |
| 807 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | 739 | sysfs_remove_link(&dev->kobj, "device"); |
| 808 | #endif | ||
| 809 | 740 | ||
| 810 | out_subsys: | 741 | out_subsys: |
| 811 | sysfs_remove_link(&dev->kobj, "subsystem"); | 742 | sysfs_remove_link(&dev->kobj, "subsystem"); |
| @@ -818,30 +749,14 @@ static void device_remove_class_symlinks(struct device *dev) | |||
| 818 | if (!dev->class) | 749 | if (!dev->class) |
| 819 | return; | 750 | return; |
| 820 | 751 | ||
| 821 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 822 | if (dev->parent && device_is_not_partition(dev)) { | ||
| 823 | char *class_name; | ||
| 824 | |||
| 825 | class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 826 | if (class_name) { | ||
| 827 | sysfs_remove_link(&dev->parent->kobj, class_name); | ||
| 828 | kfree(class_name); | ||
| 829 | } | ||
| 830 | sysfs_remove_link(&dev->kobj, "device"); | ||
| 831 | } | ||
| 832 | |||
| 833 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && | ||
| 834 | device_is_not_partition(dev)) | ||
| 835 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, | ||
| 836 | dev_name(dev)); | ||
| 837 | #else | ||
| 838 | if (dev->parent && device_is_not_partition(dev)) | 752 | if (dev->parent && device_is_not_partition(dev)) |
| 839 | sysfs_remove_link(&dev->kobj, "device"); | 753 | sysfs_remove_link(&dev->kobj, "device"); |
| 840 | |||
| 841 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | ||
| 842 | #endif | ||
| 843 | |||
| 844 | sysfs_remove_link(&dev->kobj, "subsystem"); | 754 | sysfs_remove_link(&dev->kobj, "subsystem"); |
| 755 | #ifdef CONFIG_BLOCK | ||
| 756 | if (sysfs_deprecated && dev->class == &block_class) | ||
| 757 | return; | ||
| 758 | #endif | ||
| 759 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | ||
| 845 | } | 760 | } |
| 846 | 761 | ||
| 847 | /** | 762 | /** |
| @@ -1613,41 +1528,23 @@ int device_rename(struct device *dev, const char *new_name) | |||
| 1613 | pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev), | 1528 | pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev), |
| 1614 | __func__, new_name); | 1529 | __func__, new_name); |
| 1615 | 1530 | ||
| 1616 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 1617 | if ((dev->class) && (dev->parent)) | ||
| 1618 | old_class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 1619 | #endif | ||
| 1620 | |||
| 1621 | old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); | 1531 | old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); |
| 1622 | if (!old_device_name) { | 1532 | if (!old_device_name) { |
| 1623 | error = -ENOMEM; | 1533 | error = -ENOMEM; |
| 1624 | goto out; | 1534 | goto out; |
| 1625 | } | 1535 | } |
| 1626 | 1536 | ||
| 1627 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 1628 | if (dev->class) { | 1537 | if (dev->class) { |
| 1629 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, | 1538 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, |
| 1630 | &dev->kobj, old_device_name, new_name); | 1539 | &dev->kobj, old_device_name, new_name); |
| 1631 | if (error) | 1540 | if (error) |
| 1632 | goto out; | 1541 | goto out; |
| 1633 | } | 1542 | } |
| 1634 | #endif | 1543 | |
| 1635 | error = kobject_rename(&dev->kobj, new_name); | 1544 | error = kobject_rename(&dev->kobj, new_name); |
| 1636 | if (error) | 1545 | if (error) |
| 1637 | goto out; | 1546 | goto out; |
| 1638 | 1547 | ||
| 1639 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 1640 | if (old_class_name) { | ||
| 1641 | new_class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 1642 | if (new_class_name) { | ||
| 1643 | error = sysfs_rename_link(&dev->parent->kobj, | ||
| 1644 | &dev->kobj, | ||
| 1645 | old_class_name, | ||
| 1646 | new_class_name); | ||
| 1647 | } | ||
| 1648 | } | ||
| 1649 | #endif | ||
| 1650 | |||
| 1651 | out: | 1548 | out: |
| 1652 | put_device(dev); | 1549 | put_device(dev); |
| 1653 | 1550 | ||
| @@ -1664,40 +1561,13 @@ static int device_move_class_links(struct device *dev, | |||
| 1664 | struct device *new_parent) | 1561 | struct device *new_parent) |
| 1665 | { | 1562 | { |
| 1666 | int error = 0; | 1563 | int error = 0; |
| 1667 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 1668 | char *class_name; | ||
| 1669 | 1564 | ||
| 1670 | class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 1671 | if (!class_name) { | ||
| 1672 | error = -ENOMEM; | ||
| 1673 | goto out; | ||
| 1674 | } | ||
| 1675 | if (old_parent) { | ||
| 1676 | sysfs_remove_link(&dev->kobj, "device"); | ||
| 1677 | sysfs_remove_link(&old_parent->kobj, class_name); | ||
| 1678 | } | ||
| 1679 | if (new_parent) { | ||
| 1680 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, | ||
| 1681 | "device"); | ||
| 1682 | if (error) | ||
| 1683 | goto out; | ||
| 1684 | error = sysfs_create_link(&new_parent->kobj, &dev->kobj, | ||
| 1685 | class_name); | ||
| 1686 | if (error) | ||
| 1687 | sysfs_remove_link(&dev->kobj, "device"); | ||
| 1688 | } else | ||
| 1689 | error = 0; | ||
| 1690 | out: | ||
| 1691 | kfree(class_name); | ||
| 1692 | return error; | ||
| 1693 | #else | ||
| 1694 | if (old_parent) | 1565 | if (old_parent) |
| 1695 | sysfs_remove_link(&dev->kobj, "device"); | 1566 | sysfs_remove_link(&dev->kobj, "device"); |
| 1696 | if (new_parent) | 1567 | if (new_parent) |
| 1697 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, | 1568 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, |
| 1698 | "device"); | 1569 | "device"); |
| 1699 | return error; | 1570 | return error; |
| 1700 | #endif | ||
| 1701 | } | 1571 | } |
| 1702 | 1572 | ||
| 1703 | /** | 1573 | /** |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 933442f40321..cafeaaf0428f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
| 28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 29 | 29 | ||
| 30 | static DEFINE_MUTEX(mem_sysfs_mutex); | ||
| 31 | |||
| 30 | #define MEMORY_CLASS_NAME "memory" | 32 | #define MEMORY_CLASS_NAME "memory" |
| 31 | 33 | ||
| 32 | static struct sysdev_class memory_sysdev_class = { | 34 | static struct sysdev_class memory_sysdev_class = { |
| @@ -435,6 +437,45 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn) | |||
| 435 | return 0; | 437 | return 0; |
| 436 | } | 438 | } |
| 437 | 439 | ||
| 440 | struct memory_block *find_memory_block_hinted(struct mem_section *section, | ||
| 441 | struct memory_block *hint) | ||
| 442 | { | ||
| 443 | struct kobject *kobj; | ||
| 444 | struct sys_device *sysdev; | ||
| 445 | struct memory_block *mem; | ||
| 446 | char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; | ||
| 447 | |||
| 448 | kobj = hint ? &hint->sysdev.kobj : NULL; | ||
| 449 | |||
| 450 | /* | ||
| 451 | * This only works because we know that section == sysdev->id | ||
| 452 | * slightly redundant with sysdev_register() | ||
| 453 | */ | ||
| 454 | sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section)); | ||
| 455 | |||
| 456 | kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj); | ||
| 457 | if (!kobj) | ||
| 458 | return NULL; | ||
| 459 | |||
| 460 | sysdev = container_of(kobj, struct sys_device, kobj); | ||
| 461 | mem = container_of(sysdev, struct memory_block, sysdev); | ||
| 462 | |||
| 463 | return mem; | ||
| 464 | } | ||
| 465 | |||
| 466 | /* | ||
| 467 | * For now, we have a linear search to go find the appropriate | ||
| 468 | * memory_block corresponding to a particular phys_index. If | ||
| 469 | * this gets to be a real problem, we can always use a radix | ||
| 470 | * tree or something here. | ||
| 471 | * | ||
| 472 | * This could be made generic for all sysdev classes. | ||
| 473 | */ | ||
| 474 | struct memory_block *find_memory_block(struct mem_section *section) | ||
| 475 | { | ||
| 476 | return find_memory_block_hinted(section, NULL); | ||
| 477 | } | ||
| 478 | |||
| 438 | static int add_memory_block(int nid, struct mem_section *section, | 479 | static int add_memory_block(int nid, struct mem_section *section, |
| 439 | unsigned long state, enum mem_add_context context) | 480 | unsigned long state, enum mem_add_context context) |
| 440 | { | 481 | { |
| @@ -445,8 +486,11 @@ static int add_memory_block(int nid, struct mem_section *section, | |||
| 445 | if (!mem) | 486 | if (!mem) |
| 446 | return -ENOMEM; | 487 | return -ENOMEM; |
| 447 | 488 | ||
| 489 | mutex_lock(&mem_sysfs_mutex); | ||
| 490 | |||
| 448 | mem->phys_index = __section_nr(section); | 491 | mem->phys_index = __section_nr(section); |
| 449 | mem->state = state; | 492 | mem->state = state; |
| 493 | mem->section_count++; | ||
| 450 | mutex_init(&mem->state_mutex); | 494 | mutex_init(&mem->state_mutex); |
| 451 | start_pfn = section_nr_to_pfn(mem->phys_index); | 495 | start_pfn = section_nr_to_pfn(mem->phys_index); |
| 452 | mem->phys_device = arch_get_memory_phys_device(start_pfn); | 496 | 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 | ret = register_mem_sect_under_node(mem, nid); | 509 | ret = register_mem_sect_under_node(mem, nid); |
| 466 | } | 510 | } |
| 467 | 511 | ||
| 512 | mutex_unlock(&mem_sysfs_mutex); | ||
| 468 | return ret; | 513 | return ret; |
| 469 | } | 514 | } |
| 470 | 515 | ||
| 471 | /* | ||
| 472 | * For now, we have a linear search to go find the appropriate | ||
| 473 | * memory_block corresponding to a particular phys_index. If | ||
| 474 | * this gets to be a real problem, we can always use a radix | ||
| 475 | * tree or something here. | ||
| 476 | * | ||
| 477 | * This could be made generic for all sysdev classes. | ||
| 478 | */ | ||
| 479 | struct memory_block *find_memory_block(struct mem_section *section) | ||
| 480 | { | ||
| 481 | struct kobject *kobj; | ||
| 482 | struct sys_device *sysdev; | ||
| 483 | struct memory_block *mem; | ||
| 484 | char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; | ||
| 485 | |||
| 486 | /* | ||
| 487 | * This only works because we know that section == sysdev->id | ||
| 488 | * slightly redundant with sysdev_register() | ||
| 489 | */ | ||
| 490 | sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section)); | ||
| 491 | |||
| 492 | kobj = kset_find_obj(&memory_sysdev_class.kset, name); | ||
| 493 | if (!kobj) | ||
| 494 | return NULL; | ||
| 495 | |||
| 496 | sysdev = container_of(kobj, struct sys_device, kobj); | ||
| 497 | mem = container_of(sysdev, struct memory_block, sysdev); | ||
| 498 | |||
| 499 | return mem; | ||
| 500 | } | ||
| 501 | |||
| 502 | int remove_memory_block(unsigned long node_id, struct mem_section *section, | 516 | int remove_memory_block(unsigned long node_id, struct mem_section *section, |
| 503 | int phys_device) | 517 | int phys_device) |
| 504 | { | 518 | { |
| 505 | struct memory_block *mem; | 519 | struct memory_block *mem; |
| 506 | 520 | ||
| 521 | mutex_lock(&mem_sysfs_mutex); | ||
| 507 | mem = find_memory_block(section); | 522 | mem = find_memory_block(section); |
| 508 | unregister_mem_sect_under_nodes(mem); | ||
| 509 | mem_remove_simple_file(mem, phys_index); | ||
| 510 | mem_remove_simple_file(mem, state); | ||
| 511 | mem_remove_simple_file(mem, phys_device); | ||
| 512 | mem_remove_simple_file(mem, removable); | ||
| 513 | unregister_memory(mem, section); | ||
| 514 | 523 | ||
| 524 | mem->section_count--; | ||
| 525 | if (mem->section_count == 0) { | ||
| 526 | unregister_mem_sect_under_nodes(mem); | ||
| 527 | mem_remove_simple_file(mem, phys_index); | ||
| 528 | mem_remove_simple_file(mem, state); | ||
| 529 | mem_remove_simple_file(mem, phys_device); | ||
| 530 | mem_remove_simple_file(mem, removable); | ||
| 531 | unregister_memory(mem, section); | ||
| 532 | } | ||
| 533 | |||
| 534 | mutex_unlock(&mem_sysfs_mutex); | ||
| 515 | return 0; | 535 | return 0; |
| 516 | } | 536 | } |
| 517 | 537 | ||
diff --git a/drivers/base/node.c b/drivers/base/node.c index 2872e86837b2..ee53558b452f 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
| @@ -409,25 +409,27 @@ static int link_mem_sections(int nid) | |||
| 409 | unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; | 409 | unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; |
| 410 | unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; | 410 | unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; |
| 411 | unsigned long pfn; | 411 | unsigned long pfn; |
| 412 | struct memory_block *mem_blk = NULL; | ||
| 412 | int err = 0; | 413 | int err = 0; |
| 413 | 414 | ||
| 414 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { | 415 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { |
| 415 | unsigned long section_nr = pfn_to_section_nr(pfn); | 416 | unsigned long section_nr = pfn_to_section_nr(pfn); |
| 416 | struct mem_section *mem_sect; | 417 | struct mem_section *mem_sect; |
| 417 | struct memory_block *mem_blk; | ||
| 418 | int ret; | 418 | int ret; |
| 419 | 419 | ||
| 420 | if (!present_section_nr(section_nr)) | 420 | if (!present_section_nr(section_nr)) |
| 421 | continue; | 421 | continue; |
| 422 | mem_sect = __nr_to_section(section_nr); | 422 | mem_sect = __nr_to_section(section_nr); |
| 423 | mem_blk = find_memory_block(mem_sect); | 423 | mem_blk = find_memory_block_hinted(mem_sect, mem_blk); |
| 424 | ret = register_mem_sect_under_node(mem_blk, nid); | 424 | ret = register_mem_sect_under_node(mem_blk, nid); |
| 425 | if (!err) | 425 | if (!err) |
| 426 | err = ret; | 426 | err = ret; |
| 427 | 427 | ||
| 428 | /* discard ref obtained in find_memory_block() */ | 428 | /* discard ref obtained in find_memory_block() */ |
| 429 | kobject_put(&mem_blk->sysdev.kobj); | ||
| 430 | } | 429 | } |
| 430 | |||
| 431 | if (mem_blk) | ||
| 432 | kobject_put(&mem_blk->sysdev.kobj); | ||
| 431 | return err; | 433 | return err; |
| 432 | } | 434 | } |
| 433 | 435 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c6c933f58102..3966e62ad019 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev, | |||
| 192 | { | 192 | { |
| 193 | struct resource *r; | 193 | struct resource *r; |
| 194 | 194 | ||
| 195 | if (!res) | ||
| 196 | return 0; | ||
| 197 | |||
| 195 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); | 198 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); |
| 196 | if (r) { | 199 | if (r) { |
| 197 | pdev->resource = r; | 200 | pdev->resource = r; |
| @@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources); | |||
| 215 | int platform_device_add_data(struct platform_device *pdev, const void *data, | 218 | int platform_device_add_data(struct platform_device *pdev, const void *data, |
| 216 | size_t size) | 219 | size_t size) |
| 217 | { | 220 | { |
| 218 | void *d = kmemdup(data, size, GFP_KERNEL); | 221 | void *d; |
| 222 | |||
| 223 | if (!data) | ||
| 224 | return 0; | ||
| 219 | 225 | ||
| 226 | d = kmemdup(data, size, GFP_KERNEL); | ||
| 220 | if (d) { | 227 | if (d) { |
| 221 | pdev->dev.platform_data = d; | 228 | pdev->dev.platform_data = d; |
| 222 | return 0; | 229 | return 0; |
| @@ -373,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata( | |||
| 373 | 380 | ||
| 374 | pdev->dev.parent = parent; | 381 | pdev->dev.parent = parent; |
| 375 | 382 | ||
| 376 | if (res) { | 383 | ret = platform_device_add_resources(pdev, res, num); |
| 377 | ret = platform_device_add_resources(pdev, res, num); | 384 | if (ret) |
| 378 | if (ret) | 385 | goto err; |
| 379 | goto err; | ||
| 380 | } | ||
| 381 | 386 | ||
| 382 | if (data) { | 387 | ret = platform_device_add_data(pdev, data, size); |
| 383 | ret = platform_device_add_data(pdev, data, size); | 388 | if (ret) |
| 384 | if (ret) | 389 | goto err; |
| 385 | goto err; | ||
| 386 | } | ||
| 387 | 390 | ||
| 388 | ret = platform_device_add(pdev); | 391 | ret = platform_device_add(pdev); |
| 389 | if (ret) { | 392 | if (ret) { |
| @@ -488,12 +491,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
| 488 | * if the probe was successful, and make sure any forced probes of | 491 | * if the probe was successful, and make sure any forced probes of |
| 489 | * new devices fail. | 492 | * new devices fail. |
| 490 | */ | 493 | */ |
| 491 | spin_lock(&platform_bus_type.p->klist_drivers.k_lock); | 494 | spin_lock(&drv->driver.bus->p->klist_drivers.k_lock); |
| 492 | drv->probe = NULL; | 495 | drv->probe = NULL; |
| 493 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) | 496 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) |
| 494 | retval = -ENODEV; | 497 | retval = -ENODEV; |
| 495 | drv->driver.probe = platform_drv_probe_fail; | 498 | drv->driver.probe = platform_drv_probe_fail; |
| 496 | spin_unlock(&platform_bus_type.p->klist_drivers.k_lock); | 499 | spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock); |
| 497 | 500 | ||
| 498 | if (code != retval) | 501 | if (code != retval) |
| 499 | platform_driver_unregister(drv); | 502 | platform_driver_unregister(drv); |
| @@ -530,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle( | |||
| 530 | goto err_out; | 533 | goto err_out; |
| 531 | } | 534 | } |
| 532 | 535 | ||
| 533 | if (res) { | 536 | error = platform_device_add_resources(pdev, res, n_res); |
| 534 | error = platform_device_add_resources(pdev, res, n_res); | 537 | if (error) |
| 535 | if (error) | 538 | goto err_pdev_put; |
| 536 | goto err_pdev_put; | ||
| 537 | } | ||
| 538 | 539 | ||
| 539 | if (data) { | 540 | error = platform_device_add_data(pdev, data, size); |
| 540 | error = platform_device_add_data(pdev, data, size); | 541 | if (error) |
| 541 | if (error) | 542 | goto err_pdev_put; |
| 542 | goto err_pdev_put; | ||
| 543 | } | ||
| 544 | 543 | ||
| 545 | error = platform_device_add(pdev); | 544 | error = platform_device_add(pdev); |
| 546 | if (error) | 545 | if (error) |
| @@ -976,6 +975,41 @@ struct bus_type platform_bus_type = { | |||
| 976 | }; | 975 | }; |
| 977 | EXPORT_SYMBOL_GPL(platform_bus_type); | 976 | EXPORT_SYMBOL_GPL(platform_bus_type); |
| 978 | 977 | ||
| 978 | /** | ||
| 979 | * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops | ||
| 980 | * | ||
| 981 | * This function can be used by platform code to get the current | ||
| 982 | * set of dev_pm_ops functions used by the platform_bus_type. | ||
| 983 | */ | ||
| 984 | const struct dev_pm_ops * __init platform_bus_get_pm_ops(void) | ||
| 985 | { | ||
| 986 | return platform_bus_type.pm; | ||
| 987 | } | ||
| 988 | |||
| 989 | /** | ||
| 990 | * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type | ||
| 991 | * | ||
| 992 | * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type | ||
| 993 | * | ||
| 994 | * Platform code can override the dev_pm_ops methods of | ||
| 995 | * platform_bus_type by using this function. It is expected that | ||
| 996 | * platform code will first do a platform_bus_get_pm_ops(), then | ||
| 997 | * kmemdup it, then customize selected methods and pass a pointer to | ||
| 998 | * the new struct dev_pm_ops to this function. | ||
| 999 | * | ||
| 1000 | * Since platform-specific code is customizing methods for *all* | ||
| 1001 | * devices (not just platform-specific devices) it is expected that | ||
| 1002 | * any custom overrides of these functions will keep existing behavior | ||
| 1003 | * and simply extend it. For example, any customization of the | ||
| 1004 | * runtime PM methods should continue to call the pm_generic_* | ||
| 1005 | * functions as the default ones do in addition to the | ||
| 1006 | * platform-specific behavior. | ||
| 1007 | */ | ||
| 1008 | void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm) | ||
| 1009 | { | ||
| 1010 | platform_bus_type.pm = pm; | ||
| 1011 | } | ||
| 1012 | |||
| 979 | int __init platform_bus_init(void) | 1013 | int __init platform_bus_init(void) |
| 980 | { | 1014 | { |
| 981 | int error; | 1015 | int error; |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 9354dc10a363..1667aaf4fde6 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
| @@ -432,13 +432,13 @@ int sysdev_suspend(pm_message_t state) | |||
| 432 | /* resume current sysdev */ | 432 | /* resume current sysdev */ |
| 433 | cls_driver: | 433 | cls_driver: |
| 434 | drv = NULL; | 434 | drv = NULL; |
| 435 | printk(KERN_ERR "Class suspend failed for %s\n", | 435 | printk(KERN_ERR "Class suspend failed for %s: %d\n", |
| 436 | kobject_name(&sysdev->kobj)); | 436 | kobject_name(&sysdev->kobj), ret); |
| 437 | 437 | ||
| 438 | aux_driver: | 438 | aux_driver: |
| 439 | if (drv) | 439 | if (drv) |
| 440 | printk(KERN_ERR "Class driver suspend failed for %s\n", | 440 | printk(KERN_ERR "Class driver suspend failed for %s: %d\n", |
| 441 | kobject_name(&sysdev->kobj)); | 441 | kobject_name(&sysdev->kobj), ret); |
| 442 | list_for_each_entry(err_drv, &cls->drivers, entry) { | 442 | list_for_each_entry(err_drv, &cls->drivers, entry) { |
| 443 | if (err_drv == drv) | 443 | if (err_drv == drv) |
| 444 | break; | 444 | break; |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b74331260744..db2fbe2d4146 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -248,15 +248,15 @@ config CS5535_CLOCK_EVENT_SRC | |||
| 248 | generic PIT, and are suitable for use as high-res timers. | 248 | generic PIT, and are suitable for use as high-res timers. |
| 249 | 249 | ||
| 250 | config HP_ILO | 250 | config HP_ILO |
| 251 | tristate "Channel interface driver for HP iLO/iLO2 processor" | 251 | tristate "Channel interface driver for the HP iLO processor" |
| 252 | depends on PCI | 252 | depends on PCI |
| 253 | default n | 253 | default n |
| 254 | help | 254 | help |
| 255 | The channel interface driver allows applications to communicate | 255 | The channel interface driver allows applications to communicate |
| 256 | with iLO/iLO2 management processors present on HP ProLiant | 256 | with iLO management processors present on HP ProLiant servers. |
| 257 | servers. Upon loading, the driver creates /dev/hpilo/dXccbN files, | 257 | Upon loading, the driver creates /dev/hpilo/dXccbN files, which |
| 258 | which can be used to gather data from the management processor, | 258 | can be used to gather data from the management processor, via |
| 259 | via read and write system calls. | 259 | read and write system calls. |
| 260 | 260 | ||
| 261 | To compile this driver as a module, choose M here: the | 261 | To compile this driver as a module, choose M here: the |
| 262 | module will be called hpilo. | 262 | module will be called hpilo. |
| @@ -390,6 +390,18 @@ config BMP085 | |||
| 390 | To compile this driver as a module, choose M here: the | 390 | To compile this driver as a module, choose M here: the |
| 391 | module will be called bmp085. | 391 | module will be called bmp085. |
| 392 | 392 | ||
| 393 | config PCH_PHUB | ||
| 394 | tristate "PCH Packet Hub of Intel Topcliff" | ||
| 395 | depends on PCI | ||
| 396 | help | ||
| 397 | This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of | ||
| 398 | Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded | ||
| 399 | processor. The Topcliff has MAC address and Option ROM data in SROM. | ||
| 400 | This driver can access MAC address and Option ROM data in SROM. | ||
| 401 | |||
| 402 | To compile this driver as a module, choose M here: the module will | ||
| 403 | be called pch_phub. | ||
| 404 | |||
| 393 | source "drivers/misc/c2port/Kconfig" | 405 | source "drivers/misc/c2port/Kconfig" |
| 394 | source "drivers/misc/eeprom/Kconfig" | 406 | source "drivers/misc/eeprom/Kconfig" |
| 395 | source "drivers/misc/cb710/Kconfig" | 407 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95cde2a..9f2986b4da2f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
| @@ -35,3 +35,4 @@ obj-y += eeprom/ | |||
| 35 | obj-y += cb710/ | 35 | obj-y += cb710/ |
| 36 | obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o | 36 | obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o |
| 37 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o | 37 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o |
| 38 | obj-$(CONFIG_PCH_PHUB) += pch_phub.o | ||
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 69c1f2fca141..fffc227181b0 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Driver for HP iLO/iLO2 management processor. | 2 | * Driver for the HP iLO management processor. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | 4 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. |
| 5 | * David Altobelli <david.altobelli@hp.com> | 5 | * David Altobelli <david.altobelli@hp.com> |
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c new file mode 100644 index 000000000000..744b804aca15 --- /dev/null +++ b/drivers/misc/pch_phub.c | |||
| @@ -0,0 +1,717 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; version 2 of the License. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/fs.h> | ||
| 22 | #include <linux/uaccess.h> | ||
| 23 | #include <linux/string.h> | ||
| 24 | #include <linux/pci.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/delay.h> | ||
| 27 | #include <linux/mutex.h> | ||
| 28 | #include <linux/if_ether.h> | ||
| 29 | #include <linux/ctype.h> | ||
| 30 | |||
| 31 | #define PHUB_STATUS 0x00 /* Status Register offset */ | ||
| 32 | #define PHUB_CONTROL 0x04 /* Control Register offset */ | ||
| 33 | #define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ | ||
| 34 | #define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ | ||
| 35 | #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ | ||
| 36 | #define PCH_PHUB_ROM_START_ADDR 0x14 /* ROM data area start address offset */ | ||
| 37 | |||
| 38 | /* MAX number of INT_REDUCE_CONTROL registers */ | ||
| 39 | #define MAX_NUM_INT_REDUCE_CONTROL_REG 128 | ||
| 40 | #define PCI_DEVICE_ID_PCH1_PHUB 0x8801 | ||
| 41 | #define PCH_MINOR_NOS 1 | ||
| 42 | #define CLKCFG_CAN_50MHZ 0x12000000 | ||
| 43 | #define CLKCFG_CANCLK_MASK 0xFF000000 | ||
| 44 | |||
| 45 | /* SROM ACCESS Macro */ | ||
| 46 | #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) | ||
| 47 | |||
| 48 | /* Registers address offset */ | ||
| 49 | #define PCH_PHUB_ID_REG 0x0000 | ||
| 50 | #define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004 | ||
| 51 | #define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008 | ||
| 52 | #define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C | ||
| 53 | #define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010 | ||
| 54 | #define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014 | ||
| 55 | #define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018 | ||
| 56 | #define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020 | ||
| 57 | #define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024 | ||
| 58 | #define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028 | ||
| 59 | #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C | ||
| 60 | #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 | ||
| 61 | #define CLKCFG_REG_OFFSET 0x500 | ||
| 62 | |||
| 63 | #define PCH_PHUB_OROM_SIZE 15360 | ||
| 64 | |||
| 65 | /** | ||
| 66 | * struct pch_phub_reg - PHUB register structure | ||
| 67 | * @phub_id_reg: PHUB_ID register val | ||
| 68 | * @q_pri_val_reg: QUEUE_PRI_VAL register val | ||
| 69 | * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val | ||
| 70 | * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val | ||
| 71 | * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val | ||
| 72 | * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val | ||
| 73 | * @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val | ||
| 74 | * @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val | ||
| 75 | * @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val | ||
| 76 | * @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val | ||
| 77 | * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val | ||
| 78 | * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val | ||
| 79 | * @clkcfg_reg: CLK CFG register val | ||
| 80 | * @pch_phub_base_address: Register base address | ||
| 81 | * @pch_phub_extrom_base_address: external rom base address | ||
| 82 | */ | ||
| 83 | struct pch_phub_reg { | ||
| 84 | u32 phub_id_reg; | ||
| 85 | u32 q_pri_val_reg; | ||
| 86 | u32 rc_q_maxsize_reg; | ||
| 87 | u32 bri_q_maxsize_reg; | ||
| 88 | u32 comp_resp_timeout_reg; | ||
| 89 | u32 bus_slave_control_reg; | ||
| 90 | u32 deadlock_avoid_type_reg; | ||
| 91 | u32 intpin_reg_wpermit_reg0; | ||
| 92 | u32 intpin_reg_wpermit_reg1; | ||
| 93 | u32 intpin_reg_wpermit_reg2; | ||
| 94 | u32 intpin_reg_wpermit_reg3; | ||
| 95 | u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG]; | ||
| 96 | u32 clkcfg_reg; | ||
| 97 | void __iomem *pch_phub_base_address; | ||
| 98 | void __iomem *pch_phub_extrom_base_address; | ||
| 99 | }; | ||
| 100 | |||
| 101 | /* SROM SPEC for MAC address assignment offset */ | ||
| 102 | static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa}; | ||
| 103 | |||
| 104 | static DEFINE_MUTEX(pch_phub_mutex); | ||
| 105 | |||
| 106 | /** | ||
| 107 | * pch_phub_read_modify_write_reg() - Reading modifying and writing register | ||
| 108 | * @reg_addr_offset: Register offset address value. | ||
| 109 | * @data: Writing value. | ||
| 110 | * @mask: Mask value. | ||
| 111 | */ | ||
| 112 | static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip, | ||
| 113 | unsigned int reg_addr_offset, | ||
| 114 | unsigned int data, unsigned int mask) | ||
| 115 | { | ||
| 116 | void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset; | ||
| 117 | iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* pch_phub_save_reg_conf - saves register configuration */ | ||
| 121 | static void pch_phub_save_reg_conf(struct pci_dev *pdev) | ||
| 122 | { | ||
| 123 | unsigned int i; | ||
| 124 | struct pch_phub_reg *chip = pci_get_drvdata(pdev); | ||
| 125 | |||
| 126 | void __iomem *p = chip->pch_phub_base_address; | ||
| 127 | |||
| 128 | chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG); | ||
| 129 | chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG); | ||
| 130 | chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG); | ||
| 131 | chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG); | ||
| 132 | chip->comp_resp_timeout_reg = | ||
| 133 | ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG); | ||
| 134 | chip->bus_slave_control_reg = | ||
| 135 | ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG); | ||
| 136 | chip->deadlock_avoid_type_reg = | ||
| 137 | ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG); | ||
| 138 | chip->intpin_reg_wpermit_reg0 = | ||
| 139 | ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0); | ||
| 140 | chip->intpin_reg_wpermit_reg1 = | ||
| 141 | ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1); | ||
| 142 | chip->intpin_reg_wpermit_reg2 = | ||
| 143 | ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2); | ||
| 144 | chip->intpin_reg_wpermit_reg3 = | ||
| 145 | ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3); | ||
| 146 | dev_dbg(&pdev->dev, "%s : " | ||
| 147 | "chip->phub_id_reg=%x, " | ||
| 148 | "chip->q_pri_val_reg=%x, " | ||
| 149 | "chip->rc_q_maxsize_reg=%x, " | ||
| 150 | "chip->bri_q_maxsize_reg=%x, " | ||
| 151 | "chip->comp_resp_timeout_reg=%x, " | ||
| 152 | "chip->bus_slave_control_reg=%x, " | ||
| 153 | "chip->deadlock_avoid_type_reg=%x, " | ||
| 154 | "chip->intpin_reg_wpermit_reg0=%x, " | ||
| 155 | "chip->intpin_reg_wpermit_reg1=%x, " | ||
| 156 | "chip->intpin_reg_wpermit_reg2=%x, " | ||
| 157 | "chip->intpin_reg_wpermit_reg3=%x\n", __func__, | ||
| 158 | chip->phub_id_reg, | ||
| 159 | chip->q_pri_val_reg, | ||
| 160 | chip->rc_q_maxsize_reg, | ||
| 161 | chip->bri_q_maxsize_reg, | ||
| 162 | chip->comp_resp_timeout_reg, | ||
| 163 | chip->bus_slave_control_reg, | ||
| 164 | chip->deadlock_avoid_type_reg, | ||
| 165 | chip->intpin_reg_wpermit_reg0, | ||
| 166 | chip->intpin_reg_wpermit_reg1, | ||
| 167 | chip->intpin_reg_wpermit_reg2, | ||
| 168 | chip->intpin_reg_wpermit_reg3); | ||
| 169 | for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) { | ||
| 170 | chip->int_reduce_control_reg[i] = | ||
| 171 | ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i); | ||
| 172 | dev_dbg(&pdev->dev, "%s : " | ||
| 173 | "chip->int_reduce_control_reg[%d]=%x\n", | ||
| 174 | __func__, i, chip->int_reduce_control_reg[i]); | ||
| 175 | } | ||
| 176 | chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET); | ||
| 177 | } | ||
| 178 | |||
| 179 | /* pch_phub_restore_reg_conf - restore register configuration */ | ||
| 180 | static void pch_phub_restore_reg_conf(struct pci_dev *pdev) | ||
| 181 | { | ||
| 182 | unsigned int i; | ||
| 183 | struct pch_phub_reg *chip = pci_get_drvdata(pdev); | ||
| 184 | void __iomem *p; | ||
| 185 | p = chip->pch_phub_base_address; | ||
| 186 | |||
| 187 | iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG); | ||
| 188 | iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG); | ||
| 189 | iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG); | ||
| 190 | iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG); | ||
| 191 | iowrite32(chip->comp_resp_timeout_reg, | ||
| 192 | p + PCH_PHUB_COMP_RESP_TIMEOUT_REG); | ||
| 193 | iowrite32(chip->bus_slave_control_reg, | ||
| 194 | p + PCH_PHUB_BUS_SLAVE_CONTROL_REG); | ||
| 195 | iowrite32(chip->deadlock_avoid_type_reg, | ||
| 196 | p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG); | ||
| 197 | iowrite32(chip->intpin_reg_wpermit_reg0, | ||
| 198 | p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0); | ||
| 199 | iowrite32(chip->intpin_reg_wpermit_reg1, | ||
| 200 | p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1); | ||
| 201 | iowrite32(chip->intpin_reg_wpermit_reg2, | ||
| 202 | p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2); | ||
| 203 | iowrite32(chip->intpin_reg_wpermit_reg3, | ||
| 204 | p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3); | ||
| 205 | dev_dbg(&pdev->dev, "%s : " | ||
| 206 | "chip->phub_id_reg=%x, " | ||
| 207 | "chip->q_pri_val_reg=%x, " | ||
| 208 | "chip->rc_q_maxsize_reg=%x, " | ||
| 209 | "chip->bri_q_maxsize_reg=%x, " | ||
| 210 | "chip->comp_resp_timeout_reg=%x, " | ||
| 211 | "chip->bus_slave_control_reg=%x, " | ||
| 212 | "chip->deadlock_avoid_type_reg=%x, " | ||
| 213 | "chip->intpin_reg_wpermit_reg0=%x, " | ||
| 214 | "chip->intpin_reg_wpermit_reg1=%x, " | ||
| 215 | "chip->intpin_reg_wpermit_reg2=%x, " | ||
| 216 | "chip->intpin_reg_wpermit_reg3=%x\n", __func__, | ||
| 217 | chip->phub_id_reg, | ||
| 218 | chip->q_pri_val_reg, | ||
| 219 | chip->rc_q_maxsize_reg, | ||
| 220 | chip->bri_q_maxsize_reg, | ||
| 221 | chip->comp_resp_timeout_reg, | ||
| 222 | chip->bus_slave_control_reg, | ||
| 223 | chip->deadlock_avoid_type_reg, | ||
| 224 | chip->intpin_reg_wpermit_reg0, | ||
| 225 | chip->intpin_reg_wpermit_reg1, | ||
| 226 | chip->intpin_reg_wpermit_reg2, | ||
| 227 | chip->intpin_reg_wpermit_reg3); | ||
| 228 | for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) { | ||
| 229 | iowrite32(chip->int_reduce_control_reg[i], | ||
| 230 | p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i); | ||
| 231 | dev_dbg(&pdev->dev, "%s : " | ||
| 232 | "chip->int_reduce_control_reg[%d]=%x\n", | ||
| 233 | __func__, i, chip->int_reduce_control_reg[i]); | ||
| 234 | } | ||
| 235 | |||
| 236 | iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * pch_phub_read_serial_rom() - Reading Serial ROM | ||
| 241 | * @offset_address: Serial ROM offset address to read. | ||
| 242 | * @data: Read buffer for specified Serial ROM value. | ||
| 243 | */ | ||
| 244 | static void pch_phub_read_serial_rom(struct pch_phub_reg *chip, | ||
| 245 | unsigned int offset_address, u8 *data) | ||
| 246 | { | ||
| 247 | void __iomem *mem_addr = chip->pch_phub_extrom_base_address + | ||
| 248 | offset_address; | ||
| 249 | |||
| 250 | *data = ioread8(mem_addr); | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * pch_phub_write_serial_rom() - Writing Serial ROM | ||
| 255 | * @offset_address: Serial ROM offset address. | ||
| 256 | * @data: Serial ROM value to write. | ||
| 257 | */ | ||
| 258 | static int pch_phub_write_serial_rom(struct pch_phub_reg *chip, | ||
| 259 | unsigned int offset_address, u8 data) | ||
| 260 | { | ||
| 261 | void __iomem *mem_addr = chip->pch_phub_extrom_base_address + | ||
| 262 | (offset_address & PCH_WORD_ADDR_MASK); | ||
| 263 | int i; | ||
| 264 | unsigned int word_data; | ||
| 265 | unsigned int pos; | ||
| 266 | unsigned int mask; | ||
| 267 | pos = (offset_address % 4) * 8; | ||
| 268 | mask = ~(0xFF << pos); | ||
| 269 | |||
| 270 | iowrite32(PCH_PHUB_ROM_WRITE_ENABLE, | ||
| 271 | chip->pch_phub_extrom_base_address + PHUB_CONTROL); | ||
| 272 | |||
| 273 | word_data = ioread32(mem_addr); | ||
| 274 | iowrite32((word_data & mask) | (u32)data << pos, mem_addr); | ||
| 275 | |||
| 276 | i = 0; | ||
| 277 | while (ioread8(chip->pch_phub_extrom_base_address + | ||
| 278 | PHUB_STATUS) != 0x00) { | ||
| 279 | msleep(1); | ||
| 280 | if (i == PHUB_TIMEOUT) | ||
| 281 | return -ETIMEDOUT; | ||
| 282 | i++; | ||
| 283 | } | ||
| 284 | |||
| 285 | iowrite32(PCH_PHUB_ROM_WRITE_DISABLE, | ||
| 286 | chip->pch_phub_extrom_base_address + PHUB_CONTROL); | ||
| 287 | |||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | |||
| 291 | /** | ||
| 292 | * pch_phub_read_serial_rom_val() - Read Serial ROM value | ||
| 293 | * @offset_address: Serial ROM address offset value. | ||
| 294 | * @data: Serial ROM value to read. | ||
| 295 | */ | ||
| 296 | static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip, | ||
| 297 | unsigned int offset_address, u8 *data) | ||
| 298 | { | ||
| 299 | unsigned int mem_addr; | ||
| 300 | |||
| 301 | mem_addr = PCH_PHUB_ROM_START_ADDR + | ||
| 302 | pch_phub_mac_offset[offset_address]; | ||
| 303 | |||
| 304 | pch_phub_read_serial_rom(chip, mem_addr, data); | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * pch_phub_write_serial_rom_val() - writing Serial ROM value | ||
| 309 | * @offset_address: Serial ROM address offset value. | ||
| 310 | * @data: Serial ROM value. | ||
| 311 | */ | ||
| 312 | static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip, | ||
| 313 | unsigned int offset_address, u8 data) | ||
| 314 | { | ||
| 315 | int retval; | ||
| 316 | unsigned int mem_addr; | ||
| 317 | |||
| 318 | mem_addr = PCH_PHUB_ROM_START_ADDR + | ||
| 319 | pch_phub_mac_offset[offset_address]; | ||
| 320 | |||
| 321 | retval = pch_phub_write_serial_rom(chip, mem_addr, data); | ||
| 322 | |||
| 323 | return retval; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration | ||
| 327 | * for Gigabit Ethernet MAC address | ||
| 328 | */ | ||
| 329 | static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip) | ||
| 330 | { | ||
| 331 | int retval; | ||
| 332 | |||
| 333 | retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc); | ||
| 334 | retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10); | ||
| 335 | retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01); | ||
| 336 | retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02); | ||
| 337 | |||
| 338 | retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00); | ||
| 339 | retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00); | ||
| 340 | retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00); | ||
| 341 | retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80); | ||
| 342 | |||
| 343 | retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc); | ||
| 344 | retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10); | ||
| 345 | retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01); | ||
| 346 | retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18); | ||
| 347 | |||
| 348 | retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc); | ||
| 349 | retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10); | ||
| 350 | retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01); | ||
| 351 | retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19); | ||
| 352 | |||
| 353 | retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc); | ||
| 354 | retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10); | ||
| 355 | retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01); | ||
| 356 | retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a); | ||
| 357 | |||
| 358 | retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01); | ||
| 359 | retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00); | ||
| 360 | retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00); | ||
| 361 | retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00); | ||
| 362 | |||
| 363 | return retval; | ||
| 364 | } | ||
| 365 | |||
| 366 | /** | ||
| 367 | * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address | ||
| 368 | * @offset_address: Gigabit Ethernet MAC address offset value. | ||
| 369 | * @data: Buffer of the Gigabit Ethernet MAC address value. | ||
| 370 | */ | ||
| 371 | static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) | ||
| 372 | { | ||
| 373 | int i; | ||
| 374 | for (i = 0; i < ETH_ALEN; i++) | ||
| 375 | pch_phub_read_serial_rom_val(chip, i, &data[i]); | ||
| 376 | } | ||
| 377 | |||
| 378 | /** | ||
| 379 | * pch_phub_write_gbe_mac_addr() - Write MAC address | ||
| 380 | * @offset_address: Gigabit Ethernet MAC address offset value. | ||
| 381 | * @data: Gigabit Ethernet MAC address value. | ||
| 382 | */ | ||
| 383 | static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) | ||
| 384 | { | ||
| 385 | int retval; | ||
| 386 | int i; | ||
| 387 | |||
| 388 | retval = pch_phub_gbe_serial_rom_conf(chip); | ||
| 389 | if (retval) | ||
| 390 | return retval; | ||
| 391 | |||
| 392 | for (i = 0; i < ETH_ALEN; i++) { | ||
| 393 | retval = pch_phub_write_serial_rom_val(chip, i, data[i]); | ||
| 394 | if (retval) | ||
| 395 | return retval; | ||
| 396 | } | ||
| 397 | |||
| 398 | return retval; | ||
| 399 | } | ||
| 400 | |||
| 401 | static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, | ||
| 402 | struct bin_attribute *attr, char *buf, | ||
| 403 | loff_t off, size_t count) | ||
| 404 | { | ||
| 405 | unsigned int rom_signature; | ||
| 406 | unsigned char rom_length; | ||
| 407 | unsigned int tmp; | ||
| 408 | unsigned int addr_offset; | ||
| 409 | unsigned int orom_size; | ||
| 410 | int ret; | ||
| 411 | int err; | ||
| 412 | |||
| 413 | struct pch_phub_reg *chip = | ||
| 414 | dev_get_drvdata(container_of(kobj, struct device, kobj)); | ||
| 415 | |||
| 416 | ret = mutex_lock_interruptible(&pch_phub_mutex); | ||
| 417 | if (ret) { | ||
| 418 | err = -ERESTARTSYS; | ||
| 419 | goto return_err_nomutex; | ||
| 420 | } | ||
| 421 | |||
| 422 | /* Get Rom signature */ | ||
| 423 | pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature); | ||
| 424 | rom_signature &= 0xff; | ||
| 425 | pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp); | ||
| 426 | rom_signature |= (tmp & 0xff) << 8; | ||
| 427 | if (rom_signature == 0xAA55) { | ||
| 428 | pch_phub_read_serial_rom(chip, 0x82, &rom_length); | ||
| 429 | orom_size = rom_length * 512; | ||
| 430 | if (orom_size < off) { | ||
| 431 | addr_offset = 0; | ||
| 432 | goto return_ok; | ||
| 433 | } | ||
| 434 | if (orom_size < count) { | ||
| 435 | addr_offset = 0; | ||
| 436 | goto return_ok; | ||
| 437 | } | ||
| 438 | |||
| 439 | for (addr_offset = 0; addr_offset < count; addr_offset++) { | ||
| 440 | pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off, | ||
| 441 | &buf[addr_offset]); | ||
| 442 | } | ||
| 443 | } else { | ||
| 444 | err = -ENODATA; | ||
| 445 | goto return_err; | ||
| 446 | } | ||
| 447 | return_ok: | ||
| 448 | mutex_unlock(&pch_phub_mutex); | ||
| 449 | return addr_offset; | ||
| 450 | |||
| 451 | return_err: | ||
| 452 | mutex_unlock(&pch_phub_mutex); | ||
| 453 | return_err_nomutex: | ||
| 454 | return err; | ||
| 455 | } | ||
| 456 | |||
| 457 | static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, | ||
| 458 | struct bin_attribute *attr, | ||
| 459 | char *buf, loff_t off, size_t count) | ||
| 460 | { | ||
| 461 | int err; | ||
| 462 | unsigned int addr_offset; | ||
| 463 | int ret; | ||
| 464 | struct pch_phub_reg *chip = | ||
| 465 | dev_get_drvdata(container_of(kobj, struct device, kobj)); | ||
| 466 | |||
| 467 | ret = mutex_lock_interruptible(&pch_phub_mutex); | ||
| 468 | if (ret) | ||
| 469 | return -ERESTARTSYS; | ||
| 470 | |||
| 471 | if (off > PCH_PHUB_OROM_SIZE) { | ||
| 472 | addr_offset = 0; | ||
| 473 | goto return_ok; | ||
| 474 | } | ||
| 475 | if (count > PCH_PHUB_OROM_SIZE) { | ||
| 476 | addr_offset = 0; | ||
| 477 | goto return_ok; | ||
| 478 | } | ||
| 479 | |||
| 480 | for (addr_offset = 0; addr_offset < count; addr_offset++) { | ||
| 481 | if (PCH_PHUB_OROM_SIZE < off + addr_offset) | ||
| 482 | goto return_ok; | ||
| 483 | |||
| 484 | ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off, | ||
| 485 | buf[addr_offset]); | ||
| 486 | if (ret) { | ||
| 487 | err = ret; | ||
| 488 | goto return_err; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | return_ok: | ||
| 493 | mutex_unlock(&pch_phub_mutex); | ||
| 494 | return addr_offset; | ||
| 495 | |||
| 496 | return_err: | ||
| 497 | mutex_unlock(&pch_phub_mutex); | ||
| 498 | return err; | ||
| 499 | } | ||
| 500 | |||
| 501 | static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, | ||
| 502 | char *buf) | ||
| 503 | { | ||
| 504 | u8 mac[8]; | ||
| 505 | struct pch_phub_reg *chip = dev_get_drvdata(dev); | ||
| 506 | |||
| 507 | pch_phub_read_gbe_mac_addr(chip, mac); | ||
| 508 | |||
| 509 | return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
| 510 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | ||
| 511 | } | ||
| 512 | |||
| 513 | static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, | ||
| 514 | const char *buf, size_t count) | ||
| 515 | { | ||
| 516 | u8 mac[6]; | ||
| 517 | struct pch_phub_reg *chip = dev_get_drvdata(dev); | ||
| 518 | |||
| 519 | if (count != 18) | ||
| 520 | return -EINVAL; | ||
| 521 | |||
| 522 | sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", | ||
| 523 | (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], | ||
| 524 | (u32 *)&mac[4], (u32 *)&mac[5]); | ||
| 525 | |||
| 526 | pch_phub_write_gbe_mac_addr(chip, mac); | ||
| 527 | |||
| 528 | return count; | ||
| 529 | } | ||
| 530 | |||
| 531 | static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac); | ||
| 532 | |||
| 533 | static struct bin_attribute pch_bin_attr = { | ||
| 534 | .attr = { | ||
| 535 | .name = "pch_firmware", | ||
| 536 | .mode = S_IRUGO | S_IWUSR, | ||
| 537 | }, | ||
| 538 | .size = PCH_PHUB_OROM_SIZE + 1, | ||
| 539 | .read = pch_phub_bin_read, | ||
| 540 | .write = pch_phub_bin_write, | ||
| 541 | }; | ||
| 542 | |||
| 543 | static int __devinit pch_phub_probe(struct pci_dev *pdev, | ||
| 544 | const struct pci_device_id *id) | ||
| 545 | { | ||
| 546 | int retval; | ||
| 547 | |||
| 548 | int ret; | ||
| 549 | ssize_t rom_size; | ||
| 550 | struct pch_phub_reg *chip; | ||
| 551 | |||
| 552 | chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); | ||
| 553 | if (chip == NULL) | ||
| 554 | return -ENOMEM; | ||
| 555 | |||
| 556 | ret = pci_enable_device(pdev); | ||
| 557 | if (ret) { | ||
| 558 | dev_err(&pdev->dev, | ||
| 559 | "%s : pci_enable_device FAILED(ret=%d)", __func__, ret); | ||
| 560 | goto err_pci_enable_dev; | ||
| 561 | } | ||
| 562 | dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__, | ||
| 563 | ret); | ||
| 564 | |||
| 565 | ret = pci_request_regions(pdev, KBUILD_MODNAME); | ||
| 566 | if (ret) { | ||
| 567 | dev_err(&pdev->dev, | ||
| 568 | "%s : pci_request_regions FAILED(ret=%d)", __func__, ret); | ||
| 569 | goto err_req_regions; | ||
| 570 | } | ||
| 571 | dev_dbg(&pdev->dev, "%s : " | ||
| 572 | "pci_request_regions returns %d\n", __func__, ret); | ||
| 573 | |||
| 574 | chip->pch_phub_base_address = pci_iomap(pdev, 1, 0); | ||
| 575 | |||
| 576 | |||
| 577 | if (chip->pch_phub_base_address == 0) { | ||
| 578 | dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); | ||
| 579 | ret = -ENOMEM; | ||
| 580 | goto err_pci_iomap; | ||
| 581 | } | ||
| 582 | dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " | ||
| 583 | "in pch_phub_base_address variable is %p\n", __func__, | ||
| 584 | chip->pch_phub_base_address); | ||
| 585 | chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size); | ||
| 586 | |||
| 587 | if (chip->pch_phub_extrom_base_address == 0) { | ||
| 588 | dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__); | ||
| 589 | ret = -ENOMEM; | ||
| 590 | goto err_pci_map; | ||
| 591 | } | ||
| 592 | dev_dbg(&pdev->dev, "%s : " | ||
| 593 | "pci_map_rom SUCCESS and value in " | ||
| 594 | "pch_phub_extrom_base_address variable is %p\n", __func__, | ||
| 595 | chip->pch_phub_extrom_base_address); | ||
| 596 | |||
| 597 | pci_set_drvdata(pdev, chip); | ||
| 598 | |||
| 599 | retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); | ||
| 600 | if (retval) | ||
| 601 | goto err_sysfs_create; | ||
| 602 | |||
| 603 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); | ||
| 604 | if (retval) | ||
| 605 | goto exit_bin_attr; | ||
| 606 | |||
| 607 | pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET, | ||
| 608 | CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK); | ||
| 609 | |||
| 610 | /* set the prefech value */ | ||
| 611 | iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); | ||
| 612 | /* set the interrupt delay value */ | ||
| 613 | iowrite32(0x25, chip->pch_phub_base_address + 0x44); | ||
| 614 | |||
| 615 | return 0; | ||
| 616 | exit_bin_attr: | ||
| 617 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); | ||
| 618 | |||
| 619 | err_sysfs_create: | ||
| 620 | pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); | ||
| 621 | err_pci_map: | ||
| 622 | pci_iounmap(pdev, chip->pch_phub_base_address); | ||
| 623 | err_pci_iomap: | ||
| 624 | pci_release_regions(pdev); | ||
| 625 | err_req_regions: | ||
| 626 | pci_disable_device(pdev); | ||
| 627 | err_pci_enable_dev: | ||
| 628 | kfree(chip); | ||
| 629 | dev_err(&pdev->dev, "%s returns %d\n", __func__, ret); | ||
| 630 | return ret; | ||
| 631 | } | ||
| 632 | |||
| 633 | static void __devexit pch_phub_remove(struct pci_dev *pdev) | ||
| 634 | { | ||
| 635 | struct pch_phub_reg *chip = pci_get_drvdata(pdev); | ||
| 636 | |||
| 637 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); | ||
| 638 | sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); | ||
| 639 | pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); | ||
| 640 | pci_iounmap(pdev, chip->pch_phub_base_address); | ||
| 641 | pci_release_regions(pdev); | ||
| 642 | pci_disable_device(pdev); | ||
| 643 | kfree(chip); | ||
| 644 | } | ||
| 645 | |||
| 646 | #ifdef CONFIG_PM | ||
| 647 | |||
| 648 | static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 649 | { | ||
| 650 | int ret; | ||
| 651 | |||
| 652 | pch_phub_save_reg_conf(pdev); | ||
| 653 | ret = pci_save_state(pdev); | ||
| 654 | if (ret) { | ||
| 655 | dev_err(&pdev->dev, | ||
| 656 | " %s -pci_save_state returns %d\n", __func__, ret); | ||
| 657 | return ret; | ||
| 658 | } | ||
| 659 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
| 660 | pci_disable_device(pdev); | ||
| 661 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 662 | |||
| 663 | return 0; | ||
| 664 | } | ||
| 665 | |||
| 666 | static int pch_phub_resume(struct pci_dev *pdev) | ||
| 667 | { | ||
| 668 | int ret; | ||
| 669 | |||
| 670 | pci_set_power_state(pdev, PCI_D0); | ||
| 671 | pci_restore_state(pdev); | ||
| 672 | ret = pci_enable_device(pdev); | ||
| 673 | if (ret) { | ||
| 674 | dev_err(&pdev->dev, | ||
| 675 | "%s-pci_enable_device failed(ret=%d) ", __func__, ret); | ||
| 676 | return ret; | ||
| 677 | } | ||
| 678 | |||
| 679 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
| 680 | pch_phub_restore_reg_conf(pdev); | ||
| 681 | |||
| 682 | return 0; | ||
| 683 | } | ||
| 684 | #else | ||
| 685 | #define pch_phub_suspend NULL | ||
| 686 | #define pch_phub_resume NULL | ||
| 687 | #endif /* CONFIG_PM */ | ||
| 688 | |||
| 689 | static struct pci_device_id pch_phub_pcidev_id[] = { | ||
| 690 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)}, | ||
| 691 | {0,} | ||
| 692 | }; | ||
| 693 | |||
| 694 | static struct pci_driver pch_phub_driver = { | ||
| 695 | .name = "pch_phub", | ||
| 696 | .id_table = pch_phub_pcidev_id, | ||
| 697 | .probe = pch_phub_probe, | ||
| 698 | .remove = __devexit_p(pch_phub_remove), | ||
| 699 | .suspend = pch_phub_suspend, | ||
| 700 | .resume = pch_phub_resume | ||
| 701 | }; | ||
| 702 | |||
| 703 | static int __init pch_phub_pci_init(void) | ||
| 704 | { | ||
| 705 | return pci_register_driver(&pch_phub_driver); | ||
| 706 | } | ||
| 707 | |||
| 708 | static void __exit pch_phub_pci_exit(void) | ||
| 709 | { | ||
| 710 | pci_unregister_driver(&pch_phub_driver); | ||
| 711 | } | ||
| 712 | |||
| 713 | module_init(pch_phub_pci_init); | ||
| 714 | module_exit(pch_phub_pci_exit); | ||
| 715 | |||
| 716 | MODULE_DESCRIPTION("PCH Packet Hub PCI Driver"); | ||
| 717 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 10478153641b..4f7a5829ea4c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
| @@ -412,9 +412,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
| 412 | 412 | ||
| 413 | device_initialize(&shost->shost_gendev); | 413 | device_initialize(&shost->shost_gendev); |
| 414 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); | 414 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); |
| 415 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 416 | shost->shost_gendev.bus = &scsi_bus_type; | 415 | shost->shost_gendev.bus = &scsi_bus_type; |
| 417 | #endif | ||
| 418 | shost->shost_gendev.type = &scsi_host_type; | 416 | shost->shost_gendev.type = &scsi_host_type; |
| 419 | 417 | ||
| 420 | device_initialize(&shost->shost_dev); | 418 | device_initialize(&shost->shost_dev); |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 3d0a1e6e9c48..087821fac8fe 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
| @@ -417,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
| 417 | starget->reap_ref = 1; | 417 | starget->reap_ref = 1; |
| 418 | dev->parent = get_device(parent); | 418 | dev->parent = get_device(parent); |
| 419 | dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id); | 419 | dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id); |
| 420 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 421 | dev->bus = &scsi_bus_type; | 420 | dev->bus = &scsi_bus_type; |
| 422 | #endif | ||
| 423 | dev->type = &scsi_target_type; | 421 | dev->type = &scsi_target_type; |
| 424 | starget->id = id; | 422 | starget->id = id; |
| 425 | starget->channel = channel; | 423 | starget->channel = channel; |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 4d3a6fd1a152..a858d2b87b94 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
| @@ -23,9 +23,10 @@ | |||
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
| 25 | #include <linux/kobject.h> | 25 | #include <linux/kobject.h> |
| 26 | #include <linux/cdev.h> | ||
| 26 | #include <linux/uio_driver.h> | 27 | #include <linux/uio_driver.h> |
| 27 | 28 | ||
| 28 | #define UIO_MAX_DEVICES 255 | 29 | #define UIO_MAX_DEVICES (1U << MINORBITS) |
| 29 | 30 | ||
| 30 | struct uio_device { | 31 | struct uio_device { |
| 31 | struct module *owner; | 32 | struct module *owner; |
| @@ -41,15 +42,10 @@ struct uio_device { | |||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | static int uio_major; | 44 | static int uio_major; |
| 45 | static struct cdev *uio_cdev; | ||
| 44 | static DEFINE_IDR(uio_idr); | 46 | static DEFINE_IDR(uio_idr); |
| 45 | static const struct file_operations uio_fops; | 47 | static const struct file_operations uio_fops; |
| 46 | 48 | ||
| 47 | /* UIO class infrastructure */ | ||
| 48 | static struct uio_class { | ||
| 49 | struct kref kref; | ||
| 50 | struct class *class; | ||
| 51 | } *uio_class; | ||
| 52 | |||
| 53 | /* Protect idr accesses */ | 49 | /* Protect idr accesses */ |
| 54 | static DEFINE_MUTEX(minor_lock); | 50 | static DEFINE_MUTEX(minor_lock); |
| 55 | 51 | ||
| @@ -232,45 +228,34 @@ static ssize_t show_name(struct device *dev, | |||
| 232 | struct device_attribute *attr, char *buf) | 228 | struct device_attribute *attr, char *buf) |
| 233 | { | 229 | { |
| 234 | struct uio_device *idev = dev_get_drvdata(dev); | 230 | struct uio_device *idev = dev_get_drvdata(dev); |
| 235 | if (idev) | 231 | return sprintf(buf, "%s\n", idev->info->name); |
| 236 | return sprintf(buf, "%s\n", idev->info->name); | ||
| 237 | else | ||
| 238 | return -ENODEV; | ||
| 239 | } | 232 | } |
| 240 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 241 | 233 | ||
| 242 | static ssize_t show_version(struct device *dev, | 234 | static ssize_t show_version(struct device *dev, |
| 243 | struct device_attribute *attr, char *buf) | 235 | struct device_attribute *attr, char *buf) |
| 244 | { | 236 | { |
| 245 | struct uio_device *idev = dev_get_drvdata(dev); | 237 | struct uio_device *idev = dev_get_drvdata(dev); |
| 246 | if (idev) | 238 | return sprintf(buf, "%s\n", idev->info->version); |
| 247 | return sprintf(buf, "%s\n", idev->info->version); | ||
| 248 | else | ||
| 249 | return -ENODEV; | ||
| 250 | } | 239 | } |
| 251 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | ||
| 252 | 240 | ||
| 253 | static ssize_t show_event(struct device *dev, | 241 | static ssize_t show_event(struct device *dev, |
| 254 | struct device_attribute *attr, char *buf) | 242 | struct device_attribute *attr, char *buf) |
| 255 | { | 243 | { |
| 256 | struct uio_device *idev = dev_get_drvdata(dev); | 244 | struct uio_device *idev = dev_get_drvdata(dev); |
| 257 | if (idev) | 245 | return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event)); |
| 258 | return sprintf(buf, "%u\n", | ||
| 259 | (unsigned int)atomic_read(&idev->event)); | ||
| 260 | else | ||
| 261 | return -ENODEV; | ||
| 262 | } | 246 | } |
| 263 | static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); | ||
| 264 | 247 | ||
| 265 | static struct attribute *uio_attrs[] = { | 248 | static struct device_attribute uio_class_attributes[] = { |
| 266 | &dev_attr_name.attr, | 249 | __ATTR(name, S_IRUGO, show_name, NULL), |
| 267 | &dev_attr_version.attr, | 250 | __ATTR(version, S_IRUGO, show_version, NULL), |
| 268 | &dev_attr_event.attr, | 251 | __ATTR(event, S_IRUGO, show_event, NULL), |
| 269 | NULL, | 252 | {} |
| 270 | }; | 253 | }; |
| 271 | 254 | ||
| 272 | static struct attribute_group uio_attr_grp = { | 255 | /* UIO class infrastructure */ |
| 273 | .attrs = uio_attrs, | 256 | static struct class uio_class = { |
| 257 | .name = "uio", | ||
| 258 | .dev_attrs = uio_class_attributes, | ||
| 274 | }; | 259 | }; |
| 275 | 260 | ||
| 276 | /* | 261 | /* |
| @@ -287,10 +272,6 @@ static int uio_dev_add_attributes(struct uio_device *idev) | |||
| 287 | struct uio_port *port; | 272 | struct uio_port *port; |
| 288 | struct uio_portio *portio; | 273 | struct uio_portio *portio; |
| 289 | 274 | ||
| 290 | ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp); | ||
| 291 | if (ret) | ||
| 292 | goto err_group; | ||
| 293 | |||
| 294 | for (mi = 0; mi < MAX_UIO_MAPS; mi++) { | 275 | for (mi = 0; mi < MAX_UIO_MAPS; mi++) { |
| 295 | mem = &idev->info->mem[mi]; | 276 | mem = &idev->info->mem[mi]; |
| 296 | if (mem->size == 0) | 277 | if (mem->size == 0) |
| @@ -358,8 +339,6 @@ err_map: | |||
| 358 | kobject_put(&map->kobj); | 339 | kobject_put(&map->kobj); |
| 359 | } | 340 | } |
| 360 | kobject_put(idev->map_dir); | 341 | kobject_put(idev->map_dir); |
| 361 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); | ||
| 362 | err_group: | ||
| 363 | dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); | 342 | dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); |
| 364 | return ret; | 343 | return ret; |
| 365 | } | 344 | } |
| @@ -385,8 +364,6 @@ static void uio_dev_del_attributes(struct uio_device *idev) | |||
| 385 | kobject_put(&port->portio->kobj); | 364 | kobject_put(&port->portio->kobj); |
| 386 | } | 365 | } |
| 387 | kobject_put(idev->portio_dir); | 366 | kobject_put(idev->portio_dir); |
| 388 | |||
| 389 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); | ||
| 390 | } | 367 | } |
| 391 | 368 | ||
| 392 | static int uio_get_minor(struct uio_device *idev) | 369 | 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 | struct uio_listener *listener = filep->private_data; | 502 | struct uio_listener *listener = filep->private_data; |
| 526 | struct uio_device *idev = listener->dev; | 503 | struct uio_device *idev = listener->dev; |
| 527 | 504 | ||
| 528 | if (idev->info->irq == UIO_IRQ_NONE) | 505 | if (!idev->info->irq) |
| 529 | return -EIO; | 506 | return -EIO; |
| 530 | 507 | ||
| 531 | poll_wait(filep, &idev->wait, wait); | 508 | poll_wait(filep, &idev->wait, wait); |
| @@ -543,7 +520,7 @@ static ssize_t uio_read(struct file *filep, char __user *buf, | |||
| 543 | ssize_t retval; | 520 | ssize_t retval; |
| 544 | s32 event_count; | 521 | s32 event_count; |
| 545 | 522 | ||
| 546 | if (idev->info->irq == UIO_IRQ_NONE) | 523 | if (!idev->info->irq) |
| 547 | return -EIO; | 524 | return -EIO; |
| 548 | 525 | ||
| 549 | if (count != sizeof(s32)) | 526 | if (count != sizeof(s32)) |
| @@ -591,7 +568,7 @@ static ssize_t uio_write(struct file *filep, const char __user *buf, | |||
| 591 | ssize_t retval; | 568 | ssize_t retval; |
| 592 | s32 irq_on; | 569 | s32 irq_on; |
| 593 | 570 | ||
| 594 | if (idev->info->irq == UIO_IRQ_NONE) | 571 | if (!idev->info->irq) |
| 595 | return -EIO; | 572 | return -EIO; |
| 596 | 573 | ||
| 597 | if (count != sizeof(s32)) | 574 | if (count != sizeof(s32)) |
| @@ -745,68 +722,72 @@ static const struct file_operations uio_fops = { | |||
| 745 | 722 | ||
| 746 | static int uio_major_init(void) | 723 | static int uio_major_init(void) |
| 747 | { | 724 | { |
| 748 | uio_major = register_chrdev(0, "uio", &uio_fops); | 725 | static const char name[] = "uio"; |
| 749 | if (uio_major < 0) | 726 | struct cdev *cdev = NULL; |
| 750 | return uio_major; | 727 | dev_t uio_dev = 0; |
| 751 | return 0; | 728 | int result; |
| 729 | |||
| 730 | result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name); | ||
| 731 | if (result) | ||
| 732 | goto out; | ||
| 733 | |||
| 734 | result = -ENOMEM; | ||
| 735 | cdev = cdev_alloc(); | ||
| 736 | if (!cdev) | ||
| 737 | goto out_unregister; | ||
| 738 | |||
| 739 | cdev->owner = THIS_MODULE; | ||
| 740 | cdev->ops = &uio_fops; | ||
| 741 | kobject_set_name(&cdev->kobj, "%s", name); | ||
| 742 | |||
| 743 | result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES); | ||
| 744 | if (result) | ||
| 745 | goto out_put; | ||
| 746 | |||
| 747 | uio_major = MAJOR(uio_dev); | ||
| 748 | uio_cdev = cdev; | ||
| 749 | result = 0; | ||
| 750 | out: | ||
| 751 | return result; | ||
| 752 | out_put: | ||
| 753 | kobject_put(&cdev->kobj); | ||
| 754 | out_unregister: | ||
| 755 | unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES); | ||
| 756 | goto out; | ||
| 752 | } | 757 | } |
| 753 | 758 | ||
| 754 | static void uio_major_cleanup(void) | 759 | static void uio_major_cleanup(void) |
| 755 | { | 760 | { |
| 756 | unregister_chrdev(uio_major, "uio"); | 761 | unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES); |
| 762 | cdev_del(uio_cdev); | ||
| 757 | } | 763 | } |
| 758 | 764 | ||
| 759 | static int init_uio_class(void) | 765 | static int init_uio_class(void) |
| 760 | { | 766 | { |
| 761 | int ret = 0; | 767 | int ret; |
| 762 | |||
| 763 | if (uio_class != NULL) { | ||
| 764 | kref_get(&uio_class->kref); | ||
| 765 | goto exit; | ||
| 766 | } | ||
| 767 | 768 | ||
| 768 | /* This is the first time in here, set everything up properly */ | 769 | /* This is the first time in here, set everything up properly */ |
| 769 | ret = uio_major_init(); | 770 | ret = uio_major_init(); |
| 770 | if (ret) | 771 | if (ret) |
| 771 | goto exit; | 772 | goto exit; |
| 772 | 773 | ||
| 773 | uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL); | 774 | ret = class_register(&uio_class); |
| 774 | if (!uio_class) { | 775 | if (ret) { |
| 775 | ret = -ENOMEM; | 776 | printk(KERN_ERR "class_register failed for uio\n"); |
| 776 | goto err_kzalloc; | 777 | goto err_class_register; |
| 777 | } | ||
| 778 | |||
| 779 | kref_init(&uio_class->kref); | ||
| 780 | uio_class->class = class_create(THIS_MODULE, "uio"); | ||
| 781 | if (IS_ERR(uio_class->class)) { | ||
| 782 | ret = IS_ERR(uio_class->class); | ||
| 783 | printk(KERN_ERR "class_create failed for uio\n"); | ||
| 784 | goto err_class_create; | ||
| 785 | } | 778 | } |
| 786 | return 0; | 779 | return 0; |
| 787 | 780 | ||
| 788 | err_class_create: | 781 | err_class_register: |
| 789 | kfree(uio_class); | ||
| 790 | uio_class = NULL; | ||
| 791 | err_kzalloc: | ||
| 792 | uio_major_cleanup(); | 782 | uio_major_cleanup(); |
| 793 | exit: | 783 | exit: |
| 794 | return ret; | 784 | return ret; |
| 795 | } | 785 | } |
| 796 | 786 | ||
| 797 | static void release_uio_class(struct kref *kref) | 787 | static void release_uio_class(void) |
| 798 | { | 788 | { |
| 799 | /* Ok, we cheat as we know we only have one uio_class */ | 789 | class_unregister(&uio_class); |
| 800 | class_destroy(uio_class->class); | ||
| 801 | kfree(uio_class); | ||
| 802 | uio_major_cleanup(); | 790 | uio_major_cleanup(); |
| 803 | uio_class = NULL; | ||
| 804 | } | ||
| 805 | |||
| 806 | static void uio_class_destroy(void) | ||
| 807 | { | ||
| 808 | if (uio_class) | ||
| 809 | kref_put(&uio_class->kref, release_uio_class); | ||
| 810 | } | 791 | } |
| 811 | 792 | ||
| 812 | /** | 793 | /** |
| @@ -829,10 +810,6 @@ int __uio_register_device(struct module *owner, | |||
| 829 | 810 | ||
| 830 | info->uio_dev = NULL; | 811 | info->uio_dev = NULL; |
| 831 | 812 | ||
| 832 | ret = init_uio_class(); | ||
| 833 | if (ret) | ||
| 834 | return ret; | ||
| 835 | |||
| 836 | idev = kzalloc(sizeof(*idev), GFP_KERNEL); | 813 | idev = kzalloc(sizeof(*idev), GFP_KERNEL); |
| 837 | if (!idev) { | 814 | if (!idev) { |
| 838 | ret = -ENOMEM; | 815 | ret = -ENOMEM; |
| @@ -848,7 +825,7 @@ int __uio_register_device(struct module *owner, | |||
| 848 | if (ret) | 825 | if (ret) |
| 849 | goto err_get_minor; | 826 | goto err_get_minor; |
| 850 | 827 | ||
| 851 | idev->dev = device_create(uio_class->class, parent, | 828 | idev->dev = device_create(&uio_class, parent, |
| 852 | MKDEV(uio_major, idev->minor), idev, | 829 | MKDEV(uio_major, idev->minor), idev, |
| 853 | "uio%d", idev->minor); | 830 | "uio%d", idev->minor); |
| 854 | if (IS_ERR(idev->dev)) { | 831 | if (IS_ERR(idev->dev)) { |
| @@ -863,9 +840,9 @@ int __uio_register_device(struct module *owner, | |||
| 863 | 840 | ||
| 864 | info->uio_dev = idev; | 841 | info->uio_dev = idev; |
| 865 | 842 | ||
| 866 | if (idev->info->irq >= 0) { | 843 | if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { |
| 867 | ret = request_irq(idev->info->irq, uio_interrupt, | 844 | ret = request_irq(info->irq, uio_interrupt, |
| 868 | idev->info->irq_flags, idev->info->name, idev); | 845 | info->irq_flags, info->name, idev); |
| 869 | if (ret) | 846 | if (ret) |
| 870 | goto err_request_irq; | 847 | goto err_request_irq; |
| 871 | } | 848 | } |
| @@ -875,13 +852,12 @@ int __uio_register_device(struct module *owner, | |||
| 875 | err_request_irq: | 852 | err_request_irq: |
| 876 | uio_dev_del_attributes(idev); | 853 | uio_dev_del_attributes(idev); |
| 877 | err_uio_dev_add_attributes: | 854 | err_uio_dev_add_attributes: |
| 878 | device_destroy(uio_class->class, MKDEV(uio_major, idev->minor)); | 855 | device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); |
| 879 | err_device_create: | 856 | err_device_create: |
| 880 | uio_free_minor(idev); | 857 | uio_free_minor(idev); |
| 881 | err_get_minor: | 858 | err_get_minor: |
| 882 | kfree(idev); | 859 | kfree(idev); |
| 883 | err_kzalloc: | 860 | err_kzalloc: |
| 884 | uio_class_destroy(); | ||
| 885 | return ret; | 861 | return ret; |
| 886 | } | 862 | } |
| 887 | EXPORT_SYMBOL_GPL(__uio_register_device); | 863 | EXPORT_SYMBOL_GPL(__uio_register_device); |
| @@ -902,15 +878,13 @@ void uio_unregister_device(struct uio_info *info) | |||
| 902 | 878 | ||
| 903 | uio_free_minor(idev); | 879 | uio_free_minor(idev); |
| 904 | 880 | ||
| 905 | if (info->irq >= 0) | 881 | if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) |
| 906 | free_irq(info->irq, idev); | 882 | free_irq(info->irq, idev); |
| 907 | 883 | ||
| 908 | uio_dev_del_attributes(idev); | 884 | uio_dev_del_attributes(idev); |
| 909 | 885 | ||
| 910 | dev_set_drvdata(idev->dev, NULL); | 886 | device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); |
| 911 | device_destroy(uio_class->class, MKDEV(uio_major, idev->minor)); | ||
| 912 | kfree(idev); | 887 | kfree(idev); |
| 913 | uio_class_destroy(); | ||
| 914 | 888 | ||
| 915 | return; | 889 | return; |
| 916 | } | 890 | } |
| @@ -918,11 +892,12 @@ EXPORT_SYMBOL_GPL(uio_unregister_device); | |||
| 918 | 892 | ||
| 919 | static int __init uio_init(void) | 893 | static int __init uio_init(void) |
| 920 | { | 894 | { |
| 921 | return 0; | 895 | return init_uio_class(); |
| 922 | } | 896 | } |
| 923 | 897 | ||
| 924 | static void __exit uio_exit(void) | 898 | static void __exit uio_exit(void) |
| 925 | { | 899 | { |
| 900 | release_uio_class(); | ||
| 926 | } | 901 | } |
| 927 | 902 | ||
| 928 | module_init(uio_init) | 903 | module_init(uio_init) |
diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index 85c9884a67fd..fc22e1e6f215 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c | |||
| @@ -128,12 +128,6 @@ static int __devinit probe(struct pci_dev *pdev, | |||
| 128 | struct uio_pci_generic_dev *gdev; | 128 | struct uio_pci_generic_dev *gdev; |
| 129 | int err; | 129 | int err; |
| 130 | 130 | ||
| 131 | if (!pdev->irq) { | ||
| 132 | dev_warn(&pdev->dev, "No IRQ assigned to device: " | ||
| 133 | "no support for interrupts?\n"); | ||
| 134 | return -ENODEV; | ||
| 135 | } | ||
| 136 | |||
| 137 | err = pci_enable_device(pdev); | 131 | err = pci_enable_device(pdev); |
| 138 | if (err) { | 132 | if (err) { |
| 139 | dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n", | 133 | dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n", |
| @@ -141,6 +135,13 @@ static int __devinit probe(struct pci_dev *pdev, | |||
| 141 | return err; | 135 | return err; |
| 142 | } | 136 | } |
| 143 | 137 | ||
| 138 | if (!pdev->irq) { | ||
| 139 | dev_warn(&pdev->dev, "No IRQ assigned to device: " | ||
| 140 | "no support for interrupts?\n"); | ||
| 141 | pci_disable_device(pdev); | ||
| 142 | return -ENODEV; | ||
| 143 | } | ||
| 144 | |||
| 144 | err = verify_pci_2_3(pdev); | 145 | err = verify_pci_2_3(pdev); |
| 145 | if (err) | 146 | if (err) |
| 146 | goto err_verify; | 147 | goto err_verify; |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 30f46c2cb9d5..b81bfc016a05 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
| @@ -537,14 +537,14 @@ void register_disk(struct gendisk *disk) | |||
| 537 | 537 | ||
| 538 | if (device_add(ddev)) | 538 | if (device_add(ddev)) |
| 539 | return; | 539 | return; |
| 540 | #ifndef CONFIG_SYSFS_DEPRECATED | 540 | if (!sysfs_deprecated) { |
| 541 | err = sysfs_create_link(block_depr, &ddev->kobj, | 541 | err = sysfs_create_link(block_depr, &ddev->kobj, |
| 542 | kobject_name(&ddev->kobj)); | 542 | kobject_name(&ddev->kobj)); |
| 543 | if (err) { | 543 | if (err) { |
| 544 | device_del(ddev); | 544 | device_del(ddev); |
| 545 | return; | 545 | return; |
| 546 | } | ||
| 546 | } | 547 | } |
| 547 | #endif | ||
| 548 | disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); | 548 | disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); |
| 549 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); | 549 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); |
| 550 | 550 | ||
| @@ -766,8 +766,7 @@ void del_gendisk(struct gendisk *disk) | |||
| 766 | kobject_put(disk->part0.holder_dir); | 766 | kobject_put(disk->part0.holder_dir); |
| 767 | kobject_put(disk->slave_dir); | 767 | kobject_put(disk->slave_dir); |
| 768 | disk->driverfs_dev = NULL; | 768 | disk->driverfs_dev = NULL; |
| 769 | #ifndef CONFIG_SYSFS_DEPRECATED | 769 | if (!sysfs_deprecated) |
| 770 | sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); | 770 | sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); |
| 771 | #endif | ||
| 772 | device_del(disk_to_dev(disk)); | 771 | device_del(disk_to_dev(disk)); |
| 773 | } | 772 | } |
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 4e321f7353fa..a4759833d62d 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
| @@ -179,30 +179,14 @@ static void bin_vma_open(struct vm_area_struct *vma) | |||
| 179 | struct bin_buffer *bb = file->private_data; | 179 | struct bin_buffer *bb = file->private_data; |
| 180 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 180 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 181 | 181 | ||
| 182 | if (!bb->vm_ops || !bb->vm_ops->open) | 182 | if (!bb->vm_ops) |
| 183 | return; | ||
| 184 | |||
| 185 | if (!sysfs_get_active(attr_sd)) | ||
| 186 | return; | ||
| 187 | |||
| 188 | bb->vm_ops->open(vma); | ||
| 189 | |||
| 190 | sysfs_put_active(attr_sd); | ||
| 191 | } | ||
| 192 | |||
| 193 | static void bin_vma_close(struct vm_area_struct *vma) | ||
| 194 | { | ||
| 195 | struct file *file = vma->vm_file; | ||
| 196 | struct bin_buffer *bb = file->private_data; | ||
| 197 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | ||
| 198 | |||
| 199 | if (!bb->vm_ops || !bb->vm_ops->close) | ||
| 200 | return; | 183 | return; |
| 201 | 184 | ||
| 202 | if (!sysfs_get_active(attr_sd)) | 185 | if (!sysfs_get_active(attr_sd)) |
| 203 | return; | 186 | return; |
| 204 | 187 | ||
| 205 | bb->vm_ops->close(vma); | 188 | if (bb->vm_ops->open) |
| 189 | bb->vm_ops->open(vma); | ||
| 206 | 190 | ||
| 207 | sysfs_put_active(attr_sd); | 191 | sysfs_put_active(attr_sd); |
| 208 | } | 192 | } |
| @@ -214,13 +198,15 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 214 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 198 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 215 | int ret; | 199 | int ret; |
| 216 | 200 | ||
| 217 | if (!bb->vm_ops || !bb->vm_ops->fault) | 201 | if (!bb->vm_ops) |
| 218 | return VM_FAULT_SIGBUS; | 202 | return VM_FAULT_SIGBUS; |
| 219 | 203 | ||
| 220 | if (!sysfs_get_active(attr_sd)) | 204 | if (!sysfs_get_active(attr_sd)) |
| 221 | return VM_FAULT_SIGBUS; | 205 | return VM_FAULT_SIGBUS; |
| 222 | 206 | ||
| 223 | ret = bb->vm_ops->fault(vma, vmf); | 207 | ret = VM_FAULT_SIGBUS; |
| 208 | if (bb->vm_ops->fault) | ||
| 209 | ret = bb->vm_ops->fault(vma, vmf); | ||
| 224 | 210 | ||
| 225 | sysfs_put_active(attr_sd); | 211 | sysfs_put_active(attr_sd); |
| 226 | return ret; | 212 | return ret; |
| @@ -236,13 +222,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 236 | if (!bb->vm_ops) | 222 | if (!bb->vm_ops) |
| 237 | return VM_FAULT_SIGBUS; | 223 | return VM_FAULT_SIGBUS; |
| 238 | 224 | ||
| 239 | if (!bb->vm_ops->page_mkwrite) | ||
| 240 | return 0; | ||
| 241 | |||
| 242 | if (!sysfs_get_active(attr_sd)) | 225 | if (!sysfs_get_active(attr_sd)) |
| 243 | return VM_FAULT_SIGBUS; | 226 | return VM_FAULT_SIGBUS; |
| 244 | 227 | ||
| 245 | ret = bb->vm_ops->page_mkwrite(vma, vmf); | 228 | ret = 0; |
| 229 | if (bb->vm_ops->page_mkwrite) | ||
| 230 | ret = bb->vm_ops->page_mkwrite(vma, vmf); | ||
| 246 | 231 | ||
| 247 | sysfs_put_active(attr_sd); | 232 | sysfs_put_active(attr_sd); |
| 248 | return ret; | 233 | return ret; |
| @@ -256,13 +241,15 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr, | |||
| 256 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 241 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 257 | int ret; | 242 | int ret; |
| 258 | 243 | ||
| 259 | if (!bb->vm_ops || !bb->vm_ops->access) | 244 | if (!bb->vm_ops) |
| 260 | return -EINVAL; | 245 | return -EINVAL; |
| 261 | 246 | ||
| 262 | if (!sysfs_get_active(attr_sd)) | 247 | if (!sysfs_get_active(attr_sd)) |
| 263 | return -EINVAL; | 248 | return -EINVAL; |
| 264 | 249 | ||
| 265 | ret = bb->vm_ops->access(vma, addr, buf, len, write); | 250 | ret = -EINVAL; |
| 251 | if (bb->vm_ops->access) | ||
| 252 | ret = bb->vm_ops->access(vma, addr, buf, len, write); | ||
| 266 | 253 | ||
| 267 | sysfs_put_active(attr_sd); | 254 | sysfs_put_active(attr_sd); |
| 268 | return ret; | 255 | return ret; |
| @@ -276,13 +263,15 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new) | |||
| 276 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 263 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 277 | int ret; | 264 | int ret; |
| 278 | 265 | ||
| 279 | if (!bb->vm_ops || !bb->vm_ops->set_policy) | 266 | if (!bb->vm_ops) |
| 280 | return 0; | 267 | return 0; |
| 281 | 268 | ||
| 282 | if (!sysfs_get_active(attr_sd)) | 269 | if (!sysfs_get_active(attr_sd)) |
| 283 | return -EINVAL; | 270 | return -EINVAL; |
| 284 | 271 | ||
| 285 | ret = bb->vm_ops->set_policy(vma, new); | 272 | ret = 0; |
| 273 | if (bb->vm_ops->set_policy) | ||
| 274 | ret = bb->vm_ops->set_policy(vma, new); | ||
| 286 | 275 | ||
| 287 | sysfs_put_active(attr_sd); | 276 | sysfs_put_active(attr_sd); |
| 288 | return ret; | 277 | return ret; |
| @@ -296,13 +285,15 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma, | |||
| 296 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 285 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 297 | struct mempolicy *pol; | 286 | struct mempolicy *pol; |
| 298 | 287 | ||
| 299 | if (!bb->vm_ops || !bb->vm_ops->get_policy) | 288 | if (!bb->vm_ops) |
| 300 | return vma->vm_policy; | 289 | return vma->vm_policy; |
| 301 | 290 | ||
| 302 | if (!sysfs_get_active(attr_sd)) | 291 | if (!sysfs_get_active(attr_sd)) |
| 303 | return vma->vm_policy; | 292 | return vma->vm_policy; |
| 304 | 293 | ||
| 305 | pol = bb->vm_ops->get_policy(vma, addr); | 294 | pol = vma->vm_policy; |
| 295 | if (bb->vm_ops->get_policy) | ||
| 296 | pol = bb->vm_ops->get_policy(vma, addr); | ||
| 306 | 297 | ||
| 307 | sysfs_put_active(attr_sd); | 298 | sysfs_put_active(attr_sd); |
| 308 | return pol; | 299 | return pol; |
| @@ -316,13 +307,15 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from, | |||
| 316 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 307 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 317 | int ret; | 308 | int ret; |
| 318 | 309 | ||
| 319 | if (!bb->vm_ops || !bb->vm_ops->migrate) | 310 | if (!bb->vm_ops) |
| 320 | return 0; | 311 | return 0; |
| 321 | 312 | ||
| 322 | if (!sysfs_get_active(attr_sd)) | 313 | if (!sysfs_get_active(attr_sd)) |
| 323 | return 0; | 314 | return 0; |
| 324 | 315 | ||
| 325 | ret = bb->vm_ops->migrate(vma, from, to, flags); | 316 | ret = 0; |
| 317 | if (bb->vm_ops->migrate) | ||
| 318 | ret = bb->vm_ops->migrate(vma, from, to, flags); | ||
| 326 | 319 | ||
| 327 | sysfs_put_active(attr_sd); | 320 | sysfs_put_active(attr_sd); |
| 328 | return ret; | 321 | return ret; |
| @@ -331,7 +324,6 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from, | |||
| 331 | 324 | ||
| 332 | static const struct vm_operations_struct bin_vm_ops = { | 325 | static const struct vm_operations_struct bin_vm_ops = { |
| 333 | .open = bin_vma_open, | 326 | .open = bin_vma_open, |
| 334 | .close = bin_vma_close, | ||
| 335 | .fault = bin_fault, | 327 | .fault = bin_fault, |
| 336 | .page_mkwrite = bin_page_mkwrite, | 328 | .page_mkwrite = bin_page_mkwrite, |
| 337 | .access = bin_access, | 329 | .access = bin_access, |
| @@ -377,6 +369,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma) | |||
| 377 | if (bb->mmapped && bb->vm_ops != vma->vm_ops) | 369 | if (bb->mmapped && bb->vm_ops != vma->vm_ops) |
| 378 | goto out_put; | 370 | goto out_put; |
| 379 | 371 | ||
| 372 | /* | ||
| 373 | * It is not possible to successfully wrap close. | ||
| 374 | * So error if someone is trying to use close. | ||
| 375 | */ | ||
| 376 | rc = -EINVAL; | ||
| 377 | if (vma->vm_ops && vma->vm_ops->close) | ||
| 378 | goto out_put; | ||
| 379 | |||
| 380 | rc = 0; | 380 | rc = 0; |
| 381 | bb->mmapped = 1; | 381 | bb->mmapped = 1; |
| 382 | bb->vm_ops = vma->vm_ops; | 382 | bb->vm_ops = vma->vm_ops; |
diff --git a/include/linux/device.h b/include/linux/device.h index 516fecacf27b..dd4895313468 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -751,4 +751,11 @@ do { \ | |||
| 751 | MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) | 751 | MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) |
| 752 | #define MODULE_ALIAS_CHARDEV_MAJOR(major) \ | 752 | #define MODULE_ALIAS_CHARDEV_MAJOR(major) \ |
| 753 | MODULE_ALIAS("char-major-" __stringify(major) "-*") | 753 | MODULE_ALIAS("char-major-" __stringify(major) "-*") |
| 754 | |||
| 755 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 756 | extern long sysfs_deprecated; | ||
| 757 | #else | ||
| 758 | #define sysfs_deprecated 0 | ||
| 759 | #endif | ||
| 760 | |||
| 754 | #endif /* _DEVICE_H_ */ | 761 | #endif /* _DEVICE_H_ */ |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 7950a37a7146..8f6d12151048 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
| @@ -191,6 +191,8 @@ static inline struct kobj_type *get_ktype(struct kobject *kobj) | |||
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | extern struct kobject *kset_find_obj(struct kset *, const char *); | 193 | extern struct kobject *kset_find_obj(struct kset *, const char *); |
| 194 | extern struct kobject *kset_find_obj_hinted(struct kset *, const char *, | ||
| 195 | struct kobject *); | ||
| 194 | 196 | ||
| 195 | /* The global /sys/kernel/ kobject for people to chain off of */ | 197 | /* The global /sys/kernel/ kobject for people to chain off of */ |
| 196 | extern struct kobject *kernel_kobj; | 198 | extern struct kobject *kernel_kobj; |
diff --git a/include/linux/memory.h b/include/linux/memory.h index 85582e1bcee9..06c1fa0a5c7b 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | struct memory_block { | 23 | struct memory_block { |
| 24 | unsigned long phys_index; | 24 | unsigned long phys_index; |
| 25 | unsigned long state; | 25 | unsigned long state; |
| 26 | int section_count; | ||
| 27 | |||
| 26 | /* | 28 | /* |
| 27 | * This serializes all state change requests. It isn't | 29 | * This serializes all state change requests. It isn't |
| 28 | * held during creation because the control files are | 30 | * held during creation because the control files are |
| @@ -113,6 +115,8 @@ extern int memory_dev_init(void); | |||
| 113 | extern int remove_memory_block(unsigned long, struct mem_section *, int); | 115 | extern int remove_memory_block(unsigned long, struct mem_section *, int); |
| 114 | extern int memory_notify(unsigned long val, void *v); | 116 | extern int memory_notify(unsigned long val, void *v); |
| 115 | extern int memory_isolate_notify(unsigned long val, void *v); | 117 | extern int memory_isolate_notify(unsigned long val, void *v); |
| 118 | extern struct memory_block *find_memory_block_hinted(struct mem_section *, | ||
| 119 | struct memory_block *); | ||
| 116 | extern struct memory_block *find_memory_block(struct mem_section *); | 120 | extern struct memory_block *find_memory_block(struct mem_section *); |
| 117 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) | 121 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) |
| 118 | enum mem_add_context { BOOT, HOTPLUG }; | 122 | enum mem_add_context { BOOT, HOTPLUG }; |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index d7ecad0093bb..2e700ec0601f 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
| @@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr | |||
| 138 | struct resource *res, unsigned int n_res, | 138 | struct resource *res, unsigned int n_res, |
| 139 | const void *data, size_t size); | 139 | const void *data, size_t size); |
| 140 | 140 | ||
| 141 | extern const struct dev_pm_ops * platform_bus_get_pm_ops(void); | ||
| 142 | extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm); | ||
| 143 | |||
| 141 | /* early platform driver interface */ | 144 | /* early platform driver interface */ |
| 142 | struct early_platform_driver { | 145 | struct early_platform_driver { |
| 143 | const char *class_str; | 146 | const char *class_str; |
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index 5dcc9ff72f69..d6188e5a52df 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h | |||
| @@ -108,7 +108,7 @@ extern void uio_event_notify(struct uio_info *info); | |||
| 108 | 108 | ||
| 109 | /* defines for uio_info->irq */ | 109 | /* defines for uio_info->irq */ |
| 110 | #define UIO_IRQ_CUSTOM -1 | 110 | #define UIO_IRQ_CUSTOM -1 |
| 111 | #define UIO_IRQ_NONE -2 | 111 | #define UIO_IRQ_NONE 0 |
| 112 | 112 | ||
| 113 | /* defines for uio_mem->memtype */ | 113 | /* defines for uio_mem->memtype */ |
| 114 | #define UIO_MEM_NONE 0 | 114 | #define UIO_MEM_NONE 0 |
diff --git a/include/sound/core.h b/include/sound/core.h index 89e0ac17f44a..df26ebbfa9c6 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
| @@ -133,9 +133,7 @@ struct snd_card { | |||
| 133 | int free_on_last_close; /* free in context of file_release */ | 133 | int free_on_last_close; /* free in context of file_release */ |
| 134 | wait_queue_head_t shutdown_sleep; | 134 | wait_queue_head_t shutdown_sleep; |
| 135 | struct device *dev; /* device assigned to this card */ | 135 | struct device *dev; /* device assigned to this card */ |
| 136 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 137 | struct device *card_dev; /* cardX object for sysfs */ | 136 | struct device *card_dev; /* cardX object for sysfs */ |
| 138 | #endif | ||
| 139 | 137 | ||
| 140 | #ifdef CONFIG_PM | 138 | #ifdef CONFIG_PM |
| 141 | unsigned int power_state; /* power state */ | 139 | unsigned int power_state; /* power state */ |
| @@ -196,11 +194,7 @@ struct snd_minor { | |||
| 196 | /* return a device pointer linked to each sound device as a parent */ | 194 | /* return a device pointer linked to each sound device as a parent */ |
| 197 | static inline struct device *snd_card_get_device_link(struct snd_card *card) | 195 | static inline struct device *snd_card_get_device_link(struct snd_card *card) |
| 198 | { | 196 | { |
| 199 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 200 | return card ? card->dev : NULL; | ||
| 201 | #else | ||
| 202 | return card ? card->card_dev : NULL; | 197 | return card ? card->card_dev : NULL; |
| 203 | #endif | ||
| 204 | } | 198 | } |
| 205 | 199 | ||
| 206 | /* sound.c */ | 200 | /* sound.c */ |
diff --git a/init/Kconfig b/init/Kconfig index bd125a795374..fdfd97efe0e0 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
| @@ -686,40 +686,42 @@ config MM_OWNER | |||
| 686 | bool | 686 | bool |
| 687 | 687 | ||
| 688 | config SYSFS_DEPRECATED | 688 | config SYSFS_DEPRECATED |
| 689 | bool | ||
| 690 | |||
| 691 | config SYSFS_DEPRECATED_V2 | ||
| 692 | bool "enable deprecated sysfs features to support old userspace tools" | 689 | bool "enable deprecated sysfs features to support old userspace tools" |
| 693 | depends on SYSFS | 690 | depends on SYSFS |
| 694 | default n | 691 | default n |
| 695 | select SYSFS_DEPRECATED | 692 | help |
| 696 | help | 693 | This option adds code that switches the layout of the "block" class |
| 697 | This option switches the layout of sysfs to the deprecated | 694 | devices, to not show up in /sys/class/block/, but only in |
| 698 | version. Do not use it on recent distributions. | 695 | /sys/block/. |
| 699 | 696 | ||
| 700 | The current sysfs layout features a unified device tree at | 697 | This switch is only active when the sysfs.deprecated=1 boot option is |
| 701 | /sys/devices/, which is able to express a hierarchy between | 698 | passed or the SYSFS_DEPRECATED_V2 option is set. |
| 702 | class devices. If the deprecated option is set to Y, the | 699 | |
| 703 | unified device tree is split into a bus device tree at | 700 | This option allows new kernels to run on old distributions and tools, |
| 704 | /sys/devices/ and several individual class device trees at | 701 | which might get confused by /sys/class/block/. Since 2007/2008 all |
| 705 | /sys/class/. The class and bus devices will be connected by | 702 | major distributions and tools handle this just fine. |
| 706 | "<subsystem>:<name>" and the "device" links. The "block" | 703 | |
| 707 | class devices, will not show up in /sys/class/block/. Some | 704 | Recent distributions and userspace tools after 2009/2010 depend on |
| 708 | subsystems will suppress the creation of some devices which | 705 | the existence of /sys/class/block/, and will not work with this |
| 709 | depend on the unified device tree. | 706 | option enabled. |
| 710 | 707 | ||
| 711 | This option is not a pure compatibility option that can | 708 | Only if you are using a new kernel on an old distribution, you might |
| 712 | be safely enabled on newer distributions. It will change the | 709 | need to say Y here. |
| 713 | layout of sysfs to the non-extensible deprecated version, | 710 | |
| 714 | and disable some features, which can not be exported without | 711 | config SYSFS_DEPRECATED_V2 |
| 715 | confusing older userspace tools. Since 2007/2008 all major | 712 | bool "enabled deprecated sysfs features by default" |
| 716 | distributions do not enable this option, and ship no tools which | 713 | default n |
| 717 | depend on the deprecated layout or this option. | 714 | depends on SYSFS |
| 718 | 715 | depends on SYSFS_DEPRECATED | |
| 719 | If you are using a new kernel on an older distribution, or use | 716 | help |
| 720 | older userspace tools, you might need to say Y here. Do not say Y, | 717 | Enable deprecated sysfs by default. |
| 721 | if the original kernel, that came with your distribution, has | 718 | |
| 722 | this option set to N. | 719 | See the CONFIG_SYSFS_DEPRECATED option for more details about this |
| 720 | option. | ||
| 721 | |||
| 722 | Only if you are using a new kernel on an old distribution, you might | ||
| 723 | need to say Y here. Even then, odds are you would not need it | ||
| 724 | enabled, you can always pass the boot option if absolutely necessary. | ||
| 723 | 725 | ||
| 724 | config RELAY | 726 | config RELAY |
| 725 | bool "Kernel->user space relay support (formerly relayfs)" | 727 | bool "Kernel->user space relay support (formerly relayfs)" |
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 7bd6df781ce5..3094318bfea7 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
| @@ -393,6 +393,40 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
| 393 | return 0; | 393 | return 0; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | static int ddebug_exec_query(char *query_string) | ||
| 397 | { | ||
| 398 | unsigned int flags = 0, mask = 0; | ||
| 399 | struct ddebug_query query; | ||
| 400 | #define MAXWORDS 9 | ||
| 401 | int nwords; | ||
| 402 | char *words[MAXWORDS]; | ||
| 403 | |||
| 404 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); | ||
| 405 | if (nwords <= 0) | ||
| 406 | return -EINVAL; | ||
| 407 | if (ddebug_parse_query(words, nwords-1, &query)) | ||
| 408 | return -EINVAL; | ||
| 409 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) | ||
| 410 | return -EINVAL; | ||
| 411 | |||
| 412 | /* actually go and implement the change */ | ||
| 413 | ddebug_change(&query, flags, mask); | ||
| 414 | return 0; | ||
| 415 | } | ||
| 416 | |||
| 417 | static __initdata char ddebug_setup_string[1024]; | ||
| 418 | static __init int ddebug_setup_query(char *str) | ||
| 419 | { | ||
| 420 | if (strlen(str) >= 1024) { | ||
| 421 | pr_warning("ddebug boot param string too large\n"); | ||
| 422 | return 0; | ||
| 423 | } | ||
| 424 | strcpy(ddebug_setup_string, str); | ||
| 425 | return 1; | ||
| 426 | } | ||
| 427 | |||
| 428 | __setup("ddebug_query=", ddebug_setup_query); | ||
| 429 | |||
| 396 | /* | 430 | /* |
| 397 | * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the | 431 | * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the |
| 398 | * command text from userspace, parses and executes it. | 432 | * command text from userspace, parses and executes it. |
| @@ -400,12 +434,8 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
| 400 | static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, | 434 | static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, |
| 401 | size_t len, loff_t *offp) | 435 | size_t len, loff_t *offp) |
| 402 | { | 436 | { |
| 403 | unsigned int flags = 0, mask = 0; | ||
| 404 | struct ddebug_query query; | ||
| 405 | #define MAXWORDS 9 | ||
| 406 | int nwords; | ||
| 407 | char *words[MAXWORDS]; | ||
| 408 | char tmpbuf[256]; | 437 | char tmpbuf[256]; |
| 438 | int ret; | ||
| 409 | 439 | ||
| 410 | if (len == 0) | 440 | if (len == 0) |
| 411 | return 0; | 441 | return 0; |
| @@ -419,16 +449,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, | |||
| 419 | printk(KERN_INFO "%s: read %d bytes from userspace\n", | 449 | printk(KERN_INFO "%s: read %d bytes from userspace\n", |
| 420 | __func__, (int)len); | 450 | __func__, (int)len); |
| 421 | 451 | ||
| 422 | nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS); | 452 | ret = ddebug_exec_query(tmpbuf); |
| 423 | if (nwords <= 0) | 453 | if (ret) |
| 424 | return -EINVAL; | 454 | return ret; |
| 425 | if (ddebug_parse_query(words, nwords-1, &query)) | ||
| 426 | return -EINVAL; | ||
| 427 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) | ||
| 428 | return -EINVAL; | ||
| 429 | |||
| 430 | /* actually go and implement the change */ | ||
| 431 | ddebug_change(&query, flags, mask); | ||
| 432 | 455 | ||
| 433 | *offp += len; | 456 | *offp += len; |
| 434 | return len; | 457 | return len; |
| @@ -689,13 +712,14 @@ static void ddebug_remove_all_tables(void) | |||
| 689 | mutex_unlock(&ddebug_lock); | 712 | mutex_unlock(&ddebug_lock); |
| 690 | } | 713 | } |
| 691 | 714 | ||
| 692 | static int __init dynamic_debug_init(void) | 715 | static __initdata int ddebug_init_success; |
| 716 | |||
| 717 | static int __init dynamic_debug_init_debugfs(void) | ||
| 693 | { | 718 | { |
| 694 | struct dentry *dir, *file; | 719 | struct dentry *dir, *file; |
| 695 | struct _ddebug *iter, *iter_start; | 720 | |
| 696 | const char *modname = NULL; | 721 | if (!ddebug_init_success) |
| 697 | int ret = 0; | 722 | return -ENODEV; |
| 698 | int n = 0; | ||
| 699 | 723 | ||
| 700 | dir = debugfs_create_dir("dynamic_debug", NULL); | 724 | dir = debugfs_create_dir("dynamic_debug", NULL); |
| 701 | if (!dir) | 725 | if (!dir) |
| @@ -706,6 +730,16 @@ static int __init dynamic_debug_init(void) | |||
| 706 | debugfs_remove(dir); | 730 | debugfs_remove(dir); |
| 707 | return -ENOMEM; | 731 | return -ENOMEM; |
| 708 | } | 732 | } |
| 733 | return 0; | ||
| 734 | } | ||
| 735 | |||
| 736 | static int __init dynamic_debug_init(void) | ||
| 737 | { | ||
| 738 | struct _ddebug *iter, *iter_start; | ||
| 739 | const char *modname = NULL; | ||
| 740 | int ret = 0; | ||
| 741 | int n = 0; | ||
| 742 | |||
| 709 | if (__start___verbose != __stop___verbose) { | 743 | if (__start___verbose != __stop___verbose) { |
| 710 | iter = __start___verbose; | 744 | iter = __start___verbose; |
| 711 | modname = iter->modname; | 745 | modname = iter->modname; |
| @@ -723,12 +757,26 @@ static int __init dynamic_debug_init(void) | |||
| 723 | } | 757 | } |
| 724 | ret = ddebug_add_module(iter_start, n, modname); | 758 | ret = ddebug_add_module(iter_start, n, modname); |
| 725 | } | 759 | } |
| 760 | |||
| 761 | /* ddebug_query boot param got passed -> set it up */ | ||
| 762 | if (ddebug_setup_string[0] != '\0') { | ||
| 763 | ret = ddebug_exec_query(ddebug_setup_string); | ||
| 764 | if (ret) | ||
| 765 | pr_warning("Invalid ddebug boot param %s", | ||
| 766 | ddebug_setup_string); | ||
| 767 | else | ||
| 768 | pr_info("ddebug initialized with string %s", | ||
| 769 | ddebug_setup_string); | ||
| 770 | } | ||
| 771 | |||
| 726 | out_free: | 772 | out_free: |
| 727 | if (ret) { | 773 | if (ret) |
| 728 | ddebug_remove_all_tables(); | 774 | ddebug_remove_all_tables(); |
| 729 | debugfs_remove(dir); | 775 | else |
| 730 | debugfs_remove(file); | 776 | ddebug_init_success = 1; |
| 731 | } | ||
| 732 | return 0; | 777 | return 0; |
| 733 | } | 778 | } |
| 734 | module_init(dynamic_debug_init); | 779 | /* Allow early initialization for boot messages via boot param */ |
| 780 | arch_initcall(dynamic_debug_init); | ||
| 781 | /* Debugfs setup must be done later */ | ||
| 782 | module_init(dynamic_debug_init_debugfs); | ||
diff --git a/lib/kobject.c b/lib/kobject.c index f07c57252e82..82dc34c095c2 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
| @@ -746,17 +746,56 @@ void kset_unregister(struct kset *k) | |||
| 746 | */ | 746 | */ |
| 747 | struct kobject *kset_find_obj(struct kset *kset, const char *name) | 747 | struct kobject *kset_find_obj(struct kset *kset, const char *name) |
| 748 | { | 748 | { |
| 749 | return kset_find_obj_hinted(kset, name, NULL); | ||
| 750 | } | ||
| 751 | |||
| 752 | /** | ||
| 753 | * kset_find_obj_hinted - search for object in kset given a predecessor hint. | ||
| 754 | * @kset: kset we're looking in. | ||
| 755 | * @name: object's name. | ||
| 756 | * @hint: hint to possible object's predecessor. | ||
| 757 | * | ||
| 758 | * Check the hint's next object and if it is a match return it directly, | ||
| 759 | * otherwise, fall back to the behavior of kset_find_obj(). Either way | ||
| 760 | * a reference for the returned object is held and the reference on the | ||
| 761 | * hinted object is released. | ||
| 762 | */ | ||
| 763 | struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name, | ||
| 764 | struct kobject *hint) | ||
| 765 | { | ||
| 749 | struct kobject *k; | 766 | struct kobject *k; |
| 750 | struct kobject *ret = NULL; | 767 | struct kobject *ret = NULL; |
| 751 | 768 | ||
| 752 | spin_lock(&kset->list_lock); | 769 | spin_lock(&kset->list_lock); |
| 770 | |||
| 771 | if (!hint) | ||
| 772 | goto slow_search; | ||
| 773 | |||
| 774 | /* end of list detection */ | ||
| 775 | if (hint->entry.next == kset->list.next) | ||
| 776 | goto slow_search; | ||
| 777 | |||
| 778 | k = container_of(hint->entry.next, struct kobject, entry); | ||
| 779 | if (!kobject_name(k) || strcmp(kobject_name(k), name)) | ||
| 780 | goto slow_search; | ||
| 781 | |||
| 782 | ret = kobject_get(k); | ||
| 783 | goto unlock_exit; | ||
| 784 | |||
| 785 | slow_search: | ||
| 753 | list_for_each_entry(k, &kset->list, entry) { | 786 | list_for_each_entry(k, &kset->list, entry) { |
| 754 | if (kobject_name(k) && !strcmp(kobject_name(k), name)) { | 787 | if (kobject_name(k) && !strcmp(kobject_name(k), name)) { |
| 755 | ret = kobject_get(k); | 788 | ret = kobject_get(k); |
| 756 | break; | 789 | break; |
| 757 | } | 790 | } |
| 758 | } | 791 | } |
| 792 | |||
| 793 | unlock_exit: | ||
| 759 | spin_unlock(&kset->list_lock); | 794 | spin_unlock(&kset->list_lock); |
| 795 | |||
| 796 | if (hint) | ||
| 797 | kobject_put(hint); | ||
| 798 | |||
| 760 | return ret; | 799 | return ret; |
| 761 | } | 800 | } |
| 762 | 801 | ||
diff --git a/sound/core/init.c b/sound/core/init.c index ec4a50ce5656..f7c3df8b521b 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
| @@ -395,12 +395,10 @@ int snd_card_disconnect(struct snd_card *card) | |||
| 395 | snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number); | 395 | snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number); |
| 396 | 396 | ||
| 397 | snd_info_card_disconnect(card); | 397 | snd_info_card_disconnect(card); |
| 398 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 399 | if (card->card_dev) { | 398 | if (card->card_dev) { |
| 400 | device_unregister(card->card_dev); | 399 | device_unregister(card->card_dev); |
| 401 | card->card_dev = NULL; | 400 | card->card_dev = NULL; |
| 402 | } | 401 | } |
| 403 | #endif | ||
| 404 | #ifdef CONFIG_PM | 402 | #ifdef CONFIG_PM |
| 405 | wake_up(&card->power_sleep); | 403 | wake_up(&card->power_sleep); |
| 406 | #endif | 404 | #endif |
| @@ -573,7 +571,6 @@ void snd_card_set_id(struct snd_card *card, const char *nid) | |||
| 573 | } | 571 | } |
| 574 | EXPORT_SYMBOL(snd_card_set_id); | 572 | EXPORT_SYMBOL(snd_card_set_id); |
| 575 | 573 | ||
| 576 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 577 | static ssize_t | 574 | static ssize_t |
| 578 | card_id_show_attr(struct device *dev, | 575 | card_id_show_attr(struct device *dev, |
| 579 | struct device_attribute *attr, char *buf) | 576 | struct device_attribute *attr, char *buf) |
| @@ -630,7 +627,6 @@ card_number_show_attr(struct device *dev, | |||
| 630 | 627 | ||
| 631 | static struct device_attribute card_number_attrs = | 628 | static struct device_attribute card_number_attrs = |
| 632 | __ATTR(number, S_IRUGO, card_number_show_attr, NULL); | 629 | __ATTR(number, S_IRUGO, card_number_show_attr, NULL); |
| 633 | #endif /* CONFIG_SYSFS_DEPRECATED */ | ||
| 634 | 630 | ||
| 635 | /** | 631 | /** |
| 636 | * snd_card_register - register the soundcard | 632 | * snd_card_register - register the soundcard |
| @@ -649,7 +645,7 @@ int snd_card_register(struct snd_card *card) | |||
| 649 | 645 | ||
| 650 | if (snd_BUG_ON(!card)) | 646 | if (snd_BUG_ON(!card)) |
| 651 | return -EINVAL; | 647 | return -EINVAL; |
| 652 | #ifndef CONFIG_SYSFS_DEPRECATED | 648 | |
| 653 | if (!card->card_dev) { | 649 | if (!card->card_dev) { |
| 654 | card->card_dev = device_create(sound_class, card->dev, | 650 | card->card_dev = device_create(sound_class, card->dev, |
| 655 | MKDEV(0, 0), card, | 651 | MKDEV(0, 0), card, |
| @@ -657,7 +653,7 @@ int snd_card_register(struct snd_card *card) | |||
| 657 | if (IS_ERR(card->card_dev)) | 653 | if (IS_ERR(card->card_dev)) |
| 658 | card->card_dev = NULL; | 654 | card->card_dev = NULL; |
| 659 | } | 655 | } |
| 660 | #endif | 656 | |
| 661 | if ((err = snd_device_register_all(card)) < 0) | 657 | if ((err = snd_device_register_all(card)) < 0) |
| 662 | return err; | 658 | return err; |
| 663 | mutex_lock(&snd_card_mutex); | 659 | mutex_lock(&snd_card_mutex); |
| @@ -674,7 +670,6 @@ int snd_card_register(struct snd_card *card) | |||
| 674 | if (snd_mixer_oss_notify_callback) | 670 | if (snd_mixer_oss_notify_callback) |
| 675 | snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); | 671 | snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); |
| 676 | #endif | 672 | #endif |
| 677 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 678 | if (card->card_dev) { | 673 | if (card->card_dev) { |
| 679 | err = device_create_file(card->card_dev, &card_id_attrs); | 674 | err = device_create_file(card->card_dev, &card_id_attrs); |
| 680 | if (err < 0) | 675 | if (err < 0) |
| @@ -683,7 +678,7 @@ int snd_card_register(struct snd_card *card) | |||
| 683 | if (err < 0) | 678 | if (err < 0) |
| 684 | return err; | 679 | return err; |
| 685 | } | 680 | } |
| 686 | #endif | 681 | |
| 687 | return 0; | 682 | return 0; |
| 688 | } | 683 | } |
| 689 | 684 | ||
