xref: /openbmc/linux/drivers/hid/intel-ish-hid/ipc/ipc.c (revision 943126417891372d56aa3fe46295cbf53db31370)
1 /*
2  * H/W layer of ISHTP provider device (ISH)
3  *
4  * Copyright (c) 2014-2016, Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  */
15 
16 #include <linux/sched.h>
17 #include <linux/spinlock.h>
18 #include <linux/delay.h>
19 #include <linux/jiffies.h>
20 #include "client.h"
21 #include "hw-ish.h"
22 #include "hbm.h"
23 
24 /* For FW reset flow */
25 static struct work_struct fw_reset_work;
26 static struct ishtp_device *ishtp_dev;
27 
28 /**
29  * ish_reg_read() - Read register
30  * @dev: ISHTP device pointer
31  * @offset: Register offset
32  *
33  * Read 32 bit register at a given offset
34  *
35  * Return: Read register value
36  */
37 static inline uint32_t ish_reg_read(const struct ishtp_device *dev,
38 	unsigned long offset)
39 {
40 	struct ish_hw *hw = to_ish_hw(dev);
41 
42 	return readl(hw->mem_addr + offset);
43 }
44 
45 /**
46  * ish_reg_write() - Write register
47  * @dev: ISHTP device pointer
48  * @offset: Register offset
49  * @value: Value to write
50  *
51  * Writes 32 bit register at a give offset
52  */
53 static inline void ish_reg_write(struct ishtp_device *dev,
54 				 unsigned long offset,
55 				 uint32_t value)
56 {
57 	struct ish_hw *hw = to_ish_hw(dev);
58 
59 	writel(value, hw->mem_addr + offset);
60 }
61 
62 /**
63  * _ish_read_fw_sts_reg() - Read FW status register
64  * @dev: ISHTP device pointer
65  *
66  * Read FW status register
67  *
68  * Return: Read register value
69  */
70 static inline uint32_t _ish_read_fw_sts_reg(struct ishtp_device *dev)
71 {
72 	return ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
73 }
74 
75 /**
76  * check_generated_interrupt() - Check if ISH interrupt
77  * @dev: ISHTP device pointer
78  *
79  * Check if an interrupt was generated for ISH
80  *
81  * Return: Read true or false
82  */
83 static bool check_generated_interrupt(struct ishtp_device *dev)
84 {
85 	bool interrupt_generated = true;
86 	uint32_t pisr_val = 0;
87 
88 	if (dev->pdev->device == CHV_DEVICE_ID) {
89 		pisr_val = ish_reg_read(dev, IPC_REG_PISR_CHV_AB);
90 		interrupt_generated =
91 			IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val);
92 	} else {
93 		pisr_val = ish_reg_read(dev, IPC_REG_PISR_BXT);
94 		interrupt_generated = IPC_INT_FROM_ISH_TO_HOST_BXT(pisr_val);
95 	}
96 
97 	return interrupt_generated;
98 }
99 
100 /**
101  * ish_is_input_ready() - Check if FW ready for RX
102  * @dev: ISHTP device pointer
103  *
104  * Check if ISH FW is ready for receiving data
105  *
106  * Return: Read true or false
107  */
108 static bool ish_is_input_ready(struct ishtp_device *dev)
109 {
110 	uint32_t doorbell_val;
111 
112 	doorbell_val = ish_reg_read(dev, IPC_REG_HOST2ISH_DRBL);
113 	return !IPC_IS_BUSY(doorbell_val);
114 }
115 
116 /**
117  * set_host_ready() - Indicate host ready
118  * @dev: ISHTP device pointer
119  *
120  * Set host ready indication to FW
121  */
122 static void set_host_ready(struct ishtp_device *dev)
123 {
124 	if (dev->pdev->device == CHV_DEVICE_ID) {
125 		if (dev->pdev->revision == REVISION_ID_CHT_A0 ||
126 				(dev->pdev->revision & REVISION_ID_SI_MASK) ==
127 				REVISION_ID_CHT_Ax_SI)
128 			ish_reg_write(dev, IPC_REG_HOST_COMM, 0x81);
129 		else if (dev->pdev->revision == REVISION_ID_CHT_B0 ||
130 				(dev->pdev->revision & REVISION_ID_SI_MASK) ==
131 				REVISION_ID_CHT_Bx_SI ||
132 				(dev->pdev->revision & REVISION_ID_SI_MASK) ==
133 				REVISION_ID_CHT_Kx_SI ||
134 				(dev->pdev->revision & REVISION_ID_SI_MASK) ==
135 				REVISION_ID_CHT_Dx_SI) {
136 			uint32_t host_comm_val;
137 
138 			host_comm_val = ish_reg_read(dev, IPC_REG_HOST_COMM);
139 			host_comm_val |= IPC_HOSTCOMM_INT_EN_BIT_CHV_AB | 0x81;
140 			ish_reg_write(dev, IPC_REG_HOST_COMM, host_comm_val);
141 		}
142 	} else {
143 			uint32_t host_pimr_val;
144 
145 			host_pimr_val = ish_reg_read(dev, IPC_REG_PIMR_BXT);
146 			host_pimr_val |= IPC_PIMR_INT_EN_BIT_BXT;
147 			/*
148 			 * disable interrupt generated instead of
149 			 * RX_complete_msg
150 			 */
151 			host_pimr_val &= ~IPC_HOST2ISH_BUSYCLEAR_MASK_BIT;
152 
153 			ish_reg_write(dev, IPC_REG_PIMR_BXT, host_pimr_val);
154 	}
155 }
156 
157 /**
158  * ishtp_fw_is_ready() - Check if FW ready
159  * @dev: ISHTP device pointer
160  *
161  * Check if ISH FW is ready
162  *
163  * Return: Read true or false
164  */
165 static bool ishtp_fw_is_ready(struct ishtp_device *dev)
166 {
167 	uint32_t ish_status = _ish_read_fw_sts_reg(dev);
168 
169 	return IPC_IS_ISH_ILUP(ish_status) &&
170 		IPC_IS_ISH_ISHTP_READY(ish_status);
171 }
172 
173 /**
174  * ish_set_host_rdy() - Indicate host ready
175  * @dev: ISHTP device pointer
176  *
177  * Set host ready indication to FW
178  */
179 static void ish_set_host_rdy(struct ishtp_device *dev)
180 {
181 	uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM);
182 
183 	IPC_SET_HOST_READY(host_status);
184 	ish_reg_write(dev, IPC_REG_HOST_COMM, host_status);
185 }
186 
187 /**
188  * ish_clr_host_rdy() - Indicate host not ready
189  * @dev: ISHTP device pointer
190  *
191  * Send host not ready indication to FW
192  */
193 static void ish_clr_host_rdy(struct ishtp_device *dev)
194 {
195 	uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM);
196 
197 	IPC_CLEAR_HOST_READY(host_status);
198 	ish_reg_write(dev, IPC_REG_HOST_COMM, host_status);
199 }
200 
201 /**
202  * _ishtp_read_hdr() - Read message header
203  * @dev: ISHTP device pointer
204  *
205  * Read header of 32bit length
206  *
207  * Return: Read register value
208  */
209 static uint32_t _ishtp_read_hdr(const struct ishtp_device *dev)
210 {
211 	return ish_reg_read(dev, IPC_REG_ISH2HOST_MSG);
212 }
213 
214 /**
215  * _ishtp_read - Read message
216  * @dev: ISHTP device pointer
217  * @buffer: message buffer
218  * @buffer_length: length of message buffer
219  *
220  * Read message from FW
221  *
222  * Return: Always 0
223  */
224 static int _ishtp_read(struct ishtp_device *dev, unsigned char *buffer,
225 	unsigned long buffer_length)
226 {
227 	uint32_t	i;
228 	uint32_t	*r_buf = (uint32_t *)buffer;
229 	uint32_t	msg_offs;
230 
231 	msg_offs = IPC_REG_ISH2HOST_MSG + sizeof(struct ishtp_msg_hdr);
232 	for (i = 0; i < buffer_length; i += sizeof(uint32_t))
233 		*r_buf++ = ish_reg_read(dev, msg_offs + i);
234 
235 	return 0;
236 }
237 
238 /**
239  * write_ipc_from_queue() - try to write ipc msg from Tx queue to device
240  * @dev: ishtp device pointer
241  *
242  * Check if DRBL is cleared. if it is - write the first IPC msg,  then call
243  * the callback function (unless it's NULL)
244  *
245  * Return: 0 for success else failure code
246  */
247 static int write_ipc_from_queue(struct ishtp_device *dev)
248 {
249 	struct wr_msg_ctl_info	*ipc_link;
250 	unsigned long	length;
251 	unsigned long	rem;
252 	unsigned long	flags;
253 	uint32_t	doorbell_val;
254 	uint32_t	*r_buf;
255 	uint32_t	reg_addr;
256 	int	i;
257 	void	(*ipc_send_compl)(void *);
258 	void	*ipc_send_compl_prm;
259 	static int	out_ipc_locked;
260 	unsigned long	out_ipc_flags;
261 
262 	if (dev->dev_state == ISHTP_DEV_DISABLED)
263 		return	-EINVAL;
264 
265 	spin_lock_irqsave(&dev->out_ipc_spinlock, out_ipc_flags);
266 	if (out_ipc_locked) {
267 		spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
268 		return -EBUSY;
269 	}
270 	out_ipc_locked = 1;
271 	if (!ish_is_input_ready(dev)) {
272 		out_ipc_locked = 0;
273 		spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
274 		return -EBUSY;
275 	}
276 	spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
277 
278 	spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
279 	/*
280 	 * if tx send list is empty - return 0;
281 	 * may happen, as RX_COMPLETE handler doesn't check list emptiness.
282 	 */
283 	if (list_empty(&dev->wr_processing_list)) {
284 		spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
285 		out_ipc_locked = 0;
286 		return	0;
287 	}
288 
289 	ipc_link = list_first_entry(&dev->wr_processing_list,
290 				    struct wr_msg_ctl_info, link);
291 	/* first 4 bytes of the data is the doorbell value (IPC header) */
292 	length = ipc_link->length - sizeof(uint32_t);
293 	doorbell_val = *(uint32_t *)ipc_link->inline_data;
294 	r_buf = (uint32_t *)(ipc_link->inline_data + sizeof(uint32_t));
295 
296 	/* If sending MNG_SYNC_FW_CLOCK, update clock again */
297 	if (IPC_HEADER_GET_PROTOCOL(doorbell_val) == IPC_PROTOCOL_MNG &&
298 		IPC_HEADER_GET_MNG_CMD(doorbell_val) == MNG_SYNC_FW_CLOCK) {
299 		uint64_t usec_system, usec_utc;
300 		struct ipc_time_update_msg time_update;
301 		struct time_sync_format ts_format;
302 
303 		usec_system = ktime_to_us(ktime_get_boottime());
304 		usec_utc = ktime_to_us(ktime_get_real());
305 		ts_format.ts1_source = HOST_SYSTEM_TIME_USEC;
306 		ts_format.ts2_source = HOST_UTC_TIME_USEC;
307 		ts_format.reserved = 0;
308 
309 		time_update.primary_host_time = usec_system;
310 		time_update.secondary_host_time = usec_utc;
311 		time_update.sync_info = ts_format;
312 
313 		memcpy(r_buf, &time_update,
314 		       sizeof(struct ipc_time_update_msg));
315 	}
316 
317 	for (i = 0, reg_addr = IPC_REG_HOST2ISH_MSG; i < length >> 2; i++,
318 			reg_addr += 4)
319 		ish_reg_write(dev, reg_addr, r_buf[i]);
320 
321 	rem = length & 0x3;
322 	if (rem > 0) {
323 		uint32_t reg = 0;
324 
325 		memcpy(&reg, &r_buf[length >> 2], rem);
326 		ish_reg_write(dev, reg_addr, reg);
327 	}
328 	/* Flush writes to msg registers and doorbell */
329 	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
330 
331 	/* Update IPC counters */
332 	++dev->ipc_tx_cnt;
333 	dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val);
334 
335 	ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val);
336 	out_ipc_locked = 0;
337 
338 	ipc_send_compl = ipc_link->ipc_send_compl;
339 	ipc_send_compl_prm = ipc_link->ipc_send_compl_prm;
340 	list_del_init(&ipc_link->link);
341 	list_add(&ipc_link->link, &dev->wr_free_list);
342 	spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
343 
344 	/*
345 	 * callback will be called out of spinlock,
346 	 * after ipc_link returned to free list
347 	 */
348 	if (ipc_send_compl)
349 		ipc_send_compl(ipc_send_compl_prm);
350 
351 	return 0;
352 }
353 
354 /**
355  * write_ipc_to_queue() - write ipc msg to Tx queue
356  * @dev: ishtp device instance
357  * @ipc_send_compl: Send complete callback
358  * @ipc_send_compl_prm:	Parameter to send in complete callback
359  * @msg: Pointer to message
360  * @length: Length of message
361  *
362  * Recived msg with IPC (and upper protocol) header  and add it to the device
363  *  Tx-to-write list then try to send the first IPC waiting msg
364  *  (if DRBL is cleared)
365  * This function returns negative value for failure (means free list
366  *  is empty, or msg too long) and 0 for success.
367  *
368  * Return: 0 for success else failure code
369  */
370 static int write_ipc_to_queue(struct ishtp_device *dev,
371 	void (*ipc_send_compl)(void *), void *ipc_send_compl_prm,
372 	unsigned char *msg, int length)
373 {
374 	struct wr_msg_ctl_info *ipc_link;
375 	unsigned long flags;
376 
377 	if (length > IPC_FULL_MSG_SIZE)
378 		return -EMSGSIZE;
379 
380 	spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
381 	if (list_empty(&dev->wr_free_list)) {
382 		spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
383 		return -ENOMEM;
384 	}
385 	ipc_link = list_first_entry(&dev->wr_free_list,
386 				    struct wr_msg_ctl_info, link);
387 	list_del_init(&ipc_link->link);
388 
389 	ipc_link->ipc_send_compl = ipc_send_compl;
390 	ipc_link->ipc_send_compl_prm = ipc_send_compl_prm;
391 	ipc_link->length = length;
392 	memcpy(ipc_link->inline_data, msg, length);
393 
394 	list_add_tail(&ipc_link->link, &dev->wr_processing_list);
395 	spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
396 
397 	write_ipc_from_queue(dev);
398 
399 	return 0;
400 }
401 
402 /**
403  * ipc_send_mng_msg() - Send management message
404  * @dev: ishtp device instance
405  * @msg_code: Message code
406  * @msg: Pointer to message
407  * @size: Length of message
408  *
409  * Send management message to FW
410  *
411  * Return: 0 for success else failure code
412  */
413 static int ipc_send_mng_msg(struct ishtp_device *dev, uint32_t msg_code,
414 	void *msg, size_t size)
415 {
416 	unsigned char	ipc_msg[IPC_FULL_MSG_SIZE];
417 	uint32_t	drbl_val = IPC_BUILD_MNG_MSG(msg_code, size);
418 
419 	memcpy(ipc_msg, &drbl_val, sizeof(uint32_t));
420 	memcpy(ipc_msg + sizeof(uint32_t), msg, size);
421 	return	write_ipc_to_queue(dev, NULL, NULL, ipc_msg,
422 		sizeof(uint32_t) + size);
423 }
424 
425 #define WAIT_FOR_FW_RDY			0x1
426 #define WAIT_FOR_INPUT_RDY		0x2
427 
428 /**
429  * timed_wait_for_timeout() - wait special event with timeout
430  * @dev: ISHTP device pointer
431  * @condition: indicate the condition for waiting
432  * @timeinc: time slice for every wait cycle, in ms
433  * @timeout: time in ms for timeout
434  *
435  * This function will check special event to be ready in a loop, the loop
436  * period is specificd in timeinc. Wait timeout will causes failure.
437  *
438  * Return: 0 for success else failure code
439  */
440 static int timed_wait_for_timeout(struct ishtp_device *dev, int condition,
441 				unsigned int timeinc, unsigned int timeout)
442 {
443 	bool complete = false;
444 	int ret;
445 
446 	do {
447 		if (condition == WAIT_FOR_FW_RDY) {
448 			complete = ishtp_fw_is_ready(dev);
449 		} else if (condition == WAIT_FOR_INPUT_RDY) {
450 			complete = ish_is_input_ready(dev);
451 		} else {
452 			ret = -EINVAL;
453 			goto out;
454 		}
455 
456 		if (!complete) {
457 			unsigned long left_time;
458 
459 			left_time = msleep_interruptible(timeinc);
460 			timeout -= (timeinc - left_time);
461 		}
462 	} while (!complete && timeout > 0);
463 
464 	if (complete)
465 		ret = 0;
466 	else
467 		ret = -EBUSY;
468 
469 out:
470 	return ret;
471 }
472 
473 #define TIME_SLICE_FOR_FW_RDY_MS		100
474 #define TIME_SLICE_FOR_INPUT_RDY_MS		100
475 #define TIMEOUT_FOR_FW_RDY_MS			2000
476 #define TIMEOUT_FOR_INPUT_RDY_MS		2000
477 
478 /**
479  * ish_fw_reset_handler() - FW reset handler
480  * @dev: ishtp device pointer
481  *
482  * Handle FW reset
483  *
484  * Return: 0 for success else failure code
485  */
486 static int ish_fw_reset_handler(struct ishtp_device *dev)
487 {
488 	uint32_t	reset_id;
489 	unsigned long	flags;
490 
491 	/* Read reset ID */
492 	reset_id = ish_reg_read(dev, IPC_REG_ISH2HOST_MSG) & 0xFFFF;
493 
494 	/* Clear IPC output queue */
495 	spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
496 	list_splice_init(&dev->wr_processing_list, &dev->wr_free_list);
497 	spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
498 
499 	/* ISHTP notification in IPC_RESET */
500 	ishtp_reset_handler(dev);
501 
502 	if (!ish_is_input_ready(dev))
503 		timed_wait_for_timeout(dev, WAIT_FOR_INPUT_RDY,
504 			TIME_SLICE_FOR_INPUT_RDY_MS, TIMEOUT_FOR_INPUT_RDY_MS);
505 
506 	/* ISH FW is dead */
507 	if (!ish_is_input_ready(dev))
508 		return	-EPIPE;
509 	/*
510 	 * Set HOST2ISH.ILUP. Apparently we need this BEFORE sending
511 	 * RESET_NOTIFY_ACK - FW will be checking for it
512 	 */
513 	ish_set_host_rdy(dev);
514 	/* Send RESET_NOTIFY_ACK (with reset_id) */
515 	ipc_send_mng_msg(dev, MNG_RESET_NOTIFY_ACK, &reset_id,
516 			 sizeof(uint32_t));
517 
518 	/* Wait for ISH FW'es ILUP and ISHTP_READY */
519 	timed_wait_for_timeout(dev, WAIT_FOR_FW_RDY,
520 			TIME_SLICE_FOR_FW_RDY_MS, TIMEOUT_FOR_FW_RDY_MS);
521 	if (!ishtp_fw_is_ready(dev)) {
522 		/* ISH FW is dead */
523 		uint32_t	ish_status;
524 
525 		ish_status = _ish_read_fw_sts_reg(dev);
526 		dev_err(dev->devc,
527 			"[ishtp-ish]: completed reset, ISH is dead (FWSTS = %08X)\n",
528 			ish_status);
529 		return -ENODEV;
530 	}
531 	return	0;
532 }
533 
534 #define TIMEOUT_FOR_HW_RDY_MS			300
535 
536 /**
537  * ish_fw_reset_work_fn() - FW reset worker function
538  * @unused: not used
539  *
540  * Call ish_fw_reset_handler to complete FW reset
541  */
542 static void fw_reset_work_fn(struct work_struct *unused)
543 {
544 	int	rv;
545 
546 	rv = ish_fw_reset_handler(ishtp_dev);
547 	if (!rv) {
548 		/* ISH is ILUP & ISHTP-ready. Restart ISHTP */
549 		msleep_interruptible(TIMEOUT_FOR_HW_RDY_MS);
550 		ishtp_dev->recvd_hw_ready = 1;
551 		wake_up_interruptible(&ishtp_dev->wait_hw_ready);
552 
553 		/* ISHTP notification in IPC_RESET sequence completion */
554 		ishtp_reset_compl_handler(ishtp_dev);
555 	} else
556 		dev_err(ishtp_dev->devc, "[ishtp-ish]: FW reset failed (%d)\n",
557 			rv);
558 }
559 
560 /**
561  * _ish_sync_fw_clock() -Sync FW clock with the OS clock
562  * @dev: ishtp device pointer
563  *
564  * Sync FW and OS time
565  */
566 static void _ish_sync_fw_clock(struct ishtp_device *dev)
567 {
568 	static unsigned long	prev_sync;
569 	uint64_t	usec;
570 
571 	if (prev_sync && jiffies - prev_sync < 20 * HZ)
572 		return;
573 
574 	prev_sync = jiffies;
575 	usec = ktime_to_us(ktime_get_boottime());
576 	ipc_send_mng_msg(dev, MNG_SYNC_FW_CLOCK, &usec, sizeof(uint64_t));
577 }
578 
579 /**
580  * recv_ipc() - Receive and process IPC management messages
581  * @dev: ishtp device instance
582  * @doorbell_val: doorbell value
583  *
584  * This function runs in ISR context.
585  * NOTE: Any other mng command than reset_notify and reset_notify_ack
586  * won't wake BH handler
587  */
588 static void	recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val)
589 {
590 	uint32_t	mng_cmd;
591 
592 	mng_cmd = IPC_HEADER_GET_MNG_CMD(doorbell_val);
593 
594 	switch (mng_cmd) {
595 	default:
596 		break;
597 
598 	case MNG_RX_CMPL_INDICATION:
599 		if (dev->suspend_flag) {
600 			dev->suspend_flag = 0;
601 			wake_up_interruptible(&dev->suspend_wait);
602 		}
603 		if (dev->resume_flag) {
604 			dev->resume_flag = 0;
605 			wake_up_interruptible(&dev->resume_wait);
606 		}
607 
608 		write_ipc_from_queue(dev);
609 		break;
610 
611 	case MNG_RESET_NOTIFY:
612 		if (!ishtp_dev) {
613 			ishtp_dev = dev;
614 			INIT_WORK(&fw_reset_work, fw_reset_work_fn);
615 		}
616 		schedule_work(&fw_reset_work);
617 		break;
618 
619 	case MNG_RESET_NOTIFY_ACK:
620 		dev->recvd_hw_ready = 1;
621 		wake_up_interruptible(&dev->wait_hw_ready);
622 		break;
623 	}
624 }
625 
626 /**
627  * ish_irq_handler() - ISH IRQ handler
628  * @irq: irq number
629  * @dev_id: ishtp device pointer
630  *
631  * ISH IRQ handler. If interrupt is generated and is for ISH it will process
632  * the interrupt.
633  */
634 irqreturn_t ish_irq_handler(int irq, void *dev_id)
635 {
636 	struct ishtp_device	*dev = dev_id;
637 	uint32_t	doorbell_val;
638 	bool	interrupt_generated;
639 
640 	/* Check that it's interrupt from ISH (may be shared) */
641 	interrupt_generated = check_generated_interrupt(dev);
642 
643 	if (!interrupt_generated)
644 		return IRQ_NONE;
645 
646 	doorbell_val = ish_reg_read(dev, IPC_REG_ISH2HOST_DRBL);
647 	if (!IPC_IS_BUSY(doorbell_val))
648 		return IRQ_HANDLED;
649 
650 	if (dev->dev_state == ISHTP_DEV_DISABLED)
651 		return	IRQ_HANDLED;
652 
653 	/* Sanity check: IPC dgram length in header */
654 	if (IPC_HEADER_GET_LENGTH(doorbell_val) > IPC_PAYLOAD_SIZE) {
655 		dev_err(dev->devc,
656 			"IPC hdr - bad length: %u; dropped\n",
657 			(unsigned int)IPC_HEADER_GET_LENGTH(doorbell_val));
658 		goto	eoi;
659 	}
660 
661 	switch (IPC_HEADER_GET_PROTOCOL(doorbell_val)) {
662 	default:
663 		break;
664 	case IPC_PROTOCOL_MNG:
665 		recv_ipc(dev, doorbell_val);
666 		break;
667 	case IPC_PROTOCOL_ISHTP:
668 		ishtp_recv(dev);
669 		break;
670 	}
671 
672 eoi:
673 	/* Update IPC counters */
674 	++dev->ipc_rx_cnt;
675 	dev->ipc_rx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val);
676 
677 	ish_reg_write(dev, IPC_REG_ISH2HOST_DRBL, 0);
678 	/* Flush write to doorbell */
679 	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
680 
681 	return	IRQ_HANDLED;
682 }
683 
684 /**
685  * ish_disable_dma() - disable dma communication between host and ISHFW
686  * @dev: ishtp device pointer
687  *
688  * Clear the dma enable bit and wait for dma inactive.
689  *
690  * Return: 0 for success else error code.
691  */
692 static int ish_disable_dma(struct ishtp_device *dev)
693 {
694 	unsigned int	dma_delay;
695 
696 	/* Clear the dma enable bit */
697 	ish_reg_write(dev, IPC_REG_ISH_RMP2, 0);
698 
699 	/* wait for dma inactive */
700 	for (dma_delay = 0; dma_delay < MAX_DMA_DELAY &&
701 		_ish_read_fw_sts_reg(dev) & (IPC_ISH_IN_DMA);
702 		dma_delay += 5)
703 		mdelay(5);
704 
705 	if (dma_delay >= MAX_DMA_DELAY) {
706 		dev_err(dev->devc,
707 			"Wait for DMA inactive timeout\n");
708 		return	-EBUSY;
709 	}
710 
711 	return 0;
712 }
713 
714 /**
715  * ish_wakeup() - wakeup ishfw from waiting-for-host state
716  * @dev: ishtp device pointer
717  *
718  * Set the dma enable bit and send a void message to FW,
719  * it wil wakeup FW from waiting-for-host state.
720  */
721 static void ish_wakeup(struct ishtp_device *dev)
722 {
723 	/* Set dma enable bit */
724 	ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED);
725 
726 	/*
727 	 * Send 0 IPC message so that ISH FW wakes up if it was already
728 	 * asleep.
729 	 */
730 	ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT);
731 
732 	/* Flush writes to doorbell and REMAP2 */
733 	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
734 }
735 
736 /**
737  * _ish_hw_reset() - HW reset
738  * @dev: ishtp device pointer
739  *
740  * Reset ISH HW to recover if any error
741  *
742  * Return: 0 for success else error fault code
743  */
744 static int _ish_hw_reset(struct ishtp_device *dev)
745 {
746 	struct pci_dev *pdev = dev->pdev;
747 	int	rv;
748 	uint16_t csr;
749 
750 	if (!pdev)
751 		return	-ENODEV;
752 
753 	rv = pci_reset_function(pdev);
754 	if (!rv)
755 		dev->dev_state = ISHTP_DEV_RESETTING;
756 
757 	if (!pdev->pm_cap) {
758 		dev_err(&pdev->dev, "Can't reset - no PM caps\n");
759 		return	-EINVAL;
760 	}
761 
762 	/* Disable dma communication between FW and host */
763 	if (ish_disable_dma(dev)) {
764 		dev_err(&pdev->dev,
765 			"Can't reset - stuck with DMA in-progress\n");
766 		return	-EBUSY;
767 	}
768 
769 	pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &csr);
770 
771 	csr &= ~PCI_PM_CTRL_STATE_MASK;
772 	csr |= PCI_D3hot;
773 	pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);
774 
775 	mdelay(pdev->d3_delay);
776 
777 	csr &= ~PCI_PM_CTRL_STATE_MASK;
778 	csr |= PCI_D0;
779 	pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);
780 
781 	/* Now we can enable ISH DMA operation and wakeup ISHFW */
782 	ish_wakeup(dev);
783 
784 	return	0;
785 }
786 
787 /**
788  * _ish_ipc_reset() - IPC reset
789  * @dev: ishtp device pointer
790  *
791  * Resets host and fw IPC and upper layers
792  *
793  * Return: 0 for success else error fault code
794  */
795 static int _ish_ipc_reset(struct ishtp_device *dev)
796 {
797 	struct ipc_rst_payload_type ipc_mng_msg;
798 	int	rv = 0;
799 
800 	ipc_mng_msg.reset_id = 1;
801 	ipc_mng_msg.reserved = 0;
802 
803 	set_host_ready(dev);
804 
805 	/* Clear the incoming doorbell */
806 	ish_reg_write(dev, IPC_REG_ISH2HOST_DRBL, 0);
807 	/* Flush write to doorbell */
808 	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
809 
810 	dev->recvd_hw_ready = 0;
811 
812 	/* send message */
813 	rv = ipc_send_mng_msg(dev, MNG_RESET_NOTIFY, &ipc_mng_msg,
814 		sizeof(struct ipc_rst_payload_type));
815 	if (rv) {
816 		dev_err(dev->devc, "Failed to send IPC MNG_RESET_NOTIFY\n");
817 		return	rv;
818 	}
819 
820 	wait_event_interruptible_timeout(dev->wait_hw_ready,
821 					 dev->recvd_hw_ready, 2 * HZ);
822 	if (!dev->recvd_hw_ready) {
823 		dev_err(dev->devc, "Timed out waiting for HW ready\n");
824 		rv = -ENODEV;
825 	}
826 
827 	return rv;
828 }
829 
830 /**
831  * ish_hw_start() -Start ISH HW
832  * @dev: ishtp device pointer
833  *
834  * Set host to ready state and wait for FW reset
835  *
836  * Return: 0 for success else error fault code
837  */
838 int ish_hw_start(struct ishtp_device *dev)
839 {
840 	ish_set_host_rdy(dev);
841 
842 	/* After that we can enable ISH DMA operation and wakeup ISHFW */
843 	ish_wakeup(dev);
844 
845 	set_host_ready(dev);
846 
847 	/* wait for FW-initiated reset flow */
848 	if (!dev->recvd_hw_ready)
849 		wait_event_interruptible_timeout(dev->wait_hw_ready,
850 						 dev->recvd_hw_ready,
851 						 10 * HZ);
852 
853 	if (!dev->recvd_hw_ready) {
854 		dev_err(dev->devc,
855 			"[ishtp-ish]: Timed out waiting for FW-initiated reset\n");
856 		return	-ENODEV;
857 	}
858 
859 	return 0;
860 }
861 
862 /**
863  * ish_ipc_get_header() -Get doorbell value
864  * @dev: ishtp device pointer
865  * @length: length of message
866  * @busy: busy status
867  *
868  * Get door bell value from message header
869  *
870  * Return: door bell value
871  */
872 static uint32_t ish_ipc_get_header(struct ishtp_device *dev, int length,
873 				   int busy)
874 {
875 	uint32_t drbl_val;
876 
877 	drbl_val = IPC_BUILD_HEADER(length, IPC_PROTOCOL_ISHTP, busy);
878 
879 	return drbl_val;
880 }
881 
882 static const struct ishtp_hw_ops ish_hw_ops = {
883 	.hw_reset = _ish_hw_reset,
884 	.ipc_reset = _ish_ipc_reset,
885 	.ipc_get_header = ish_ipc_get_header,
886 	.ishtp_read = _ishtp_read,
887 	.write = write_ipc_to_queue,
888 	.get_fw_status = _ish_read_fw_sts_reg,
889 	.sync_fw_clock = _ish_sync_fw_clock,
890 	.ishtp_read_hdr = _ishtp_read_hdr
891 };
892 
893 /**
894  * ish_dev_init() -Initialize ISH devoce
895  * @pdev: PCI device
896  *
897  * Allocate ISHTP device and initialize IPC processing
898  *
899  * Return: ISHTP device instance on success else NULL
900  */
901 struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
902 {
903 	struct ishtp_device *dev;
904 	int	i;
905 
906 	dev = devm_kzalloc(&pdev->dev,
907 			   sizeof(struct ishtp_device) + sizeof(struct ish_hw),
908 			   GFP_KERNEL);
909 	if (!dev)
910 		return NULL;
911 
912 	ishtp_device_init(dev);
913 
914 	init_waitqueue_head(&dev->wait_hw_ready);
915 
916 	spin_lock_init(&dev->wr_processing_spinlock);
917 	spin_lock_init(&dev->out_ipc_spinlock);
918 
919 	/* Init IPC processing and free lists */
920 	INIT_LIST_HEAD(&dev->wr_processing_list);
921 	INIT_LIST_HEAD(&dev->wr_free_list);
922 	for (i = 0; i < IPC_TX_FIFO_SIZE; i++) {
923 		struct wr_msg_ctl_info	*tx_buf;
924 
925 		tx_buf = devm_kzalloc(&pdev->dev,
926 				      sizeof(struct wr_msg_ctl_info),
927 				      GFP_KERNEL);
928 		if (!tx_buf) {
929 			/*
930 			 * IPC buffers may be limited or not available
931 			 * at all - although this shouldn't happen
932 			 */
933 			dev_err(dev->devc,
934 				"[ishtp-ish]: failure in Tx FIFO allocations (%d)\n",
935 				i);
936 			break;
937 		}
938 		list_add_tail(&tx_buf->link, &dev->wr_free_list);
939 	}
940 
941 	dev->ops = &ish_hw_ops;
942 	dev->devc = &pdev->dev;
943 	dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);
944 	return dev;
945 }
946 
947 /**
948  * ish_device_disable() - Disable ISH device
949  * @dev: ISHTP device pointer
950  *
951  * Disable ISH by clearing host ready to inform firmware.
952  */
953 void	ish_device_disable(struct ishtp_device *dev)
954 {
955 	struct pci_dev *pdev = dev->pdev;
956 
957 	if (!pdev)
958 		return;
959 
960 	/* Disable dma communication between FW and host */
961 	if (ish_disable_dma(dev)) {
962 		dev_err(&pdev->dev,
963 			"Can't reset - stuck with DMA in-progress\n");
964 		return;
965 	}
966 
967 	/* Put ISH to D3hot state for power saving */
968 	pci_set_power_state(pdev, PCI_D3hot);
969 
970 	dev->dev_state = ISHTP_DEV_DISABLED;
971 	ish_clr_host_rdy(dev);
972 }
973