diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-davinci.c')
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 2ead9b9eebb7..75d6ab177055 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -33,7 +33,7 @@ #include <linux/io.h> #include <linux/slab.h> #include <linux/cpufreq.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/of_device.h> #include <linux/platform_data/i2c-davinci.h> #include <linux/pm_runtime.h> @@ -139,7 +139,6 @@ struct davinci_i2c_dev { u8 terminate; struct i2c_adapter adapter; #ifdef CONFIG_CPU_FREQ - struct completion xfr_complete; struct notifier_block freq_transition; #endif struct davinci_i2c_platform_data *pdata; @@ -294,7 +293,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) } /* - * This routine does i2c bus recovery by using i2c_generic_gpio_recovery + * This routine does i2c bus recovery by using i2c_generic_scl_recovery * which is provided by I2C Bus recovery infrastructure. */ static void davinci_i2c_prepare_recovery(struct i2c_adapter *adap) @@ -316,7 +315,7 @@ static void davinci_i2c_unprepare_recovery(struct i2c_adapter *adap) } static struct i2c_bus_recovery_info davinci_i2c_gpio_recovery_info = { - .recover_bus = i2c_generic_gpio_recovery, + .recover_bus = i2c_generic_scl_recovery, .prepare_recovery = davinci_i2c_prepare_recovery, .unprepare_recovery = davinci_i2c_unprepare_recovery, }; @@ -567,9 +566,6 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } ret = num; -#ifdef CONFIG_CPU_FREQ - complete(&dev->xfr_complete); -#endif out: pm_runtime_mark_last_busy(dev->dev); @@ -717,13 +713,15 @@ static int i2c_davinci_cpufreq_transition(struct notifier_block *nb, struct davinci_i2c_dev *dev; dev = container_of(nb, struct davinci_i2c_dev, freq_transition); + + i2c_lock_adapter(&dev->adapter); if (val == CPUFREQ_PRECHANGE) { - wait_for_completion(&dev->xfr_complete); davinci_i2c_reset_ctrl(dev, 0); } else if (val == CPUFREQ_POSTCHANGE) { i2c_davinci_calc_clk_dividers(dev); davinci_i2c_reset_ctrl(dev, 1); } + i2c_unlock_adapter(&dev->adapter); return 0; } @@ -769,6 +767,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) struct davinci_i2c_dev *dev; struct i2c_adapter *adap; struct resource *mem; + struct i2c_bus_recovery_info *rinfo; int r, irq; irq = platform_get_irq(pdev, 0); @@ -789,9 +788,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) } init_completion(&dev->cmd_complete); -#ifdef CONFIG_CPU_FREQ - init_completion(&dev->xfr_complete); -#endif + dev->dev = &pdev->dev; dev->irq = irq; dev->pdata = dev_get_platdata(&pdev->dev); @@ -868,10 +865,20 @@ static int davinci_i2c_probe(struct platform_device *pdev) if (dev->pdata->has_pfunc) adap->bus_recovery_info = &davinci_i2c_scl_recovery_info; - else if (dev->pdata->scl_pin) { - adap->bus_recovery_info = &davinci_i2c_gpio_recovery_info; - adap->bus_recovery_info->scl_gpio = dev->pdata->scl_pin; - adap->bus_recovery_info->sda_gpio = dev->pdata->sda_pin; + else if (dev->pdata->gpio_recovery) { + rinfo = &davinci_i2c_gpio_recovery_info; + adap->bus_recovery_info = rinfo; + rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl", + GPIOD_OUT_HIGH_OPEN_DRAIN); + if (IS_ERR(rinfo->scl_gpiod)) { + r = PTR_ERR(rinfo->scl_gpiod); + goto err_unuse_clocks; + } + rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN); + if (IS_ERR(rinfo->sda_gpiod)) { + r = PTR_ERR(rinfo->sda_gpiod); + goto err_unuse_clocks; + } } adap->nr = pdev->id; |