Lines Matching +full:probe +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2012-2016, Intel Corporation.
15 #include "ishtp-dev.h"
28 * ishtp_recv() - process ishtp message
42 msg_hdr = dev->ops->ishtp_read_hdr(dev); in ishtp_recv()
46 dev->ops->sync_fw_clock(dev); in ishtp_recv()
49 dev->ishtp_msg_hdr = msg_hdr; in ishtp_recv()
52 if (ishtp_hdr->length > dev->mtu) { in ishtp_recv()
53 dev_err(dev->devc, in ishtp_recv()
54 "ISHTP hdr - bad length: %u; dropped [%08X]\n", in ishtp_recv()
55 (unsigned int)ishtp_hdr->length, msg_hdr); in ishtp_recv()
60 if (!ishtp_hdr->host_addr && !ishtp_hdr->fw_addr) in ishtp_recv()
62 /* ISHTP fixed-client message */ in ishtp_recv()
63 else if (!ishtp_hdr->host_addr) in ishtp_recv()
72 * ishtp_send_msg() - Send ishtp message
91 drbl_val = dev->ops->ipc_get_header(dev, hdr->length + in ishtp_send_msg()
97 memcpy(ipc_msg + 2 * sizeof(uint32_t), msg, hdr->length); in ishtp_send_msg()
98 return dev->ops->write(dev, ipc_send_compl, ipc_send_compl_prm, in ishtp_send_msg()
99 ipc_msg, 2 * sizeof(uint32_t) + hdr->length); in ishtp_send_msg()
103 * ishtp_write_message() - Send ishtp single fragment message
120 * ishtp_fw_cl_by_uuid() - locate index of fw client
126 * Return: fw client index or -ENOENT if not found
132 for (i = 0; i < dev->fw_clients_num; ++i) { in ishtp_fw_cl_by_uuid()
133 if (guid_equal(uuid, &dev->fw_clients[i].props.protocol_name)) in ishtp_fw_cl_by_uuid()
136 return -ENOENT; in ishtp_fw_cl_by_uuid()
141 * ishtp_fw_cl_get_client() - return client information to client
155 spin_lock_irqsave(&dev->fw_clients_lock, flags); in ishtp_fw_cl_get_client()
157 spin_unlock_irqrestore(&dev->fw_clients_lock, flags); in ishtp_fw_cl_get_client()
158 if (i < 0 || dev->fw_clients[i].props.fixed_address) in ishtp_fw_cl_get_client()
161 return &dev->fw_clients[i]; in ishtp_fw_cl_get_client()
166 * ishtp_get_fw_client_id() - Get fw client id
169 * This interface is used to reset HW get FW client id.
175 return fw_client->client_id; in ishtp_get_fw_client_id()
180 * ishtp_fw_cl_by_id() - return index to fw_clients for client_id
186 * Return: index on success, -ENOENT on failure.
190 int i, res = -ENOENT; in ishtp_fw_cl_by_id()
193 spin_lock_irqsave(&dev->fw_clients_lock, flags); in ishtp_fw_cl_by_id()
194 for (i = 0; i < dev->fw_clients_num; i++) { in ishtp_fw_cl_by_id()
195 if (dev->fw_clients[i].client_id == client_id) { in ishtp_fw_cl_by_id()
200 spin_unlock_irqrestore(&dev->fw_clients_lock, flags); in ishtp_fw_cl_by_id()
206 * ishtp_cl_device_probe() - Bus probe() callback
209 * This is a bus probe callback and calls the drive probe function.
211 * Return: Return value from driver probe() call.
221 driver = to_ishtp_cl_driver(dev->driver); in ishtp_cl_device_probe()
222 if (!driver || !driver->probe) in ishtp_cl_device_probe()
223 return -ENODEV; in ishtp_cl_device_probe()
225 return driver->probe(device); in ishtp_cl_device_probe()
229 * ishtp_cl_bus_match() - Bus match() callback
244 return(device->fw_client ? guid_equal(&driver->id[0].guid, in ishtp_cl_bus_match()
245 &device->fw_client->props.protocol_name) : 0); in ishtp_cl_bus_match()
249 * ishtp_cl_device_remove() - Bus remove() callback
261 struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver); in ishtp_cl_device_remove()
263 if (device->event_cb) { in ishtp_cl_device_remove()
264 device->event_cb = NULL; in ishtp_cl_device_remove()
265 cancel_work_sync(&device->event_work); in ishtp_cl_device_remove()
268 if (driver->remove) in ishtp_cl_device_remove()
269 driver->remove(device); in ishtp_cl_device_remove()
273 * ishtp_cl_device_suspend() - Bus suspend callback
289 driver = to_ishtp_cl_driver(dev->driver); in ishtp_cl_device_suspend()
290 if (driver && driver->driver.pm) { in ishtp_cl_device_suspend()
291 if (driver->driver.pm->suspend) in ishtp_cl_device_suspend()
292 ret = driver->driver.pm->suspend(dev); in ishtp_cl_device_suspend()
299 * ishtp_cl_device_resume() - Bus resume callback
315 driver = to_ishtp_cl_driver(dev->driver); in ishtp_cl_device_resume()
316 if (driver && driver->driver.pm) { in ishtp_cl_device_resume()
317 if (driver->driver.pm->resume) in ishtp_cl_device_resume()
318 ret = driver->driver.pm->resume(dev); in ishtp_cl_device_resume()
325 * ishtp_cl_device_reset() - Reset callback
328 * This is a callback when HW reset is done and the device need
331 * Return: Return value from driver reset() call.
338 device->event_cb = NULL; in ishtp_cl_device_reset()
339 cancel_work_sync(&device->event_work); in ishtp_cl_device_reset()
341 driver = to_ishtp_cl_driver(device->dev.driver); in ishtp_cl_device_reset()
342 if (driver && driver->reset) in ishtp_cl_device_reset()
343 ret = driver->reset(device); in ishtp_cl_device_reset()
354 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; in modalias_show()
367 return -ENOMEM; in ishtp_cl_uevent()
384 .probe = ishtp_cl_device_probe,
401 * ishtp_bus_add_device() - Function to create device on bus
418 spin_lock_irqsave(&dev->device_list_lock, flags); in ishtp_bus_add_device()
419 list_for_each_entry(device, &dev->device_list, device_link) { in ishtp_bus_add_device()
420 if (!strcmp(name, dev_name(&device->dev))) { in ishtp_bus_add_device()
421 device->fw_client = &dev->fw_clients[ in ishtp_bus_add_device()
422 dev->fw_client_presentation_num - 1]; in ishtp_bus_add_device()
423 spin_unlock_irqrestore(&dev->device_list_lock, flags); in ishtp_bus_add_device()
428 spin_unlock_irqrestore(&dev->device_list_lock, flags); in ishtp_bus_add_device()
434 device->dev.parent = dev->devc; in ishtp_bus_add_device()
435 device->dev.bus = &ishtp_cl_bus_type; in ishtp_bus_add_device()
436 device->dev.type = &ishtp_cl_device_type; in ishtp_bus_add_device()
437 device->ishtp_dev = dev; in ishtp_bus_add_device()
439 device->fw_client = in ishtp_bus_add_device()
440 &dev->fw_clients[dev->fw_client_presentation_num - 1]; in ishtp_bus_add_device()
442 dev_set_name(&device->dev, "%s", name); in ishtp_bus_add_device()
444 spin_lock_irqsave(&dev->device_list_lock, flags); in ishtp_bus_add_device()
445 list_add_tail(&device->device_link, &dev->device_list); in ishtp_bus_add_device()
446 spin_unlock_irqrestore(&dev->device_list_lock, flags); in ishtp_bus_add_device()
448 status = device_register(&device->dev); in ishtp_bus_add_device()
450 spin_lock_irqsave(&dev->device_list_lock, flags); in ishtp_bus_add_device()
451 list_del(&device->device_link); in ishtp_bus_add_device()
452 spin_unlock_irqrestore(&dev->device_list_lock, flags); in ishtp_bus_add_device()
453 dev_err(dev->devc, "Failed to register ISHTP client device\n"); in ishtp_bus_add_device()
454 put_device(&device->dev); in ishtp_bus_add_device()
464 * ishtp_bus_remove_device() - Function to relase device on bus
474 device_unregister(&device->dev); in ishtp_bus_remove_device()
478 * ishtp_cl_driver_register() - Client driver register
485 * Return: Return value of driver_register or -ENODEV if not ready
491 return -ENODEV; in ishtp_cl_driver_register()
493 driver->driver.name = driver->name; in ishtp_cl_driver_register()
494 driver->driver.owner = owner; in ishtp_cl_driver_register()
495 driver->driver.bus = &ishtp_cl_bus_type; in ishtp_cl_driver_register()
497 return driver_register(&driver->driver); in ishtp_cl_driver_register()
502 * ishtp_cl_driver_unregister() - Client driver unregister
509 driver_unregister(&driver->driver); in ishtp_cl_driver_unregister()
514 * ishtp_bus_event_work() - event work function
527 if (device->event_cb) in ishtp_bus_event_work()
528 device->event_cb(device); in ishtp_bus_event_work()
532 * ishtp_cl_bus_rx_event() - schedule event work
540 if (!device || !device->event_cb) in ishtp_cl_bus_rx_event()
543 if (device->event_cb) in ishtp_cl_bus_rx_event()
544 schedule_work(&device->event_work); in ishtp_cl_bus_rx_event()
548 * ishtp_register_event_cb() - Register callback
554 * Return: Return 0 or -EALREADY if already registered
559 if (device->event_cb) in ishtp_register_event_cb()
560 return -EALREADY; in ishtp_register_event_cb()
562 device->event_cb = event_cb; in ishtp_register_event_cb()
563 INIT_WORK(&device->event_work, ishtp_bus_event_work); in ishtp_register_event_cb()
570 * ishtp_get_device() - update usage count for the device
577 cl_device->reference_count++; in ishtp_get_device()
582 * ishtp_put_device() - decrement usage count for the device
589 cl_device->reference_count--; in ishtp_put_device()
594 * ishtp_set_drvdata() - set client driver data
598 * Set client driver data to cl_device->driver_data.
602 cl_device->driver_data = data; in ishtp_set_drvdata()
607 * ishtp_get_drvdata() - get client driver data
610 * Get client driver data from cl_device->driver_data.
616 return cl_device->driver_data; in ishtp_get_drvdata()
621 * ishtp_dev_to_cl_device() - get ishtp_cl_device instance from device instance
635 * ishtp_bus_new_client() - Create a new client
653 * If appropriate driver has loaded, this will trigger its probe(). in ishtp_bus_new_client()
654 * Otherwise, probe() will be called when driver is loaded in ishtp_bus_new_client()
656 i = dev->fw_client_presentation_num - 1; in ishtp_bus_new_client()
657 device_uuid = dev->fw_clients[i].props.protocol_name; in ishtp_bus_new_client()
660 return -ENOMEM; in ishtp_bus_new_client()
665 return -ENOENT; in ishtp_bus_new_client()
674 * ishtp_cl_device_bind() - bind a device
687 if (!cl->fw_client_id || cl->state != ISHTP_CL_CONNECTED) in ishtp_cl_device_bind()
688 return -EFAULT; in ishtp_cl_device_bind()
690 rv = -ENOENT; in ishtp_cl_device_bind()
691 spin_lock_irqsave(&cl->dev->device_list_lock, flags); in ishtp_cl_device_bind()
692 list_for_each_entry(cl_device, &cl->dev->device_list, in ishtp_cl_device_bind()
694 if (cl_device->fw_client && in ishtp_cl_device_bind()
695 cl_device->fw_client->client_id == cl->fw_client_id) { in ishtp_cl_device_bind()
696 cl->device = cl_device; in ishtp_cl_device_bind()
701 spin_unlock_irqrestore(&cl->dev->device_list_lock, flags); in ishtp_cl_device_bind()
706 * ishtp_bus_remove_all_clients() - Remove all clients
708 * @warm_reset: Reset due to FW reset dure to errors or S3 suspend
710 * This is part of reset/remove flow. This function the main processing
711 * only targets error processing, if the FW has forced reset or
712 * error to remove connected clients. When warm reset the client devices are
722 spin_lock_irqsave(&ishtp_dev->cl_list_lock, flags); in ishtp_bus_remove_all_clients()
723 list_for_each_entry(cl, &ishtp_dev->cl_list, link) { in ishtp_bus_remove_all_clients()
724 cl->state = ISHTP_CL_DISCONNECTED; in ishtp_bus_remove_all_clients()
727 * Wake any pending process. The waiter would check dev->state in ishtp_bus_remove_all_clients()
731 wake_up_interruptible(&cl->wait_ctrl_res); in ishtp_bus_remove_all_clients()
746 spin_unlock_irqrestore(&ishtp_dev->cl_list_lock, flags); in ishtp_bus_remove_all_clients()
752 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags); in ishtp_bus_remove_all_clients()
753 list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list, in ishtp_bus_remove_all_clients()
755 cl_device->fw_client = NULL; in ishtp_bus_remove_all_clients()
756 if (warm_reset && cl_device->reference_count) in ishtp_bus_remove_all_clients()
759 list_del(&cl_device->device_link); in ishtp_bus_remove_all_clients()
760 spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags); in ishtp_bus_remove_all_clients()
762 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags); in ishtp_bus_remove_all_clients()
764 spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags); in ishtp_bus_remove_all_clients()
767 spin_lock_irqsave(&ishtp_dev->fw_clients_lock, flags); in ishtp_bus_remove_all_clients()
768 kfree(ishtp_dev->fw_clients); in ishtp_bus_remove_all_clients()
769 ishtp_dev->fw_clients = NULL; in ishtp_bus_remove_all_clients()
770 ishtp_dev->fw_clients_num = 0; in ishtp_bus_remove_all_clients()
771 ishtp_dev->fw_client_presentation_num = 0; in ishtp_bus_remove_all_clients()
772 ishtp_dev->fw_client_index = 0; in ishtp_bus_remove_all_clients()
773 bitmap_zero(ishtp_dev->fw_clients_map, ISHTP_CLIENTS_MAX); in ishtp_bus_remove_all_clients()
774 spin_unlock_irqrestore(&ishtp_dev->fw_clients_lock, flags); in ishtp_bus_remove_all_clients()
779 * ishtp_reset_handler() - IPC reset handler
788 /* Handle FW-initiated reset */ in ishtp_reset_handler()
789 dev->dev_state = ISHTP_DEV_RESETTING; in ishtp_reset_handler()
791 /* Clear BH processing queue - no further HBMs */ in ishtp_reset_handler()
792 spin_lock_irqsave(&dev->rd_msg_spinlock, flags); in ishtp_reset_handler()
793 dev->rd_msg_fifo_head = dev->rd_msg_fifo_tail = 0; in ishtp_reset_handler()
794 spin_unlock_irqrestore(&dev->rd_msg_spinlock, flags); in ishtp_reset_handler()
796 /* Handle ISH FW reset against upper layers */ in ishtp_reset_handler()
802 * ishtp_reset_compl_handler() - Reset completion handler
810 dev->dev_state = ISHTP_DEV_INIT_CLIENTS; in ishtp_reset_compl_handler()
811 dev->hbm_state = ISHTP_HBM_START; in ishtp_reset_compl_handler()
817 * ishtp_use_dma_transfer() - Function to use DMA
829 * ishtp_device() - Return device pointer
830 * @device: ISH-TP client device instance
839 return &device->dev; in ishtp_device()
844 * ishtp_wait_resume() - Wait for IPC resume
856 if (dev->resume_flag) in ishtp_wait_resume()
857 wait_event_interruptible_timeout(dev->resume_wait, in ishtp_wait_resume()
858 !dev->resume_flag, in ishtp_wait_resume()
861 return (!dev->resume_flag); in ishtp_wait_resume()
866 * ishtp_get_pci_device() - Return PCI device dev pointer
869 * @device: ISH-TP client device instance
875 return device->ishtp_dev->devc; in ishtp_get_pci_device()
880 * ishtp_trace_callback() - Return trace callback
881 * @cl_device: ISH-TP client device instance
889 return cl_device->ishtp_dev->print_log; in ishtp_trace_callback()
894 * ish_hw_reset() - Call HW reset IPC callback
897 * This interface is used to reset HW in case of error.
903 return dev->ops->hw_reset(dev); in ish_hw_reset()
908 * ishtp_bus_register() - Function to register bus
920 * ishtp_bus_unregister() - Function to unregister bus