Commit 7ef85f5f authored by Jarkko Nikula's avatar Jarkko Nikula Committed by Wolfram Sang

i2c: core: Reduce stack size of acpi_i2c_space_handler()

sizeof(struct i2c_client) is 1088 bytes on a CONFIG_X86_64=y build and
produces following warning when CONFIG_FRAME_WARN is set to 1024:

drivers/i2c/i2c-core.c: In function ‘acpi_i2c_space_handler’:
drivers/i2c/i2c-core.c:367:1: warning: the frame size of 1152 bytes is
larger than 1024 bytes [-Wframe-larger-than=]

This is not critical given that kernel stack is 16 kB on x86_64 but lets
reduce the stack usage by allocating the struct i2c_client from the heap.
Signed-off-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent edc9102a
...@@ -258,7 +258,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, ...@@ -258,7 +258,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command,
struct acpi_connection_info *info = &data->info; struct acpi_connection_info *info = &data->info;
struct acpi_resource_i2c_serialbus *sb; struct acpi_resource_i2c_serialbus *sb;
struct i2c_adapter *adapter = data->adapter; struct i2c_adapter *adapter = data->adapter;
struct i2c_client client; struct i2c_client *client;
struct acpi_resource *ares; struct acpi_resource *ares;
u32 accessor_type = function >> 16; u32 accessor_type = function >> 16;
u8 action = function & ACPI_IO_MASK; u8 action = function & ACPI_IO_MASK;
...@@ -269,6 +269,12 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, ...@@ -269,6 +269,12 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command,
if (ACPI_FAILURE(ret)) if (ACPI_FAILURE(ret))
return ret; return ret;
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
ret = AE_NO_MEMORY;
goto err;
}
if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
ret = AE_BAD_PARAMETER; ret = AE_BAD_PARAMETER;
goto err; goto err;
...@@ -280,75 +286,73 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, ...@@ -280,75 +286,73 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command,
goto err; goto err;
} }
memset(&client, 0, sizeof(client)); client->adapter = adapter;
client.adapter = adapter; client->addr = sb->slave_address;
client.addr = sb->slave_address;
client.flags = 0;
if (sb->access_mode == ACPI_I2C_10BIT_MODE) if (sb->access_mode == ACPI_I2C_10BIT_MODE)
client.flags |= I2C_CLIENT_TEN; client->flags |= I2C_CLIENT_TEN;
switch (accessor_type) { switch (accessor_type) {
case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV: case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV:
if (action == ACPI_READ) { if (action == ACPI_READ) {
status = i2c_smbus_read_byte(&client); status = i2c_smbus_read_byte(client);
if (status >= 0) { if (status >= 0) {
gsb->bdata = status; gsb->bdata = status;
status = 0; status = 0;
} }
} else { } else {
status = i2c_smbus_write_byte(&client, gsb->bdata); status = i2c_smbus_write_byte(client, gsb->bdata);
} }
break; break;
case ACPI_GSB_ACCESS_ATTRIB_BYTE: case ACPI_GSB_ACCESS_ATTRIB_BYTE:
if (action == ACPI_READ) { if (action == ACPI_READ) {
status = i2c_smbus_read_byte_data(&client, command); status = i2c_smbus_read_byte_data(client, command);
if (status >= 0) { if (status >= 0) {
gsb->bdata = status; gsb->bdata = status;
status = 0; status = 0;
} }
} else { } else {
status = i2c_smbus_write_byte_data(&client, command, status = i2c_smbus_write_byte_data(client, command,
gsb->bdata); gsb->bdata);
} }
break; break;
case ACPI_GSB_ACCESS_ATTRIB_WORD: case ACPI_GSB_ACCESS_ATTRIB_WORD:
if (action == ACPI_READ) { if (action == ACPI_READ) {
status = i2c_smbus_read_word_data(&client, command); status = i2c_smbus_read_word_data(client, command);
if (status >= 0) { if (status >= 0) {
gsb->wdata = status; gsb->wdata = status;
status = 0; status = 0;
} }
} else { } else {
status = i2c_smbus_write_word_data(&client, command, status = i2c_smbus_write_word_data(client, command,
gsb->wdata); gsb->wdata);
} }
break; break;
case ACPI_GSB_ACCESS_ATTRIB_BLOCK: case ACPI_GSB_ACCESS_ATTRIB_BLOCK:
if (action == ACPI_READ) { if (action == ACPI_READ) {
status = i2c_smbus_read_block_data(&client, command, status = i2c_smbus_read_block_data(client, command,
gsb->data); gsb->data);
if (status >= 0) { if (status >= 0) {
gsb->len = status; gsb->len = status;
status = 0; status = 0;
} }
} else { } else {
status = i2c_smbus_write_block_data(&client, command, status = i2c_smbus_write_block_data(client, command,
gsb->len, gsb->data); gsb->len, gsb->data);
} }
break; break;
case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE: case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE:
if (action == ACPI_READ) { if (action == ACPI_READ) {
status = acpi_gsb_i2c_read_bytes(&client, command, status = acpi_gsb_i2c_read_bytes(client, command,
gsb->data, info->access_length); gsb->data, info->access_length);
if (status > 0) if (status > 0)
status = 0; status = 0;
} else { } else {
status = acpi_gsb_i2c_write_bytes(&client, command, status = acpi_gsb_i2c_write_bytes(client, command,
gsb->data, info->access_length); gsb->data, info->access_length);
} }
break; break;
...@@ -362,6 +366,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, ...@@ -362,6 +366,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command,
gsb->status = status; gsb->status = status;
err: err:
kfree(client);
ACPI_FREE(ares); ACPI_FREE(ares);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment