Lines Matching +full:their +full:- +full:claim +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0-only
45 if (strcmp(dev_name(dev), driver->name) == 0) in hsi_bus_match()
62 kfree(cl->tx_cfg.channels); in hsi_client_release()
63 kfree(cl->rx_cfg.channels); in hsi_client_release()
77 cl->tx_cfg = info->tx_cfg; in hsi_new_client()
78 if (cl->tx_cfg.channels) { in hsi_new_client()
79 size = cl->tx_cfg.num_channels * sizeof(*cl->tx_cfg.channels); in hsi_new_client()
80 cl->tx_cfg.channels = kmemdup(info->tx_cfg.channels, size, in hsi_new_client()
82 if (!cl->tx_cfg.channels) in hsi_new_client()
86 cl->rx_cfg = info->rx_cfg; in hsi_new_client()
87 if (cl->rx_cfg.channels) { in hsi_new_client()
88 size = cl->rx_cfg.num_channels * sizeof(*cl->rx_cfg.channels); in hsi_new_client()
89 cl->rx_cfg.channels = kmemdup(info->rx_cfg.channels, size, in hsi_new_client()
91 if (!cl->rx_cfg.channels) in hsi_new_client()
95 cl->device.bus = &hsi_bus_type; in hsi_new_client()
96 cl->device.parent = &port->device; in hsi_new_client()
97 cl->device.release = hsi_client_release; in hsi_new_client()
98 dev_set_name(&cl->device, "%s", info->name); in hsi_new_client()
99 cl->device.platform_data = info->platform_data; in hsi_new_client()
100 if (info->archdata) in hsi_new_client()
101 cl->device.archdata = *info->archdata; in hsi_new_client()
102 if (device_register(&cl->device) < 0) { in hsi_new_client()
103 pr_err("hsi: failed to register client: %s\n", info->name); in hsi_new_client()
104 put_device(&cl->device); in hsi_new_client()
110 kfree(cl->tx_cfg.channels); in hsi_new_client()
124 if (cl_info->info.hsi_id == hsi->id) { in hsi_scan_board_info()
125 p = hsi_find_port_num(hsi, cl_info->info.port); in hsi_scan_board_info()
128 hsi_new_client(p, &cl_info->info); in hsi_scan_board_info()
152 return -EINVAL; in hsi_of_property_parse_mode()
172 return -EINVAL; in hsi_of_property_parse_flow()
187 if (strcmp(arb_mode, "round-robin") == 0) in hsi_of_property_parse_arb_mode()
192 return -EINVAL; in hsi_of_property_parse_arb_mode()
214 err = hsi_of_property_parse_mode(client, "hsi-mode", &mode); in hsi_add_client_from_dt()
216 err = hsi_of_property_parse_mode(client, "hsi-rx-mode", in hsi_add_client_from_dt()
217 &cl->rx_cfg.mode); in hsi_add_client_from_dt()
221 err = hsi_of_property_parse_mode(client, "hsi-tx-mode", in hsi_add_client_from_dt()
222 &cl->tx_cfg.mode); in hsi_add_client_from_dt()
226 cl->rx_cfg.mode = mode; in hsi_add_client_from_dt()
227 cl->tx_cfg.mode = mode; in hsi_add_client_from_dt()
230 err = of_property_read_u32(client, "hsi-speed-kbps", in hsi_add_client_from_dt()
231 &cl->tx_cfg.speed); in hsi_add_client_from_dt()
234 cl->rx_cfg.speed = cl->tx_cfg.speed; in hsi_add_client_from_dt()
236 err = hsi_of_property_parse_flow(client, "hsi-flow", in hsi_add_client_from_dt()
237 &cl->rx_cfg.flow); in hsi_add_client_from_dt()
241 err = hsi_of_property_parse_arb_mode(client, "hsi-arb-mode", in hsi_add_client_from_dt()
242 &cl->rx_cfg.arb_mode); in hsi_add_client_from_dt()
246 prop = of_find_property(client, "hsi-channel-ids", &length); in hsi_add_client_from_dt()
248 err = -EINVAL; in hsi_add_client_from_dt()
254 cl->rx_cfg.num_channels = cells; in hsi_add_client_from_dt()
255 cl->tx_cfg.num_channels = cells; in hsi_add_client_from_dt()
256 cl->rx_cfg.channels = kcalloc(cells, sizeof(channel), GFP_KERNEL); in hsi_add_client_from_dt()
257 if (!cl->rx_cfg.channels) { in hsi_add_client_from_dt()
258 err = -ENOMEM; in hsi_add_client_from_dt()
262 cl->tx_cfg.channels = kcalloc(cells, sizeof(channel), GFP_KERNEL); in hsi_add_client_from_dt()
263 if (!cl->tx_cfg.channels) { in hsi_add_client_from_dt()
264 err = -ENOMEM; in hsi_add_client_from_dt()
270 err = of_property_read_u32_index(client, "hsi-channel-ids", i, in hsi_add_client_from_dt()
275 err = of_property_read_string_index(client, "hsi-channel-names", in hsi_add_client_from_dt()
283 cl->rx_cfg.channels[i] = channel; in hsi_add_client_from_dt()
284 cl->tx_cfg.channels[i] = channel; in hsi_add_client_from_dt()
287 cl->rx_cfg.num_hw_channels = max_chan + 1; in hsi_add_client_from_dt()
288 cl->tx_cfg.num_hw_channels = max_chan + 1; in hsi_add_client_from_dt()
290 cl->device.bus = &hsi_bus_type; in hsi_add_client_from_dt()
291 cl->device.parent = &port->device; in hsi_add_client_from_dt()
292 cl->device.release = hsi_client_release; in hsi_add_client_from_dt()
293 cl->device.of_node = client; in hsi_add_client_from_dt()
295 dev_set_name(&cl->device, "%s", name); in hsi_add_client_from_dt()
296 if (device_register(&cl->device) < 0) { in hsi_add_client_from_dt()
298 put_device(&cl->device); in hsi_add_client_from_dt()
304 kfree(cl->tx_cfg.channels); in hsi_add_client_from_dt()
306 kfree(cl->rx_cfg.channels); in hsi_add_client_from_dt()
316 /* register hsi-char device */ in hsi_add_clients_from_dt()
345 kfree(hsi->port); in hsi_controller_release()
355 * hsi_port_unregister_clients - Unregister an HSI port
360 device_for_each_child(&port->device, NULL, hsi_remove_client); in hsi_port_unregister_clients()
365 * hsi_unregister_controller - Unregister an HSI controller
370 device_for_each_child(&hsi->device, NULL, hsi_remove_port); in hsi_unregister_controller()
371 device_unregister(&hsi->device); in hsi_unregister_controller()
376 * hsi_register_controller - Register an HSI controller and its ports
379 * Returns -errno on failure, 0 on success.
386 err = device_add(&hsi->device); in hsi_register_controller()
389 for (i = 0; i < hsi->num_ports; i++) { in hsi_register_controller()
390 hsi->port[i]->device.parent = &hsi->device; in hsi_register_controller()
391 err = device_add(&hsi->port[i]->device); in hsi_register_controller()
400 while (i-- > 0) in hsi_register_controller()
401 device_del(&hsi->port[i]->device); in hsi_register_controller()
402 device_del(&hsi->device); in hsi_register_controller()
409 * hsi_register_client_driver - Register an HSI client to the HSI bus
412 * Returns -errno on failure, 0 on success.
416 drv->driver.bus = &hsi_bus_type; in hsi_register_client_driver()
418 return driver_register(&drv->driver); in hsi_register_client_driver()
433 * hsi_put_controller - Free an HSI controller
438 * to free their allocated hsi_controller structures before a successful
448 for (i = 0; i < hsi->num_ports; i++) in hsi_put_controller()
449 if (hsi->port && hsi->port[i]) in hsi_put_controller()
450 put_device(&hsi->port[i]->device); in hsi_put_controller()
451 put_device(&hsi->device); in hsi_put_controller()
456 * hsi_alloc_controller - Allocate an HSI controller and its ports
479 hsi->num_ports = n_ports; in hsi_alloc_controller()
480 hsi->port = port; in hsi_alloc_controller()
481 hsi->device.release = hsi_controller_release; in hsi_alloc_controller()
482 device_initialize(&hsi->device); in hsi_alloc_controller()
488 port[i]->num = i; in hsi_alloc_controller()
489 port[i]->async = hsi_dummy_msg; in hsi_alloc_controller()
490 port[i]->setup = hsi_dummy_cl; in hsi_alloc_controller()
491 port[i]->flush = hsi_dummy_cl; in hsi_alloc_controller()
492 port[i]->start_tx = hsi_dummy_cl; in hsi_alloc_controller()
493 port[i]->stop_tx = hsi_dummy_cl; in hsi_alloc_controller()
494 port[i]->release = hsi_dummy_cl; in hsi_alloc_controller()
495 mutex_init(&port[i]->lock); in hsi_alloc_controller()
496 BLOCKING_INIT_NOTIFIER_HEAD(&port[i]->n_head); in hsi_alloc_controller()
497 dev_set_name(&port[i]->device, "port%d", i); in hsi_alloc_controller()
498 hsi->port[i]->device.release = hsi_port_release; in hsi_alloc_controller()
499 device_initialize(&hsi->port[i]->device); in hsi_alloc_controller()
511 * hsi_free_msg - Free an HSI message
520 sg_free_table(&msg->sgt); in hsi_free_msg()
526 * hsi_alloc_msg - Allocate an HSI message
548 err = sg_alloc_table(&msg->sgt, nents, flags); in hsi_alloc_msg()
559 * hsi_async - Submit an HSI transfer to the controller
567 * HSI controllers relay on pre-allocated buffers from their clients and they
568 * do not allocate buffers on their own.
575 * Returns -errno on failure or 0 on success
582 return -EACCES; in hsi_async()
584 WARN_ON_ONCE(!msg->destructor || !msg->complete); in hsi_async()
585 msg->cl = cl; in hsi_async()
587 return port->async(msg); in hsi_async()
592 * hsi_claim_port - Claim the HSI client's port
593 * @cl: HSI client that wants to claim its port
596 * Returns -errno on failure, 0 on success.
603 mutex_lock(&port->lock); in hsi_claim_port()
604 if ((port->claimed) && (!port->shared || !share)) { in hsi_claim_port()
605 err = -EBUSY; in hsi_claim_port()
608 if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) { in hsi_claim_port()
609 err = -ENODEV; in hsi_claim_port()
612 port->claimed++; in hsi_claim_port()
613 port->shared = !!share; in hsi_claim_port()
614 cl->pclaimed = 1; in hsi_claim_port()
616 mutex_unlock(&port->lock); in hsi_claim_port()
623 * hsi_release_port - Release the HSI client's port
630 mutex_lock(&port->lock); in hsi_release_port()
632 port->release(cl); in hsi_release_port()
633 if (cl->pclaimed) in hsi_release_port()
634 port->claimed--; in hsi_release_port()
635 BUG_ON(port->claimed < 0); in hsi_release_port()
636 cl->pclaimed = 0; in hsi_release_port()
637 if (!port->claimed) in hsi_release_port()
638 port->shared = 0; in hsi_release_port()
639 module_put(to_hsi_controller(port->device.parent)->owner); in hsi_release_port()
640 mutex_unlock(&port->lock); in hsi_release_port()
649 (*cl->ehandler)(cl, event); in hsi_event_notifier_call()
655 * hsi_register_port_event - Register a client to receive port events
664 * Returns -errno on error, or 0 on success.
671 if (!handler || cl->ehandler) in hsi_register_port_event()
672 return -EINVAL; in hsi_register_port_event()
674 return -EACCES; in hsi_register_port_event()
675 cl->ehandler = handler; in hsi_register_port_event()
676 cl->nb.notifier_call = hsi_event_notifier_call; in hsi_register_port_event()
678 return blocking_notifier_chain_register(&port->n_head, &cl->nb); in hsi_register_port_event()
683 * hsi_unregister_port_event - Stop receiving port events for a client
686 * Clients should call this function before releasing their associated
689 * Returns -errno on error, or 0 on success.
698 err = blocking_notifier_chain_unregister(&port->n_head, &cl->nb); in hsi_unregister_port_event()
700 cl->ehandler = NULL; in hsi_unregister_port_event()
707 * hsi_event - Notifies clients about port events
716 * HSI_EVENT_START_RX - Incoming wake line high
717 * HSI_EVENT_STOP_RX - Incoming wake line down
719 * Returns -errno on error, or 0 on success.
723 return blocking_notifier_call_chain(&port->n_head, event, NULL); in hsi_event()
728 * hsi_get_channel_id_by_name - acquire channel id by channel name
733 * requesting IRQs or GPIOs by name. This function assumes the same
736 * Returns -errno on error or channel id on success.
742 if (!cl->rx_cfg.channels) in hsi_get_channel_id_by_name()
743 return -ENOENT; in hsi_get_channel_id_by_name()
745 for (i = 0; i < cl->rx_cfg.num_channels; i++) in hsi_get_channel_id_by_name()
746 if (!strcmp(cl->rx_cfg.channels[i].name, name)) in hsi_get_channel_id_by_name()
747 return cl->rx_cfg.channels[i].id; in hsi_get_channel_id_by_name()
749 return -ENXIO; in hsi_get_channel_id_by_name()
766 MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework");