diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-nomadik.c')
-rw-r--r-- | drivers/i2c/busses/i2c-nomadik.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 61b00edacb08..02c3115a2dfa 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -22,9 +22,10 @@ #include <linux/err.h> #include <linux/clk.h> #include <linux/io.h> -#include <linux/regulator/consumer.h> #include <linux/pm_runtime.h> #include <linux/platform_data/i2c-nomadik.h> +#include <linux/of.h> +#include <linux/of_i2c.h> #define DRIVER_NAME "nmk-i2c" @@ -146,7 +147,6 @@ struct i2c_nmk_client { * @stop: stop condition. * @xfer_complete: acknowledge completion for a I2C message. * @result: controller propogated result. - * @regulator: pointer to i2c regulator. * @busy: Busy doing transfer. */ struct nmk_i2c_dev { @@ -160,7 +160,6 @@ struct nmk_i2c_dev { int stop; struct completion xfer_complete; int result; - struct regulator *regulator; bool busy; }; @@ -643,11 +642,13 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, dev->busy = true; - if (dev->regulator) - regulator_enable(dev->regulator); pm_runtime_get_sync(&dev->adev->dev); - clk_enable(dev->clk); + status = clk_prepare_enable(dev->clk); + if (status) { + dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); + goto out_clk; + } status = init_hw(dev); if (status) @@ -674,10 +675,9 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, } out: - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); +out_clk: pm_runtime_put_sync(&dev->adev->dev); - if (dev->regulator) - regulator_disable(dev->regulator); dev->busy = false; @@ -920,18 +920,42 @@ static struct nmk_i2c_controller u8500_i2c = { .sm = I2C_FREQ_MODE_FAST, }; +static void nmk_i2c_of_probe(struct device_node *np, + struct nmk_i2c_controller *pdata) +{ + of_property_read_u32(np, "clock-frequency", &pdata->clk_freq); + + /* This driver only supports 'standard' and 'fast' modes of operation. */ + if (pdata->clk_freq <= 100000) + pdata->sm = I2C_FREQ_MODE_STANDARD; + else + pdata->sm = I2C_FREQ_MODE_FAST; +} + static atomic_t adapter_id = ATOMIC_INIT(0); static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; struct nmk_i2c_controller *pdata = adev->dev.platform_data; + struct device_node *np = adev->dev.of_node; struct nmk_i2c_dev *dev; struct i2c_adapter *adap; - if (!pdata) - /* No i2c configuration found, using the default. */ - pdata = &u8500_i2c; + if (!pdata) { + if (np) { + pdata = devm_kzalloc(&adev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + ret = -ENOMEM; + goto err_no_mem; + } + /* Provide the default configuration as a base. */ + memcpy(pdata, &u8500_i2c, sizeof(struct nmk_i2c_controller)); + nmk_i2c_of_probe(np, pdata); + } else + /* No i2c configuration found, using the default. */ + pdata = &u8500_i2c; + } dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); if (!dev) { @@ -957,12 +981,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) goto err_irq; } - dev->regulator = regulator_get(&adev->dev, "v-i2c"); - if (IS_ERR(dev->regulator)) { - dev_warn(&adev->dev, "could not get i2c regulator\n"); - dev->regulator = NULL; - } - pm_suspend_ignore_children(&adev->dev, true); dev->clk = clk_get(&adev->dev, NULL); @@ -973,6 +991,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) } adap = &dev->adap; + adap->dev.of_node = np; adap->dev.parent = &adev->dev; adap->owner = THIS_MODULE; adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; @@ -1002,6 +1021,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) goto err_add_adap; } + of_i2c_register_devices(adap); + pm_runtime_put(&adev->dev); return 0; @@ -1009,8 +1030,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) err_add_adap: clk_put(dev->clk); err_no_clk: - if (dev->regulator) - regulator_put(dev->regulator); free_irq(dev->irq, dev); err_irq: iounmap(dev->virtbase); @@ -1038,8 +1057,6 @@ static int nmk_i2c_remove(struct amba_device *adev) if (res) release_mem_region(res->start, resource_size(res)); clk_put(dev->clk); - if (dev->regulator) - regulator_put(dev->regulator); pm_runtime_disable(&adev->dev); amba_set_drvdata(adev, NULL); kfree(dev); |