Avoid initializing multiple pvpanic devices when configure multiple
pvpanic device driver type. Make sure that only one pvpanic device
is working.

Signed-off-by: Peng Hao <peng.h...@zte.com.cn>
---
 drivers/misc/pvpanic/pvpanic.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c
index ccadec0..3c9d957 100644
--- a/drivers/misc/pvpanic/pvpanic.c
+++ b/drivers/misc/pvpanic/pvpanic.c
@@ -15,10 +15,13 @@
 #include <linux/types.h>
 
 static struct {
+       struct mutex lock;
        struct platform_device *pdev;
        void __iomem *base;
        bool is_ioport;
-} pvpanic_data;
+} pvpanic_data = {
+       .lock = __MUTEX_INITIALIZER(pvpanic_data.lock),
+};
 
 #define PVPANIC_PANICKED        (1 << 0)
 
@@ -50,9 +53,17 @@ int pvpanic_add_device(struct device *dev, struct resource 
*res)
        struct platform_device *pdev;
        int ret;
 
+       mutex_lock(&pvpanic_data.lock);
+       if (pvpanic_data.pdev) {
+               mutex_unlock(&pvpanic_data.lock);
+               return -EEXIST;
+       }
+
        pdev = platform_device_alloc("pvpanic", -1);
-       if (!pdev)
+       if (!pdev) {
+               mutex_unlock(&pvpanic_data.lock);
                return -ENOMEM;
+       }
 
        pdev->dev.parent = dev;
 
@@ -64,9 +75,11 @@ int pvpanic_add_device(struct device *dev, struct resource 
*res)
        if (ret)
                goto err;
        pvpanic_data.pdev = pdev;
+       mutex_unlock(&pvpanic_data.lock);
 
        return 0;
 err:
+       mutex_unlock(&pvpanic_data.lock);
        platform_device_put(pdev);
        return ret;
 }
@@ -74,8 +87,10 @@ int pvpanic_add_device(struct device *dev, struct resource 
*res)
 
 void pvpanic_remove_device(void)
 {
+       mutex_lock(&pvpanic_data.lock);
        platform_device_unregister(pvpanic_data.pdev);
        pvpanic_data.pdev = NULL;
+       mutex_unlock(&pvpanic_data.lock);
 }
 EXPORT_SYMBOL_GPL(pvpanic_remove_device);
 
-- 
1.8.3.1

Reply via email to