Merge tag 'driver-core-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-block.git] / drivers / s390 / cio / device.c
index 9e0cf44ff9d4b2abc2134d933e0b25883f78e765..8eb089b99cde92bad4670656b281b4cfcc8425b6 100644 (file)
@@ -80,7 +80,7 @@ ccw_bus_match (struct device * dev, struct device_driver * drv)
  * specified size. Return length of resulting string (excluding trailing '\0')
  * even if string doesn't fit buffer (snprintf semantics). */
 static int snprint_alias(char *buf, size_t size,
-                        struct ccw_device_id *id, const char *suffix)
+                        const struct ccw_device_id *id, const char *suffix)
 {
        int len;
 
@@ -101,10 +101,10 @@ static int snprint_alias(char *buf, size_t size,
 
 /* Set up environment variables for ccw device uevent. Return 0 on success,
  * non-zero otherwise. */
-static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int ccw_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-       struct ccw_device *cdev = to_ccwdev(dev);
-       struct ccw_device_id *id = &(cdev->id);
+       const struct ccw_device *cdev = to_ccwdev(dev);
+       const struct ccw_device_id *id = &(cdev->id);
        int ret;
        char modalias_buf[30];
 
@@ -244,10 +244,13 @@ int ccw_device_is_orphan(struct ccw_device *cdev)
 
 static void ccw_device_unregister(struct ccw_device *cdev)
 {
+       mutex_lock(&cdev->reg_mutex);
        if (device_is_registered(&cdev->dev)) {
                /* Undo device_add(). */
                device_del(&cdev->dev);
        }
+       mutex_unlock(&cdev->reg_mutex);
+
        if (cdev->private->flags.initialized) {
                cdev->private->flags.initialized = 0;
                /* Release reference from device_initialize(). */
@@ -653,11 +656,13 @@ static void ccw_device_do_unbind_bind(struct ccw_device *cdev)
 {
        int ret;
 
+       mutex_lock(&cdev->reg_mutex);
        if (device_is_registered(&cdev->dev)) {
                device_release_driver(&cdev->dev);
                ret = device_attach(&cdev->dev);
                WARN_ON(ret == -ENODEV);
        }
+       mutex_unlock(&cdev->reg_mutex);
 }
 
 static void
@@ -740,6 +745,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch,
        INIT_LIST_HEAD(&priv->cmb_list);
        init_waitqueue_head(&priv->wait_q);
        timer_setup(&priv->timer, ccw_device_timeout, 0);
+       mutex_init(&cdev->reg_mutex);
 
        atomic_set(&priv->onoff, 0);
        cdev->ccwlock = sch->lock;
@@ -825,6 +831,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
         * be registered). We need to reprobe since we may now have sense id
         * information.
         */
+       mutex_lock(&cdev->reg_mutex);
        if (device_is_registered(&cdev->dev)) {
                if (!cdev->drv) {
                        ret = device_reprobe(&cdev->dev);
@@ -847,12 +854,14 @@ static void io_subchannel_register(struct ccw_device *cdev)
                spin_lock_irqsave(sch->lock, flags);
                sch_set_cdev(sch, NULL);
                spin_unlock_irqrestore(sch->lock, flags);
+               mutex_unlock(&cdev->reg_mutex);
                /* Release initial device reference. */
                put_device(&cdev->dev);
                goto out_err;
        }
 out:
        cdev->private->flags.recog_done = 1;
+       mutex_unlock(&cdev->reg_mutex);
        wake_up(&cdev->private->wait_q);
 out_err:
        if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))