dev_dbg/dynamic_debug: Update to use printk_emit, optimize stack
[cascardo/linux.git] / drivers / base / core.c
index 5e6e00b..d325b9d 100644 (file)
@@ -184,6 +184,17 @@ static void device_release(struct kobject *kobj)
        struct device *dev = kobj_to_dev(kobj);
        struct device_private *p = dev->p;
 
+       /*
+        * Some platform devices are driven without driver attached
+        * and managed resources may have been acquired.  Make sure
+        * all resources are released.
+        *
+        * Drivers still can add resources into device after device
+        * is deleted but alive, so release devres here to avoid
+        * possible memory leak.
+        */
+       devres_release_all(dev);
+
        if (dev->release)
                dev->release(dev);
        else if (dev->type && dev->type->release)
@@ -1196,13 +1207,6 @@ void device_del(struct device *dev)
        bus_remove_device(dev);
        driver_deferred_probe_del(dev);
 
-       /*
-        * Some platform devices are driven without driver attached
-        * and managed resources may have been acquired.  Make sure
-        * all resources are released.
-        */
-       devres_release_all(dev);
-
        /* Notify the platform of the removal, in case they
         * need to do anything...
         */
@@ -1861,26 +1865,19 @@ void device_shutdown(void)
  */
 
 #ifdef CONFIG_PRINTK
-int __dev_printk(const char *level, const struct device *dev,
-                struct va_format *vaf)
+int create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
 {
-       char dict[128];
-       const char *level_extra = "";
-       size_t dictlen = 0;
        const char *subsys;
-
-       if (!dev)
-               return printk("%s(NULL device *): %pV", level, vaf);
+       size_t pos = 0;
 
        if (dev->class)
                subsys = dev->class->name;
        else if (dev->bus)
                subsys = dev->bus->name;
        else
-               goto skip;
+               return 0;
 
-       dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
-                           "SUBSYSTEM=%s", subsys);
+       pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys);
 
        /*
         * Add device identifier DEVICE=:
@@ -1896,32 +1893,41 @@ int __dev_printk(const char *level, const struct device *dev,
                        c = 'b';
                else
                        c = 'c';
-               dictlen++;
-               dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
-                                  "DEVICE=%c%u:%u",
-                                  c, MAJOR(dev->devt), MINOR(dev->devt));
+               pos++;
+               pos += snprintf(hdr + pos, hdrlen - pos,
+                               "DEVICE=%c%u:%u",
+                               c, MAJOR(dev->devt), MINOR(dev->devt));
        } else if (strcmp(subsys, "net") == 0) {
                struct net_device *net = to_net_dev(dev);
 
-               dictlen++;
-               dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
-                                   "DEVICE=n%u", net->ifindex);
+               pos++;
+               pos += snprintf(hdr + pos, hdrlen - pos,
+                               "DEVICE=n%u", net->ifindex);
        } else {
-               dictlen++;
-               dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
-                                   "DEVICE=+%s:%s", subsys, dev_name(dev));
+               pos++;
+               pos += snprintf(hdr + pos, hdrlen - pos,
+                               "DEVICE=+%s:%s", subsys, dev_name(dev));
        }
-skip:
-       if (level[2])
-               level_extra = &level[2]; /* skip past KERN_SOH "L" */
 
-       return printk_emit(0, level[1] - '0',
-                          dictlen ? dict : NULL, dictlen,
-                          "%s %s: %s%pV",
-                          dev_driver_string(dev), dev_name(dev),
-                          level_extra, vaf);
+       return pos;
+}
+EXPORT_SYMBOL(create_syslog_header);
+
+static int __dev_printk(const char *level, const struct device *dev,
+                       struct va_format *vaf)
+{
+       char hdr[128];
+       size_t hdrlen;
+
+       if (!dev)
+               return printk("%s(NULL device *): %pV", level, vaf);
+
+       hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
+
+       return printk_emit(0, level[1] - '0', hdrlen ? hdr : NULL, hdrlen,
+                          "%s %s: %pV",
+                          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, ...)
@@ -1936,6 +1942,7 @@ int dev_printk(const char *level, const struct device *dev,
        vaf.va = &args;
 
        r = __dev_printk(level, dev, &vaf);
+
        va_end(args);
 
        return r;
@@ -1955,6 +1962,7 @@ int func(const struct device *dev, const char *fmt, ...)  \
        vaf.va = &args;                                         \
                                                                \
        r = __dev_printk(kern_level, dev, &vaf);                \
+                                                               \
        va_end(args);                                           \
                                                                \
        return r;                                               \