diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 987c124432c5..069a41f116dd 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -107,7 +107,7 @@ static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data) | |||
107 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) | 107 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) |
108 | info->flags |= I2C_CLIENT_TEN; | 108 | info->flags |= I2C_CLIENT_TEN; |
109 | } | 109 | } |
110 | } else if (info->irq < 0) { | 110 | } else if (!info->irq) { |
111 | struct resource r; | 111 | struct resource r; |
112 | 112 | ||
113 | if (acpi_dev_resource_interrupt(ares, 0, &r)) | 113 | if (acpi_dev_resource_interrupt(ares, 0, &r)) |
@@ -134,7 +134,6 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | |||
134 | 134 | ||
135 | memset(&info, 0, sizeof(info)); | 135 | memset(&info, 0, sizeof(info)); |
136 | info.fwnode = acpi_fwnode_handle(adev); | 136 | info.fwnode = acpi_fwnode_handle(adev); |
137 | info.irq = -1; | ||
138 | 137 | ||
139 | INIT_LIST_HEAD(&resource_list); | 138 | INIT_LIST_HEAD(&resource_list); |
140 | ret = acpi_dev_get_resources(adev, &resource_list, | 139 | ret = acpi_dev_get_resources(adev, &resource_list, |
@@ -258,7 +257,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, | |||
258 | struct acpi_connection_info *info = &data->info; | 257 | struct acpi_connection_info *info = &data->info; |
259 | struct acpi_resource_i2c_serialbus *sb; | 258 | struct acpi_resource_i2c_serialbus *sb; |
260 | struct i2c_adapter *adapter = data->adapter; | 259 | struct i2c_adapter *adapter = data->adapter; |
261 | struct i2c_client client; | 260 | struct i2c_client *client; |
262 | struct acpi_resource *ares; | 261 | struct acpi_resource *ares; |
263 | u32 accessor_type = function >> 16; | 262 | u32 accessor_type = function >> 16; |
264 | u8 action = function & ACPI_IO_MASK; | 263 | u8 action = function & ACPI_IO_MASK; |
@@ -269,6 +268,12 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, | |||
269 | if (ACPI_FAILURE(ret)) | 268 | if (ACPI_FAILURE(ret)) |
270 | return ret; | 269 | return ret; |
271 | 270 | ||
271 | client = kzalloc(sizeof(*client), GFP_KERNEL); | ||
272 | if (!client) { | ||
273 | ret = AE_NO_MEMORY; | ||
274 | goto err; | ||
275 | } | ||
276 | |||
272 | if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { | 277 | if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { |
273 | ret = AE_BAD_PARAMETER; | 278 | ret = AE_BAD_PARAMETER; |
274 | goto err; | 279 | goto err; |
@@ -280,75 +285,73 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, | |||
280 | goto err; | 285 | goto err; |
281 | } | 286 | } |
282 | 287 | ||
283 | memset(&client, 0, sizeof(client)); | 288 | client->adapter = adapter; |
284 | client.adapter = adapter; | 289 | client->addr = sb->slave_address; |
285 | client.addr = sb->slave_address; | ||
286 | client.flags = 0; | ||
287 | 290 | ||
288 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) | 291 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) |
289 | client.flags |= I2C_CLIENT_TEN; | 292 | client->flags |= I2C_CLIENT_TEN; |
290 | 293 | ||
291 | switch (accessor_type) { | 294 | switch (accessor_type) { |
292 | case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV: | 295 | case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV: |
293 | if (action == ACPI_READ) { | 296 | if (action == ACPI_READ) { |
294 | status = i2c_smbus_read_byte(&client); | 297 | status = i2c_smbus_read_byte(client); |
295 | if (status >= 0) { | 298 | if (status >= 0) { |
296 | gsb->bdata = status; | 299 | gsb->bdata = status; |
297 | status = 0; | 300 | status = 0; |
298 | } | 301 | } |
299 | } else { | 302 | } else { |
300 | status = i2c_smbus_write_byte(&client, gsb->bdata); | 303 | status = i2c_smbus_write_byte(client, gsb->bdata); |
301 | } | 304 | } |
302 | break; | 305 | break; |
303 | 306 | ||
304 | case ACPI_GSB_ACCESS_ATTRIB_BYTE: | 307 | case ACPI_GSB_ACCESS_ATTRIB_BYTE: |
305 | if (action == ACPI_READ) { | 308 | if (action == ACPI_READ) { |
306 | status = i2c_smbus_read_byte_data(&client, command); | 309 | status = i2c_smbus_read_byte_data(client, command); |
307 | if (status >= 0) { | 310 | if (status >= 0) { |
308 | gsb->bdata = status; | 311 | gsb->bdata = status; |
309 | status = 0; | 312 | status = 0; |
310 | } | 313 | } |
311 | } else { | 314 | } else { |
312 | status = i2c_smbus_write_byte_data(&client, command, | 315 | status = i2c_smbus_write_byte_data(client, command, |
313 | gsb->bdata); | 316 | gsb->bdata); |
314 | } | 317 | } |
315 | break; | 318 | break; |
316 | 319 | ||
317 | case ACPI_GSB_ACCESS_ATTRIB_WORD: | 320 | case ACPI_GSB_ACCESS_ATTRIB_WORD: |
318 | if (action == ACPI_READ) { | 321 | if (action == ACPI_READ) { |
319 | status = i2c_smbus_read_word_data(&client, command); | 322 | status = i2c_smbus_read_word_data(client, command); |
320 | if (status >= 0) { | 323 | if (status >= 0) { |
321 | gsb->wdata = status; | 324 | gsb->wdata = status; |
322 | status = 0; | 325 | status = 0; |
323 | } | 326 | } |
324 | } else { | 327 | } else { |
325 | status = i2c_smbus_write_word_data(&client, command, | 328 | status = i2c_smbus_write_word_data(client, command, |
326 | gsb->wdata); | 329 | gsb->wdata); |
327 | } | 330 | } |
328 | break; | 331 | break; |
329 | 332 | ||
330 | case ACPI_GSB_ACCESS_ATTRIB_BLOCK: | 333 | case ACPI_GSB_ACCESS_ATTRIB_BLOCK: |
331 | if (action == ACPI_READ) { | 334 | if (action == ACPI_READ) { |
332 | status = i2c_smbus_read_block_data(&client, command, | 335 | status = i2c_smbus_read_block_data(client, command, |
333 | gsb->data); | 336 | gsb->data); |
334 | if (status >= 0) { | 337 | if (status >= 0) { |
335 | gsb->len = status; | 338 | gsb->len = status; |
336 | status = 0; | 339 | status = 0; |
337 | } | 340 | } |
338 | } else { | 341 | } else { |
339 | status = i2c_smbus_write_block_data(&client, command, | 342 | status = i2c_smbus_write_block_data(client, command, |
340 | gsb->len, gsb->data); | 343 | gsb->len, gsb->data); |
341 | } | 344 | } |
342 | break; | 345 | break; |
343 | 346 | ||
344 | case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE: | 347 | case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE: |
345 | if (action == ACPI_READ) { | 348 | if (action == ACPI_READ) { |
346 | status = acpi_gsb_i2c_read_bytes(&client, command, | 349 | status = acpi_gsb_i2c_read_bytes(client, command, |
347 | gsb->data, info->access_length); | 350 | gsb->data, info->access_length); |
348 | if (status > 0) | 351 | if (status > 0) |
349 | status = 0; | 352 | status = 0; |
350 | } else { | 353 | } else { |
351 | status = acpi_gsb_i2c_write_bytes(&client, command, | 354 | status = acpi_gsb_i2c_write_bytes(client, command, |
352 | gsb->data, info->access_length); | 355 | gsb->data, info->access_length); |
353 | } | 356 | } |
354 | break; | 357 | break; |
@@ -362,6 +365,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, | |||
362 | gsb->status = status; | 365 | gsb->status = status; |
363 | 366 | ||
364 | err: | 367 | err: |
368 | kfree(client); | ||
365 | ACPI_FREE(ares); | 369 | ACPI_FREE(ares); |
366 | return ret; | 370 | return ret; |
367 | } | 371 | } |
@@ -632,8 +636,13 @@ static int i2c_device_probe(struct device *dev) | |||
632 | if (!client) | 636 | if (!client) |
633 | return 0; | 637 | return 0; |
634 | 638 | ||
635 | if (!client->irq && dev->of_node) { | 639 | if (!client->irq) { |
636 | int irq = of_irq_get(dev->of_node, 0); | 640 | int irq = -ENOENT; |
641 | |||
642 | if (dev->of_node) | ||
643 | irq = of_irq_get(dev->of_node, 0); | ||
644 | else if (ACPI_COMPANION(dev)) | ||
645 | irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0); | ||
637 | 646 | ||
638 | if (irq == -EPROBE_DEFER) | 647 | if (irq == -EPROBE_DEFER) |
639 | return irq; | 648 | return irq; |
@@ -1272,7 +1281,7 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, | |||
1272 | } | 1281 | } |
1273 | 1282 | ||
1274 | addr = of_get_property(node, "reg", &len); | 1283 | addr = of_get_property(node, "reg", &len); |
1275 | if (!addr || (len < sizeof(int))) { | 1284 | if (!addr || (len < sizeof(*addr))) { |
1276 | dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", | 1285 | dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", |
1277 | node->full_name); | 1286 | node->full_name); |
1278 | return ERR_PTR(-EINVAL); | 1287 | return ERR_PTR(-EINVAL); |
@@ -1673,7 +1682,7 @@ void i2c_del_adapter(struct i2c_adapter *adap) | |||
1673 | * FIXME: This is old code and should ideally be replaced by an | 1682 | * FIXME: This is old code and should ideally be replaced by an |
1674 | * alternative which results in decoupling the lifetime of the struct | 1683 | * alternative which results in decoupling the lifetime of the struct |
1675 | * device from the i2c_adapter, like spi or netdev do. Any solution | 1684 | * device from the i2c_adapter, like spi or netdev do. Any solution |
1676 | * should be throughly tested with DEBUG_KOBJECT_RELEASE enabled! | 1685 | * should be thoroughly tested with DEBUG_KOBJECT_RELEASE enabled! |
1677 | */ | 1686 | */ |
1678 | init_completion(&adap->dev_released); | 1687 | init_completion(&adap->dev_released); |
1679 | device_unregister(&adap->dev); | 1688 | device_unregister(&adap->dev); |
@@ -2914,18 +2923,24 @@ int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) | |||
2914 | { | 2923 | { |
2915 | int ret; | 2924 | int ret; |
2916 | 2925 | ||
2917 | if (!client || !slave_cb) | 2926 | if (!client || !slave_cb) { |
2927 | WARN(1, "insufficent data\n"); | ||
2918 | return -EINVAL; | 2928 | return -EINVAL; |
2929 | } | ||
2919 | 2930 | ||
2920 | if (!(client->flags & I2C_CLIENT_TEN)) { | 2931 | if (!(client->flags & I2C_CLIENT_TEN)) { |
2921 | /* Enforce stricter address checking */ | 2932 | /* Enforce stricter address checking */ |
2922 | ret = i2c_check_addr_validity(client->addr); | 2933 | ret = i2c_check_addr_validity(client->addr); |
2923 | if (ret) | 2934 | if (ret) { |
2935 | dev_err(&client->dev, "%s: invalid address\n", __func__); | ||
2924 | return ret; | 2936 | return ret; |
2937 | } | ||
2925 | } | 2938 | } |
2926 | 2939 | ||
2927 | if (!client->adapter->algo->reg_slave) | 2940 | if (!client->adapter->algo->reg_slave) { |
2941 | dev_err(&client->dev, "%s: not supported by adapter\n", __func__); | ||
2928 | return -EOPNOTSUPP; | 2942 | return -EOPNOTSUPP; |
2943 | } | ||
2929 | 2944 | ||
2930 | client->slave_cb = slave_cb; | 2945 | client->slave_cb = slave_cb; |
2931 | 2946 | ||
@@ -2933,8 +2948,10 @@ int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) | |||
2933 | ret = client->adapter->algo->reg_slave(client); | 2948 | ret = client->adapter->algo->reg_slave(client); |
2934 | i2c_unlock_adapter(client->adapter); | 2949 | i2c_unlock_adapter(client->adapter); |
2935 | 2950 | ||
2936 | if (ret) | 2951 | if (ret) { |
2937 | client->slave_cb = NULL; | 2952 | client->slave_cb = NULL; |
2953 | dev_err(&client->dev, "%s: adapter returned error %d\n", __func__, ret); | ||
2954 | } | ||
2938 | 2955 | ||
2939 | return ret; | 2956 | return ret; |
2940 | } | 2957 | } |
@@ -2944,8 +2961,10 @@ int i2c_slave_unregister(struct i2c_client *client) | |||
2944 | { | 2961 | { |
2945 | int ret; | 2962 | int ret; |
2946 | 2963 | ||
2947 | if (!client->adapter->algo->unreg_slave) | 2964 | if (!client->adapter->algo->unreg_slave) { |
2965 | dev_err(&client->dev, "%s: not supported by adapter\n", __func__); | ||
2948 | return -EOPNOTSUPP; | 2966 | return -EOPNOTSUPP; |
2967 | } | ||
2949 | 2968 | ||
2950 | i2c_lock_adapter(client->adapter); | 2969 | i2c_lock_adapter(client->adapter); |
2951 | ret = client->adapter->algo->unreg_slave(client); | 2970 | ret = client->adapter->algo->unreg_slave(client); |
@@ -2953,6 +2972,8 @@ int i2c_slave_unregister(struct i2c_client *client) | |||
2953 | 2972 | ||
2954 | if (ret == 0) | 2973 | if (ret == 0) |
2955 | client->slave_cb = NULL; | 2974 | client->slave_cb = NULL; |
2975 | else | ||
2976 | dev_err(&client->dev, "%s: adapter returned error %d\n", __func__, ret); | ||
2956 | 2977 | ||
2957 | return ret; | 2978 | return ret; |
2958 | } | 2979 | } |