@@ -144,13 +144,9 @@ int tpm_chip_register(struct tpm_chip *chip)
if (rc)
return rc;
- rc = tpm_sysfs_add_device(chip);
- if (rc)
- goto del_misc;
-
rc = tpm_add_ppi(chip);
if (rc)
- goto del_sysfs;
+ goto out_err;
chip->bios_dir = tpm_bios_log_setup(chip->devname);
@@ -160,9 +156,7 @@ int tpm_chip_register(struct tpm_chip *chip)
spin_unlock(&driver_lock);
return 0;
-del_sysfs:
- tpm_sysfs_del_device(chip);
-del_misc:
+out_err:
tpm_dev_del_device(chip);
return rc;
}
@@ -185,7 +179,6 @@ void tpm_chip_unregister(struct tpm_chip *chip)
spin_unlock(&driver_lock);
synchronize_rcu();
- tpm_sysfs_del_device(chip);
tpm_remove_ppi(chip);
if (chip->bios_dir)
@@ -22,6 +22,8 @@
#include <linux/major.h>
#include "tpm.h"
+ATTRIBUTE_GROUPS(tpm_dev);
+
struct file_priv {
struct tpm_chip *chip;
@@ -199,6 +201,8 @@ int tpm_dev_add_device(struct tpm_chip *chip)
else
chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
+ chip->dev.groups = tpm_dev_groups;
+
dev_set_name(&chip->dev, chip->devname);
rc = device_register(&chip->dev);
@@ -263,7 +263,7 @@ static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(timeouts);
-static struct attribute *tpm_dev_attrs[] = {
+struct attribute *tpm_dev_attrs[] = {
&dev_attr_pubek.attr,
&dev_attr_pcrs.attr,
&dev_attr_enabled.attr,
@@ -276,24 +276,3 @@ static struct attribute *tpm_dev_attrs[] = {
&dev_attr_timeouts.attr,
NULL,
};
-
-static const struct attribute_group tpm_dev_group = {
- .attrs = tpm_dev_attrs,
-};
-
-int tpm_sysfs_add_device(struct tpm_chip *chip)
-{
- int err;
- err = sysfs_create_group(&chip->pdev->kobj,
- &tpm_dev_group);
-
- if (err)
- dev_err(chip->pdev,
- "failed to create sysfs attributes, %d\n", err);
- return err;
-}
-
-void tpm_sysfs_del_device(struct tpm_chip *chip)
-{
- sysfs_remove_group(&chip->pdev->kobj, &tpm_dev_group);
-}
@@ -324,6 +324,7 @@ struct tpm_cmd_t {
extern struct class *tpm_class;
extern dev_t tpm_devt;
+extern struct attribute *tpm_dev_attrs[];
ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
@@ -347,8 +348,6 @@ extern void tpm_chip_unregister(struct tpm_chip *chip);
int tpm_dev_add_device(struct tpm_chip *chip);
void tpm_dev_del_device(struct tpm_chip *chip);
-int tpm_sysfs_add_device(struct tpm_chip *chip);
-void tpm_sysfs_del_device(struct tpm_chip *chip);
int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
sysfs attributes were created into wrong place (platform device directory) and they had a race condition where user space might get announced about the device before sysfs were created. This patch uses the groups field in struct device to resolve this issue. BIOS log and PPI are still kept racy in order to not break up backwards compatibility. Moving device sysfs attributes to a different place should not be a problem because they are not machine consumable anyway (which is of course wrong but what can you do since they already exist). Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- drivers/char/tpm/tpm-chip.c | 11 ++--------- drivers/char/tpm/tpm-dev.c | 4 ++++ drivers/char/tpm/tpm-sysfs.c | 23 +---------------------- drivers/char/tpm/tpm.h | 3 +-- 4 files changed, 8 insertions(+), 33 deletions(-)