xref: /openbmc/linux/drivers/hid/intel-ish-hid/ishtp/init.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*2025cf9eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
23703f53bSSrinivas Pandruvada /*
33703f53bSSrinivas Pandruvada  * Initialization protocol for ISHTP driver
43703f53bSSrinivas Pandruvada  *
53703f53bSSrinivas Pandruvada  * Copyright (c) 2003-2016, Intel Corporation.
63703f53bSSrinivas Pandruvada  */
73703f53bSSrinivas Pandruvada 
83703f53bSSrinivas Pandruvada #include <linux/export.h>
93703f53bSSrinivas Pandruvada #include <linux/slab.h>
103703f53bSSrinivas Pandruvada #include <linux/sched.h>
113703f53bSSrinivas Pandruvada #include "ishtp-dev.h"
123703f53bSSrinivas Pandruvada #include "hbm.h"
133703f53bSSrinivas Pandruvada #include "client.h"
143703f53bSSrinivas Pandruvada 
153703f53bSSrinivas Pandruvada /**
163703f53bSSrinivas Pandruvada  * ishtp_dev_state_str() -Convert to string format
173703f53bSSrinivas Pandruvada  * @state: state to convert
183703f53bSSrinivas Pandruvada  *
193703f53bSSrinivas Pandruvada  * Convert state to string for prints
203703f53bSSrinivas Pandruvada  *
213703f53bSSrinivas Pandruvada  * Return: character pointer to converted string
223703f53bSSrinivas Pandruvada  */
ishtp_dev_state_str(int state)233703f53bSSrinivas Pandruvada const char *ishtp_dev_state_str(int state)
243703f53bSSrinivas Pandruvada {
253703f53bSSrinivas Pandruvada 	switch (state) {
263703f53bSSrinivas Pandruvada 	case ISHTP_DEV_INITIALIZING:
273703f53bSSrinivas Pandruvada 		return	"INITIALIZING";
283703f53bSSrinivas Pandruvada 	case ISHTP_DEV_INIT_CLIENTS:
293703f53bSSrinivas Pandruvada 		return	"INIT_CLIENTS";
303703f53bSSrinivas Pandruvada 	case ISHTP_DEV_ENABLED:
313703f53bSSrinivas Pandruvada 		return	"ENABLED";
323703f53bSSrinivas Pandruvada 	case ISHTP_DEV_RESETTING:
333703f53bSSrinivas Pandruvada 		return	"RESETTING";
343703f53bSSrinivas Pandruvada 	case ISHTP_DEV_DISABLED:
353703f53bSSrinivas Pandruvada 		return	"DISABLED";
363703f53bSSrinivas Pandruvada 	case ISHTP_DEV_POWER_DOWN:
373703f53bSSrinivas Pandruvada 		return	"POWER_DOWN";
383703f53bSSrinivas Pandruvada 	case ISHTP_DEV_POWER_UP:
393703f53bSSrinivas Pandruvada 		return	"POWER_UP";
403703f53bSSrinivas Pandruvada 	default:
413703f53bSSrinivas Pandruvada 		return "unknown";
423703f53bSSrinivas Pandruvada 	}
433703f53bSSrinivas Pandruvada }
443703f53bSSrinivas Pandruvada 
453703f53bSSrinivas Pandruvada /**
463703f53bSSrinivas Pandruvada  * ishtp_device_init() - ishtp device init
473703f53bSSrinivas Pandruvada  * @dev: ISHTP device instance
483703f53bSSrinivas Pandruvada  *
493703f53bSSrinivas Pandruvada  * After ISHTP device is alloacted, this function is used to initialize
503703f53bSSrinivas Pandruvada  * each field which includes spin lock, work struct and lists
513703f53bSSrinivas Pandruvada  */
ishtp_device_init(struct ishtp_device * dev)523703f53bSSrinivas Pandruvada void ishtp_device_init(struct ishtp_device *dev)
533703f53bSSrinivas Pandruvada {
543703f53bSSrinivas Pandruvada 	dev->dev_state = ISHTP_DEV_INITIALIZING;
553703f53bSSrinivas Pandruvada 	INIT_LIST_HEAD(&dev->cl_list);
563703f53bSSrinivas Pandruvada 	INIT_LIST_HEAD(&dev->device_list);
573703f53bSSrinivas Pandruvada 	dev->rd_msg_fifo_head = 0;
583703f53bSSrinivas Pandruvada 	dev->rd_msg_fifo_tail = 0;
593703f53bSSrinivas Pandruvada 	spin_lock_init(&dev->rd_msg_spinlock);
603703f53bSSrinivas Pandruvada 
613703f53bSSrinivas Pandruvada 	init_waitqueue_head(&dev->wait_hbm_recvd_msg);
623703f53bSSrinivas Pandruvada 	spin_lock_init(&dev->read_list_spinlock);
633703f53bSSrinivas Pandruvada 	spin_lock_init(&dev->device_lock);
643703f53bSSrinivas Pandruvada 	spin_lock_init(&dev->device_list_lock);
653703f53bSSrinivas Pandruvada 	spin_lock_init(&dev->cl_list_lock);
663703f53bSSrinivas Pandruvada 	spin_lock_init(&dev->fw_clients_lock);
673703f53bSSrinivas Pandruvada 	INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn);
683703f53bSSrinivas Pandruvada 
693703f53bSSrinivas Pandruvada 	bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX);
703703f53bSSrinivas Pandruvada 	dev->open_handle_count = 0;
713703f53bSSrinivas Pandruvada 
723703f53bSSrinivas Pandruvada 	/*
733703f53bSSrinivas Pandruvada 	 * Reserving client ID 0 for ISHTP Bus Message communications
743703f53bSSrinivas Pandruvada 	 */
753703f53bSSrinivas Pandruvada 	bitmap_set(dev->host_clients_map, 0, 1);
763703f53bSSrinivas Pandruvada 
773703f53bSSrinivas Pandruvada 	INIT_LIST_HEAD(&dev->read_list.list);
783703f53bSSrinivas Pandruvada 
793703f53bSSrinivas Pandruvada }
803703f53bSSrinivas Pandruvada EXPORT_SYMBOL(ishtp_device_init);
813703f53bSSrinivas Pandruvada 
823703f53bSSrinivas Pandruvada /**
833703f53bSSrinivas Pandruvada  * ishtp_start() - Start ISH processing
843703f53bSSrinivas Pandruvada  * @dev: ISHTP device instance
853703f53bSSrinivas Pandruvada  *
863703f53bSSrinivas Pandruvada  * Start ISHTP processing by sending query subscriber message
873703f53bSSrinivas Pandruvada  *
883703f53bSSrinivas Pandruvada  * Return: 0 on success else -ENODEV
893703f53bSSrinivas Pandruvada  */
ishtp_start(struct ishtp_device * dev)903703f53bSSrinivas Pandruvada int ishtp_start(struct ishtp_device *dev)
913703f53bSSrinivas Pandruvada {
923703f53bSSrinivas Pandruvada 	if (ishtp_hbm_start_wait(dev)) {
933703f53bSSrinivas Pandruvada 		dev_err(dev->devc, "HBM haven't started");
943703f53bSSrinivas Pandruvada 		goto err;
953703f53bSSrinivas Pandruvada 	}
963703f53bSSrinivas Pandruvada 
973703f53bSSrinivas Pandruvada 	/* suspend & resume notification - send QUERY_SUBSCRIBERS msg */
983703f53bSSrinivas Pandruvada 	ishtp_query_subscribers(dev);
993703f53bSSrinivas Pandruvada 
1003703f53bSSrinivas Pandruvada 	return 0;
1013703f53bSSrinivas Pandruvada err:
1023703f53bSSrinivas Pandruvada 	dev_err(dev->devc, "link layer initialization failed.\n");
1033703f53bSSrinivas Pandruvada 	dev->dev_state = ISHTP_DEV_DISABLED;
1043703f53bSSrinivas Pandruvada 	return -ENODEV;
1053703f53bSSrinivas Pandruvada }
1063703f53bSSrinivas Pandruvada EXPORT_SYMBOL(ishtp_start);
107