i2c: imx: make bus recovery through pinctrl optional
[cascardo/linux.git] / drivers / i2c / busses / i2c-imx.c
index cb11eee..592a8f2 100644 (file)
@@ -984,11 +984,24 @@ static void i2c_imx_unprepare_recovery(struct i2c_adapter *adap)
        pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_default);
 }
 
-static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
+/*
+ * We switch SCL and SDA to their GPIO function and do some bitbanging
+ * for bus recovery. These alternative pinmux settings can be
+ * described in the device tree by a separate pinctrl state "gpio". If
+ * this is missing this is not a big problem, the only implication is
+ * that we can't do bus recovery.
+ */
+static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
                struct platform_device *pdev)
 {
        struct i2c_bus_recovery_info *rinfo = &i2c_imx->rinfo;
 
+       i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
+       if (!i2c_imx->pinctrl || IS_ERR(i2c_imx->pinctrl)) {
+               dev_info(&pdev->dev, "can't get pinctrl, bus recovery not supported\n");
+               return PTR_ERR(i2c_imx->pinctrl);
+       }
+
        i2c_imx->pinctrl_pins_default = pinctrl_lookup_state(i2c_imx->pinctrl,
                        PINCTRL_STATE_DEFAULT);
        i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
@@ -1001,7 +1014,7 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
            IS_ERR(i2c_imx->pinctrl_pins_default) ||
            IS_ERR(i2c_imx->pinctrl_pins_gpio)) {
                dev_dbg(&pdev->dev, "recovery information incomplete\n");
-               return;
+               return 0;
        }
 
        dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
@@ -1011,6 +1024,8 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
        rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
        rinfo->recover_bus = i2c_generic_gpio_recovery;
        i2c_imx->adapter.bus_recovery_info = rinfo;
+
+       return 0;
 }
 
 static u32 i2c_imx_func(struct i2c_adapter *adapter)
@@ -1081,12 +1096,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
                return ret;
        }
 
-       i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
-       if (IS_ERR(i2c_imx->pinctrl)) {
-               ret = PTR_ERR(i2c_imx->pinctrl);
-               goto clk_disable;
-       }
-
        /* Request IRQ */
        ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
                                pdev->name, i2c_imx);
@@ -1125,7 +1134,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
                        i2c_imx, IMX_I2C_I2CR);
        imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
 
-       i2c_imx_init_recovery_info(i2c_imx, pdev);
+       /* Init optional bus recovery function */
+       ret = i2c_imx_init_recovery_info(i2c_imx, pdev);
+       /* Give it another chance if pinctrl used is not ready yet */
+       if (ret == -EPROBE_DEFER)
+               goto rpm_disable;
 
        /* Add I2C adapter */
        ret = i2c_add_numbered_adapter(&i2c_imx->adapter);