diff options
author | Jean Delvare <khali@linux-fr.org> | 2013-02-27 20:01:40 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2013-03-27 03:51:50 -0400 |
commit | 1b295c839b3931244f37cb52265017b298518f69 (patch) | |
tree | c038771c40f4cd287950983f59a41ee2923f673d | |
parent | 7a6674dabfe240cc7015fc201f9662d0640e8081 (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.c | 75 |
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 | ||
88 | static int of_i2c_gpio_probe(struct device_node *np, | 88 | static 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 | |||
106 | static 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", ®)) | 113 | if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) |
@@ -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 | ||
120 | static int i2c_gpio_probe(struct platform_device *pdev) | 124 | static 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 | ||
213 | err_add_bus: | 238 | err_add_bus: |
214 | gpio_free(pdata->scl_pin); | 239 | gpio_free(scl_pin); |
215 | err_request_scl: | 240 | err_request_scl: |
216 | gpio_free(pdata->sda_pin); | 241 | gpio_free(sda_pin); |
217 | err_request_sda: | 242 | err_request_sda: |
218 | return ret; | 243 | return ret; |
219 | } | 244 | } |