Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 25 Oct 2011 10:13:59 +0000 (12:13 +0200)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 25 Oct 2011 10:13:59 +0000 (12:13 +0200)
* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (38 commits)
  mm: memory hotplug: Check if pages are correctly reserved on a per-section basis
  Revert "memory hotplug: Correct page reservation checking"
  Update email address for stable patch submission
  dynamic_debug: fix undefined reference to `__netdev_printk'
  dynamic_debug: use a single printk() to emit messages
  dynamic_debug: remove num_enabled accounting
  dynamic_debug: consolidate repetitive struct _ddebug descriptor definitions
  uio: Support physical addresses >32 bits on 32-bit systems
  sysfs: add unsigned long cast to prevent compile warning
  drivers: base: print rejected matches with DEBUG_DRIVER
  memory hotplug: Correct page reservation checking
  memory hotplug: Refuse to add unaligned memory regions
  remove the messy code file Documentation/zh_CN/SubmitChecklist
  ARM: mxc: convert device creation to use platform_device_register_full
  new helper to create platform devices with dma mask
  docs/driver-model: Update device class docs
  docs/driver-model: Document device.groups
  kobj_uevent: Ignore if some listeners cannot handle message
  dynamic_debug: make netif_dbg() call __netdev_printk()
  dynamic_debug: make netdev_dbg() call __netdev_printk()
  ...

29 files changed:
Documentation/DocBook/uio-howto.tmpl
Documentation/driver-model/binding.txt
Documentation/driver-model/device.txt
Documentation/filesystems/sysfs.txt
Documentation/stable_kernel_rules.txt
Documentation/zh_CN/SubmitChecklist [deleted file]
MAINTAINERS
arch/arm/plat-mxc/devices.c
arch/arm/plat-mxc/include/mach/devices-common.h
drivers/base/core.c
drivers/base/dd.c
drivers/base/memory.c
drivers/base/platform.c
drivers/misc/pch_phub.c
drivers/uio/uio.c
drivers/uio/uio_pci_generic.c
drivers/uio/uio_pdrv_genirq.c
fs/debugfs/inode.c
fs/sysfs/dir.c
fs/sysfs/inode.c
fs/sysfs/sysfs.h
include/linux/device.h
include/linux/dynamic_debug.h
include/linux/netdevice.h
include/linux/platform_device.h
include/linux/uio_driver.h
lib/dynamic_debug.c
lib/kobject_uevent.c
net/core/dev.c

index 7c4b514..54883de 100644 (file)
@@ -529,7 +529,7 @@ memory (e.g. allocated with <function>kmalloc()</function>). There's also
 </para></listitem>
 
 <listitem><para>
-<varname>unsigned long addr</varname>: Required if the mapping is used.
+<varname>phys_addr_t addr</varname>: Required if the mapping is used.
 Fill in the address of your memory block. This address is the one that
 appears in sysfs.
 </para></listitem>
index f7ec9d6..abfc8e2 100644 (file)
@@ -48,10 +48,6 @@ devclass_add_device is called to enumerate the device within the class
 and actually register it with the class, which happens with the
 class's register_dev callback.
 
-NOTE: The device class structures and core routines to manipulate them
-are not in the mainline kernel, so the discussion is still a bit
-speculative. 
-
 
 Driver
 ~~~~~~
index bdefe72..1e70220 100644 (file)
@@ -45,33 +45,52 @@ struct device_attribute {
                         const char *buf, size_t count);
 };
 
-Attributes of devices can be exported via drivers using a simple
-procfs-like interface. 
+Attributes of devices can be exported by a device driver through sysfs.
 
 Please see Documentation/filesystems/sysfs.txt for more information
 on how sysfs works.
 
+As explained in Documentation/kobject.txt, device attributes must be be
+created before the KOBJ_ADD uevent is generated. The only way to realize
+that is by defining an attribute group.
+
 Attributes are declared using a macro called DEVICE_ATTR:
 
 #define DEVICE_ATTR(name,mode,show,store)
 
 Example:
 
-DEVICE_ATTR(power,0644,show_power,store_power);
+static DEVICE_ATTR(type, 0444, show_type, NULL);
+static DEVICE_ATTR(power, 0644, show_power, store_power);
 
-This declares a structure of type struct device_attribute named
-'dev_attr_power'. This can then be added and removed to the device's
-directory using:
+This declares two structures of type struct device_attribute with respective
+names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be
+organized as follows into a group:
 
-int device_create_file(struct device *device, struct device_attribute * entry);
-void device_remove_file(struct device * dev, struct device_attribute * attr);
+static struct attribute *dev_attrs[] = {
+       &dev_attr_type.attr,
+       &dev_attr_power.attr,
+       NULL,
+};
 
-Example:
+static struct attribute_group dev_attr_group = {
+       .attrs = dev_attrs,
+};
+
+static const struct attribute_group *dev_attr_groups[] = {
+       &dev_attr_group,
+       NULL,
+};
+
+This array of groups can then be associated with a device by setting the
+group pointer in struct device before device_register() is invoked:
 
-device_create_file(dev,&dev_attr_power);
-device_remove_file(dev,&dev_attr_power);
+      dev->groups = dev_attr_groups;
+      device_register(dev);
 
-The file name will be 'power' with a mode of 0644 (-rw-r--r--).
+The device_register() function will use the 'groups' pointer to create the
+device attributes and the device_unregister() function will use this pointer
+to remove the device attributes.
 
 Word of warning:  While the kernel allows device_create_file() and
 device_remove_file() to be called on a device at any time, userspace has
@@ -84,24 +103,4 @@ not know about the new attributes.
 This is important for device driver that need to publish additional
 attributes for a device at driver probe time.  If the device driver simply
 calls device_create_file() on the device structure passed to it, then
-userspace will never be notified of the new attributes.  Instead, it should
-probably use class_create() and class->dev_attrs to set up a list of
-desired attributes in the modules_init function, and then in the .probe()
-hook, and then use device_create() to create a new device as a child
-of the probed device.  The new device will generate a new uevent and
-properly advertise the new attributes to userspace.
-
-For example, if a driver wanted to add the following attributes:
-struct device_attribute mydriver_attribs[] = {
-       __ATTR(port_count, 0444, port_count_show),
-       __ATTR(serial_number, 0444, serial_number_show),
-       NULL
-};
-
-Then in the module init function is would do:
-       mydriver_class = class_create(THIS_MODULE, "my_attrs");
-       mydriver_class.dev_attr = mydriver_attribs;
-
-And assuming 'dev' is the struct device passed into the probe hook, the driver
-probe function would do something like:
-       device_create(&mydriver_class, dev, chrdev, &private_data, "my_name");
+userspace will never be notified of the new attributes.
index 597f728..07235ca 100644 (file)
@@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects.
 Patrick Mochel <mochel@osdl.org>
 Mike Murphy <mamurph@cs.clemson.edu>
 
-Revised:    15 July 2010
+Revised:    16 August 2011
 Original:   10 January 2003
 
 
@@ -370,3 +370,11 @@ int driver_create_file(struct device_driver *, const struct driver_attribute *);
 void driver_remove_file(struct device_driver *, const struct driver_attribute *);
 
 
+Documentation
+~~~~~~~~~~~~~
+
+The sysfs directory structure and the attributes in each directory define an
+ABI between the kernel and user space. As for any ABI, it is important that
+this ABI is stable and properly documented. All new sysfs attributes must be
+documented in Documentation/ABI. See also Documentation/ABI/README for more
+information.
index e213f45..21fd05c 100644 (file)
@@ -24,10 +24,10 @@ Rules on what kind of patches are accepted, and which ones are not, into the
 Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
-   stable@kernel.org.  You must note the upstream commit ID in the changelog
-   of your submission.
+   stable@vger.kernel.org.  You must note the upstream commit ID in the
+   changelog of your submission.
  - To have the patch automatically included in the stable tree, add the tag
-     Cc: stable@kernel.org
+     Cc: stable@vger.kernel.org
    in the sign-off area. Once the patch is merged it will be applied to
    the stable tree without anything else needing to be done by the author
    or subsystem maintainer.
@@ -35,10 +35,10 @@ Procedure for submitting patches to the -stable tree:
    cherry-picked than this can be specified in the following format in
    the sign-off area:
 
-     Cc: <stable@kernel.org> # .32.x: a1f84a3: sched: Check for idle
-     Cc: <stable@kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
-     Cc: <stable@kernel.org> # .32.x: fd21073: sched: Fix affinity logic
-     Cc: <stable@kernel.org> # .32.x
+     Cc: <stable@vger.kernel.org> # .32.x: a1f84a3: sched: Check for idle
+     Cc: <stable@vger.kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
+     Cc: <stable@vger.kernel.org> # .32.x: fd21073: sched: Fix affinity logic
+     Cc: <stable@vger.kernel.org> # .32.x
     Signed-off-by: Ingo Molnar <mingo@elte.hu>
 
    The tag sequence has the meaning of:
diff --git a/Documentation/zh_CN/SubmitChecklist b/Documentation/zh_CN/SubmitChecklist
deleted file mode 100644 (file)
index 4c741d6..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-Chinese translated version of Documentation/SubmitChecklist
-
-If you have any comment or update to the content, please contact the
-original document maintainer directly.  However, if you have a problem
-communicating in English you can also ask the Chinese maintainer for
-help.  Contact the Chinese maintainer if this translation is outdated
-or if there is a problem with the translation.
-
-Chinese maintainer: Harry Wei <harryxiyou@gmail.com>
----------------------------------------------------------------------
-Documentation/SubmitChecklist µÄÖÐÎÄ·­Òë
-
-Èç¹ûÏëÆÀÂÛ»ò¸üб¾ÎĵÄÄÚÈÝ£¬ÇëÖ±½ÓÁªÏµÔ­ÎĵµµÄά»¤Õß¡£Èç¹ûÄãʹÓÃÓ¢ÎÄ
-½»Á÷ÓÐÀ§ÄѵĻ°£¬Ò²¿ÉÒÔÏòÖÐÎÄ°æά»¤ÕßÇóÖú¡£Èç¹û±¾·­Òë¸üв»¼°Ê±»òÕß·­
-Òë´æÔÚÎÊÌ⣬ÇëÁªÏµÖÐÎÄ°æά»¤Õß¡£
-
-ÖÐÎÄ°æά»¤Õߣº ¼ÖÍþÍþ Harry Wei <harryxiyou@gmail.com>
-ÖÐÎÄ°æ·­ÒëÕߣº ¼ÖÍþÍþ Harry Wei <harryxiyou@gmail.com>
-ÖÐÎÄ°æУÒëÕߣº ¼ÖÍþÍþ Harry Wei <harryxiyou@gmail.com>
-
-
-ÒÔÏÂΪÕýÎÄ
----------------------------------------------------------------------
-LinuxÄÚºËÌá½»Çåµ¥
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-ÕâÀïÓÐһЩÄں˿ª·¢ÕßÓ¦¸Ã×öµÄ»ù±¾ÊÂÇ飬Èç¹ûËûÃÇÏë¿´µ½×Ô¼ºµÄÄں˲¹¶¡Ìá½»
-±»½ÓÊܵĸü¿ì¡£
-
-ÕâЩ¶¼Êdz¬³öDocumentation/SubmittingPatchesÎĵµÀïËùÌṩµÄÒÔ¼°ÆäËû
-¹ØÓÚÌá½»LinuxÄں˲¹¶¡µÄ˵Ã÷¡£
-
-1£ºÈç¹ûÄãʹÓÃÁËÒ»¸ö¹¦ÄÜÄÇô¾Í#include¶¨Òå/ÉùÃ÷ÄǸö¹¦ÄܵÄÄǸöÎļþ¡£
-   ²»ÒªÒÀ¿¿ÆäËû¼ä½ÓÒýÈ붨Òå/ÉùÃ÷ÄǸö¹¦ÄܵÄÍ·Îļþ¡£
-
-2£º¹¹½¨¼ò½àÊÊÓûòÕ߸ü¸ÄCONFIGÑ¡Ïî =y£¬=m£¬»òÕß=n¡£
-   ²»ÒªÓбàÒ뾯¸æ/´íÎ󣬠²»ÒªÓÐÁ´½Ó¾¯¸æ/´íÎó¡£
-
-2b£ºÍ¨¹ý allnoconfig, allmodconfig
-
-2c£ºµ±Ê¹Óà0=builddir ³É¹¦µØ¹¹½¨
-
-3£ºÍ¨¹ýʹÓñ¾µØ½»²æ±àÒ빤¾ß»òÕßÆäËûһЩ¹¹½¨²úËù£¬ÔÚ¶àCPU¿ò¼ÜÉϹ¹½¨¡£
-
-4£ºppc64 ÊÇÒ»¸öºÜºÃµÄ¼ì²é½»²æ±àÒëµÄ¿ò¼Ü£¬ÒòΪËüÍùÍù°Ñ¡®unsigned long¡¯
-   µ±64λֵÀ´Ê¹Óá£
-
-5£º°´ÕÕDocumentation/CodingStyleÎļþÀïµÄÏêϸÃèÊö£¬¼ì²éÄã²¹¶¡µÄÕûÌå·ç¸ñ¡£
-   Ê¹Óò¹¶¡·ç¸ñ¼ì²éËöËéµÄÎ¥¹æ(scripts/checkpatch.pl)£¬ÉóºËÔ±ÓÅÏÈÌá½»¡£
-   ÄãÓ¦¸Ãµ÷ÕûÒÅÁôÔÚÄã²¹¶¡ÖеÄËùÓÐÎ¥¹æ¡£
-
-6£ºÈκθüлòÕ߸Ķ¯CONFIGÑ¡Ï²»ÄÜ´òÂÒÅäÖò˵¥¡£
-
-7£ºËùÓеÄKconfigÑ¡Ïî¸üж¼ÒªÓÐ˵Ã÷ÎÄ×Ö¡£
-
-8£ºÒѾ­ÈÏÕæµØ×ܽáÁËÏà¹ØµÄKconfig×éºÏ¡£ÕâÊǺÜÄÑͨ¹ý²âÊÔ×öºÃµÄ--ÄÔÁ¦ÔÚÕâÀïϽµ¡£
-
-9£º¼ì²é¾ßÓмò½àÐÔ¡£
-
-10£ºÊ¹ÓÃ'make checkstack'ºÍ'make namespacecheck'¼ì²é£¬È»ºóÐÞ¸ÄËùÕÒµ½µÄÎÊÌâ¡£
-    ×¢Ò⣺¶ÑÕ»¼ì²é²»»áÃ÷È·µØ³öÏÖÎÊÌ⣬µ«ÊÇÈκεÄÒ»¸öº¯ÊýÔÚ¶ÑÕ»ÉÏʹÓöàÓÚ512×Ö½Ú
-    ¶¼Òª×¼±¸Ð޸ġ£
-
-11£º°üº¬kernel-docµ½È«¾ÖÄÚºËAPIsÎļþ¡££¨²»ÒªÇó¾²Ì¬µÄº¯Êý£¬µ«ÊÇ°üº¬Ò²ÎÞËùν¡££©
-    Ê¹ÓÃ'make htmldocs'»òÕß'make mandocs'À´¼ì²ékernel-doc£¬È»ºóÐÞ¸ÄÈκÎ
-    ·¢ÏÖµÄÎÊÌâ¡£
-
-12£ºÒѾ­Í¨¹ýCONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
-    CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
-    CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEP²âÊÔ£¬²¢ÇÒͬʱ¶¼
-    Ê¹ÄÜ¡£
-
-13£ºÒѾ­¶¼¹¹½¨²¢ÇÒʹÓûòÕß²»Ê¹ÓàCONFIG_SMP ºÍ CONFIG_PREEMPT²âÊÔÖ´ÐÐʱ¼ä¡£
-
-14£ºÈç¹û²¹¶¡Ó°ÏìIO/Disk£¬µÈµÈ£ºÒѾ­Í¨¹ýʹÓûòÕß²»Ê¹ÓàCONFIG_LBDAF ²âÊÔ¡£
-
-15£ºËùÓеÄcodepathsÒѾ­ÐÐʹËùÓÐlockdepÆôÓù¦ÄÜ¡£
-
-16£ºËùÓеÄ/proc¼Ç¼¸üж¼Òª×÷³ÉÎļþ·ÅÔÚDocumentation/Ŀ¼Ï¡£
-
-17£ºËùÓеÄÄÚºËÆô¶¯²ÎÊý¸üж¼±»¼Ç¼µ½Documentation/kernel-parameters.txtÎļþÖС£
-
-18£ºËùÓеÄÄ£¿é²ÎÊý¸üж¼ÓÃMODULE_PARM_DESC()¼Ç¼¡£
-
-19£ºËùÓеÄÓû§¿Õ¼ä½Ó¿Ú¸üж¼±»¼Ç¼µ½Documentation/ABI/¡£²é¿´Documentation/ABI/README
-    ¿ÉÒÔ»ñµÃ¸ü¶àµÄÐÅÏ¢¡£¸Ä±äÓû§¿Õ¼ä½Ó¿ÚµÄ²¹¶¡Ó¦¸Ã±»Óʼþ³­Ë͸ølinux-api@vger.kernel.org¡£
-
-20£º¼ì²éËüÊDz»ÊǶ¼Í¨¹ý`make headers_check'¡£
-
-21£ºÒѾ­Í¨¹ýÖÁÉÙÒýÈëslabºÍpage-allocationʧ°Ü¼ì²é¡£²é¿´Documentation/fault-injection/¡£
-
-22£ºÐ¼ÓÈëµÄÔ´ÂëÒѾ­Í¨¹ý`gcc -W'£¨Ê¹ÓÃ"make EXTRA_CFLAGS=-W"£©±àÒë¡£ÕâÑù½«²úÉúºÜ¶à·³ÄÕ£¬
-    µ«ÊǶÔÓÚÑ°ÕÒ©¶´ºÜÓÐÒæ´¦£¬ÀýÈç:"warning: comparison between signed and unsigned"¡£
-
-23£ºµ±Ëü±»ºÏ²¢µ½-mm²¹¶¡¼¯ºóÔÙ²âÊÔ£¬ÓÃÀ´È·¶¨ËüÊÇ·ñ»¹ºÍ²¹¶¡¶ÓÁÐÖеÄÆäËû²¹¶¡Ò»Æð¹¤×÷ÒÔ¼°ÔÚVM£¬VFS
-    ºÍÆäËû×ÓϵͳÖи÷¸ö±ä»¯¡£
-
-24£ºËùÓеÄÄÚ´æÆÁÕÏ{e.g., barrier(), rmb(), wmb()}ÐèÒªÔÚÔ´´úÂëÖеÄÒ»¸ö×¢ÊÍÀ´½âÊÍËûÃǶ¼ÊǸÉʲôµÄ
-    ÒÔ¼°Ô­Òò¡£
-
-25£ºÈç¹ûÓÐÈκÎÊäÈëÊä³ö¿ØÖƵIJ¹¶¡±»Ìí¼Ó£¬Ò²Òª¸üÐÂDocumentation/ioctl/ioctl-number.txt¡£
-
-26£ºÈç¹ûÄãµÄ¸ü¸Ä´úÂëÒÀ¿¿»òÕßʹÓÃÈκεÄÄÚºËAPIs»òÕßÓëÏÂÃæµÄkconfig·ûºÅÓйØϵµÄ¹¦ÄÜ£¬Äã¾ÍÒª
-    Ê¹ÓÃÏà¹ØµÄkconfig·ûºÅ¹Ø±Õ£¬ and/or =m£¨Èç¹ûÑ¡ÏîÌṩ£©[ÔÚͬһʱ¼ä²»ÊÇËùÓõĶ¼ÆôÓ㬽ö½ö¸÷¸ö»òÕß×ÔÓÉ
-    ×éºÏËûÃÇ]£º
-
-    CONFIG_SMP, CONFIG_SYSFS, CONFIG_PROC_FS, CONFIG_INPUT, CONFIG_PCI,
-    CONFIG_BLOCK, CONFIG_PM, CONFIG_HOTPLUG, CONFIG_MAGIC_SYSRQ,
-    CONFIG_NET, CONFIG_INET=n (ºóÒ»¸öʹÓàCONFIG_NET=y)
index 5ccf370..e1b0c92 100644 (file)
@@ -2294,6 +2294,12 @@ L:       netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/wan/dscc4.c
 
+DYNAMIC DEBUG
+M:     Jason Baron <jbaron@redhat.com>
+S:     Maintained
+F:     lib/dynamic_debug.c
+F:     include/linux/dynamic_debug.h
+
 DZ DECSTATION DZ11 SERIAL DRIVER
 M:     "Maciej W. Rozycki" <macro@linux-mips.org>
 S:     Maintained
index 0d6ed31..a34b2ae 100644 (file)
@@ -37,59 +37,6 @@ int __init mxc_register_device(struct platform_device *pdev, void *data)
        return ret;
 }
 
-struct platform_device *__init imx_add_platform_device_dmamask(
-               const char *name, int id,
-               const struct resource *res, unsigned int num_resources,
-               const void *data, size_t size_data, u64 dmamask)
-{
-       int ret = -ENOMEM;
-       struct platform_device *pdev;
-
-       pdev = platform_device_alloc(name, id);
-       if (!pdev)
-               goto err;
-
-       if (dmamask) {
-               /*
-                * This memory isn't freed when the device is put,
-                * I don't have a nice idea for that though.  Conceptually
-                * dma_mask in struct device should not be a pointer.
-                * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
-                */
-               pdev->dev.dma_mask =
-                       kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
-               if (!pdev->dev.dma_mask)
-                       /* ret is still -ENOMEM; */
-                       goto err;
-
-               *pdev->dev.dma_mask = dmamask;
-               pdev->dev.coherent_dma_mask = dmamask;
-       }
-
-       if (res) {
-               ret = platform_device_add_resources(pdev, res, num_resources);
-               if (ret)
-                       goto err;
-       }
-
-       if (data) {
-               ret = platform_device_add_data(pdev, data, size_data);
-               if (ret)
-                       goto err;
-       }
-
-       ret = platform_device_add(pdev);
-       if (ret) {
-err:
-               if (dmamask)
-                       kfree(pdev->dev.dma_mask);
-               platform_device_put(pdev);
-               return ERR_PTR(ret);
-       }
-
-       return pdev;
-}
-
 struct device mxc_aips_bus = {
        .init_name      = "mxc_aips",
        .parent         = &platform_bus,
index 524538a..543525d 100644 (file)
 extern struct device mxc_aips_bus;
 extern struct device mxc_ahb_bus;
 
-struct platform_device *imx_add_platform_device_dmamask(
+static inline struct platform_device *imx_add_platform_device_dmamask(
                const char *name, int id,
                const struct resource *res, unsigned int num_resources,
-               const void *data, size_t size_data, u64 dmamask);
+               const void *data, size_t size_data, u64 dmamask)
+{
+       struct platform_device_info pdevinfo = {
+               .name = name,
+               .id = id,
+               .res = res,
+               .num_res = num_resources,
+               .data = data,
+               .size_data = size_data,
+               .dma_mask = dmamask,
+       };
+       return platform_device_register_full(&pdevinfo);
+}
 
 static inline struct platform_device *imx_add_platform_device(
                const char *name, int id,
index bc8729d..82c8654 100644 (file)
@@ -1764,8 +1764,8 @@ void device_shutdown(void)
 
 #ifdef CONFIG_PRINTK
 
-static int __dev_printk(const char *level, const struct device *dev,
-                       struct va_format *vaf)
+int __dev_printk(const char *level, const struct device *dev,
+                struct va_format *vaf)
 {
        if (!dev)
                return printk("%s(NULL device *): %pV", level, vaf);
@@ -1773,6 +1773,7 @@ static int __dev_printk(const char *level, const struct device *dev,
        return printk("%s%s %s: %pV",
                      level, dev_driver_string(dev), dev_name(dev), vaf);
 }
+EXPORT_SYMBOL(__dev_printk);
 
 int dev_printk(const char *level, const struct device *dev,
               const char *fmt, ...)
index 6658da7..142e3d6 100644 (file)
@@ -147,6 +147,9 @@ probe_failed:
                printk(KERN_WARNING
                       "%s: probe of %s failed with error %d\n",
                       drv->name, dev_name(dev), ret);
+       } else {
+               pr_debug("%s: probe of %s rejects match %d\n",
+                      drv->name, dev_name(dev), ret);
        }
        /*
         * Ignore errors returned by ->probe so that the next driver can try
index 2840ed4..8272d92 100644 (file)
@@ -223,6 +223,42 @@ int memory_isolate_notify(unsigned long val, void *v)
        return atomic_notifier_call_chain(&memory_isolate_chain, val, v);
 }
 
+/*
+ * The probe routines leave the pages reserved, just as the bootmem code does.
+ * Make sure they're still that way.
+ */
+static bool pages_correctly_reserved(unsigned long start_pfn,
+                                       unsigned long nr_pages)
+{
+       int i, j;
+       struct page *page;
+       unsigned long pfn = start_pfn;
+
+       /*
+        * memmap between sections is not contiguous except with
+        * SPARSEMEM_VMEMMAP. We lookup the page once per section
+        * and assume memmap is contiguous within each section
+        */
+       for (i = 0; i < sections_per_block; i++, pfn += PAGES_PER_SECTION) {
+               if (WARN_ON_ONCE(!pfn_valid(pfn)))
+                       return false;
+               page = pfn_to_page(pfn);
+
+               for (j = 0; j < PAGES_PER_SECTION; j++) {
+                       if (PageReserved(page + j))
+                               continue;
+
+                       printk(KERN_WARNING "section number %ld page number %d "
+                               "not reserved, was it already online?\n",
+                               pfn_to_section_nr(pfn), j);
+
+                       return false;
+               }
+       }
+
+       return true;
+}
+
 /*
  * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
  * OK to have direct references to sparsemem variables in here.
@@ -230,7 +266,6 @@ int memory_isolate_notify(unsigned long val, void *v)
 static int
 memory_block_action(unsigned long phys_index, unsigned long action)
 {
-       int i;
        unsigned long start_pfn, start_paddr;
        unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
        struct page *first_page;
@@ -238,26 +273,13 @@ memory_block_action(unsigned long phys_index, unsigned long action)
 
        first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
 
-       /*
-        * The probe routines leave the pages reserved, just
-        * as the bootmem code does.  Make sure they're still
-        * that way.
-        */
-       if (action == MEM_ONLINE) {
-               for (i = 0; i < nr_pages; i++) {
-                       if (PageReserved(first_page+i))
-                               continue;
-
-                       printk(KERN_WARNING "section number %ld page number %d "
-                               "not reserved, was it already online?\n",
-                               phys_index, i);
-                       return -EBUSY;
-               }
-       }
-
        switch (action) {
                case MEM_ONLINE:
                        start_pfn = page_to_pfn(first_page);
+
+                       if (!pages_correctly_reserved(start_pfn, nr_pages))
+                               return -EBUSY;
+
                        ret = online_pages(start_pfn, nr_pages);
                        break;
                case MEM_OFFLINE:
@@ -380,9 +402,13 @@ memory_probe_store(struct class *class, struct class_attribute *attr,
        u64 phys_addr;
        int nid;
        int i, ret;
+       unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block;
 
        phys_addr = simple_strtoull(buf, NULL, 0);
 
+       if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
+               return -EINVAL;
+
        for (i = 0; i < sections_per_block; i++) {
                nid = memory_add_physaddr_to_nid(phys_addr);
                ret = add_memory(nid, phys_addr,
index 99a5272..7a24895 100644 (file)
@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev)
 EXPORT_SYMBOL_GPL(platform_device_unregister);
 
 /**
- * platform_device_register_resndata - add a platform-level device with
+ * platform_device_register_full - add a platform-level device with
  * resources and platform-specific data
  *
- * @parent: parent device for the device we're adding
- * @name: base name of the device we're adding
- * @id: instance id
- * @res: set of resources that needs to be allocated for the device
- * @num: number of resources
- * @data: platform specific data for this platform device
- * @size: size of platform specific data
+ * @pdevinfo: data used to create device
  *
  * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
-struct platform_device *platform_device_register_resndata(
-               struct device *parent,
-               const char *name, int id,
-               const struct resource *res, unsigned int num,
-               const void *data, size_t size)
+struct platform_device *platform_device_register_full(
+               struct platform_device_info *pdevinfo)
 {
        int ret = -ENOMEM;
        struct platform_device *pdev;
 
-       pdev = platform_device_alloc(name, id);
+       pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
        if (!pdev)
-               goto err;
-
-       pdev->dev.parent = parent;
+               goto err_alloc;
+
+       pdev->dev.parent = pdevinfo->parent;
+
+       if (pdevinfo->dma_mask) {
+               /*
+                * This memory isn't freed when the device is put,
+                * I don't have a nice idea for that though.  Conceptually
+                * dma_mask in struct device should not be a pointer.
+                * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+                */
+               pdev->dev.dma_mask =
+                       kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+               if (!pdev->dev.dma_mask)
+                       goto err;
+
+               *pdev->dev.dma_mask = pdevinfo->dma_mask;
+               pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
+       }
 
-       ret = platform_device_add_resources(pdev, res, num);
+       ret = platform_device_add_resources(pdev,
+                       pdevinfo->res, pdevinfo->num_res);
        if (ret)
                goto err;
 
-       ret = platform_device_add_data(pdev, data, size);
+       ret = platform_device_add_data(pdev,
+                       pdevinfo->data, pdevinfo->size_data);
        if (ret)
                goto err;
 
        ret = platform_device_add(pdev);
        if (ret) {
 err:
+               kfree(pdev->dev.dma_mask);
+
+err_alloc:
                platform_device_put(pdev);
                return ERR_PTR(ret);
        }
 
        return pdev;
 }
-EXPORT_SYMBOL_GPL(platform_device_register_resndata);
+EXPORT_SYMBOL_GPL(platform_device_register_full);
 
 static int platform_drv_probe(struct device *_dev)
 {
@@ -614,7 +626,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
                return rc;
 
        add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
-               (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
+                       pdev->name);
        return 0;
 }
 
index 0fd7e77..dee33ad 100644 (file)
@@ -90,6 +90,7 @@
 #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3       0x002C
 #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE   0x0040
 #define CLKCFG_REG_OFFSET                      0x500
+#define FUNCSEL_REG_OFFSET                     0x508
 
 #define PCH_PHUB_OROM_SIZE 15360
 
  * @intpin_reg_wpermit_reg3:           INTPIN_REG_WPERMIT register 3 val
  * @int_reduce_control_reg:            INT_REDUCE_CONTROL registers val
  * @clkcfg_reg:                                CLK CFG register val
+ * @funcsel_reg:                       Function select register value
  * @pch_phub_base_address:             Register base address
  * @pch_phub_extrom_base_address:      external rom base address
  * @pch_mac_start_address:             MAC address area start address
@@ -128,6 +130,7 @@ struct pch_phub_reg {
        u32 intpin_reg_wpermit_reg3;
        u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
        u32 clkcfg_reg;
+       u32 funcsel_reg;
        void __iomem *pch_phub_base_address;
        void __iomem *pch_phub_extrom_base_address;
        u32 pch_mac_start_address;
@@ -211,6 +214,8 @@ static void pch_phub_save_reg_conf(struct pci_dev *pdev)
                        __func__, i, chip->int_reduce_control_reg[i]);
        }
        chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
+       if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
+               chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET);
 }
 
 /* pch_phub_restore_reg_conf - restore register configuration */
@@ -271,6 +276,8 @@ static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
        }
 
        iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
+       if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
+               iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET);
 }
 
 /**
@@ -594,8 +601,7 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
 
        pch_phub_read_gbe_mac_addr(chip, mac);
 
-       return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+       return sprintf(buf, "%pM\n", mac);
 }
 
 static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
index d2efe82..a783d53 100644 (file)
@@ -69,7 +69,7 @@ static ssize_t map_name_show(struct uio_mem *mem, char *buf)
 
 static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
 {
-       return sprintf(buf, "0x%lx\n", mem->addr);
+       return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr);
 }
 
 static ssize_t map_size_show(struct uio_mem *mem, char *buf)
@@ -79,7 +79,7 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf)
 
 static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
 {
-       return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK);
+       return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr & ~PAGE_MASK);
 }
 
 struct map_sysfs_entry {
@@ -634,8 +634,7 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
                page = virt_to_page(idev->info->mem[mi].addr + offset);
        else
-               page = vmalloc_to_page((void *)idev->info->mem[mi].addr
-                                                       + offset);
+               page = vmalloc_to_page((void *)(unsigned long)idev->info->mem[mi].addr + offset);
        get_page(page);
        vmf->page = page;
        return 0;
@@ -750,14 +749,13 @@ static int uio_major_init(void)
 
        uio_major = MAJOR(uio_dev);
        uio_cdev = cdev;
-       result = 0;
-out:
-       return result;
+       return 0;
 out_put:
        kobject_put(&cdev->kobj);
 out_unregister:
        unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
-       goto out;
+out:
+       return result;
 }
 
 static void uio_major_cleanup(void)
index fc22e1e..02bd47b 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/uio_driver.h>
-#include <linux/spinlock.h>
 
 #define DRIVER_VERSION "0.01.0"
 #define DRIVER_AUTHOR  "Michael S. Tsirkin <mst@redhat.com>"
@@ -33,7 +32,6 @@
 struct uio_pci_generic_dev {
        struct uio_info info;
        struct pci_dev *pdev;
-       spinlock_t lock; /* guards command register accesses */
 };
 
 static inline struct uio_pci_generic_dev *
@@ -57,7 +55,6 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
        BUILD_BUG_ON(PCI_COMMAND % 4);
        BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
 
-       spin_lock_irq(&gdev->lock);
        pci_block_user_cfg_access(pdev);
 
        /* Read both command and status registers in a single 32-bit operation.
@@ -83,7 +80,6 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
 done:
 
        pci_unblock_user_cfg_access(pdev);
-       spin_unlock_irq(&gdev->lock);
        return ret;
 }
 
@@ -158,7 +154,6 @@ static int __devinit probe(struct pci_dev *pdev,
        gdev->info.irq_flags = IRQF_SHARED;
        gdev->info.handler = irqhandler;
        gdev->pdev = pdev;
-       spin_lock_init(&gdev->lock);
 
        if (uio_register_device(&pdev->dev, &gdev->info))
                goto err_register;
index bae96d2..0b2ed71 100644 (file)
@@ -253,7 +253,7 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
 };
 
 #ifdef CONFIG_OF
-static const struct of_device_id __devinitconst uio_of_genirq_match[] = {
+static const struct of_device_id uio_of_genirq_match[] = {
        { /* empty for now */ },
 };
 MODULE_DEVICE_TABLE(of, uio_of_genirq_match);
index e7a7a2f..f3a257d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  file.c - part of debugfs, a tiny little debug file system
+ *  inode.c - part of debugfs, a tiny little debug file system
  *
  *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
  *  Copyright (C) 2004 IBM Inc.
index ea9120a..83bb9d1 100644 (file)
@@ -43,20 +43,48 @@ static DEFINE_IDA(sysfs_ino_ida);
 static void sysfs_link_sibling(struct sysfs_dirent *sd)
 {
        struct sysfs_dirent *parent_sd = sd->s_parent;
-       struct sysfs_dirent **pos;
 
-       BUG_ON(sd->s_sibling);
-
-       /* Store directory entries in order by ino.  This allows
-        * readdir to properly restart without having to add a
-        * cursor into the s_dir.children list.
-        */
-       for (pos = &parent_sd->s_dir.children; *pos; pos = &(*pos)->s_sibling) {
-               if (sd->s_ino < (*pos)->s_ino)
-                       break;
+       struct rb_node **p;
+       struct rb_node *parent;
+
+       if (sysfs_type(sd) == SYSFS_DIR)
+               parent_sd->s_dir.subdirs++;
+
+       p = &parent_sd->s_dir.inode_tree.rb_node;
+       parent = NULL;
+       while (*p) {
+               parent = *p;
+#define node   rb_entry(parent, struct sysfs_dirent, inode_node)
+               if (sd->s_ino < node->s_ino) {
+                       p = &node->inode_node.rb_left;
+               } else if (sd->s_ino > node->s_ino) {
+                       p = &node->inode_node.rb_right;
+               } else {
+                       printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n",
+                              (unsigned long) sd->s_ino);
+                       BUG();
+               }
+#undef node
        }
-       sd->s_sibling = *pos;
-       *pos = sd;
+       rb_link_node(&sd->inode_node, parent, p);
+       rb_insert_color(&sd->inode_node, &parent_sd->s_dir.inode_tree);
+
+       p = &parent_sd->s_dir.name_tree.rb_node;
+       parent = NULL;
+       while (*p) {
+               int c;
+               parent = *p;
+#define node   rb_entry(parent, struct sysfs_dirent, name_node)
+               c = strcmp(sd->s_name, node->s_name);
+               if (c < 0) {
+                       p = &node->name_node.rb_left;
+               } else {
+                       p = &node->name_node.rb_right;
+               }
+#undef node
+       }
+       rb_link_node(&sd->name_node, parent, p);
+       rb_insert_color(&sd->name_node, &parent_sd->s_dir.name_tree);
 }
 
 /**
@@ -71,16 +99,11 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
  */
 static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
 {
-       struct sysfs_dirent **pos;
+       if (sysfs_type(sd) == SYSFS_DIR)
+               sd->s_parent->s_dir.subdirs--;
 
-       for (pos = &sd->s_parent->s_dir.children; *pos;
-            pos = &(*pos)->s_sibling) {
-               if (*pos == sd) {
-                       *pos = sd->s_sibling;
-                       sd->s_sibling = NULL;
-                       break;
-               }
-       }
+       rb_erase(&sd->inode_node, &sd->s_parent->s_dir.inode_tree);
+       rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree);
 }
 
 /**
@@ -126,7 +149,6 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
  */
 void sysfs_put_active(struct sysfs_dirent *sd)
 {
-       struct completion *cmpl;
        int v;
 
        if (unlikely(!sd))
@@ -138,10 +160,9 @@ void sysfs_put_active(struct sysfs_dirent *sd)
                return;
 
        /* atomic_dec_return() is a mb(), we'll always see the updated
-        * sd->s_sibling.
+        * sd->u.completion.
         */
-       cmpl = (void *)sd->s_sibling;
-       complete(cmpl);
+       complete(sd->u.completion);
 }
 
 /**
@@ -155,16 +176,16 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
        DECLARE_COMPLETION_ONSTACK(wait);
        int v;
 
-       BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
+       BUG_ON(!(sd->s_flags & SYSFS_FLAG_REMOVED));
 
        if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
                return;
 
-       sd->s_sibling = (void *)&wait;
+       sd->u.completion = (void *)&wait;
 
        rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
        /* atomic_add_return() is a mb(), put_active() will always see
-        * the updated sd->s_sibling.
+        * the updated sd->u.completion.
         */
        v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
 
@@ -173,8 +194,6 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
                wait_for_completion(&wait);
        }
 
-       sd->s_sibling = NULL;
-
        lock_acquired(&sd->dep_map, _RET_IP_);
        rwsem_release(&sd->dep_map, 1, _RET_IP_);
 }
@@ -490,7 +509,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
        }
 
        sd->s_flags |= SYSFS_FLAG_REMOVED;
-       sd->s_sibling = acxt->removed;
+       sd->u.removed_list = acxt->removed;
        acxt->removed = sd;
 }
 
@@ -514,8 +533,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
        while (acxt->removed) {
                struct sysfs_dirent *sd = acxt->removed;
 
-               acxt->removed = sd->s_sibling;
-               sd->s_sibling = NULL;
+               acxt->removed = sd->u.removed_list;
 
                sysfs_deactivate(sd);
                unmap_bin_file(sd);
@@ -540,15 +558,36 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
                                       const void *ns,
                                       const unsigned char *name)
 {
-       struct sysfs_dirent *sd;
+       struct rb_node *p = parent_sd->s_dir.name_tree.rb_node;
+       struct sysfs_dirent *found = NULL;
+
+       while (p) {
+               int c;
+#define node   rb_entry(p, struct sysfs_dirent, name_node)
+               c = strcmp(name, node->s_name);
+               if (c < 0) {
+                       p = node->name_node.rb_left;
+               } else if (c > 0) {
+                       p = node->name_node.rb_right;
+               } else {
+                       found = node;
+                       p = node->name_node.rb_left;
+               }
+#undef node
+       }
 
-       for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
-               if (ns && sd->s_ns && (sd->s_ns != ns))
-                       continue;
-               if (!strcmp(sd->s_name, name))
-                       return sd;
+       if (found && ns) {
+               while (found->s_ns && found->s_ns != ns) {
+                       p = rb_next(&found->name_node);
+                       if (!p)
+                               return NULL;
+                       found = rb_entry(p, struct sysfs_dirent, name_node);
+                       if (strcmp(name, found->s_name))
+                               return NULL;
+               }
        }
-       return NULL;
+
+       return found;
 }
 
 /**
@@ -744,21 +783,19 @@ void sysfs_remove_subdir(struct sysfs_dirent *sd)
 static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
 {
        struct sysfs_addrm_cxt acxt;
-       struct sysfs_dirent **pos;
+       struct rb_node *pos;
 
        if (!dir_sd)
                return;
 
        pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
        sysfs_addrm_start(&acxt, dir_sd);
-       pos = &dir_sd->s_dir.children;
-       while (*pos) {
-               struct sysfs_dirent *sd = *pos;
-
+       pos = rb_first(&dir_sd->s_dir.inode_tree);
+       while (pos) {
+               struct sysfs_dirent *sd = rb_entry(pos, struct sysfs_dirent, inode_node);
+               pos = rb_next(pos);
                if (sysfs_type(sd) != SYSFS_DIR)
                        sysfs_remove_one(&acxt, sd);
-               else
-                       pos = &(*pos)->s_sibling;
        }
        sysfs_addrm_finish(&acxt);
 
@@ -881,12 +918,28 @@ static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
                        pos = NULL;
        }
        if (!pos && (ino > 1) && (ino < INT_MAX)) {
-               pos = parent_sd->s_dir.children;
-               while (pos && (ino > pos->s_ino))
-                       pos = pos->s_sibling;
+               struct rb_node *p = parent_sd->s_dir.inode_tree.rb_node;
+               while (p) {
+#define node   rb_entry(p, struct sysfs_dirent, inode_node)
+                       if (ino < node->s_ino) {
+                               pos = node;
+                               p = node->inode_node.rb_left;
+                       } else if (ino > node->s_ino) {
+                               p = node->inode_node.rb_right;
+                       } else {
+                               pos = node;
+                               break;
+                       }
+#undef node
+               }
+       }
+       while (pos && pos->s_ns && pos->s_ns != ns) {
+               struct rb_node *p = rb_next(&pos->inode_node);
+               if (!p)
+                       pos = NULL;
+               else
+                       pos = rb_entry(p, struct sysfs_dirent, inode_node);
        }
-       while (pos && pos->s_ns && pos->s_ns != ns)
-               pos = pos->s_sibling;
        return pos;
 }
 
@@ -894,10 +947,13 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
        struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
 {
        pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
-       if (pos)
-               pos = pos->s_sibling;
-       while (pos && pos->s_ns && pos->s_ns != ns)
-               pos = pos->s_sibling;
+       if (pos) do {
+               struct rb_node *p = rb_next(&pos->inode_node);
+               if (!p)
+                       pos = NULL;
+               else
+                       pos = rb_entry(p, struct sysfs_dirent, inode_node);
+       } while (pos && pos->s_ns && pos->s_ns != ns);
        return pos;
 }
 
index e3f091a..1ee18c8 100644 (file)
@@ -202,18 +202,6 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
        inode->i_ctime = iattr->ia_ctime;
 }
 
-static int sysfs_count_nlink(struct sysfs_dirent *sd)
-{
-       struct sysfs_dirent *child;
-       int nr = 0;
-
-       for (child = sd->s_dir.children; child; child = child->s_sibling)
-               if (sysfs_type(child) == SYSFS_DIR)
-                       nr++;
-
-       return nr + 2;
-}
-
 static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
 {
        struct sysfs_inode_attrs *iattrs = sd->s_iattr;
@@ -230,7 +218,7 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
        }
 
        if (sysfs_type(sd) == SYSFS_DIR)
-               inode->i_nlink = sysfs_count_nlink(sd);
+               inode->i_nlink = sd->s_dir.subdirs + 2;
 }
 
 int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
index 845ab3a..ce29e28 100644 (file)
 #include <linux/lockdep.h>
 #include <linux/kobject_ns.h>
 #include <linux/fs.h>
+#include <linux/rbtree.h>
 
 struct sysfs_open_dirent;
 
 /* type-specific structures for sysfs_dirent->s_* union members */
 struct sysfs_elem_dir {
        struct kobject          *kobj;
-       /* children list starts here and goes through sd->s_sibling */
-       struct sysfs_dirent     *children;
+
+       unsigned long           subdirs;
+
+       struct rb_root          inode_tree;
+       struct rb_root          name_tree;
 };
 
 struct sysfs_elem_symlink {
@@ -56,9 +60,16 @@ struct sysfs_dirent {
        struct lockdep_map      dep_map;
 #endif
        struct sysfs_dirent     *s_parent;
-       struct sysfs_dirent     *s_sibling;
        const char              *s_name;
 
+       struct rb_node          inode_node;
+       struct rb_node          name_node;
+
+       union {
+               struct completion       *completion;
+               struct sysfs_dirent     *removed_list;
+       } u;
+
        const void              *s_ns; /* namespace tag */
        union {
                struct sysfs_elem_dir           s_dir;
index c20dfbf..4639419 100644 (file)
@@ -785,6 +785,8 @@ extern const char *dev_driver_string(const struct device *dev);
 
 #ifdef CONFIG_PRINTK
 
+extern int __dev_printk(const char *level, const struct device *dev,
+                       struct va_format *vaf);
 extern int dev_printk(const char *level, const struct device *dev,
                      const char *fmt, ...)
        __attribute__ ((format (printf, 3, 4)));
@@ -805,6 +807,9 @@ extern int _dev_info(const struct device *dev, const char *fmt, ...)
 
 #else
 
+static inline int __dev_printk(const char *level, const struct device *dev,
+                              struct va_format *vaf)
+        { return 0; }
 static inline int dev_printk(const char *level, const struct device *dev,
                      const char *fmt, ...)
        __attribute__ ((format (printf, 3, 4)));
index e747ecd..13aae80 100644 (file)
@@ -1,13 +1,6 @@
 #ifndef _DYNAMIC_DEBUG_H
 #define _DYNAMIC_DEBUG_H
 
-/* dynamic_printk_enabled, and dynamic_printk_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.
- */
-extern long long dynamic_debug_enabled;
-extern long long dynamic_debug_enabled2;
-
 /*
  * An instance of this structure is created in a special
  * ELF section at every dynamic debug callsite.  At runtime,
@@ -47,26 +40,55 @@ extern int ddebug_remove_module(const char *mod_name);
 extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
        __attribute__ ((format (printf, 2, 3)));
 
-#define dynamic_pr_debug(fmt, ...) do {                                        \
-       static struct _ddebug descriptor                                \
-       __used                                                          \
-       __attribute__((section("__verbose"), aligned(8))) =             \
-       { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__,            \
-               _DPRINTK_FLAGS_DEFAULT };                               \
-       if (unlikely(descriptor.enabled))                               \
-               __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
-       } while (0)
-
-
-#define dynamic_dev_dbg(dev, fmt, ...) do {                            \
-       static struct _ddebug descriptor                                \
-       __used                                                          \
-       __attribute__((section("__verbose"), aligned(8))) =             \
-       { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__,            \
-               _DPRINTK_FLAGS_DEFAULT };                               \
-       if (unlikely(descriptor.enabled))                               \
-               dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__);        \
-       } while (0)
+struct device;
+
+extern int __dynamic_dev_dbg(struct _ddebug *descriptor,
+                            const struct device *dev,
+                            const char *fmt, ...)
+       __attribute__ ((format (printf, 3, 4)));
+
+struct net_device;
+
+extern int __dynamic_netdev_dbg(struct _ddebug *descriptor,
+                            const struct net_device *dev,
+                            const char *fmt, ...)
+       __attribute__ ((format (printf, 3, 4)));
+
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)               \
+       static struct _ddebug __used __aligned(8)               \
+       __attribute__((section("__verbose"))) name = {          \
+               .modname = KBUILD_MODNAME,                      \
+               .function = __func__,                           \
+               .filename = __FILE__,                           \
+               .format = (fmt),                                \
+               .lineno = __LINE__,                             \
+               .flags =  _DPRINTK_FLAGS_DEFAULT,               \
+               .enabled = false,                               \
+       }
+
+#define dynamic_pr_debug(fmt, ...)                             \
+do {                                                           \
+       DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);         \
+       if (unlikely(descriptor.enabled))                       \
+               __dynamic_pr_debug(&descriptor, pr_fmt(fmt),    \
+                                  ##__VA_ARGS__);              \
+} while (0)
+
+#define dynamic_dev_dbg(dev, fmt, ...)                         \
+do {                                                           \
+       DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
+       if (unlikely(descriptor.enabled))                       \
+               __dynamic_dev_dbg(&descriptor, dev, fmt,        \
+                                 ##__VA_ARGS__);               \
+} while (0)
+
+#define dynamic_netdev_dbg(dev, fmt, ...)                      \
+do {                                                           \
+       DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);         \
+       if (unlikely(descriptor.enabled))                       \
+               __dynamic_netdev_dbg(&descriptor, dev, fmt,     \
+                                    ##__VA_ARGS__);            \
+} while (0)
 
 #else
 
index ddee79b..2797260 100644 (file)
@@ -2617,6 +2617,9 @@ static inline const char *netdev_name(const struct net_device *dev)
        return dev->name;
 }
 
+extern int __netdev_printk(const char *level, const struct net_device *dev,
+                       struct va_format *vaf);
+
 extern int netdev_printk(const char *level, const struct net_device *dev,
                         const char *format, ...)
        __attribute__ ((format (printf, 3, 4)));
@@ -2644,8 +2647,7 @@ extern int netdev_info(const struct net_device *dev, const char *format, ...)
 #elif defined(CONFIG_DYNAMIC_DEBUG)
 #define netdev_dbg(__dev, format, args...)                     \
 do {                                                           \
-       dynamic_dev_dbg((__dev)->dev.parent, "%s: " format,     \
-                       netdev_name(__dev), ##args);            \
+       dynamic_netdev_dbg(__dev, format, ##args);              \
 } while (0)
 #else
 #define netdev_dbg(__dev, format, args...)                     \
@@ -2712,9 +2714,7 @@ do {                                                              \
 #define netif_dbg(priv, type, netdev, format, args...)         \
 do {                                                           \
        if (netif_msg_##type(priv))                             \
-               dynamic_dev_dbg((netdev)->dev.parent,           \
-                               "%s: " format,                  \
-                               netdev_name(netdev), ##args);   \
+               dynamic_netdev_dbg(netdev, format, ##args);     \
 } while (0)
 #else
 #define netif_dbg(priv, type, dev, format, args...)                    \
index 27bb05a..651a066 100644 (file)
@@ -49,10 +49,54 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u
 extern int platform_get_irq_byname(struct platform_device *, const char *);
 extern int platform_add_devices(struct platform_device **, int);
 
-extern struct platform_device *platform_device_register_resndata(
+struct platform_device_info {
+               struct device *parent;
+
+               const char *name;
+               int id;
+
+               const struct resource *res;
+               unsigned int num_res;
+
+               const void *data;
+               size_t size_data;
+               u64 dma_mask;
+};
+extern struct platform_device *platform_device_register_full(
+               struct platform_device_info *pdevinfo);
+
+/**
+ * platform_device_register_resndata - add a platform-level device with
+ * resources and platform-specific data
+ *
+ * @parent: parent device for the device we're adding
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @res: set of resources that needs to be allocated for the device
+ * @num: number of resources
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
+ */
+static inline struct platform_device *platform_device_register_resndata(
                struct device *parent, const char *name, int id,
                const struct resource *res, unsigned int num,
-               const void *data, size_t size);
+               const void *data, size_t size) {
+
+       struct platform_device_info pdevinfo = {
+               .parent = parent,
+               .name = name,
+               .id = id,
+               .res = res,
+               .num_res = num,
+               .data = data,
+               .size_data = size,
+               .dma_mask = 0,
+       };
+
+       return platform_device_register_full(&pdevinfo);
+}
 
 /**
  * platform_device_register_simple - add a platform-level device and its resources
index 665517c..fd99ff9 100644 (file)
@@ -23,7 +23,10 @@ struct uio_map;
 /**
  * struct uio_mem - description of a UIO memory region
  * @name:              name of the memory region for identification
- * @addr:              address of the device's memory
+ * @addr:              address of the device's memory (phys_addr is used since
+ *                     addr can be logical, virtual, or physical & phys_addr_t
+ *                     should always be large enough to handle any of the
+ *                     address types)
  * @size:              size of IO
  * @memtype:           type of memory addr points to
  * @internal_addr:     ioremap-ped version of addr, for driver internal use
@@ -31,7 +34,7 @@ struct uio_map;
  */
 struct uio_mem {
        const char              *name;
-       unsigned long           addr;
+       phys_addr_t             addr;
        unsigned long           size;
        int                     memtype;
        void __iomem            *internal_addr;
index 79fc20b..dcdade3 100644 (file)
@@ -10,6 +10,8 @@
  * Copyright (C) 2011 Bart Van Assche.  All Rights Reserved.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -29,6 +31,8 @@
 #include <linux/jump_label.h>
 #include <linux/hardirq.h>
 #include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
 
 extern struct _ddebug __start___verbose[];
 extern struct _ddebug __stop___verbose[];
@@ -37,7 +41,6 @@ struct ddebug_table {
        struct list_head link;
        char *mod_name;
        unsigned int num_ddebugs;
-       unsigned int num_enabled;
        struct _ddebug *ddebugs;
 };
 
@@ -147,19 +150,13 @@ static void ddebug_change(const struct ddebug_query *query,
                        newflags = (dp->flags & mask) | flags;
                        if (newflags == dp->flags)
                                continue;
-
-                       if (!newflags)
-                               dt->num_enabled--;
-                       else if (!dp->flags)
-                               dt->num_enabled++;
                        dp->flags = newflags;
                        if (newflags)
                                dp->enabled = 1;
                        else
                                dp->enabled = 0;
                        if (verbose)
-                               printk(KERN_INFO
-                                       "ddebug: changed %s:%d [%s]%s %s\n",
+                               pr_info("changed %s:%d [%s]%s %s\n",
                                        dp->filename, dp->lineno,
                                        dt->mod_name, dp->function,
                                        ddebug_describe_flags(dp, flagbuf,
@@ -169,7 +166,7 @@ static void ddebug_change(const struct ddebug_query *query,
        mutex_unlock(&ddebug_lock);
 
        if (!nfound && verbose)
-               printk(KERN_INFO "ddebug: no matches for query\n");
+               pr_info("no matches for query\n");
 }
 
 /*
@@ -214,10 +211,10 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
 
        if (verbose) {
                int i;
-               printk(KERN_INFO "%s: split into words:", __func__);
+               pr_info("split into words:");
                for (i = 0 ; i < nwords ; i++)
-                       printk(" \"%s\"", words[i]);
-               printk("\n");
+                       pr_cont(" \"%s\"", words[i]);
+               pr_cont("\n");
        }
 
        return nwords;
@@ -329,16 +326,15 @@ static int ddebug_parse_query(char *words[], int nwords,
                        }
                } else {
                        if (verbose)
-                               printk(KERN_ERR "%s: unknown keyword \"%s\"\n",
-                                       __func__, words[i]);
+                               pr_err("unknown keyword \"%s\"\n", words[i]);
                        return -EINVAL;
                }
        }
 
        if (verbose)
-               printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" "
-                      "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
-                       __func__, query->function, query->filename,
+               pr_info("q->function=\"%s\" q->filename=\"%s\" "
+                       "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
+                       query->function, query->filename,
                        query->module, query->format, query->first_lineno,
                        query->last_lineno);
 
@@ -367,7 +363,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
                return -EINVAL;
        }
        if (verbose)
-               printk(KERN_INFO "%s: op='%c'\n", __func__, op);
+               pr_info("op='%c'\n", op);
 
        for ( ; *str ; ++str) {
                for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
@@ -382,7 +378,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
        if (flags == 0)
                return -EINVAL;
        if (verbose)
-               printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags);
+               pr_info("flags=0x%x\n", flags);
 
        /* calculate final *flagsp, *maskp according to mask and op */
        switch (op) {
@@ -400,8 +396,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
                break;
        }
        if (verbose)
-               printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n",
-                       __func__, *flagsp, *maskp);
+               pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
        return 0;
 }
 
@@ -426,40 +421,117 @@ static int ddebug_exec_query(char *query_string)
        return 0;
 }
 
+#define PREFIX_SIZE 64
+
+static int remaining(int wrote)
+{
+       if (PREFIX_SIZE - wrote > 0)
+               return PREFIX_SIZE - wrote;
+       return 0;
+}
+
+static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
+{
+       int pos_after_tid;
+       int pos = 0;
+
+       pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG);
+       if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
+               if (in_interrupt())
+                       pos += snprintf(buf + pos, remaining(pos), "%s ",
+                                               "<intr>");
+               else
+                       pos += snprintf(buf + pos, remaining(pos), "[%d] ",
+                                               task_pid_vnr(current));
+       }
+       pos_after_tid = pos;
+       if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
+               pos += snprintf(buf + pos, remaining(pos), "%s:",
+                                       desc->modname);
+       if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
+               pos += snprintf(buf + pos, remaining(pos), "%s:",
+                                       desc->function);
+       if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
+               pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno);
+       if (pos - pos_after_tid)
+               pos += snprintf(buf + pos, remaining(pos), " ");
+       if (pos >= PREFIX_SIZE)
+               buf[PREFIX_SIZE - 1] = '\0';
+
+       return buf;
+}
+
 int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
 {
        va_list args;
        int res;
+       struct va_format vaf;
+       char buf[PREFIX_SIZE];
 
        BUG_ON(!descriptor);
        BUG_ON(!fmt);
 
        va_start(args, fmt);
-       res = printk(KERN_DEBUG);
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) {
-               if (in_interrupt())
-                       res += printk(KERN_CONT "<intr> ");
-               else
-                       res += printk(KERN_CONT "[%d] ", task_pid_vnr(current));
-       }
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME)
-               res += printk(KERN_CONT "%s:", descriptor->modname);
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
-               res += printk(KERN_CONT "%s:", descriptor->function);
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO)
-               res += printk(KERN_CONT "%d ", descriptor->lineno);
-       res += vprintk(fmt, args);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
        va_end(args);
 
        return res;
 }
 EXPORT_SYMBOL(__dynamic_pr_debug);
 
+int __dynamic_dev_dbg(struct _ddebug *descriptor,
+                     const struct device *dev, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+       int res;
+       char buf[PREFIX_SIZE];
+
+       BUG_ON(!descriptor);
+       BUG_ON(!fmt);
+
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
+       va_end(args);
+
+       return res;
+}
+EXPORT_SYMBOL(__dynamic_dev_dbg);
+
+#ifdef CONFIG_NET
+
+int __dynamic_netdev_dbg(struct _ddebug *descriptor,
+                     const struct net_device *dev, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+       int res;
+       char buf[PREFIX_SIZE];
+
+       BUG_ON(!descriptor);
+       BUG_ON(!fmt);
+
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
+       va_end(args);
+
+       return res;
+}
+EXPORT_SYMBOL(__dynamic_netdev_dbg);
+
+#endif
+
 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");
+               pr_warn("ddebug boot param string too large\n");
                return 0;
        }
        strcpy(ddebug_setup_string, str);
@@ -487,8 +559,7 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
                return -EFAULT;
        tmpbuf[len] = '\0';
        if (verbose)
-               printk(KERN_INFO "%s: read %d bytes from userspace\n",
-                       __func__, (int)len);
+               pr_info("read %d bytes from userspace\n", (int)len);
 
        ret = ddebug_exec_query(tmpbuf);
        if (ret)
@@ -551,8 +622,7 @@ static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
        int n = *pos;
 
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p *pos=%lld\n",
-                       __func__, m, (unsigned long long)*pos);
+               pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
 
        mutex_lock(&ddebug_lock);
 
@@ -577,8 +647,8 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
        struct _ddebug *dp;
 
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n",
-                       __func__, m, p, (unsigned long long)*pos);
+               pr_info("called m=%p p=%p *pos=%lld\n",
+                       m, p, (unsigned long long)*pos);
 
        if (p == SEQ_START_TOKEN)
                dp = ddebug_iter_first(iter);
@@ -601,8 +671,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
        char flagsbuf[8];
 
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p p=%p\n",
-                       __func__, m, p);
+               pr_info("called m=%p p=%p\n", m, p);
 
        if (p == SEQ_START_TOKEN) {
                seq_puts(m,
@@ -627,8 +696,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
 static void ddebug_proc_stop(struct seq_file *m, void *p)
 {
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p p=%p\n",
-                       __func__, m, p);
+               pr_info("called m=%p p=%p\n", m, p);
        mutex_unlock(&ddebug_lock);
 }
 
@@ -651,7 +719,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file)
        int err;
 
        if (verbose)
-               printk(KERN_INFO "%s: called\n", __func__);
+               pr_info("called\n");
 
        iter = kzalloc(sizeof(*iter), GFP_KERNEL);
        if (iter == NULL)
@@ -695,7 +763,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
        }
        dt->mod_name = new_name;
        dt->num_ddebugs = n;
-       dt->num_enabled = 0;
        dt->ddebugs = tab;
 
        mutex_lock(&ddebug_lock);
@@ -703,8 +770,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
        mutex_unlock(&ddebug_lock);
 
        if (verbose)
-               printk(KERN_INFO "%u debug prints in module %s\n",
-                                n, dt->mod_name);
+               pr_info("%u debug prints in module %s\n", n, dt->mod_name);
        return 0;
 }
 EXPORT_SYMBOL_GPL(ddebug_add_module);
@@ -726,8 +792,7 @@ int ddebug_remove_module(const char *mod_name)
        int ret = -ENOENT;
 
        if (verbose)
-               printk(KERN_INFO "%s: removing module \"%s\"\n",
-                               __func__, mod_name);
+               pr_info("removing module \"%s\"\n", mod_name);
 
        mutex_lock(&ddebug_lock);
        list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
@@ -803,8 +868,8 @@ static int __init dynamic_debug_init(void)
        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);
+                       pr_warn("Invalid ddebug boot param %s",
+                               ddebug_setup_string);
                else
                        pr_info("ddebug initialized with string %s",
                                ddebug_setup_string);
index 70af0a7..ad72a03 100644 (file)
@@ -282,7 +282,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
                                                            kobj_bcast_filter,
                                                            kobj);
                        /* ENOBUFS should be handled in userspace */
-                       if (retval == -ENOBUFS)
+                       if (retval == -ENOBUFS || retval == -ESRCH)
                                retval = 0;
                } else
                        retval = -ENOMEM;
index b10ff0a..231d312 100644 (file)
@@ -6298,7 +6298,7 @@ const char *netdev_drivername(const struct net_device *dev)
        return empty;
 }
 
-static int __netdev_printk(const char *level, const struct net_device *dev,
+int __netdev_printk(const char *level, const struct net_device *dev,
                           struct va_format *vaf)
 {
        int r;
@@ -6313,6 +6313,7 @@ static int __netdev_printk(const char *level, const struct net_device *dev,
 
        return r;
 }
+EXPORT_SYMBOL(__netdev_printk);
 
 int netdev_printk(const char *level, const struct net_device *dev,
                  const char *format, ...)