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