diff options
| -rw-r--r-- | drivers/misc/vib-gpio.c | 22 | 
1 files changed, 20 insertions, 2 deletions
| diff --git a/drivers/misc/vib-gpio.c b/drivers/misc/vib-gpio.c index a013f214e83..98a17d79b10 100644 --- a/drivers/misc/vib-gpio.c +++ b/drivers/misc/vib-gpio.c @@ -33,6 +33,7 @@ struct vib_gpio_data {  	struct work_struct vib_work;  	struct hrtimer timer;  	spinlock_t lock; +	struct mutex io_mutex; /* protect GPIO & regulator operations */  	struct regulator *reg;  	int gpio; @@ -46,20 +47,28 @@ struct vib_gpio_data {  static int power_on(struct vib_gpio_data *vib_data)  { -	if (vib_data->reg) +	if (vib_data->reg) { +		dev_dbg(vib_data->dev.dev, "enable regulator\n");  		return regulator_enable(vib_data->reg); +	}  	return 0;  }  static int power_off(struct vib_gpio_data *vib_data)  { -	if (vib_data->reg) +	if (vib_data->reg) { +		dev_dbg(vib_data->dev.dev, "disable regulator\n");  		return regulator_disable(vib_data->reg); +	}  	return 0;  }  static void vib_gpio_set(struct vib_gpio_data *vib_data, int on)  { +	dev_dbg(vib_data->dev.dev, "%s(%d)\n", __func__, on); + +	mutex_lock(&(vib_data->io_mutex)); +  	if (on) {  		if (!vib_data->vib_power_state) {  			power_on(vib_data); @@ -78,6 +87,8 @@ static void vib_gpio_set(struct vib_gpio_data *vib_data, int on)  			vib_data->vib_power_state = 0;  		}  	} + +	mutex_unlock(&(vib_data->io_mutex));  }  static void vib_gpio_update(struct work_struct *work) @@ -93,6 +104,7 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)  {  	struct vib_gpio_data *vib_data =  	    container_of(timer, struct vib_gpio_data, timer); +	dev_dbg(vib_data->dev.dev, "Timer expired: disabling vibrator\n");  	vib_data->vib_state = 0;  	schedule_work(&vib_data->vib_work);  	return HRTIMER_NORESTART; @@ -117,6 +129,8 @@ static void vib_gpio_enable(struct timed_output_dev *dev, int value)  	    container_of(dev, struct vib_gpio_data, dev);  	unsigned long flags; +	dev_dbg(dev->dev, "Enable vibrator for %dms\n", value); +  	spin_lock_irqsave(&vib_data->lock, flags);  	hrtimer_cancel(&vib_data->timer); @@ -149,6 +163,8 @@ static int vib_gpio_probe(struct platform_device *pdev)  		goto err;  	} +	mutex_init(&(vib_data->io_mutex)); +  	platform_set_drvdata(pdev, vib_data);  	vib_data->gpio = -1; @@ -207,6 +223,7 @@ static int vib_gpio_probe(struct platform_device *pdev)  reg_put:  	regulator_put(vib_data->reg); +	mutex_destroy(&(vib_data->io_mutex));  free_mem:  	kfree(vib_data);  err: @@ -219,6 +236,7 @@ static int vib_gpio_remove(struct platform_device *pdev)  	timed_output_dev_unregister(&vib_data->dev);  	regulator_put(vib_data->reg); +	mutex_destroy(&(vib_data->io_mutex));  	kfree(vib_data);  	return 0; |