diff options
| author | Doug Zobel <dzobel1@motorola.com> | 2014-05-22 16:03:22 -0500 | 
|---|---|---|
| committer | Douglas Zobel <dzobel1@motorola.com> | 2014-05-22 21:45:41 +0000 | 
| commit | f0b8dfa7d5127e162e5c0ce1f653ced28800e015 (patch) | |
| tree | ab45864bed76ee212bd50917fe362d495052a77d /drivers/misc/vib-gpio.c | |
| parent | 53b3696135313573b60b726675c0721361b956cd (diff) | |
| download | olio-linux-3.10-f0b8dfa7d5127e162e5c0ce1f653ced28800e015.tar.xz olio-linux-3.10-f0b8dfa7d5127e162e5c0ce1f653ced28800e015.zip | |
IKXCLOCK-1246 watch was vibrating continuously
Make IO operations (GPIO & regulator) atomic.  Also add more debug logging.
Change-Id: Ifba24a6753447a3abce7bd6fe5becb2c431a179f
Diffstat (limited to 'drivers/misc/vib-gpio.c')
| -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; |