greybus: gpio-gb: convert to use gb_operation_sync
This converts the GPIO protocol driver to use gb_operation_sync, removing lots of places where the create/send/destroy pattern was being used to send greybus messages. Signed-off-by: Greg Kroah-Hartman <greg@kroah.com> Reviewed-by: Alex Elder <elder@linaro.org>
This commit is contained in:
parent
e51f1d1a77
commit
7d5bbb1735
|
@ -116,337 +116,193 @@ struct gb_gpio_set_debounce_request {
|
||||||
* This request only uses the connection field, and if successful,
|
* This request only uses the connection field, and if successful,
|
||||||
* fills in the major and minor protocol version of the target.
|
* fills in the major and minor protocol version of the target.
|
||||||
*/
|
*/
|
||||||
static int
|
static int gb_gpio_proto_version_operation(struct gb_gpio_controller *ggc)
|
||||||
gb_gpio_proto_version_operation(struct gb_gpio_controller *gb_gpio_controller)
|
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_proto_version_response response;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_proto_version_response *response;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* protocol version request has no payload */
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_PROTOCOL_VERSION,
|
||||||
operation = gb_operation_create(connection,
|
NULL, 0, &response, sizeof(response));
|
||||||
GB_GPIO_TYPE_PROTOCOL_VERSION,
|
if (ret)
|
||||||
0, sizeof(*response));
|
return ret;
|
||||||
if (!operation)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
if (response.major > GB_GPIO_VERSION_MAJOR) {
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("version operation failed (%d)\n", ret);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = operation->response->payload;
|
|
||||||
if (response->major > GB_GPIO_VERSION_MAJOR) {
|
|
||||||
pr_err("unsupported major version (%hhu > %hhu)\n",
|
pr_err("unsupported major version (%hhu > %hhu)\n",
|
||||||
response->major, GB_GPIO_VERSION_MAJOR);
|
response.major, GB_GPIO_VERSION_MAJOR);
|
||||||
ret = -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
} else {
|
|
||||||
gb_gpio_controller->version_major = response->major;
|
|
||||||
gb_gpio_controller->version_minor = response->minor;
|
|
||||||
}
|
}
|
||||||
out:
|
ggc->version_major = response.major;
|
||||||
gb_operation_destroy(operation);
|
ggc->version_minor = response.minor;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
|
||||||
|
{
|
||||||
|
struct gb_gpio_line_count_response response;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_LINE_COUNT,
|
||||||
|
NULL, 0, &response, sizeof(response));
|
||||||
|
if (!ret)
|
||||||
|
ggc->line_max = response.count;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_line_count_operation(struct gb_gpio_controller *gb_gpio_controller)
|
static int gb_gpio_activate_operation(struct gb_gpio_controller *ggc, u8 which)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_activate_request request;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_line_count_response *response;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* line count request has no payload */
|
if (which > ggc->line_max)
|
||||||
operation = gb_operation_create(connection,
|
|
||||||
GB_GPIO_TYPE_LINE_COUNT,
|
|
||||||
0, sizeof(*response));
|
|
||||||
if (!operation)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("line count operation failed (%d)\n", ret);
|
|
||||||
} else {
|
|
||||||
response = operation->response->payload;
|
|
||||||
gb_gpio_controller->line_max = response->count;
|
|
||||||
}
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gb_gpio_activate_operation(struct gb_gpio_controller *gb_gpio_controller,
|
|
||||||
u8 which)
|
|
||||||
{
|
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_activate_request *request;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* activate response has no payload */
|
request.which = which;
|
||||||
operation = gb_operation_create(connection,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE,
|
||||||
GB_GPIO_TYPE_ACTIVATE,
|
&request, sizeof(request), NULL, 0);
|
||||||
sizeof(*request), 0);
|
if (!ret)
|
||||||
if (!operation)
|
ggc->lines[which].active = true;
|
||||||
return -ENOMEM;
|
|
||||||
request = operation->request->payload;
|
|
||||||
request->which = which;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret)
|
|
||||||
pr_err("activate operation failed (%d)\n", ret);
|
|
||||||
else
|
|
||||||
gb_gpio_controller->lines[which].active = true;
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_deactivate_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which)
|
u8 which)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_deactivate_request request;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_deactivate_request *request;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* deactivate response has no payload */
|
request.which = which;
|
||||||
operation = gb_operation_create(connection,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DEACTIVATE,
|
||||||
GB_GPIO_TYPE_DEACTIVATE,
|
&request, sizeof(request), NULL, 0);
|
||||||
sizeof(*request), 0);
|
if (!ret)
|
||||||
if (!operation)
|
ggc->lines[which].active = false;
|
||||||
return -ENOMEM;
|
|
||||||
request = operation->request->payload;
|
|
||||||
request->which = which;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret)
|
|
||||||
pr_err("deactivate operation failed (%d)\n", ret);
|
|
||||||
else
|
|
||||||
gb_gpio_controller->lines[which].active = false;
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_get_direction_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which)
|
u8 which)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_get_direction_request request;
|
||||||
struct gb_operation *operation;
|
struct gb_gpio_get_direction_response response;
|
||||||
struct gb_gpio_get_direction_request *request;
|
|
||||||
struct gb_gpio_get_direction_response *response;
|
|
||||||
int ret;
|
int ret;
|
||||||
u8 direction;
|
u8 direction;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
operation = gb_operation_create(connection,
|
request.which = which;
|
||||||
GB_GPIO_TYPE_GET_DIRECTION,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_GET_DIRECTION,
|
||||||
sizeof(*request), sizeof(*response));
|
&request, sizeof(request),
|
||||||
if (!operation)
|
&response, sizeof(response));
|
||||||
return -ENOMEM;
|
if (ret)
|
||||||
request = operation->request->payload;
|
return ret;
|
||||||
request->which = which;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
direction = response.direction;
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("get direction operation failed (%d)\n", ret);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = operation->response->payload;
|
|
||||||
direction = response->direction;
|
|
||||||
if (direction && direction != 1)
|
if (direction && direction != 1)
|
||||||
pr_warn("gpio %u direction was %u (should be 0 or 1)\n",
|
pr_warn("gpio %u direction was %u (should be 0 or 1)\n",
|
||||||
which, direction);
|
which, direction);
|
||||||
gb_gpio_controller->lines[which].direction = direction ? 1 : 0;
|
ggc->lines[which].direction = direction ? 1 : 0;
|
||||||
out:
|
return 0;
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_direction_in_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_direction_in_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which)
|
u8 which)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_direction_in_request request;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_direction_in_request *request;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* direction_in response has no payload */
|
request.which = which;
|
||||||
operation = gb_operation_create(connection,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DIRECTION_IN,
|
||||||
GB_GPIO_TYPE_DIRECTION_IN,
|
&request, sizeof(request), NULL, 0);
|
||||||
sizeof(*request), 0);
|
if (!ret)
|
||||||
if (!operation)
|
ggc->lines[which].direction = 1;
|
||||||
return -ENOMEM;
|
|
||||||
request = operation->request->payload;
|
|
||||||
request->which = which;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret)
|
|
||||||
pr_err("direction in operation failed (%d)\n", ret);
|
|
||||||
else
|
|
||||||
gb_gpio_controller->lines[which].direction = 1;
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_direction_out_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_direction_out_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which, bool value_high)
|
u8 which, bool value_high)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_direction_out_request request;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_direction_out_request *request;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* direction_out response has no payload */
|
request.which = which;
|
||||||
operation = gb_operation_create(connection,
|
request.value = value_high ? 1 : 0;
|
||||||
GB_GPIO_TYPE_DIRECTION_OUT,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DIRECTION_OUT,
|
||||||
sizeof(*request), 0);
|
&request, sizeof(request), NULL, 0);
|
||||||
if (!operation)
|
if (!ret)
|
||||||
return -ENOMEM;
|
ggc->lines[which].direction = 0;
|
||||||
request = operation->request->payload;
|
|
||||||
request->which = which;
|
|
||||||
request->value = value_high ? 1 : 0;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret)
|
|
||||||
pr_err("direction out operation failed (%d)\n", ret);
|
|
||||||
else
|
|
||||||
gb_gpio_controller->lines[which].direction = 0;
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_get_value_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_get_value_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which)
|
u8 which)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_get_value_request request;
|
||||||
struct gb_operation *operation;
|
struct gb_gpio_get_value_response response;
|
||||||
struct gb_gpio_get_value_request *request;
|
|
||||||
struct gb_gpio_get_value_response *response;
|
|
||||||
int ret;
|
int ret;
|
||||||
u8 value;
|
u8 value;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
operation = gb_operation_create(connection,
|
request.which = which;
|
||||||
GB_GPIO_TYPE_GET_VALUE,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_GET_VALUE,
|
||||||
sizeof(*request), sizeof(*response));
|
&request, sizeof(request),
|
||||||
if (!operation)
|
&response, sizeof(response));
|
||||||
return -ENOMEM;
|
if (ret)
|
||||||
request = operation->request->payload;
|
return ret;
|
||||||
request->which = which;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
value = response.value;
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("get value operation failed (%d)\n", ret);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = operation->response->payload;
|
|
||||||
value = response->value;
|
|
||||||
if (value && value != 1)
|
if (value && value != 1)
|
||||||
pr_warn("gpio %u value was %u (should be 0 or 1)\n",
|
pr_warn("gpio %u value was %u (should be 0 or 1)\n",
|
||||||
which, value);
|
which, value);
|
||||||
gb_gpio_controller->lines[which].value = value ? 1 : 0;
|
ggc->lines[which].value = value ? 1 : 0;
|
||||||
out:
|
return 0;
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_set_value_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_set_value_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which, bool value_high)
|
u8 which, bool value_high)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_set_value_request request;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_set_value_request *request;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* set_value response has no payload */
|
request.which = which;
|
||||||
operation = gb_operation_create(connection,
|
request.value = value_high ? 1 : 0;
|
||||||
GB_GPIO_TYPE_SET_VALUE,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_VALUE,
|
||||||
sizeof(*request), 0);
|
&request, sizeof(request), NULL, 0);
|
||||||
if (!operation)
|
if (!ret) {
|
||||||
return -ENOMEM;
|
/* XXX should this set direction to out? */
|
||||||
request = operation->request->payload;
|
ggc->lines[which].value = request.value;
|
||||||
request->which = which;
|
}
|
||||||
request->value = value_high ? 1 : 0;
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret)
|
|
||||||
pr_err("set value operation failed (%d)\n", ret);
|
|
||||||
else /* XXX should this set direction to out? */
|
|
||||||
gb_gpio_controller->lines[which].value = request->value;
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *gb_gpio_controller,
|
static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *ggc,
|
||||||
u8 which, u16 debounce_usec)
|
u8 which, u16 debounce_usec)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = gb_gpio_controller->connection;
|
struct gb_gpio_set_debounce_request request;
|
||||||
struct gb_operation *operation;
|
|
||||||
struct gb_gpio_set_debounce_request *request;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (which > gb_gpio_controller->line_max)
|
if (which > ggc->line_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* set_debounce response has no payload */
|
request.which = which;
|
||||||
operation = gb_operation_create(connection,
|
request.usec = cpu_to_le16(debounce_usec);
|
||||||
GB_GPIO_TYPE_SET_DEBOUNCE,
|
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_DEBOUNCE,
|
||||||
sizeof(*request), 0);
|
&request, sizeof(request), NULL, 0);
|
||||||
if (!operation)
|
if (!ret)
|
||||||
return -ENOMEM;
|
ggc->lines[which].debounce_usec = debounce_usec;
|
||||||
request = operation->request->payload;
|
|
||||||
request->which = which;
|
|
||||||
request->usec = cpu_to_le16(debounce_usec);
|
|
||||||
|
|
||||||
/* Synchronous operation--no callback */
|
|
||||||
ret = gb_operation_request_send(operation, NULL);
|
|
||||||
if (ret)
|
|
||||||
pr_err("set debounce operation failed (%d)\n", ret);
|
|
||||||
else
|
|
||||||
gb_gpio_controller->lines[which].debounce_usec =
|
|
||||||
le16_to_cpu(request->usec);
|
|
||||||
gb_operation_destroy(operation);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue