aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2013-02-27 20:01:40 -0500
committerWolfram Sang <wsa@the-dreams.de>2013-03-27 03:51:50 -0400
commit1b295c839b3931244f37cb52265017b298518f69 (patch)
treec038771c40f4cd287950983f59a41ee2923f673d
parent7a6674dabfe240cc7015fc201f9662d0640e8081 (diff)
i2c: gpio: Add support for deferred probing
GPIOs may not be available immediately when i2c-gpio looks for them. Implement support for deferred probing so that probing can be attempted again later when GPIO pins are finally available. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Bo Shen <voice.shen@atmel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-gpio.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index f3fa4332bbdf..bc6e139c6e7f 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -85,23 +85,29 @@ static int i2c_gpio_getscl(void *data)
85 return gpio_get_value(pdata->scl_pin); 85 return gpio_get_value(pdata->scl_pin);
86} 86}
87 87
88static int of_i2c_gpio_probe(struct device_node *np, 88static int of_i2c_gpio_get_pins(struct device_node *np,
89 struct i2c_gpio_platform_data *pdata) 89 unsigned int *sda_pin, unsigned int *scl_pin)
90{ 90{
91 u32 reg;
92
93 if (of_gpio_count(np) < 2) 91 if (of_gpio_count(np) < 2)
94 return -ENODEV; 92 return -ENODEV;
95 93
96 pdata->sda_pin = of_get_gpio(np, 0); 94 *sda_pin = of_get_gpio(np, 0);
97 pdata->scl_pin = of_get_gpio(np, 1); 95 *scl_pin = of_get_gpio(np, 1);
98 96
99 if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) { 97 if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) {
100 pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", 98 pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
101 np->full_name, pdata->sda_pin, pdata->scl_pin); 99 np->full_name, *sda_pin, *scl_pin);
102 return -ENODEV; 100 return -ENODEV;
103 } 101 }
104 102
103 return 0;
104}
105
106static void of_i2c_gpio_get_props(struct device_node *np,
107 struct i2c_gpio_platform_data *pdata)
108{
109 u32 reg;
110
105 of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); 111 of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
106 112
107 if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg)) 113 if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
@@ -113,8 +119,6 @@ static int of_i2c_gpio_probe(struct device_node *np,
113 of_property_read_bool(np, "i2c-gpio,scl-open-drain"); 119 of_property_read_bool(np, "i2c-gpio,scl-open-drain");
114 pdata->scl_is_output_only = 120 pdata->scl_is_output_only =
115 of_property_read_bool(np, "i2c-gpio,scl-output-only"); 121 of_property_read_bool(np, "i2c-gpio,scl-output-only");
116
117 return 0;
118} 122}
119 123
120static int i2c_gpio_probe(struct platform_device *pdev) 124static int i2c_gpio_probe(struct platform_device *pdev)
@@ -123,31 +127,52 @@ static int i2c_gpio_probe(struct platform_device *pdev)
123 struct i2c_gpio_platform_data *pdata; 127 struct i2c_gpio_platform_data *pdata;
124 struct i2c_algo_bit_data *bit_data; 128 struct i2c_algo_bit_data *bit_data;
125 struct i2c_adapter *adap; 129 struct i2c_adapter *adap;
130 unsigned int sda_pin, scl_pin;
126 int ret; 131 int ret;
127 132
128 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 133 /* First get the GPIO pins; if it fails, we'll defer the probe. */
129 if (!priv)
130 return -ENOMEM;
131 adap = &priv->adap;
132 bit_data = &priv->bit_data;
133 pdata = &priv->pdata;
134
135 if (pdev->dev.of_node) { 134 if (pdev->dev.of_node) {
136 ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata); 135 ret = of_i2c_gpio_get_pins(pdev->dev.of_node,
136 &sda_pin, &scl_pin);
137 if (ret) 137 if (ret)
138 return ret; 138 return ret;
139 } else { 139 } else {
140 if (!pdev->dev.platform_data) 140 if (!pdev->dev.platform_data)
141 return -ENXIO; 141 return -ENXIO;
142 memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); 142 pdata = pdev->dev.platform_data;
143 sda_pin = pdata->sda_pin;
144 scl_pin = pdata->scl_pin;
143 } 145 }
144 146
145 ret = gpio_request(pdata->sda_pin, "sda"); 147 ret = gpio_request(sda_pin, "sda");
146 if (ret) 148 if (ret) {
149 if (ret == -EINVAL)
150 ret = -EPROBE_DEFER; /* Try again later */
147 goto err_request_sda; 151 goto err_request_sda;
148 ret = gpio_request(pdata->scl_pin, "scl"); 152 }
149 if (ret) 153 ret = gpio_request(scl_pin, "scl");
154 if (ret) {
155 if (ret == -EINVAL)
156 ret = -EPROBE_DEFER; /* Try again later */
150 goto err_request_scl; 157 goto err_request_scl;
158 }
159
160 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
161 if (!priv) {
162 ret = -ENOMEM;
163 goto err_add_bus;
164 }
165 adap = &priv->adap;
166 bit_data = &priv->bit_data;
167 pdata = &priv->pdata;
168
169 if (pdev->dev.of_node) {
170 pdata->sda_pin = sda_pin;
171 pdata->scl_pin = scl_pin;
172 of_i2c_gpio_get_props(pdev->dev.of_node, pdata);
173 } else {
174 memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
175 }
151 176
152 if (pdata->sda_is_open_drain) { 177 if (pdata->sda_is_open_drain) {
153 gpio_direction_output(pdata->sda_pin, 1); 178 gpio_direction_output(pdata->sda_pin, 1);
@@ -211,9 +236,9 @@ static int i2c_gpio_probe(struct platform_device *pdev)
211 return 0; 236 return 0;
212 237
213err_add_bus: 238err_add_bus:
214 gpio_free(pdata->scl_pin); 239 gpio_free(scl_pin);
215err_request_scl: 240err_request_scl:
216 gpio_free(pdata->sda_pin); 241 gpio_free(sda_pin);
217err_request_sda: 242err_request_sda:
218 return ret; 243 return ret;
219} 244}