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