tpm: Provide strong locking for device removal
[cascardo/linux.git] / drivers / char / tpm / tpm.h
index 5d33ba5..c6376b1 100644 (file)
@@ -170,7 +170,13 @@ struct tpm_chip {
        struct device dev;
        struct cdev cdev;
 
+       /* A driver callback under ops cannot be run unless ops_sem is held
+        * (sometimes implicitly, eg for the sysfs code). ops becomes null
+        * when the driver is unregistered, see tpm_try_get_ops.
+        */
+       struct rw_semaphore ops_sem;
        const struct tpm_class_ops *ops;
+
        unsigned int flags;
 
        int dev_num;            /* /dev/tpm# */
@@ -195,11 +201,6 @@ struct tpm_chip {
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
 
-static inline void tpm_chip_put(struct tpm_chip *chip)
-{
-       module_put(chip->dev.parent->driver->owner);
-}
-
 static inline int tpm_read_index(int base, int index)
 {
        outb(index, base);
@@ -507,6 +508,9 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
                             wait_queue_head_t *, bool);
 
 struct tpm_chip *tpm_chip_find_get(int chip_num);
+__must_check int tpm_try_get_ops(struct tpm_chip *chip);
+void tpm_put_ops(struct tpm_chip *chip);
+
 extern struct tpm_chip *tpmm_chip_alloc(struct device *dev,
                                       const struct tpm_class_ops *ops);
 extern int tpm_chip_register(struct tpm_chip *chip);