162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Initialization protocol for ISHTP driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2003-2016, Intel Corporation. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/export.h> 962306a36Sopenharmony_ci#include <linux/slab.h> 1062306a36Sopenharmony_ci#include <linux/sched.h> 1162306a36Sopenharmony_ci#include "ishtp-dev.h" 1262306a36Sopenharmony_ci#include "hbm.h" 1362306a36Sopenharmony_ci#include "client.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/** 1662306a36Sopenharmony_ci * ishtp_dev_state_str() -Convert to string format 1762306a36Sopenharmony_ci * @state: state to convert 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Convert state to string for prints 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * Return: character pointer to converted string 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ciconst char *ishtp_dev_state_str(int state) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci switch (state) { 2662306a36Sopenharmony_ci case ISHTP_DEV_INITIALIZING: 2762306a36Sopenharmony_ci return "INITIALIZING"; 2862306a36Sopenharmony_ci case ISHTP_DEV_INIT_CLIENTS: 2962306a36Sopenharmony_ci return "INIT_CLIENTS"; 3062306a36Sopenharmony_ci case ISHTP_DEV_ENABLED: 3162306a36Sopenharmony_ci return "ENABLED"; 3262306a36Sopenharmony_ci case ISHTP_DEV_RESETTING: 3362306a36Sopenharmony_ci return "RESETTING"; 3462306a36Sopenharmony_ci case ISHTP_DEV_DISABLED: 3562306a36Sopenharmony_ci return "DISABLED"; 3662306a36Sopenharmony_ci case ISHTP_DEV_POWER_DOWN: 3762306a36Sopenharmony_ci return "POWER_DOWN"; 3862306a36Sopenharmony_ci case ISHTP_DEV_POWER_UP: 3962306a36Sopenharmony_ci return "POWER_UP"; 4062306a36Sopenharmony_ci default: 4162306a36Sopenharmony_ci return "unknown"; 4262306a36Sopenharmony_ci } 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/** 4662306a36Sopenharmony_ci * ishtp_device_init() - ishtp device init 4762306a36Sopenharmony_ci * @dev: ISHTP device instance 4862306a36Sopenharmony_ci * 4962306a36Sopenharmony_ci * After ISHTP device is alloacted, this function is used to initialize 5062306a36Sopenharmony_ci * each field which includes spin lock, work struct and lists 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_civoid ishtp_device_init(struct ishtp_device *dev) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci dev->dev_state = ISHTP_DEV_INITIALIZING; 5562306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->cl_list); 5662306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->device_list); 5762306a36Sopenharmony_ci dev->rd_msg_fifo_head = 0; 5862306a36Sopenharmony_ci dev->rd_msg_fifo_tail = 0; 5962306a36Sopenharmony_ci spin_lock_init(&dev->rd_msg_spinlock); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci init_waitqueue_head(&dev->wait_hbm_recvd_msg); 6262306a36Sopenharmony_ci spin_lock_init(&dev->read_list_spinlock); 6362306a36Sopenharmony_ci spin_lock_init(&dev->device_lock); 6462306a36Sopenharmony_ci spin_lock_init(&dev->device_list_lock); 6562306a36Sopenharmony_ci spin_lock_init(&dev->cl_list_lock); 6662306a36Sopenharmony_ci spin_lock_init(&dev->fw_clients_lock); 6762306a36Sopenharmony_ci INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX); 7062306a36Sopenharmony_ci dev->open_handle_count = 0; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* 7362306a36Sopenharmony_ci * Reserving client ID 0 for ISHTP Bus Message communications 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_ci bitmap_set(dev->host_clients_map, 0, 1); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->read_list.list); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ciEXPORT_SYMBOL(ishtp_device_init); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/** 8362306a36Sopenharmony_ci * ishtp_start() - Start ISH processing 8462306a36Sopenharmony_ci * @dev: ISHTP device instance 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * Start ISHTP processing by sending query subscriber message 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * Return: 0 on success else -ENODEV 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_ciint ishtp_start(struct ishtp_device *dev) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci if (ishtp_hbm_start_wait(dev)) { 9362306a36Sopenharmony_ci dev_err(dev->devc, "HBM haven't started"); 9462306a36Sopenharmony_ci goto err; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci /* suspend & resume notification - send QUERY_SUBSCRIBERS msg */ 9862306a36Sopenharmony_ci ishtp_query_subscribers(dev); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci return 0; 10162306a36Sopenharmony_cierr: 10262306a36Sopenharmony_ci dev_err(dev->devc, "link layer initialization failed.\n"); 10362306a36Sopenharmony_ci dev->dev_state = ISHTP_DEV_DISABLED; 10462306a36Sopenharmony_ci return -ENODEV; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ciEXPORT_SYMBOL(ishtp_start); 107