Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 23 Oct 2010 02:36:42 +0000 (19:36 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 23 Oct 2010 02:36:42 +0000 (19:36 -0700)
* 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
  ...

1  2 
Documentation/kernel-parameters.txt
MAINTAINERS
block/genhd.c
drivers/misc/hpilo.c
drivers/scsi/hosts.c
drivers/uio/uio.c
fs/partitions/check.c
init/Kconfig
lib/dynamic_debug.c

@@@ -43,10 -43,11 +43,11 @@@ parameter is applicable
        AVR32   AVR32 architecture is enabled.
        AX25    Appropriate AX.25 support is enabled.
        BLACKFIN Blackfin architecture is enabled.
-       DRM     Direct Rendering Management support is enabled.
        EDD     BIOS Enhanced Disk Drive Services (EDD) is enabled
        EFI     EFI Partitioning (GPT) is enabled
        EIDE    EIDE/ATAPI support is enabled.
+       DRM     Direct Rendering Management support is enabled.
+       DYNAMIC_DEBUG Build in debug messages and enable them at runtime
        FB      The frame buffer device is enabled.
        GCOV    GCOV profiling is enabled.
        HW      Appropriate hardware is enabled.
@@@ -455,7 -456,7 +456,7 @@@ and is between 256 and 4096 characters
                        [ARM] imx_timer1,OSTS,netx_timer,mpu_timer2,
                                pxa_timer,timer3,32k_counter,timer0_1
                        [AVR32] avr32
 -                      [X86-32] pit,hpet,tsc,vmi-timer;
 +                      [X86-32] pit,hpet,tsc;
                                scx200_hrt on Geode; cyclone on IBM x440
                        [MIPS] MIPS
                        [PARISC] cr16
                        Format: <port#>,<type>
                        See also Documentation/input/joystick-parport.txt
  
+       ddebug_query=   [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
+                       time. See Documentation/dynamic-debug-howto.txt for
+                       details.
        debug           [KNL] Enable kernel debugging (events log level).
  
        debug_locks_verbose=
                        Reserves a hole at the top of the kernel virtual
                        address space.
  
 +      reservelow=     [X86]
 +                      Format: nn[K]
 +                      Set the amount of memory to reserve for BIOS at
 +                      the bottom of the address space.
 +
        reset_devices   [KNL] Force drivers to reset the underlying device
                        during initialization.
  
                        in <PAGE_SIZE> units (needed only for swap files).
                        See  Documentation/power/swsusp-and-swap-files.txt
  
 +      hibernate=      [HIBERNATION]
 +              noresume        Don't check if there's a hibernation image
 +                              present during boot.
 +              nocompress      Don't compress/decompress hibernation images.
 +
        retain_initrd   [RAM] Keep initrd memory after extraction
  
        rhash_entries=  [KNL,NET]
  
        switches=       [HW,M68k]
  
+       sysfs.deprecated=0|1 [KNL]
+                       Enable/disable old style sysfs layout for old udev
+                       on older distributions. When this option is enabled
+                       very new udev will not work anymore. When this option
+                       is disabled (or CONFIG_SYSFS_DEPRECATED not compiled)
+                       in older udev will not work anymore.
+                       Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in
+                       the kernel configuration.
        sysrq_always_enabled
                        [KNL]
                        Ignore sysrq setting - this boot parameter will
                        disables clocksource verification at runtime.
                        Used to enable high-resolution timer mode on older
                        hardware, and in virtualized environment.
 +                      [x86] noirqtime: Do not use TSC to do irq accounting.
 +                      Used to run time disable IRQ_TIME_ACCOUNTING on any
 +                      platforms where RDTSC is slow and this accounting
 +                      can add overhead.
  
        turbografx.map[2|3]=    [HW,JOY]
                        TurboGraFX parallel port interface
diff --combined MAINTAINERS
@@@ -990,23 -990,11 +990,23 @@@ S:      Supporte
  F:    arch/arm/mach-shmobile/
  F:    drivers/sh/
  
 +ARM/TELECHIPS ARM ARCHITECTURE
 +M:    "Hans J. Koch" <hjk@linutronix.de>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +F:    arch/arm/plat-tcc/
 +F:    arch/arm/mach-tcc8k/
 +
  ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
  M:    Lennert Buytenhek <kernel@wantstofly.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  
 +ARM/TETON BGA MACHINE SUPPORT
 +M:    Mark F. Brown <mark.brown314@gmail.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +
  ARM/THECUS N2100 MACHINE SUPPORT
  M:    Lennert Buytenhek <kernel@wantstofly.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -1539,8 -1527,6 +1539,8 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    Documentation/filesystems/ceph.txt
  F:    fs/ceph
 +F:    net/ceph
 +F:    include/linux/ceph
  
  CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
  M:    David Vrabel <david.vrabel@csr.com>
@@@ -2064,14 -2050,16 +2064,16 @@@ F:   drivers/block/drbd
  F:    lib/lru_cache.c
  F:    Documentation/blockdev/drbd/
  
- DRIVER CORE, KOBJECTS, AND SYSFS
+ DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
  M:    Greg Kroah-Hartman <gregkh@suse.de>
  T:    quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
  S:    Supported
  F:    Documentation/kobject.txt
  F:    drivers/base/
  F:    fs/sysfs/
+ F:    fs/debugfs/
  F:    include/linux/kobj*
+ F:    include/linux/debugfs.h
  F:    lib/kobj*
  
  DRM DRIVERS
@@@ -3253,12 -3241,6 +3255,12 @@@ F:    drivers/net/irda
  F:    include/net/irda/
  F:    net/irda/
  
 +IRQ SUBSYSTEM
 +M:    Thomas Gleixner <tglx@linutronix.de>
 +S:    Maintained
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core
 +F:    kernel/irq/
 +
  ISAPNP
  M:    Jaroslav Kysela <perex@perex.cz>
  S:    Maintained
@@@ -4825,15 -4807,6 +4827,15 @@@ F:    fs/qnx4
  F:    include/linux/qnx4_fs.h
  F:    include/linux/qnxtypes.h
  
 +RADOS BLOCK DEVICE (RBD)
 +F:    include/linux/qnxtypes.h
 +M:    Yehuda Sadeh <yehuda@hq.newdream.net>
 +M:    Sage Weil <sage@newdream.net>
 +M:    ceph-devel@vger.kernel.org
 +S:    Supported
 +F:    drivers/block/rbd.c
 +F:    drivers/block/rbd_types.h
 +
  RADEON FRAMEBUFFER DISPLAY DRIVER
  M:    Benjamin Herrenschmidt <benh@kernel.crashing.org>
  L:    linux-fbdev@vger.kernel.org
diff --combined block/genhd.c
@@@ -22,9 -22,7 +22,7 @@@
  #include "blk.h"
  
  static DEFINE_MUTEX(block_class_lock);
- #ifndef CONFIG_SYSFS_DEPRECATED
  struct kobject *block_depr;
- #endif
  
  /* for extended dynamic devt allocation, currently only one major is used */
  #define MAX_EXT_DEVT          (1 << MINORBITS)
@@@ -541,15 -539,13 +539,15 @@@ void add_disk(struct gendisk *disk
        disk->major = MAJOR(devt);
        disk->first_minor = MINOR(devt);
  
 +      /* Register BDI before referencing it from bdev */ 
 +      bdi = &disk->queue->backing_dev_info;
 +      bdi_register_dev(bdi, disk_devt(disk));
 +
        blk_register_region(disk_devt(disk), disk->minors, NULL,
                            exact_match, exact_lock, disk);
        register_disk(disk);
        blk_register_queue(disk);
  
 -      bdi = &disk->queue->backing_dev_info;
 -      bdi_register_dev(bdi, disk_devt(disk));
        retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
                                   "bdi");
        WARN_ON(retval);
@@@ -644,7 -640,6 +642,7 @@@ void __init printk_all_partitions(void
                struct hd_struct *part;
                char name_buf[BDEVNAME_SIZE];
                char devt_buf[BDEVT_SIZE];
 +              u8 uuid[PARTITION_META_INFO_UUIDLTH * 2 + 1];
  
                /*
                 * Don't show empty devices or things that have been
                while ((part = disk_part_iter_next(&piter))) {
                        bool is_part0 = part == &disk->part0;
  
 -                      printk("%s%s %10llu %s", is_part0 ? "" : "  ",
 +                      uuid[0] = 0;
 +                      if (part->info)
 +                              part_unpack_uuid(part->info->uuid, uuid);
 +
 +                      printk("%s%s %10llu %s %s", is_part0 ? "" : "  ",
                               bdevt_str(part_devt(part), devt_buf),
                               (unsigned long long)part->nr_sects >> 1,
 -                             disk_name(disk, part->partno, name_buf));
 +                             disk_name(disk, part->partno, name_buf), uuid);
                        if (is_part0) {
                                if (disk->driverfs_dev != NULL &&
                                    disk->driverfs_dev->driver != NULL)
@@@ -810,10 -801,9 +808,9 @@@ static int __init genhd_device_init(voi
  
        register_blkdev(BLOCK_EXT_MAJOR, "blkext");
  
- #ifndef CONFIG_SYSFS_DEPRECATED
        /* create top-level block dir */
-       block_depr = kobject_create_and_add("block", NULL);
- #endif
+       if (!sysfs_deprecated)
+               block_depr = kobject_create_and_add("block", NULL);
        return 0;
  }
  
@@@ -932,15 -922,8 +929,15 @@@ static void disk_free_ptbl_rcu_cb(struc
  {
        struct disk_part_tbl *ptbl =
                container_of(head, struct disk_part_tbl, rcu_head);
 +      struct gendisk *disk = ptbl->disk;
 +      struct request_queue *q = disk->queue;
 +      unsigned long flags;
  
        kfree(ptbl);
 +
 +      spin_lock_irqsave(q->queue_lock, flags);
 +      elv_quiesce_end(q);
 +      spin_unlock_irqrestore(q->queue_lock, flags);
  }
  
  /**
@@@ -958,17 -941,11 +955,17 @@@ static void disk_replace_part_tbl(struc
                                  struct disk_part_tbl *new_ptbl)
  {
        struct disk_part_tbl *old_ptbl = disk->part_tbl;
 +      struct request_queue *q = disk->queue;
  
        rcu_assign_pointer(disk->part_tbl, new_ptbl);
  
        if (old_ptbl) {
                rcu_assign_pointer(old_ptbl->last_lookup, NULL);
 +
 +              spin_lock_irq(q->queue_lock);
 +              elv_quiesce_start(q);
 +              spin_unlock_irq(q->queue_lock);
 +
                call_rcu(&old_ptbl->rcu_head, disk_free_ptbl_rcu_cb);
        }
  }
@@@ -1009,7 -986,6 +1006,7 @@@ int disk_expand_part_tbl(struct gendis
                return -ENOMEM;
  
        new_ptbl->len = target;
 +      new_ptbl->disk = disk;
  
        for (i = 0; i < len; i++)
                rcu_assign_pointer(new_ptbl->part[i], old_ptbl->part[i]);
@@@ -1025,7 -1001,6 +1022,7 @@@ static void disk_release(struct device 
        kfree(disk->random);
        disk_replace_part_tbl(disk, NULL);
        free_part_stats(&disk->part0);
 +      free_part_info(&disk->part0);
        kfree(disk);
  }
  struct class block_class = {
diff --combined drivers/misc/hpilo.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * Driver for HP iLO/iLO2 management processor.
+  * Driver for the HP iLO management processor.
   *
   * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
   *    David Altobelli <david.altobelli@hp.com>
@@@ -640,7 -640,6 +640,7 @@@ static const struct file_operations ilo
        .poll           = ilo_poll,
        .open           = ilo_open,
        .release        = ilo_close,
 +      .llseek         = noop_llseek,
  };
  
  static irqreturn_t ilo_isr(int irq, void *data)
diff --combined drivers/scsi/hosts.c
@@@ -376,7 -376,6 +376,7 @@@ struct Scsi_Host *scsi_host_alloc(struc
        shost->this_id = sht->this_id;
        shost->can_queue = sht->can_queue;
        shost->sg_tablesize = sht->sg_tablesize;
 +      shost->sg_prot_tablesize = sht->sg_prot_tablesize;
        shost->cmd_per_lun = sht->cmd_per_lun;
        shost->unchecked_isa_dma = sht->unchecked_isa_dma;
        shost->use_clustering = sht->use_clustering;
  
        device_initialize(&shost->shost_gendev);
        dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
- #ifndef CONFIG_SYSFS_DEPRECATED
        shost->shost_gendev.bus = &scsi_bus_type;
- #endif
        shost->shost_gendev.type = &scsi_host_type;
  
        device_initialize(&shost->shost_dev);
diff --combined drivers/uio/uio.c
  #include <linux/sched.h>
  #include <linux/string.h>
  #include <linux/kobject.h>
+ #include <linux/cdev.h>
  #include <linux/uio_driver.h>
  
- #define UIO_MAX_DEVICES 255
+ #define UIO_MAX_DEVICES               (1U << MINORBITS)
  
  struct uio_device {
        struct module           *owner;
  };
  
  static int uio_major;
+ static struct cdev *uio_cdev;
  static DEFINE_IDR(uio_idr);
  static const struct file_operations uio_fops;
  
- /* UIO class infrastructure */
- static struct uio_class {
-       struct kref kref;
-       struct class *class;
- } *uio_class;
  /* Protect idr accesses */
  static DEFINE_MUTEX(minor_lock);
  
@@@ -232,45 -228,34 +228,34 @@@ static ssize_t show_name(struct device 
                         struct device_attribute *attr, char *buf)
  {
        struct uio_device *idev = dev_get_drvdata(dev);
-       if (idev)
-               return sprintf(buf, "%s\n", idev->info->name);
-       else
-               return -ENODEV;
+       return sprintf(buf, "%s\n", idev->info->name);
  }
- static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
  
  static ssize_t show_version(struct device *dev,
                            struct device_attribute *attr, char *buf)
  {
        struct uio_device *idev = dev_get_drvdata(dev);
-       if (idev)
-               return sprintf(buf, "%s\n", idev->info->version);
-       else
-               return -ENODEV;
+       return sprintf(buf, "%s\n", idev->info->version);
  }
- static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
  
  static ssize_t show_event(struct device *dev,
                          struct device_attribute *attr, char *buf)
  {
        struct uio_device *idev = dev_get_drvdata(dev);
-       if (idev)
-               return sprintf(buf, "%u\n",
-                               (unsigned int)atomic_read(&idev->event));
-       else
-               return -ENODEV;
+       return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
  }
- static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
  
- static struct attribute *uio_attrs[] = {
-       &dev_attr_name.attr,
-       &dev_attr_version.attr,
-       &dev_attr_event.attr,
-       NULL,
+ static struct device_attribute uio_class_attributes[] = {
+       __ATTR(name, S_IRUGO, show_name, NULL),
+       __ATTR(version, S_IRUGO, show_version, NULL),
+       __ATTR(event, S_IRUGO, show_event, NULL),
+       {}
  };
  
- static struct attribute_group uio_attr_grp = {
-       .attrs = uio_attrs,
+ /* UIO class infrastructure */
+ static struct class uio_class = {
+       .name = "uio",
+       .dev_attrs = uio_class_attributes,
  };
  
  /*
@@@ -287,10 -272,6 +272,6 @@@ static int uio_dev_add_attributes(struc
        struct uio_port *port;
        struct uio_portio *portio;
  
-       ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
-       if (ret)
-               goto err_group;
        for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
                mem = &idev->info->mem[mi];
                if (mem->size == 0)
@@@ -358,8 -339,6 +339,6 @@@ err_map
                kobject_put(&map->kobj);
        }
        kobject_put(idev->map_dir);
-       sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
- err_group:
        dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
        return ret;
  }
@@@ -385,8 -364,6 +364,6 @@@ static void uio_dev_del_attributes(stru
                kobject_put(&port->portio->kobj);
        }
        kobject_put(idev->portio_dir);
-       sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
  }
  
  static int uio_get_minor(struct uio_device *idev)
@@@ -525,7 -502,7 +502,7 @@@ static unsigned int uio_poll(struct fil
        struct uio_listener *listener = filep->private_data;
        struct uio_device *idev = listener->dev;
  
-       if (idev->info->irq == UIO_IRQ_NONE)
+       if (!idev->info->irq)
                return -EIO;
  
        poll_wait(filep, &idev->wait, wait);
@@@ -543,7 -520,7 +520,7 @@@ static ssize_t uio_read(struct file *fi
        ssize_t retval;
        s32 event_count;
  
-       if (idev->info->irq == UIO_IRQ_NONE)
+       if (!idev->info->irq)
                return -EIO;
  
        if (count != sizeof(s32))
@@@ -591,7 -568,7 +568,7 @@@ static ssize_t uio_write(struct file *f
        ssize_t retval;
        s32 irq_on;
  
-       if (idev->info->irq == UIO_IRQ_NONE)
+       if (!idev->info->irq)
                return -EIO;
  
        if (count != sizeof(s32))
@@@ -740,73 -717,76 +717,77 @@@ static const struct file_operations uio
        .mmap           = uio_mmap,
        .poll           = uio_poll,
        .fasync         = uio_fasync,
 +      .llseek         = noop_llseek,
  };
  
  static int uio_major_init(void)
  {
-       uio_major = register_chrdev(0, "uio", &uio_fops);
-       if (uio_major < 0)
-               return uio_major;
-       return 0;
+       static const char name[] = "uio";
+       struct cdev *cdev = NULL;
+       dev_t uio_dev = 0;
+       int result;
+       result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name);
+       if (result)
+               goto out;
+       result = -ENOMEM;
+       cdev = cdev_alloc();
+       if (!cdev)
+               goto out_unregister;
+       cdev->owner = THIS_MODULE;
+       cdev->ops = &uio_fops;
+       kobject_set_name(&cdev->kobj, "%s", name);
+       result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES);
+       if (result)
+               goto out_put;
+       uio_major = MAJOR(uio_dev);
+       uio_cdev = cdev;
+       result = 0;
+ out:
+       return result;
+ out_put:
+       kobject_put(&cdev->kobj);
+ out_unregister:
+       unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
+       goto out;
  }
  
  static void uio_major_cleanup(void)
  {
-       unregister_chrdev(uio_major, "uio");
+       unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES);
+       cdev_del(uio_cdev);
  }
  
  static int init_uio_class(void)
  {
-       int ret = 0;
-       if (uio_class != NULL) {
-               kref_get(&uio_class->kref);
-               goto exit;
-       }
+       int ret;
  
        /* This is the first time in here, set everything up properly */
        ret = uio_major_init();
        if (ret)
                goto exit;
  
-       uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
-       if (!uio_class) {
-               ret = -ENOMEM;
-               goto err_kzalloc;
-       }
-       kref_init(&uio_class->kref);
-       uio_class->class = class_create(THIS_MODULE, "uio");
-       if (IS_ERR(uio_class->class)) {
-               ret = IS_ERR(uio_class->class);
-               printk(KERN_ERR "class_create failed for uio\n");
-               goto err_class_create;
+       ret = class_register(&uio_class);
+       if (ret) {
+               printk(KERN_ERR "class_register failed for uio\n");
+               goto err_class_register;
        }
        return 0;
  
- err_class_create:
-       kfree(uio_class);
-       uio_class = NULL;
- err_kzalloc:
+ err_class_register:
        uio_major_cleanup();
  exit:
        return ret;
  }
  
- static void release_uio_class(struct kref *kref)
+ static void release_uio_class(void)
  {
-       /* Ok, we cheat as we know we only have one uio_class */
-       class_destroy(uio_class->class);
-       kfree(uio_class);
+       class_unregister(&uio_class);
        uio_major_cleanup();
-       uio_class = NULL;
- }
- static void uio_class_destroy(void)
- {
-       if (uio_class)
-               kref_put(&uio_class->kref, release_uio_class);
  }
  
  /**
@@@ -829,10 -809,6 +810,6 @@@ int __uio_register_device(struct modul
  
        info->uio_dev = NULL;
  
-       ret = init_uio_class();
-       if (ret)
-               return ret;
        idev = kzalloc(sizeof(*idev), GFP_KERNEL);
        if (!idev) {
                ret = -ENOMEM;
        if (ret)
                goto err_get_minor;
  
-       idev->dev = device_create(uio_class->class, parent,
+       idev->dev = device_create(&uio_class, parent,
                                  MKDEV(uio_major, idev->minor), idev,
                                  "uio%d", idev->minor);
        if (IS_ERR(idev->dev)) {
  
        info->uio_dev = idev;
  
-       if (idev->info->irq >= 0) {
-               ret = request_irq(idev->info->irq, uio_interrupt,
-                                 idev->info->irq_flags, idev->info->name, idev);
+       if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
+               ret = request_irq(info->irq, uio_interrupt,
+                                 info->irq_flags, info->name, idev);
                if (ret)
                        goto err_request_irq;
        }
  err_request_irq:
        uio_dev_del_attributes(idev);
  err_uio_dev_add_attributes:
-       device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
+       device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
  err_device_create:
        uio_free_minor(idev);
  err_get_minor:
        kfree(idev);
  err_kzalloc:
-       uio_class_destroy();
        return ret;
  }
  EXPORT_SYMBOL_GPL(__uio_register_device);
@@@ -902,15 -877,13 +878,13 @@@ void uio_unregister_device(struct uio_i
  
        uio_free_minor(idev);
  
-       if (info->irq >= 0)
+       if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
                free_irq(info->irq, idev);
  
        uio_dev_del_attributes(idev);
  
-       dev_set_drvdata(idev->dev, NULL);
-       device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
+       device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
        kfree(idev);
-       uio_class_destroy();
  
        return;
  }
@@@ -918,11 -891,12 +892,12 @@@ EXPORT_SYMBOL_GPL(uio_unregister_device
  
  static int __init uio_init(void)
  {
-       return 0;
+       return init_uio_class();
  }
  
  static void __exit uio_exit(void)
  {
+       release_uio_class();
  }
  
  module_init(uio_init)
diff --combined fs/partitions/check.c
@@@ -352,7 -352,6 +352,7 @@@ static void part_release(struct device 
  {
        struct hd_struct *p = dev_to_part(dev);
        free_part_stats(p);
 +      free_part_info(p);
        kfree(p);
  }
  
@@@ -365,25 -364,17 +365,25 @@@ struct device_type part_type = 
  static void delete_partition_rcu_cb(struct rcu_head *head)
  {
        struct hd_struct *part = container_of(head, struct hd_struct, rcu_head);
 +      struct gendisk *disk = part_to_disk(part);
 +      struct request_queue *q = disk->queue;
 +      unsigned long flags;
  
        part->start_sect = 0;
        part->nr_sects = 0;
        part_stat_set_all(part, 0);
        put_device(part_to_dev(part));
 +
 +      spin_lock_irqsave(q->queue_lock, flags);
 +      elv_quiesce_end(q);
 +      spin_unlock_irqrestore(q->queue_lock, flags);
  }
  
  void delete_partition(struct gendisk *disk, int partno)
  {
        struct disk_part_tbl *ptbl = disk->part_tbl;
        struct hd_struct *part;
 +      struct request_queue *q = disk->queue;
  
        if (partno >= ptbl->len)
                return;
        kobject_put(part->holder_dir);
        device_del(part_to_dev(part));
  
 +      spin_lock_irq(q->queue_lock);
 +      elv_quiesce_start(q);
 +      spin_unlock_irq(q->queue_lock);
 +
        call_rcu(&part->rcu_head, delete_partition_rcu_cb);
  }
  
@@@ -414,8 -401,7 +414,8 @@@ static DEVICE_ATTR(whole_disk, S_IRUSR 
                   whole_disk_show, NULL);
  
  struct hd_struct *add_partition(struct gendisk *disk, int partno,
 -                              sector_t start, sector_t len, int flags)
 +                              sector_t start, sector_t len, int flags,
 +                              struct partition_meta_info *info)
  {
        struct hd_struct *p;
        dev_t devt = MKDEV(0, 0);
        p->partno = partno;
        p->policy = get_disk_ro(disk);
  
 +      if (info) {
 +              struct partition_meta_info *pinfo = alloc_part_info(disk);
 +              if (!pinfo)
 +                      goto out_free_stats;
 +              memcpy(pinfo, info, sizeof(*info));
 +              p->info = pinfo;
 +      }
 +
        dname = dev_name(ddev);
        if (isdigit(dname[strlen(dname) - 1]))
                dev_set_name(pdev, "%sp%d", dname, partno);
  
        err = blk_alloc_devt(p, &devt);
        if (err)
 -              goto out_free_stats;
 +              goto out_free_info;
        pdev->devt = devt;
  
        /* delay uevent until 'holders' subdir is created */
  
        return p;
  
 +out_free_info:
 +      free_part_info(p);
  out_free_stats:
        free_part_stats(p);
  out_free:
@@@ -537,14 -513,14 +537,14 @@@ void register_disk(struct gendisk *disk
  
        if (device_add(ddev))
                return;
- #ifndef CONFIG_SYSFS_DEPRECATED
-       err = sysfs_create_link(block_depr, &ddev->kobj,
-                               kobject_name(&ddev->kobj));
-       if (err) {
-               device_del(ddev);
-               return;
+       if (!sysfs_deprecated) {
+               err = sysfs_create_link(block_depr, &ddev->kobj,
+                                       kobject_name(&ddev->kobj));
+               if (err) {
+                       device_del(ddev);
+                       return;
+               }
        }
- #endif
        disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
        disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
  
@@@ -666,7 -642,6 +666,7 @@@ rescan
        /* add partitions */
        for (p = 1; p < state->limit; p++) {
                sector_t size, from;
 +              struct partition_meta_info *info = NULL;
  
                size = state->parts[p].size;
                if (!size)
                                size = get_capacity(disk) - from;
                        }
                }
 +
 +              if (state->parts[p].has_info)
 +                      info = &state->parts[p].info;
                part = add_partition(disk, p, from, size,
 -                                   state->parts[p].flags);
 +                                   state->parts[p].flags,
 +                                   &state->parts[p].info);
                if (IS_ERR(part)) {
                        printk(KERN_ERR " %s: p%d could not be added: %ld\n",
                               disk->disk_name, p, -PTR_ERR(part));
@@@ -766,8 -737,7 +766,7 @@@ void del_gendisk(struct gendisk *disk
        kobject_put(disk->part0.holder_dir);
        kobject_put(disk->slave_dir);
        disk->driverfs_dev = NULL;
- #ifndef CONFIG_SYSFS_DEPRECATED
-       sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
- #endif
+       if (!sysfs_deprecated)
+               sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
        device_del(disk_to_dev(disk));
  }
diff --combined init/Kconfig
@@@ -21,13 -21,6 +21,13 @@@ config CONSTRUCTOR
        depends on !UML
        default y
  
 +config HAVE_IRQ_WORK
 +      bool
 +
 +config IRQ_WORK
 +      bool
 +      depends on HAVE_IRQ_WORK
 +
  menu "General setup"
  
  config EXPERIMENTAL
@@@ -71,7 -64,7 +71,7 @@@ config BROKEN_ON_SM
  
  config LOCK_KERNEL
        bool
 -      depends on SMP || PREEMPT
 +      depends on (SMP || PREEMPT) && BKL
        default y
  
  config INIT_ENV_ARG_LIMIT
@@@ -339,8 -332,6 +339,8 @@@ config AUDIT_TRE
        depends on AUDITSYSCALL
        select FSNOTIFY
  
 +source "kernel/irq/Kconfig"
 +
  menu "RCU Subsystem"
  
  choice
  
  config TREE_RCU
        bool "Tree-based hierarchical RCU"
 +      depends on !PREEMPT && SMP
        help
          This option selects the RCU implementation that is
          designed for very large SMP system with hundreds or
          smaller systems.
  
  config TREE_PREEMPT_RCU
 -      bool "Preemptable tree-based hierarchical RCU"
 +      bool "Preemptible tree-based hierarchical RCU"
        depends on PREEMPT
        help
          This option selects the RCU implementation that is
@@@ -375,22 -365,8 +375,22 @@@ config TINY_RC
          is not required.  This option greatly reduces the
          memory footprint of RCU.
  
 +config TINY_PREEMPT_RCU
 +      bool "Preemptible UP-only small-memory-footprint RCU"
 +      depends on !SMP && PREEMPT
 +      help
 +        This option selects the RCU implementation that is designed
 +        for real-time UP systems.  This option greatly reduces the
 +        memory footprint of RCU.
 +
  endchoice
  
 +config PREEMPT_RCU
 +      def_bool ( TREE_PREEMPT_RCU || TINY_PREEMPT_RCU )
 +      help
 +        This option enables preemptible-RCU code that is common between
 +        the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations.
 +
  config RCU_TRACE
        bool "Enable tracing for RCU"
        depends on TREE_RCU || TREE_PREEMPT_RCU
@@@ -411,12 -387,9 +411,12 @@@ config RCU_FANOU
        help
          This option controls the fanout of hierarchical implementations
          of RCU, allowing RCU to work efficiently on machines with
 -        large numbers of CPUs.  This value must be at least the cube
 -        root of NR_CPUS, which allows NR_CPUS up to 32,768 for 32-bit
 -        systems and up to 262,144 for 64-bit systems.
 +        large numbers of CPUs.  This value must be at least the fourth
 +        root of NR_CPUS, which allows NR_CPUS to be insanely large.
 +        The default value of RCU_FANOUT should be used for production
 +        systems, but if you are stress-testing the RCU implementation
 +        itself, small RCU_FANOUT values allow you to test large-system
 +        code paths on small(er) systems.
  
          Select a specific number if testing RCU itself.
          Take the default if unsure.
@@@ -661,14 -634,11 +661,14 @@@ config BLK_CGROU
  
        Currently, CFQ IO scheduler uses it to recognize task groups and
        control disk bandwidth allocation (proportional time slice allocation)
 -      to such task groups.
 +      to such task groups. It is also used by bio throttling logic in
 +      block layer to implement upper limit in IO rates on a device.
  
        This option only enables generic Block IO controller infrastructure.
 -      One needs to also enable actual IO controlling logic in CFQ for it
 -      to take effect. (CONFIG_CFQ_GROUP_IOSCHED=y).
 +      One needs to also enable actual IO controlling logic/policy. For
 +      enabling proportional weight division of disk bandwidth in CFQ seti
 +      CONFIG_CFQ_GROUP_IOSCHED=y and for enabling throttling policy set
 +      CONFIG_BLK_THROTTLE=y.
  
        See Documentation/cgroups/blkio-controller.txt for more information.
  
@@@ -686,40 -656,42 +686,42 @@@ config MM_OWNE
        bool
  
  config SYSFS_DEPRECATED
-       bool
- config SYSFS_DEPRECATED_V2
        bool "enable deprecated sysfs features to support old userspace tools"
        depends on SYSFS
        default n
-       select SYSFS_DEPRECATED
-       help
-         This option switches the layout of sysfs to the deprecated
-         version. Do not use it on recent distributions.
-         The current sysfs layout features a unified device tree at
-         /sys/devices/, which is able to express a hierarchy between
-         class devices. If the deprecated option is set to Y, the
-         unified device tree is split into a bus device tree at
-         /sys/devices/ and several individual class device trees at
-         /sys/class/. The class and bus devices will be connected by
-         "<subsystem>:<name>" and the "device" links. The "block"
-         class devices, will not show up in /sys/class/block/. Some
-         subsystems will suppress the creation of some devices which
-         depend on the unified device tree.
-         This option is not a pure compatibility option that can
-         be safely enabled on newer distributions. It will change the
-         layout of sysfs to the non-extensible deprecated version,
-         and disable some features, which can not be exported without
-         confusing older userspace tools. Since 2007/2008 all major
-         distributions do not enable this option, and ship no tools which
-         depend on the deprecated layout or this option.
-         If you are using a new kernel on an older distribution, or use
-         older userspace tools, you might need to say Y here. Do not say Y,
-         if the original kernel, that came with your distribution, has
-         this option set to N.
+       help
+         This option adds code that switches the layout of the "block" class
+         devices, to not show up in /sys/class/block/, but only in
+         /sys/block/.
+         This switch is only active when the sysfs.deprecated=1 boot option is
+         passed or the SYSFS_DEPRECATED_V2 option is set.
+         This option allows new kernels to run on old distributions and tools,
+         which might get confused by /sys/class/block/. Since 2007/2008 all
+         major distributions and tools handle this just fine.
+         Recent distributions and userspace tools after 2009/2010 depend on
+         the existence of /sys/class/block/, and will not work with this
+         option enabled.
+         Only if you are using a new kernel on an old distribution, you might
+         need to say Y here.
+ config SYSFS_DEPRECATED_V2
+       bool "enabled deprecated sysfs features by default"
+       default n
+       depends on SYSFS
+       depends on SYSFS_DEPRECATED
+       help
+         Enable deprecated sysfs by default.
+         See the CONFIG_SYSFS_DEPRECATED option for more details about this
+         option.
+         Only if you are using a new kernel on an old distribution, you might
+         need to say Y here. Even then, odds are you would not need it
+         enabled, you can always pass the boot option if absolutely necessary.
  
  config RELAY
        bool "Kernel->user space relay support (formerly relayfs)"
@@@ -1017,7 -989,6 +1019,7 @@@ config PERF_EVENT
        default y if (PROFILING || PERF_COUNTERS)
        depends on HAVE_PERF_EVENTS
        select ANON_INODES
 +      select IRQ_WORK
        help
          Enable kernel support for various performance events provided
          by software and hardware.
diff --combined lib/dynamic_debug.c
  #include <linux/dynamic_debug.h>
  #include <linux/debugfs.h>
  #include <linux/slab.h>
 +#include <linux/jump_label.h>
  
  extern struct _ddebug __start___verbose[];
  extern struct _ddebug __stop___verbose[];
  
 -/* dynamic_debug_enabled, and dynamic_debug_enabled2 are bitmasks in which
 - * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
 - * use independent hash functions, to reduce the chance of false positives.
 - */
 -long long dynamic_debug_enabled;
 -EXPORT_SYMBOL_GPL(dynamic_debug_enabled);
 -long long dynamic_debug_enabled2;
 -EXPORT_SYMBOL_GPL(dynamic_debug_enabled2);
 -
  struct ddebug_table {
        struct list_head link;
        char *mod_name;
@@@ -79,6 -87,26 +79,6 @@@ static char *ddebug_describe_flags(stru
        return buf;
  }
  
 -/*
 - * must be called with ddebug_lock held
 - */
 -
 -static int disabled_hash(char hash, bool first_table)
 -{
 -      struct ddebug_table *dt;
 -      char table_hash_value;
 -
 -      list_for_each_entry(dt, &ddebug_tables, link) {
 -              if (first_table)
 -                      table_hash_value = dt->ddebugs->primary_hash;
 -              else
 -                      table_hash_value = dt->ddebugs->secondary_hash;
 -              if (dt->num_enabled && (hash == table_hash_value))
 -                      return 0;
 -      }
 -      return 1;
 -}
 -
  /*
   * Search the tables for _ddebug's which match the given
   * `query' and apply the `flags' and `mask' to them.  Tells
@@@ -142,9 -170,17 +142,9 @@@ static void ddebug_change(const struct 
                                dt->num_enabled++;
                        dp->flags = newflags;
                        if (newflags) {
 -                              dynamic_debug_enabled |=
 -                                              (1LL << dp->primary_hash);
 -                              dynamic_debug_enabled2 |=
 -                                              (1LL << dp->secondary_hash);
 +                              jump_label_enable(&dp->enabled);
                        } else {
 -                              if (disabled_hash(dp->primary_hash, true))
 -                                      dynamic_debug_enabled &=
 -                                              ~(1LL << dp->primary_hash);
 -                              if (disabled_hash(dp->secondary_hash, false))
 -                                      dynamic_debug_enabled2 &=
 -                                              ~(1LL << dp->secondary_hash);
 +                              jump_label_disable(&dp->enabled);
                        }
                        if (verbose)
                                printk(KERN_INFO
@@@ -393,6 -429,40 +393,40 @@@ static int ddebug_parse_flags(const cha
        return 0;
  }
  
+ static int ddebug_exec_query(char *query_string)
+ {
+       unsigned int flags = 0, mask = 0;
+       struct ddebug_query query;
+ #define MAXWORDS 9
+       int nwords;
+       char *words[MAXWORDS];
+       nwords = ddebug_tokenize(query_string, words, MAXWORDS);
+       if (nwords <= 0)
+               return -EINVAL;
+       if (ddebug_parse_query(words, nwords-1, &query))
+               return -EINVAL;
+       if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
+               return -EINVAL;
+       /* actually go and implement the change */
+       ddebug_change(&query, flags, mask);
+       return 0;
+ }
+ static __initdata char ddebug_setup_string[1024];
+ static __init int ddebug_setup_query(char *str)
+ {
+       if (strlen(str) >= 1024) {
+               pr_warning("ddebug boot param string too large\n");
+               return 0;
+       }
+       strcpy(ddebug_setup_string, str);
+       return 1;
+ }
+ __setup("ddebug_query=", ddebug_setup_query);
  /*
   * File_ops->write method for <debugfs>/dynamic_debug/conrol.  Gathers the
   * command text from userspace, parses and executes it.
  static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
                                  size_t len, loff_t *offp)
  {
-       unsigned int flags = 0, mask = 0;
-       struct ddebug_query query;
- #define MAXWORDS 9
-       int nwords;
-       char *words[MAXWORDS];
        char tmpbuf[256];
+       int ret;
  
        if (len == 0)
                return 0;
                printk(KERN_INFO "%s: read %d bytes from userspace\n",
                        __func__, (int)len);
  
-       nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS);
-       if (nwords <= 0)
-               return -EINVAL;
-       if (ddebug_parse_query(words, nwords-1, &query))
-               return -EINVAL;
-       if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
-               return -EINVAL;
-       /* actually go and implement the change */
-       ddebug_change(&query, flags, mask);
+       ret = ddebug_exec_query(tmpbuf);
+       if (ret)
+               return ret;
  
        *offp += len;
        return len;
@@@ -689,13 -748,14 +712,14 @@@ static void ddebug_remove_all_tables(vo
        mutex_unlock(&ddebug_lock);
  }
  
- static int __init dynamic_debug_init(void)
+ static __initdata int ddebug_init_success;
+ static int __init dynamic_debug_init_debugfs(void)
  {
        struct dentry *dir, *file;
-       struct _ddebug *iter, *iter_start;
-       const char *modname = NULL;
-       int ret = 0;
-       int n = 0;
+       if (!ddebug_init_success)
+               return -ENODEV;
  
        dir = debugfs_create_dir("dynamic_debug", NULL);
        if (!dir)
                debugfs_remove(dir);
                return -ENOMEM;
        }
+       return 0;
+ }
+ static int __init dynamic_debug_init(void)
+ {
+       struct _ddebug *iter, *iter_start;
+       const char *modname = NULL;
+       int ret = 0;
+       int n = 0;
        if (__start___verbose != __stop___verbose) {
                iter = __start___verbose;
                modname = iter->modname;
                }
                ret = ddebug_add_module(iter_start, n, modname);
        }
+       /* ddebug_query boot param got passed -> set it up */
+       if (ddebug_setup_string[0] != '\0') {
+               ret = ddebug_exec_query(ddebug_setup_string);
+               if (ret)
+                       pr_warning("Invalid ddebug boot param %s",
+                                  ddebug_setup_string);
+               else
+                       pr_info("ddebug initialized with string %s",
+                               ddebug_setup_string);
+       }
  out_free:
-       if (ret) {
+       if (ret)
                ddebug_remove_all_tables();
-               debugfs_remove(dir);
-               debugfs_remove(file);
-       }
+       else
+               ddebug_init_success = 1;
        return 0;
  }
- module_init(dynamic_debug_init);
+ /* Allow early initialization for boot messages via boot param */
+ arch_initcall(dynamic_debug_init);
+ /* Debugfs setup must be done later */
+ module_init(dynamic_debug_init_debugfs);