585 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Greybus CPort control protocol.4 *5 * Copyright 2015 Google Inc.6 * Copyright 2015 Linaro Ltd.7 */8 9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/slab.h>12#include <linux/greybus.h>13 14/* Highest control-protocol version supported */15#define GB_CONTROL_VERSION_MAJOR 016#define GB_CONTROL_VERSION_MINOR 117 18static int gb_control_get_version(struct gb_control *control)19{20 struct gb_interface *intf = control->connection->intf;21 struct gb_control_version_request request;22 struct gb_control_version_response response;23 int ret;24 25 request.major = GB_CONTROL_VERSION_MAJOR;26 request.minor = GB_CONTROL_VERSION_MINOR;27 28 ret = gb_operation_sync(control->connection,29 GB_CONTROL_TYPE_VERSION,30 &request, sizeof(request), &response,31 sizeof(response));32 if (ret) {33 dev_err(&intf->dev,34 "failed to get control-protocol version: %d\n",35 ret);36 return ret;37 }38 39 if (response.major > request.major) {40 dev_err(&intf->dev,41 "unsupported major control-protocol version (%u > %u)\n",42 response.major, request.major);43 return -ENOTSUPP;44 }45 46 control->protocol_major = response.major;47 control->protocol_minor = response.minor;48 49 dev_dbg(&intf->dev, "%s - %u.%u\n", __func__, response.major,50 response.minor);51 52 return 0;53}54 55static int gb_control_get_bundle_version(struct gb_control *control,56 struct gb_bundle *bundle)57{58 struct gb_interface *intf = control->connection->intf;59 struct gb_control_bundle_version_request request;60 struct gb_control_bundle_version_response response;61 int ret;62 63 request.bundle_id = bundle->id;64 65 ret = gb_operation_sync(control->connection,66 GB_CONTROL_TYPE_BUNDLE_VERSION,67 &request, sizeof(request),68 &response, sizeof(response));69 if (ret) {70 dev_err(&intf->dev,71 "failed to get bundle %u class version: %d\n",72 bundle->id, ret);73 return ret;74 }75 76 bundle->class_major = response.major;77 bundle->class_minor = response.minor;78 79 dev_dbg(&intf->dev, "%s - %u: %u.%u\n", __func__, bundle->id,80 response.major, response.minor);81 82 return 0;83}84 85int gb_control_get_bundle_versions(struct gb_control *control)86{87 struct gb_interface *intf = control->connection->intf;88 struct gb_bundle *bundle;89 int ret;90 91 if (!control->has_bundle_version)92 return 0;93 94 list_for_each_entry(bundle, &intf->bundles, links) {95 ret = gb_control_get_bundle_version(control, bundle);96 if (ret)97 return ret;98 }99 100 return 0;101}102 103/* Get Manifest's size from the interface */104int gb_control_get_manifest_size_operation(struct gb_interface *intf)105{106 struct gb_control_get_manifest_size_response response;107 struct gb_connection *connection = intf->control->connection;108 int ret;109 110 ret = gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST_SIZE,111 NULL, 0, &response, sizeof(response));112 if (ret) {113 dev_err(&connection->intf->dev,114 "failed to get manifest size: %d\n", ret);115 return ret;116 }117 118 return le16_to_cpu(response.size);119}120 121/* Reads Manifest from the interface */122int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,123 size_t size)124{125 struct gb_connection *connection = intf->control->connection;126 127 return gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST,128 NULL, 0, manifest, size);129}130 131int gb_control_connected_operation(struct gb_control *control, u16 cport_id)132{133 struct gb_control_connected_request request;134 135 request.cport_id = cpu_to_le16(cport_id);136 return gb_operation_sync(control->connection, GB_CONTROL_TYPE_CONNECTED,137 &request, sizeof(request), NULL, 0);138}139 140int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id)141{142 struct gb_control_disconnected_request request;143 144 request.cport_id = cpu_to_le16(cport_id);145 return gb_operation_sync(control->connection,146 GB_CONTROL_TYPE_DISCONNECTED, &request,147 sizeof(request), NULL, 0);148}149 150int gb_control_disconnecting_operation(struct gb_control *control,151 u16 cport_id)152{153 struct gb_control_disconnecting_request *request;154 struct gb_operation *operation;155 int ret;156 157 operation = gb_operation_create_core(control->connection,158 GB_CONTROL_TYPE_DISCONNECTING,159 sizeof(*request), 0, 0,160 GFP_KERNEL);161 if (!operation)162 return -ENOMEM;163 164 request = operation->request->payload;165 request->cport_id = cpu_to_le16(cport_id);166 167 ret = gb_operation_request_send_sync(operation);168 if (ret) {169 dev_err(&control->dev, "failed to send disconnecting: %d\n",170 ret);171 }172 173 gb_operation_put(operation);174 175 return ret;176}177 178int gb_control_mode_switch_operation(struct gb_control *control)179{180 struct gb_operation *operation;181 int ret;182 183 operation = gb_operation_create_core(control->connection,184 GB_CONTROL_TYPE_MODE_SWITCH,185 0, 0,186 GB_OPERATION_FLAG_UNIDIRECTIONAL,187 GFP_KERNEL);188 if (!operation)189 return -ENOMEM;190 191 ret = gb_operation_request_send_sync(operation);192 if (ret)193 dev_err(&control->dev, "failed to send mode switch: %d\n", ret);194 195 gb_operation_put(operation);196 197 return ret;198}199 200static int gb_control_bundle_pm_status_map(u8 status)201{202 switch (status) {203 case GB_CONTROL_BUNDLE_PM_INVAL:204 return -EINVAL;205 case GB_CONTROL_BUNDLE_PM_BUSY:206 return -EBUSY;207 case GB_CONTROL_BUNDLE_PM_NA:208 return -ENOMSG;209 case GB_CONTROL_BUNDLE_PM_FAIL:210 default:211 return -EREMOTEIO;212 }213}214 215int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id)216{217 struct gb_control_bundle_pm_request request;218 struct gb_control_bundle_pm_response response;219 int ret;220 221 request.bundle_id = bundle_id;222 ret = gb_operation_sync(control->connection,223 GB_CONTROL_TYPE_BUNDLE_SUSPEND, &request,224 sizeof(request), &response, sizeof(response));225 if (ret) {226 dev_err(&control->dev, "failed to send bundle %u suspend: %d\n",227 bundle_id, ret);228 return ret;229 }230 231 if (response.status != GB_CONTROL_BUNDLE_PM_OK) {232 dev_err(&control->dev, "failed to suspend bundle %u: %d\n",233 bundle_id, response.status);234 return gb_control_bundle_pm_status_map(response.status);235 }236 237 return 0;238}239 240int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id)241{242 struct gb_control_bundle_pm_request request;243 struct gb_control_bundle_pm_response response;244 int ret;245 246 request.bundle_id = bundle_id;247 ret = gb_operation_sync(control->connection,248 GB_CONTROL_TYPE_BUNDLE_RESUME, &request,249 sizeof(request), &response, sizeof(response));250 if (ret) {251 dev_err(&control->dev, "failed to send bundle %u resume: %d\n",252 bundle_id, ret);253 return ret;254 }255 256 if (response.status != GB_CONTROL_BUNDLE_PM_OK) {257 dev_err(&control->dev, "failed to resume bundle %u: %d\n",258 bundle_id, response.status);259 return gb_control_bundle_pm_status_map(response.status);260 }261 262 return 0;263}264 265int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id)266{267 struct gb_control_bundle_pm_request request;268 struct gb_control_bundle_pm_response response;269 int ret;270 271 request.bundle_id = bundle_id;272 ret = gb_operation_sync(control->connection,273 GB_CONTROL_TYPE_BUNDLE_DEACTIVATE, &request,274 sizeof(request), &response, sizeof(response));275 if (ret) {276 dev_err(&control->dev,277 "failed to send bundle %u deactivate: %d\n", bundle_id,278 ret);279 return ret;280 }281 282 if (response.status != GB_CONTROL_BUNDLE_PM_OK) {283 dev_err(&control->dev, "failed to deactivate bundle %u: %d\n",284 bundle_id, response.status);285 return gb_control_bundle_pm_status_map(response.status);286 }287 288 return 0;289}290 291int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id)292{293 struct gb_control_bundle_pm_request request;294 struct gb_control_bundle_pm_response response;295 int ret;296 297 if (!control->has_bundle_activate)298 return 0;299 300 request.bundle_id = bundle_id;301 ret = gb_operation_sync(control->connection,302 GB_CONTROL_TYPE_BUNDLE_ACTIVATE, &request,303 sizeof(request), &response, sizeof(response));304 if (ret) {305 dev_err(&control->dev,306 "failed to send bundle %u activate: %d\n", bundle_id,307 ret);308 return ret;309 }310 311 if (response.status != GB_CONTROL_BUNDLE_PM_OK) {312 dev_err(&control->dev, "failed to activate bundle %u: %d\n",313 bundle_id, response.status);314 return gb_control_bundle_pm_status_map(response.status);315 }316 317 return 0;318}319 320static int gb_control_interface_pm_status_map(u8 status)321{322 switch (status) {323 case GB_CONTROL_INTF_PM_BUSY:324 return -EBUSY;325 case GB_CONTROL_INTF_PM_NA:326 return -ENOMSG;327 default:328 return -EREMOTEIO;329 }330}331 332int gb_control_interface_suspend_prepare(struct gb_control *control)333{334 struct gb_control_intf_pm_response response;335 int ret;336 337 ret = gb_operation_sync(control->connection,338 GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE, NULL, 0,339 &response, sizeof(response));340 if (ret) {341 dev_err(&control->dev,342 "failed to send interface suspend prepare: %d\n", ret);343 return ret;344 }345 346 if (response.status != GB_CONTROL_INTF_PM_OK) {347 dev_err(&control->dev, "interface error while preparing suspend: %d\n",348 response.status);349 return gb_control_interface_pm_status_map(response.status);350 }351 352 return 0;353}354 355int gb_control_interface_deactivate_prepare(struct gb_control *control)356{357 struct gb_control_intf_pm_response response;358 int ret;359 360 ret = gb_operation_sync(control->connection,361 GB_CONTROL_TYPE_INTF_DEACTIVATE_PREPARE, NULL,362 0, &response, sizeof(response));363 if (ret) {364 dev_err(&control->dev, "failed to send interface deactivate prepare: %d\n",365 ret);366 return ret;367 }368 369 if (response.status != GB_CONTROL_INTF_PM_OK) {370 dev_err(&control->dev, "interface error while preparing deactivate: %d\n",371 response.status);372 return gb_control_interface_pm_status_map(response.status);373 }374 375 return 0;376}377 378int gb_control_interface_hibernate_abort(struct gb_control *control)379{380 struct gb_control_intf_pm_response response;381 int ret;382 383 ret = gb_operation_sync(control->connection,384 GB_CONTROL_TYPE_INTF_HIBERNATE_ABORT, NULL, 0,385 &response, sizeof(response));386 if (ret) {387 dev_err(&control->dev,388 "failed to send interface aborting hibernate: %d\n",389 ret);390 return ret;391 }392 393 if (response.status != GB_CONTROL_INTF_PM_OK) {394 dev_err(&control->dev, "interface error while aborting hibernate: %d\n",395 response.status);396 return gb_control_interface_pm_status_map(response.status);397 }398 399 return 0;400}401 402static ssize_t vendor_string_show(struct device *dev,403 struct device_attribute *attr, char *buf)404{405 struct gb_control *control = to_gb_control(dev);406 407 return scnprintf(buf, PAGE_SIZE, "%s\n", control->vendor_string);408}409static DEVICE_ATTR_RO(vendor_string);410 411static ssize_t product_string_show(struct device *dev,412 struct device_attribute *attr, char *buf)413{414 struct gb_control *control = to_gb_control(dev);415 416 return scnprintf(buf, PAGE_SIZE, "%s\n", control->product_string);417}418static DEVICE_ATTR_RO(product_string);419 420static struct attribute *control_attrs[] = {421 &dev_attr_vendor_string.attr,422 &dev_attr_product_string.attr,423 NULL,424};425ATTRIBUTE_GROUPS(control);426 427static void gb_control_release(struct device *dev)428{429 struct gb_control *control = to_gb_control(dev);430 431 gb_connection_destroy(control->connection);432 433 kfree(control->vendor_string);434 kfree(control->product_string);435 436 kfree(control);437}438 439const struct device_type greybus_control_type = {440 .name = "greybus_control",441 .release = gb_control_release,442};443 444struct gb_control *gb_control_create(struct gb_interface *intf)445{446 struct gb_connection *connection;447 struct gb_control *control;448 449 control = kzalloc(sizeof(*control), GFP_KERNEL);450 if (!control)451 return ERR_PTR(-ENOMEM);452 453 control->intf = intf;454 455 connection = gb_connection_create_control(intf);456 if (IS_ERR(connection)) {457 dev_err(&intf->dev,458 "failed to create control connection: %ld\n",459 PTR_ERR(connection));460 kfree(control);461 return ERR_CAST(connection);462 }463 464 control->connection = connection;465 466 control->dev.parent = &intf->dev;467 control->dev.bus = &greybus_bus_type;468 control->dev.type = &greybus_control_type;469 control->dev.groups = control_groups;470 control->dev.dma_mask = intf->dev.dma_mask;471 device_initialize(&control->dev);472 dev_set_name(&control->dev, "%s.ctrl", dev_name(&intf->dev));473 474 gb_connection_set_data(control->connection, control);475 476 return control;477}478 479int gb_control_enable(struct gb_control *control)480{481 int ret;482 483 dev_dbg(&control->connection->intf->dev, "%s\n", __func__);484 485 ret = gb_connection_enable_tx(control->connection);486 if (ret) {487 dev_err(&control->connection->intf->dev,488 "failed to enable control connection: %d\n",489 ret);490 return ret;491 }492 493 ret = gb_control_get_version(control);494 if (ret)495 goto err_disable_connection;496 497 if (control->protocol_major > 0 || control->protocol_minor > 1)498 control->has_bundle_version = true;499 500 /* FIXME: use protocol version instead */501 if (!(control->intf->quirks & GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE))502 control->has_bundle_activate = true;503 504 return 0;505 506err_disable_connection:507 gb_connection_disable(control->connection);508 509 return ret;510}511 512void gb_control_disable(struct gb_control *control)513{514 dev_dbg(&control->connection->intf->dev, "%s\n", __func__);515 516 if (control->intf->disconnected)517 gb_connection_disable_forced(control->connection);518 else519 gb_connection_disable(control->connection);520}521 522int gb_control_suspend(struct gb_control *control)523{524 gb_connection_disable(control->connection);525 526 return 0;527}528 529int gb_control_resume(struct gb_control *control)530{531 int ret;532 533 ret = gb_connection_enable_tx(control->connection);534 if (ret) {535 dev_err(&control->connection->intf->dev,536 "failed to enable control connection: %d\n", ret);537 return ret;538 }539 540 return 0;541}542 543int gb_control_add(struct gb_control *control)544{545 int ret;546 547 ret = device_add(&control->dev);548 if (ret) {549 dev_err(&control->dev,550 "failed to register control device: %d\n",551 ret);552 return ret;553 }554 555 return 0;556}557 558void gb_control_del(struct gb_control *control)559{560 if (device_is_registered(&control->dev))561 device_del(&control->dev);562}563 564struct gb_control *gb_control_get(struct gb_control *control)565{566 get_device(&control->dev);567 568 return control;569}570 571void gb_control_put(struct gb_control *control)572{573 put_device(&control->dev);574}575 576void gb_control_mode_switch_prepare(struct gb_control *control)577{578 gb_connection_mode_switch_prepare(control->connection);579}580 581void gb_control_mode_switch_complete(struct gb_control *control)582{583 gb_connection_mode_switch_complete(control->connection);584}585