aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 4f34823e86b1..0ac2f90ab840 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -155,6 +155,35 @@ static void i2c_device_shutdown(struct device *dev)
155 driver->shutdown(client); 155 driver->shutdown(client);
156} 156}
157 157
158#ifdef CONFIG_SUSPEND
159static int i2c_device_pm_suspend(struct device *dev)
160{
161 const struct dev_pm_ops *pm;
162
163 if (!dev->driver)
164 return 0;
165 pm = dev->driver->pm;
166 if (!pm || !pm->suspend)
167 return 0;
168 return pm->suspend(dev);
169}
170
171static int i2c_device_pm_resume(struct device *dev)
172{
173 const struct dev_pm_ops *pm;
174
175 if (!dev->driver)
176 return 0;
177 pm = dev->driver->pm;
178 if (!pm || !pm->resume)
179 return 0;
180 return pm->resume(dev);
181}
182#else
183#define i2c_device_pm_suspend NULL
184#define i2c_device_pm_resume NULL
185#endif
186
158static int i2c_device_suspend(struct device *dev, pm_message_t mesg) 187static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
159{ 188{
160 struct i2c_client *client = i2c_verify_client(dev); 189 struct i2c_client *client = i2c_verify_client(dev);
@@ -219,6 +248,11 @@ static const struct attribute_group *i2c_dev_attr_groups[] = {
219 NULL 248 NULL
220}; 249};
221 250
251const static struct dev_pm_ops i2c_device_pm_ops = {
252 .suspend = i2c_device_pm_suspend,
253 .resume = i2c_device_pm_resume,
254};
255
222struct bus_type i2c_bus_type = { 256struct bus_type i2c_bus_type = {
223 .name = "i2c", 257 .name = "i2c",
224 .match = i2c_device_match, 258 .match = i2c_device_match,
@@ -227,6 +261,7 @@ struct bus_type i2c_bus_type = {
227 .shutdown = i2c_device_shutdown, 261 .shutdown = i2c_device_shutdown,
228 .suspend = i2c_device_suspend, 262 .suspend = i2c_device_suspend,
229 .resume = i2c_device_resume, 263 .resume = i2c_device_resume,
264 .pm = &i2c_device_pm_ops,
230}; 265};
231EXPORT_SYMBOL_GPL(i2c_bus_type); 266EXPORT_SYMBOL_GPL(i2c_bus_type);
232 267
@@ -1184,7 +1219,7 @@ static int i2c_detect_address(struct i2c_client *temp_client,
1184 /* Finally call the custom detection function */ 1219 /* Finally call the custom detection function */
1185 memset(&info, 0, sizeof(struct i2c_board_info)); 1220 memset(&info, 0, sizeof(struct i2c_board_info));
1186 info.addr = addr; 1221 info.addr = addr;
1187 err = driver->detect(temp_client, -1, &info); 1222 err = driver->detect(temp_client, &info);
1188 if (err) { 1223 if (err) {
1189 /* -ENODEV is returned if the detection fails. We catch it 1224 /* -ENODEV is returned if the detection fails. We catch it
1190 here as this isn't an error. */ 1225 here as this isn't an error. */
@@ -1214,13 +1249,13 @@ static int i2c_detect_address(struct i2c_client *temp_client,
1214 1249
1215static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) 1250static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
1216{ 1251{
1217 const struct i2c_client_address_data *address_data; 1252 const unsigned short *address_list;
1218 struct i2c_client *temp_client; 1253 struct i2c_client *temp_client;
1219 int i, err = 0; 1254 int i, err = 0;
1220 int adap_id = i2c_adapter_id(adapter); 1255 int adap_id = i2c_adapter_id(adapter);
1221 1256
1222 address_data = driver->address_data; 1257 address_list = driver->address_list;
1223 if (!driver->detect || !address_data) 1258 if (!driver->detect || !address_list)
1224 return 0; 1259 return 0;
1225 1260
1226 /* Set up a temporary client to help detect callback */ 1261 /* Set up a temporary client to help detect callback */
@@ -1235,7 +1270,7 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
1235 1270
1236 /* Stop here if we can't use SMBUS_QUICK */ 1271 /* Stop here if we can't use SMBUS_QUICK */
1237 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { 1272 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
1238 if (address_data->normal_i2c[0] == I2C_CLIENT_END) 1273 if (address_list[0] == I2C_CLIENT_END)
1239 goto exit_free; 1274 goto exit_free;
1240 1275
1241 dev_warn(&adapter->dev, "SMBus Quick command not supported, " 1276 dev_warn(&adapter->dev, "SMBus Quick command not supported, "
@@ -1244,11 +1279,10 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
1244 goto exit_free; 1279 goto exit_free;
1245 } 1280 }
1246 1281
1247 for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { 1282 for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
1248 dev_dbg(&adapter->dev, "found normal entry for adapter %d, " 1283 dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
1249 "addr 0x%02x\n", adap_id, 1284 "addr 0x%02x\n", adap_id, address_list[i]);
1250 address_data->normal_i2c[i]); 1285 temp_client->addr = address_list[i];
1251 temp_client->addr = address_data->normal_i2c[i];
1252 err = i2c_detect_address(temp_client, driver); 1286 err = i2c_detect_address(temp_client, driver);
1253 if (err) 1287 if (err)
1254 goto exit_free; 1288 goto exit_free;