diff options
| author | Alok Chauhan <alokc@codeaurora.org> | 2013-10-31 02:52:06 +0530 |
|---|---|---|
| committer | Michael Bohan <mbohan@codeaurora.org> | 2014-02-05 09:33:59 -0800 |
| commit | 6ebd2ec1a5f17bd9fb1a2d88150be866cded14a0 (patch) | |
| tree | 517f2d6640f411302ccfc0b7cbb9d456126297b1 | |
| parent | 994e9b0e5d47bfaa9887d44234459260c84707c0 (diff) | |
i2c-msm-v2: Add support for pinctrl handling
Request i2c gpio pins using pinctrl framework. This
will replace existing handling of gpio configuration.
Change-Id: I3f969b3dbdb300d3975750773e94d60bd27f9880
Signed-off-by: Alok Chauhan <alokc@codeaurora.org>
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-msm-v2.txt | 6 | ||||
| -rw-r--r-- | arch/arm/mach-msm/include/mach/i2c-msm.h | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-msm-v2.c | 130 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-msm-v2.h | 14 |
4 files changed, 48 insertions, 106 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c-msm-v2.txt b/Documentation/devicetree/bindings/i2c/i2c-msm-v2.txt index cbd9f4a05cb..4f22b809912 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-msm-v2.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-msm-v2.txt @@ -22,10 +22,6 @@ Required alias: 'i2c{n}' where n is the bus number. Optional property: - - qcom,gpio-scl : I2C clock GPIO. When exist the GPIO is requested on - runtime-PM active and freed on suspend. - - qcom,gpio-sda : I2C data GPIO. When exist the GPIO is requested on - runtime-PM active and freed on suspend. - qcom,noise-rjct-scl : number of low samples on clock line to consider it low. When missing default to 0. - qcom,noise-rjct-sda : number of low samples on data line to consider it low. @@ -52,8 +48,6 @@ Example: interrupts = <0 104 0>, <0 238 0>; qcom,clk-freq-out = <100000>; qcom,clk-freq-in = <24000000>; - qcom,gpio-scl = <&msmgpio 7 0>; - qcom,gpio-sda = <&msmgpio 6 0>; qcom,noise-rjct-scl = <0>; qcom,noise-rjct-sda = <0>; qcom,bam-pipe-idx-cons = <18>; diff --git a/arch/arm/mach-msm/include/mach/i2c-msm.h b/arch/arm/mach-msm/include/mach/i2c-msm.h index bc8e8dd80bf..1bc7e49843e 100644 --- a/arch/arm/mach-msm/include/mach/i2c-msm.h +++ b/arch/arm/mach-msm/include/mach/i2c-msm.h @@ -25,8 +25,6 @@ * @bam_pipe_idx_cons index of BAM's consumer pipe * @bam_pipe_idx_prod index of BAM's producer pipe * @bam_disable disables DMA transfers. - * @gpio_scl clock GPIO pin number - * @gpio_sda data GPIO pin number * @noise_rjct_scl number of low samples on clock line to consider it low. * @noise_rjct_sda number of low samples on data line to consider it low. * @active_only when set, votes when system active and removes the vote when @@ -41,8 +39,6 @@ struct i2c_msm_v2_platform_data { u32 bam_pipe_idx_cons; u32 bam_pipe_idx_prod; bool bam_disable; - int gpio_scl; - int gpio_sda; int noise_rjct_scl; int noise_rjct_sda; bool active_only; diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index a2d4962d7c0..ab04a097916 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -29,15 +29,12 @@ #include <linux/time.h> #include <linux/slab.h> #include <linux/pm_runtime.h> -#include <linux/gpio.h> #include <linux/dma-mapping.h> #include <linux/i2c.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/of_i2c.h> #include <linux/debugfs.h> #include <mach/i2c-msm.h> -#include <mach/gpiomux.h> #include <mach/sps.h> #include <mach/msm_bus.h> #include <mach/msm_bus_board.h> @@ -401,34 +398,6 @@ static void i2c_msm_dbg_xfer_dump(struct i2c_msm_ctrl *ctrl) fifo->rx_bc); } -static void i2c_msm_dbg_gpio_dump(struct i2c_msm_ctrl *ctrl, int gpio_num, - const char *gpio_name) -{ - struct gpiomux_setting cur_conf; - if (msm_gpiomux_write(gpio_num, GPIOMUX_ACTIVE, NULL, &cur_conf)) { - dev_err(ctrl->dev, "error reading %s-gpio:#%d active setting\n", - gpio_name, gpio_num); - return; - } - dev_info(ctrl->dev, - "dump %s-gpio:#%d state: func:%d drv:%d pull:%d dir:%d\n", - gpio_name, gpio_num, cur_conf.func, cur_conf.drv, cur_conf.pull, - cur_conf.dir); - - if (msm_gpiomux_write(gpio_num, GPIOMUX_ACTIVE, &cur_conf, NULL)) - dev_err(ctrl->dev, - "error restoring %s-gpio:#%d active setting\n", - gpio_name, gpio_num); -} - -static void i2c_msm_dbg_gpios_dump(struct i2c_msm_ctrl *ctrl) -{ - i2c_msm_dbg_gpio_dump(ctrl, ctrl->rsrcs.gpios[I2C_MSM_GPIO_SDA], - "sda"); - i2c_msm_dbg_gpio_dump(ctrl, ctrl->rsrcs.gpios[I2C_MSM_GPIO_SCL], - "scl"); -} - static const char * const i2c_msm_dbg_tag_val_to_str_tbl[] = { "NOP_WAIT", /* 0x80 */ "START", /* 0x81 */ @@ -2672,7 +2641,6 @@ static int i2c_msm_xfer_wait_for_completion(struct i2c_msm_ctrl *ctrl) i2c_msm_dbg_xfer_dump(ctrl); i2c_msm_dbg_qup_reg_dump(ctrl); i2c_msm_dbg_inp_fifo_dump(ctrl); - i2c_msm_dbg_gpios_dump(ctrl); xfer->err |= I2C_MSM_ERR_TIMEOUT; ret = -EIO; } else { @@ -2899,7 +2867,6 @@ enum i2c_msm_dt_entry_status { enum i2c_msm_dt_entry_type { DT_U32, - DT_GPIO, DT_BOOL, DT_ID, /* of_alias_get_id() */ }; @@ -2922,13 +2889,6 @@ static int i2c_msm_dt_to_pdata_populate(struct i2c_msm_ctrl *ctrl, for (; itr->dt_name ; ++itr) { switch (itr->type) { - case DT_GPIO: - ret = of_get_named_gpio(node, itr->dt_name, 0); - if (gpio_is_valid(ret)) { - *((int *) itr->ptr_data) = ret; - ret = 0; - } - break; case DT_U32: ret = of_property_read_u32(node, itr->dt_name, (u32 *) itr->ptr_data); @@ -3012,10 +2972,6 @@ static int i2c_msm_rsrcs_dt_to_pdata(struct i2c_msm_ctrl *ctrl, &(*pdata)->noise_rjct_scl, DT_OPT, DT_U32, 0}, {"qcom,noise-rjct-sda", &(*pdata)->noise_rjct_sda, DT_OPT, DT_U32, 0}, - {"qcom,gpio-scl", - &(*pdata)->gpio_scl, DT_SGST, DT_GPIO, 0}, - {"qcom,gpio-sda", - &(*pdata)->gpio_sda, DT_SGST, DT_GPIO, 0}, {NULL, NULL, 0, 0, 0}, }; @@ -3109,60 +3065,50 @@ static void i2c_msm_rsrcs_irq_teardown(struct i2c_msm_ctrl *ctrl) } /* - * i2c_msm_rsrcs_gpio_init: initializes the GPIO entries in driver struct + * i2c_msm_rsrcs_gpio_pinctrl_init: initializes the pinctrl for i2c gpios * * @pre platform data must be initialized */ -static void i2c_msm_rsrcs_gpio_init(struct i2c_msm_ctrl *ctrl) -{ - int i; - /* invalidate all */ - for (i = 0; i < ARRAY_SIZE(i2c_msm_gpio_names); ++i) - ctrl->rsrcs.gpios[i] = -EINVAL; - - ctrl->rsrcs.gpios[I2C_MSM_GPIO_SCL] = ctrl->pdata->gpio_scl; - ctrl->rsrcs.gpios[I2C_MSM_GPIO_SDA] = ctrl->pdata->gpio_sda; -} - -static int i2c_msm_pm_gpio_acquire(struct i2c_msm_ctrl *ctrl) +static int i2c_msm_rsrcs_gpio_pinctrl_init(struct i2c_msm_ctrl *ctrl) { - int i, ret; - - for (i = 0; i < ARRAY_SIZE(i2c_msm_gpio_names); ++i) { - const int gpio_num = ctrl->rsrcs.gpios[i]; - - if (gpio_num >= 0) { - ret = gpio_request(gpio_num, i2c_msm_gpio_names[i]); - if (ret) { - dev_err(ctrl->dev, - "gpio_request(num:%d, name=%s) err:%d\n", - gpio_num, i2c_msm_gpio_names[i], ret); - goto error; - } - } + ctrl->rsrcs.pinctrl = devm_pinctrl_get(ctrl->dev); + if (IS_ERR_OR_NULL(ctrl->rsrcs.pinctrl)) { + dev_err(ctrl->dev, "failed to get pinctrl\n"); + return PTR_ERR(ctrl->rsrcs.pinctrl); } - return 0; -error: - while (--i >= 0) { - const int gpio_num = ctrl->rsrcs.gpios[i]; + ctrl->rsrcs.gpio_state_active + = pinctrl_lookup_state(ctrl->rsrcs.pinctrl, + PINCTRL_STATE_DEFAULT); + if (IS_ERR_OR_NULL(ctrl->rsrcs.gpio_state_active)) + dev_info(ctrl->dev, "can not get default pinstate\n"); - if (gpio_num >= 0) - gpio_free(gpio_num); - } - return ret; + ctrl->rsrcs.gpio_state_suspend + = pinctrl_lookup_state(ctrl->rsrcs.pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR_OR_NULL(ctrl->rsrcs.gpio_state_suspend)) + dev_info(ctrl->dev, "can not get sleep pinstate\n"); + return 0; } -static void i2c_msm_pm_gpio_release(struct i2c_msm_ctrl *ctrl) +static void i2c_msm_pm_pinctrl_state(struct i2c_msm_ctrl *ctrl, + bool runtime_active) { - int i; - - for (i = 0; i < ARRAY_SIZE(i2c_msm_gpio_names); ++i) { - const int gpio_num = ctrl->rsrcs.gpios[i]; + int ret; + struct pinctrl_state *pins_state; - if (gpio_num >= 0) - gpio_free(gpio_num); - } + pins_state = runtime_active ? ctrl->rsrcs.gpio_state_active + : ctrl->rsrcs.gpio_state_suspend; + if (!IS_ERR_OR_NULL(pins_state)) { + ret = pinctrl_select_state(ctrl->rsrcs.pinctrl, pins_state); + if (ret) + dev_err(ctrl->dev, "can not set %s pins\n", + runtime_active ? PINCTRL_STATE_DEFAULT + : PINCTRL_STATE_SLEEP); + } else + dev_err(ctrl->dev, "not a valid '%s' pinstate\n", + runtime_active ? PINCTRL_STATE_DEFAULT + : PINCTRL_STATE_SLEEP); } /* @@ -3446,7 +3392,7 @@ static int i2c_msm_pm_suspend_impl(struct device *dev) disable_irq(ctrl->rsrcs.irq); i2c_msm_pm_clk_unvote(ctrl); - i2c_msm_pm_gpio_release(ctrl); + i2c_msm_pm_pinctrl_state(ctrl, false); return 0; } @@ -3457,7 +3403,7 @@ static int i2c_msm_pm_resume_impl(struct device *dev) i2c_msm_dbg(ctrl, MSM_DBG, "resuming..."); - i2c_msm_pm_gpio_acquire(ctrl); + i2c_msm_pm_pinctrl_state(ctrl, true); i2c_msm_pm_clk_vote(ctrl); enable_irq(ctrl->rsrcs.irq); (*ctrl->ver.init)(ctrl); @@ -3671,7 +3617,10 @@ static int i2c_msm_probe(struct platform_device *pdev) i2c_msm_pm_clk_unvote(ctrl); - i2c_msm_rsrcs_gpio_init(ctrl); + ret = i2c_msm_rsrcs_gpio_pinctrl_init(ctrl); + if (ret) + goto err_no_pinctrl; + i2c_msm_pm_rt_init(ctrl->dev); /* allocate xfer modes */ @@ -3702,6 +3651,7 @@ rcrcs_err: i2c_msm_rsrcs_irq_teardown(ctrl); irq_err: (*ctrl->ver.destroy)(ctrl); +err_no_pinctrl: ver_err: i2c_msm_pm_clk_unvote(ctrl); i2c_msm_rsrcs_clk_teardown(ctrl); diff --git a/drivers/i2c/busses/i2c-msm-v2.h b/drivers/i2c/busses/i2c-msm-v2.h index 8ea64b95970..aa167d74817 100644 --- a/drivers/i2c/busses/i2c-msm-v2.h +++ b/drivers/i2c/busses/i2c-msm-v2.h @@ -495,13 +495,15 @@ struct qup_i2c_clk_path_vote { * @base I2C controller virtual base address */ struct i2c_msm_resources { - struct resource *mem; - void __iomem *base; /* virtual */ - struct clk *core_clk; - struct clk *iface_clk; + struct resource *mem; + void __iomem *base; /* virtual */ + struct clk *core_clk; + struct clk *iface_clk; struct qup_i2c_clk_path_vote clk_path_vote; - int gpios[ARRAY_SIZE(i2c_msm_gpio_names)]; - int irq; + int irq; + struct pinctrl *pinctrl; + struct pinctrl_state *gpio_state_active; + struct pinctrl_state *gpio_state_suspend; }; /* |
