1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Initialization protocol for ISHTP driver 4 * 5 * Copyright (c) 2003-2016, Intel Corporation. 6 */ 7 8 #include <linux/devm-helpers.h> 9 #include <linux/export.h> 10 #include <linux/slab.h> 11 #include <linux/sched.h> 12 #include "ishtp-dev.h" 13 #include "hbm.h" 14 #include "client.h" 15 #include "loader.h" 16 17 /** 18 * ishtp_dev_state_str() -Convert to string format 19 * @state: state to convert 20 * 21 * Convert state to string for prints 22 * 23 * Return: character pointer to converted string 24 */ 25 const char *ishtp_dev_state_str(int state) 26 { 27 switch (state) { 28 case ISHTP_DEV_INITIALIZING: 29 return "INITIALIZING"; 30 case ISHTP_DEV_INIT_CLIENTS: 31 return "INIT_CLIENTS"; 32 case ISHTP_DEV_ENABLED: 33 return "ENABLED"; 34 case ISHTP_DEV_RESETTING: 35 return "RESETTING"; 36 case ISHTP_DEV_DISABLED: 37 return "DISABLED"; 38 case ISHTP_DEV_POWER_DOWN: 39 return "POWER_DOWN"; 40 case ISHTP_DEV_POWER_UP: 41 return "POWER_UP"; 42 default: 43 return "unknown"; 44 } 45 } 46 47 /** 48 * ishtp_device_init() - ishtp device init 49 * @dev: ISHTP device instance 50 * 51 * After ISHTP device is alloacted, this function is used to initialize 52 * each field which includes spin lock, work struct and lists 53 */ 54 void ishtp_device_init(struct ishtp_device *dev) 55 { 56 int ret; 57 58 dev->dev_state = ISHTP_DEV_INITIALIZING; 59 INIT_LIST_HEAD(&dev->cl_list); 60 INIT_LIST_HEAD(&dev->device_list); 61 dev->rd_msg_fifo_head = 0; 62 dev->rd_msg_fifo_tail = 0; 63 spin_lock_init(&dev->rd_msg_spinlock); 64 65 init_waitqueue_head(&dev->wait_hbm_recvd_msg); 66 init_waitqueue_head(&dev->wait_loader_recvd_msg); 67 spin_lock_init(&dev->read_list_spinlock); 68 spin_lock_init(&dev->device_lock); 69 spin_lock_init(&dev->device_list_lock); 70 spin_lock_init(&dev->cl_list_lock); 71 spin_lock_init(&dev->fw_clients_lock); 72 INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn); 73 74 bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX); 75 dev->open_handle_count = 0; 76 77 /* 78 * Reserving client ID 0 for ISHTP Bus Message communications 79 */ 80 bitmap_set(dev->host_clients_map, 0, 1); 81 82 INIT_LIST_HEAD(&dev->read_list.list); 83 84 ret = devm_work_autocancel(dev->devc, &dev->work_fw_loader, ishtp_loader_work); 85 if (ret) 86 dev_err_probe(dev->devc, ret, "Failed to initialise FW loader work\n"); 87 } 88 EXPORT_SYMBOL(ishtp_device_init); 89 90 /** 91 * ishtp_start() - Start ISH processing 92 * @dev: ISHTP device instance 93 * 94 * Start ISHTP processing by sending query subscriber message 95 * 96 * Return: 0 on success else -ENODEV 97 */ 98 int ishtp_start(struct ishtp_device *dev) 99 { 100 if (ishtp_hbm_start_wait(dev)) { 101 dev_err(dev->devc, "HBM haven't started"); 102 goto err; 103 } 104 105 /* suspend & resume notification - send QUERY_SUBSCRIBERS msg */ 106 ishtp_query_subscribers(dev); 107 108 return 0; 109 err: 110 dev_err(dev->devc, "link layer initialization failed.\n"); 111 dev->dev_state = ISHTP_DEV_DISABLED; 112 return -ENODEV; 113 } 114 EXPORT_SYMBOL(ishtp_start); 115