driver/char/tpm: fix regression causesd by ppi
authorGang Wei <gang.wei@intel.com>
Tue, 9 Oct 2012 09:35:22 +0000 (17:35 +0800)
committerKent Yoder <key@linux.vnet.ibm.com>
Wed, 10 Oct 2012 14:50:56 +0000 (09:50 -0500)
This patch try to fix the S3 regression https://lkml.org/lkml/2012/10/5/433,
which includes below line:
[ 1554.684638] sysfs: cannot create duplicate filename '/devices/pnp0/00:0c/ppi'

The root cause is that ppi sysfs teardown code is MIA, so while S3 resume,
the ppi kobject will be created again upon existing one.

To make the tear down code simple, change the ppi subfolder creation from
using kobject_create_and_add to just using a named ppi attribute_group. Then
ppi sysfs teardown could be done with a simple sysfs_remove_group call.

Adjusted the name & return type for ppi sysfs init function.

Reported-by: Ben Guthro <ben@guthro.net>
Signed-off-by: Gang Wei <gang.wei@intel.com>
Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_ppi.c

index f26afdb1a7026aed8a0173ff7a17ea87524661dd..b429f1ea1b976c9e0d5e267e8fe03ce47df89470 100644 (file)
@@ -1259,6 +1259,7 @@ void tpm_remove_hardware(struct device *dev)
 
        misc_deregister(&chip->vendor.miscdev);
        sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
+       tpm_remove_ppi(&dev->kobj);
        tpm_bios_log_teardown(chip->bios_dir);
 
        /* write it this way to be explicit (chip->dev == dev) */
@@ -1476,7 +1477,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
                goto put_device;
        }
 
-       if (sys_add_ppi(&dev->kobj)) {
+       if (tpm_add_ppi(&dev->kobj)) {
                misc_deregister(&chip->vendor.miscdev);
                goto put_device;
        }
index 02c266aa2bf712657d3507071c1b266a4215e3c2..8ef7649a50aa7d31f32360ea81ad0668cf041065 100644 (file)
@@ -329,10 +329,15 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
                             wait_queue_head_t *);
 
 #ifdef CONFIG_ACPI
-extern ssize_t sys_add_ppi(struct kobject *parent);
+extern int tpm_add_ppi(struct kobject *);
+extern void tpm_remove_ppi(struct kobject *);
 #else
-static inline ssize_t sys_add_ppi(struct kobject *parent)
+static inline int tpm_add_ppi(struct kobject *parent)
 {
        return 0;
 }
+
+static inline void tpm_remove_ppi(struct kobject *parent)
+{
+}
 #endif
index f27b58cfae98fd160168e942e009150c7c2d3f58..720ebcf29fdfbb9a9bf05a44cee1fc4e53e4a238 100644 (file)
@@ -444,18 +444,20 @@ static struct attribute *ppi_attrs[] = {
        &dev_attr_vs_operations.attr, NULL,
 };
 static struct attribute_group ppi_attr_grp = {
+       .name = "ppi",
        .attrs = ppi_attrs
 };
 
-ssize_t sys_add_ppi(struct kobject *parent)
+int tpm_add_ppi(struct kobject *parent)
 {
-       struct kobject *ppi;
-       ppi = kobject_create_and_add("ppi", parent);
-       if (sysfs_create_group(ppi, &ppi_attr_grp))
-               return -EFAULT;
-       else
-               return 0;
+       return sysfs_create_group(parent, &ppi_attr_grp);
+}
+EXPORT_SYMBOL_GPL(tpm_add_ppi);
+
+void tpm_remove_ppi(struct kobject *parent)
+{
+       sysfs_remove_group(parent, &ppi_attr_grp);
 }
-EXPORT_SYMBOL_GPL(sys_add_ppi);
+EXPORT_SYMBOL_GPL(tpm_remove_ppi);
 
 MODULE_LICENSE("GPL");