cros_ec_spi.c 21.3 KB
Newer Older
1
2
3
4
// SPDX-License-Identifier: GPL-2.0
// SPI interface for ChromeOS Embedded Controller
//
// Copyright (C) 2012 Google, Inc
Simon Glass's avatar
Simon Glass committed
5
6
7
8
9
10

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/cros_ec.h>
#include <linux/mfd/cros_ec_commands.h>
11
#include <linux/of.h>
Simon Glass's avatar
Simon Glass committed
12
13
14
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
15
#include <uapi/linux/sched/types.h>
Simon Glass's avatar
Simon Glass committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

/* The header byte, which follows the preamble */
#define EC_MSG_HEADER			0xec

/*
 * Number of EC preamble bytes we read at a time. Since it takes
 * about 400-500us for the EC to respond there is not a lot of
 * point in tuning this. If the EC could respond faster then
 * we could increase this so that might expect the preamble and
 * message to occur in a single transaction. However, the maximum
 * SPI transfer size is 256 bytes, so at 5MHz we need a response
 * time of perhaps <320us (200 bytes / 1600 bits).
 */
#define EC_MSG_PREAMBLE_COUNT		32

/*
32
33
34
35
36
37
 * Allow for a long time for the EC to respond.  We support i2c
 * tunneling and support fairly long messages for the tunnel (249
 * bytes long at the moment).  If we're talking to a 100 kHz device
 * on the other end and need to transfer ~256 bytes, then we need:
 *  10 us/bit * ~10 bits/byte * ~256 bytes = ~25ms
 *
38
39
40
41
42
 * We'll wait 8 times that to handle clock stretching and other
 * paranoia.  Note that some battery gas gauge ICs claim to have a
 * clock stretch of 144ms in rare situations.  That's incentive for
 * not directly passing i2c through, but it's too late for that for
 * existing hardware.
43
44
45
46
47
48
49
 *
 * It's pretty unlikely that we'll really see a 249 byte tunnel in
 * anything other than testing.  If this was more common we might
 * consider having slow commands like this require a GET_STATUS
 * wait loop.  The 'flash write' command would be another candidate
 * for this, clocking in at 2-3ms.
 */
50
#define EC_MSG_DEADLINE_MS		200
Simon Glass's avatar
Simon Glass committed
51
52
53
54

/*
  * Time between raising the SPI chip select (for the end of a
  * transaction) and dropping it again (for the next transaction).
55
56
57
  * If we go too fast, the EC will miss the transaction. We know that we
  * need at least 70 us with the 16 MHz STM32 EC, so go with 200 us to be
  * safe.
Simon Glass's avatar
Simon Glass committed
58
  */
59
#define EC_SPI_RECOVERY_TIME_NS	(200 * 1000)
Simon Glass's avatar
Simon Glass committed
60
61
62
63
64

/**
 * struct cros_ec_spi - information about a SPI-connected EC
 *
 * @spi: SPI device we are connected to
65
 * @last_transfer_ns: time that we last finished a transfer.
66
67
 * @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that
 *      is sent when we want to turn on CS at the start of a transaction.
68
69
 * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
 *      is sent when we want to turn off CS at the end of a transaction.
70
 * @high_pri_worker: Used to schedule high priority work.
Simon Glass's avatar
Simon Glass committed
71
72
73
74
 */
struct cros_ec_spi {
	struct spi_device *spi;
	s64 last_transfer_ns;
75
	unsigned int start_of_msg_delay;
76
	unsigned int end_of_msg_delay;
77
	struct kthread_worker *high_pri_worker;
Simon Glass's avatar
Simon Glass committed
78
79
};

80
81
82
83
84
85
86
87
88
89
90
91
92
93
typedef int (*cros_ec_xfer_fn_t) (struct cros_ec_device *ec_dev,
				  struct cros_ec_command *ec_msg);

/**
 * struct cros_ec_xfer_work_params - params for our high priority workers
 *
 * @work: The work_struct needed to queue work
 * @fn: The function to use to transfer
 * @ec_dev: ChromeOS EC device
 * @ec_msg: Message to transfer
 * @ret: The return value of the function
 */

struct cros_ec_xfer_work_params {
94
	struct kthread_work work;
95
96
97
98
99
100
	cros_ec_xfer_fn_t fn;
	struct cros_ec_device *ec_dev;
	struct cros_ec_command *ec_msg;
	int ret;
};

Simon Glass's avatar
Simon Glass committed
101
static void debug_packet(struct device *dev, const char *name, u8 *ptr,
102
			 int len)
Simon Glass's avatar
Simon Glass committed
103
104
105
106
107
108
{
#ifdef DEBUG
	int i;

	dev_dbg(dev, "%s: ", name);
	for (i = 0; i < len; i++)
109
110
111
		pr_cont(" %02x", ptr[i]);

	pr_cont("\n");
Simon Glass's avatar
Simon Glass committed
112
113
114
#endif
}

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
static int terminate_request(struct cros_ec_device *ec_dev)
{
	struct cros_ec_spi *ec_spi = ec_dev->priv;
	struct spi_message msg;
	struct spi_transfer trans;
	int ret;

	/*
	 * Turn off CS, possibly adding a delay to ensure the rising edge
	 * doesn't come too soon after the end of the data.
	 */
	spi_message_init(&msg);
	memset(&trans, 0, sizeof(trans));
	trans.delay_usecs = ec_spi->end_of_msg_delay;
	spi_message_add_tail(&trans, &msg);

131
	ret = spi_sync_locked(ec_spi->spi, &msg);
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

	/* Reset end-of-response timer */
	ec_spi->last_transfer_ns = ktime_get_ns();
	if (ret < 0) {
		dev_err(ec_dev->dev,
			"cs-deassert spi transfer failed: %d\n",
			ret);
	}

	return ret;
}

/**
 * receive_n_bytes - receive n bytes from the EC.
 *
 * Assumes buf is a pointer into the ec_dev->din buffer
 */
static int receive_n_bytes(struct cros_ec_device *ec_dev, u8 *buf, int n)
{
	struct cros_ec_spi *ec_spi = ec_dev->priv;
	struct spi_transfer trans;
	struct spi_message msg;
	int ret;

	BUG_ON(buf - ec_dev->din + n > ec_dev->din_size);

	memset(&trans, 0, sizeof(trans));
	trans.cs_change = 1;
	trans.rx_buf = buf;
	trans.len = n;

	spi_message_init(&msg);
	spi_message_add_tail(&trans, &msg);
165
	ret = spi_sync_locked(ec_spi->spi, &msg);
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	if (ret < 0)
		dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);

	return ret;
}

/**
 * cros_ec_spi_receive_packet - Receive a packet from the EC.
 *
 * This function has two phases: reading the preamble bytes (since if we read
 * data from the EC before it is ready to send, we just get preamble) and
 * reading the actual message.
 *
 * The received data is placed into ec_dev->din.
 *
 * @ec_dev: ChromeOS EC device
 * @need_len: Number of message bytes we need to read
 */
static int cros_ec_spi_receive_packet(struct cros_ec_device *ec_dev,
				      int need_len)
{
	struct ec_host_response *response;
	u8 *ptr, *end;
	int ret;
	unsigned long deadline;
	int todo;

193
	BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT);
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

	/* Receive data until we see the header byte */
	deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
	while (true) {
		unsigned long start_jiffies = jiffies;

		ret = receive_n_bytes(ec_dev,
				      ec_dev->din,
				      EC_MSG_PREAMBLE_COUNT);
		if (ret < 0)
			return ret;

		ptr = ec_dev->din;
		for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
			if (*ptr == EC_SPI_FRAME_START) {
				dev_dbg(ec_dev->dev, "msg found at %zd\n",
					ptr - ec_dev->din);
				break;
			}
		}
		if (ptr != end)
			break;

		/*
		 * Use the time at the start of the loop as a timeout.  This
		 * gives us one last shot at getting the transfer and is useful
		 * in case we got context switched out for a while.
		 */
		if (time_after(start_jiffies, deadline)) {
			dev_warn(ec_dev->dev, "EC failed to respond in time\n");
			return -ETIMEDOUT;
		}
	}

	/*
	 * ptr now points to the header byte. Copy any valid data to the
	 * start of our buffer
	 */
	todo = end - ++ptr;
	BUG_ON(todo < 0 || todo > ec_dev->din_size);
	todo = min(todo, need_len);
	memmove(ec_dev->din, ptr, todo);
	ptr = ec_dev->din + todo;
	dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n",
		need_len, todo);
	need_len -= todo;

	/* If the entire response struct wasn't read, get the rest of it. */
	if (todo < sizeof(*response)) {
		ret = receive_n_bytes(ec_dev, ptr, sizeof(*response) - todo);
		if (ret < 0)
			return -EBADMSG;
		ptr += (sizeof(*response) - todo);
		todo = sizeof(*response);
	}

	response = (struct ec_host_response *)ec_dev->din;

	/* Abort if data_len is too large. */
	if (response->data_len > ec_dev->din_size)
		return -EMSGSIZE;

	/* Receive data until we have it all */
	while (need_len > 0) {
		/*
		 * We can't support transfers larger than the SPI FIFO size
		 * unless we have DMA. We don't have DMA on the ISP SPI ports
		 * for Exynos. We need a way of asking SPI driver for
		 * maximum-supported transfer size.
		 */
		todo = min(need_len, 256);
		dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
			todo, need_len, ptr - ec_dev->din);

		ret = receive_n_bytes(ec_dev, ptr, todo);
		if (ret < 0)
			return ret;

		ptr += todo;
		need_len -= todo;
	}

	dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);

	return 0;
}

Simon Glass's avatar
Simon Glass committed
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/**
 * cros_ec_spi_receive_response - Receive a response from the EC.
 *
 * This function has two phases: reading the preamble bytes (since if we read
 * data from the EC before it is ready to send, we just get preamble) and
 * reading the actual message.
 *
 * The received data is placed into ec_dev->din.
 *
 * @ec_dev: ChromeOS EC device
 * @need_len: Number of message bytes we need to read
 */
static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
					int need_len)
{
	u8 *ptr, *end;
	int ret;
	unsigned long deadline;
	int todo;

301
	BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT);
302

Simon Glass's avatar
Simon Glass committed
303
304
	/* Receive data until we see the header byte */
	deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
305
306
307
	while (true) {
		unsigned long start_jiffies = jiffies;

308
309
310
311
		ret = receive_n_bytes(ec_dev,
				      ec_dev->din,
				      EC_MSG_PREAMBLE_COUNT);
		if (ret < 0)
Simon Glass's avatar
Simon Glass committed
312
313
			return ret;

314
		ptr = ec_dev->din;
Simon Glass's avatar
Simon Glass committed
315
		for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
316
			if (*ptr == EC_SPI_FRAME_START) {
317
				dev_dbg(ec_dev->dev, "msg found at %zd\n",
Simon Glass's avatar
Simon Glass committed
318
319
320
321
					ptr - ec_dev->din);
				break;
			}
		}
322
323
		if (ptr != end)
			break;
Simon Glass's avatar
Simon Glass committed
324

325
326
327
328
329
330
		/*
		 * Use the time at the start of the loop as a timeout.  This
		 * gives us one last shot at getting the transfer and is useful
		 * in case we got context switched out for a while.
		 */
		if (time_after(start_jiffies, deadline)) {
Simon Glass's avatar
Simon Glass committed
331
332
333
			dev_warn(ec_dev->dev, "EC failed to respond in time\n");
			return -ETIMEDOUT;
		}
334
	}
Simon Glass's avatar
Simon Glass committed
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

	/*
	 * ptr now points to the header byte. Copy any valid data to the
	 * start of our buffer
	 */
	todo = end - ++ptr;
	BUG_ON(todo < 0 || todo > ec_dev->din_size);
	todo = min(todo, need_len);
	memmove(ec_dev->din, ptr, todo);
	ptr = ec_dev->din + todo;
	dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n",
		 need_len, todo);
	need_len -= todo;

	/* Receive data until we have it all */
	while (need_len > 0) {
		/*
		 * We can't support transfers larger than the SPI FIFO size
		 * unless we have DMA. We don't have DMA on the ISP SPI ports
		 * for Exynos. We need a way of asking SPI driver for
		 * maximum-supported transfer size.
		 */
		todo = min(need_len, 256);
358
		dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
Simon Glass's avatar
Simon Glass committed
359
360
			todo, need_len, ptr - ec_dev->din);

361
362
		ret = receive_n_bytes(ec_dev, ptr, todo);
		if (ret < 0)
Simon Glass's avatar
Simon Glass committed
363
364
365
366
367
368
369
			return ret;

		debug_packet(ec_dev->dev, "interim", ptr, todo);
		ptr += todo;
		need_len -= todo;
	}

370
	dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);
Simon Glass's avatar
Simon Glass committed
371
372
373
374

	return 0;
}

375
/**
376
 * do_cros_ec_pkt_xfer_spi - Transfer a packet over SPI and receive the reply
377
378
379
380
 *
 * @ec_dev: ChromeOS EC device
 * @ec_msg: Message to transfer
 */
381
382
static int do_cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
				   struct cros_ec_command *ec_msg)
383
384
385
{
	struct ec_host_response *response;
	struct cros_ec_spi *ec_spi = ec_dev->priv;
386
	struct spi_transfer trans, trans_delay;
387
388
389
390
391
	struct spi_message msg;
	int i, len;
	u8 *ptr;
	u8 *rx_buf;
	u8 sum;
392
	u8 rx_byte;
393
	int ret = 0, final_ret;
394
	unsigned long delay;
395
396
397
398
399

	len = cros_ec_prepare_tx(ec_dev, ec_msg);
	dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);

	/* If it's too soon to do another transaction, wait */
400
401
402
	delay = ktime_get_ns() - ec_spi->last_transfer_ns;
	if (delay < EC_SPI_RECOVERY_TIME_NS)
		ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
403
404

	rx_buf = kzalloc(len, GFP_KERNEL);
405
406
407
408
	if (!rx_buf)
		return -ENOMEM;

	spi_bus_lock(ec_spi->spi->master);
409

410
411
412
413
414
415
416
417
418
419
420
	/*
	 * Leave a gap between CS assertion and clocking of data to allow the
	 * EC time to wakeup.
	 */
	spi_message_init(&msg);
	if (ec_spi->start_of_msg_delay) {
		memset(&trans_delay, 0, sizeof(trans_delay));
		trans_delay.delay_usecs = ec_spi->start_of_msg_delay;
		spi_message_add_tail(&trans_delay, &msg);
	}

421
422
423
424
425
426
427
	/* Transmit phase - send our message */
	memset(&trans, 0, sizeof(trans));
	trans.tx_buf = ec_dev->dout;
	trans.rx_buf = rx_buf;
	trans.len = len;
	trans.cs_change = 1;
	spi_message_add_tail(&trans, &msg);
428
	ret = spi_sync_locked(ec_spi->spi, &msg);
429
430
431
432
433

	/* Get the response */
	if (!ret) {
		/* Verify that EC can process command */
		for (i = 0; i < len; i++) {
434
			rx_byte = rx_buf[i];
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
			/*
			 * Seeing the PAST_END, RX_BAD_DATA, or NOT_READY
			 * markers are all signs that the EC didn't fully
			 * receive our command. e.g., if the EC is flashing
			 * itself, it can't respond to any commands and instead
			 * clocks out EC_SPI_PAST_END from its SPI hardware
			 * buffer. Similar occurrences can happen if the AP is
			 * too slow to clock out data after asserting CS -- the
			 * EC will abort and fill its buffer with
			 * EC_SPI_RX_BAD_DATA.
			 *
			 * In all cases, these errors should be safe to retry.
			 * Report -EAGAIN and let the caller decide what to do
			 * about that.
			 */
450
451
452
			if (rx_byte == EC_SPI_PAST_END  ||
			    rx_byte == EC_SPI_RX_BAD_DATA ||
			    rx_byte == EC_SPI_NOT_READY) {
453
				ret = -EAGAIN;
454
455
456
457
458
				break;
			}
		}
	}

459
460
461
	if (!ret)
		ret = cros_ec_spi_receive_packet(ec_dev,
				ec_msg->insize + sizeof(*response));
462
	else if (ret != -EAGAIN)
463
464
		dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);

465
	final_ret = terminate_request(ec_dev);
466
467
468

	spi_bus_unlock(ec_spi->spi->master);

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
	if (!ret)
		ret = final_ret;
	if (ret < 0)
		goto exit;

	ptr = ec_dev->din;

	/* check response error code */
	response = (struct ec_host_response *)ptr;
	ec_msg->result = response->result;

	ret = cros_ec_check_result(ec_dev, ec_msg);
	if (ret)
		goto exit;

	len = response->data_len;
	sum = 0;
	if (len > ec_msg->insize) {
		dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
			len, ec_msg->insize);
		ret = -EMSGSIZE;
		goto exit;
	}

	for (i = 0; i < sizeof(*response); i++)
		sum += ptr[i];

	/* copy response packet payload and compute checksum */
	memcpy(ec_msg->data, ptr + sizeof(*response), len);
	for (i = 0; i < len; i++)
		sum += ec_msg->data[i];

	if (sum) {
		dev_err(ec_dev->dev,
			"bad packet checksum, calculated %x\n",
			sum);
		ret = -EBADMSG;
		goto exit;
	}

	ret = len;
exit:
	kfree(rx_buf);
	if (ec_msg->command == EC_CMD_REBOOT_EC)
		msleep(EC_REBOOT_DELAY_MS);

	return ret;
}

Simon Glass's avatar
Simon Glass committed
518
/**
519
 * do_cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply
Simon Glass's avatar
Simon Glass committed
520
521
522
523
 *
 * @ec_dev: ChromeOS EC device
 * @ec_msg: Message to transfer
 */
524
525
static int do_cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
				   struct cros_ec_command *ec_msg)
Simon Glass's avatar
Simon Glass committed
526
527
528
529
530
531
{
	struct cros_ec_spi *ec_spi = ec_dev->priv;
	struct spi_transfer trans;
	struct spi_message msg;
	int i, len;
	u8 *ptr;
532
	u8 *rx_buf;
533
	u8 rx_byte;
Simon Glass's avatar
Simon Glass committed
534
535
	int sum;
	int ret = 0, final_ret;
536
	unsigned long delay;
Simon Glass's avatar
Simon Glass committed
537
538
539
540
541

	len = cros_ec_prepare_tx(ec_dev, ec_msg);
	dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);

	/* If it's too soon to do another transaction, wait */
542
543
544
	delay = ktime_get_ns() - ec_spi->last_transfer_ns;
	if (delay < EC_SPI_RECOVERY_TIME_NS)
		ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
Simon Glass's avatar
Simon Glass committed
545

546
	rx_buf = kzalloc(len, GFP_KERNEL);
547
548
549
550
	if (!rx_buf)
		return -ENOMEM;

	spi_bus_lock(ec_spi->spi->master);
551

Simon Glass's avatar
Simon Glass committed
552
553
	/* Transmit phase - send our message */
	debug_packet(ec_dev->dev, "out", ec_dev->dout, len);
554
	memset(&trans, 0, sizeof(trans));
Simon Glass's avatar
Simon Glass committed
555
	trans.tx_buf = ec_dev->dout;
556
	trans.rx_buf = rx_buf;
Simon Glass's avatar
Simon Glass committed
557
558
559
560
	trans.len = len;
	trans.cs_change = 1;
	spi_message_init(&msg);
	spi_message_add_tail(&trans, &msg);
561
	ret = spi_sync_locked(ec_spi->spi, &msg);
Simon Glass's avatar
Simon Glass committed
562
563
564

	/* Get the response */
	if (!ret) {
565
566
		/* Verify that EC can process command */
		for (i = 0; i < len; i++) {
567
			rx_byte = rx_buf[i];
568
			/* See comments in cros_ec_pkt_xfer_spi() */
569
570
571
			if (rx_byte == EC_SPI_PAST_END  ||
			    rx_byte == EC_SPI_RX_BAD_DATA ||
			    rx_byte == EC_SPI_NOT_READY) {
572
				ret = -EAGAIN;
573
574
575
				break;
			}
		}
Simon Glass's avatar
Simon Glass committed
576
577
	}

578
579
580
	if (!ret)
		ret = cros_ec_spi_receive_response(ec_dev,
				ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
581
	else if (ret != -EAGAIN)
582
583
		dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);

584
	final_ret = terminate_request(ec_dev);
585
586
587

	spi_bus_unlock(ec_spi->spi->master);

Simon Glass's avatar
Simon Glass committed
588
589
	if (!ret)
		ret = final_ret;
590
	if (ret < 0)
591
		goto exit;
Simon Glass's avatar
Simon Glass committed
592
593

	ptr = ec_dev->din;
594
595
596
597
598

	/* check response error code */
	ec_msg->result = ptr[0];
	ret = cros_ec_check_result(ec_dev, ec_msg);
	if (ret)
599
		goto exit;
600

Simon Glass's avatar
Simon Glass committed
601
602
	len = ptr[1];
	sum = ptr[0] + ptr[1];
603
	if (len > ec_msg->insize) {
Simon Glass's avatar
Simon Glass committed
604
		dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
605
			len, ec_msg->insize);
606
607
		ret = -ENOSPC;
		goto exit;
Simon Glass's avatar
Simon Glass committed
608
609
610
611
612
	}

	/* copy response packet payload and compute checksum */
	for (i = 0; i < len; i++) {
		sum += ptr[i + 2];
613
		if (ec_msg->insize)
614
			ec_msg->data[i] = ptr[i + 2];
Simon Glass's avatar
Simon Glass committed
615
616
617
618
619
620
621
622
623
	}
	sum &= 0xff;

	debug_packet(ec_dev->dev, "in", ptr, len + 3);

	if (sum != ptr[len + 2]) {
		dev_err(ec_dev->dev,
			"bad packet checksum, expected %02x, got %02x\n",
			sum, ptr[len + 2]);
624
625
		ret = -EBADMSG;
		goto exit;
Simon Glass's avatar
Simon Glass committed
626
627
	}

628
	ret = len;
629
exit:
630
	kfree(rx_buf);
631
632
633
	if (ec_msg->command == EC_CMD_REBOOT_EC)
		msleep(EC_REBOOT_DELAY_MS);

634
	return ret;
Simon Glass's avatar
Simon Glass committed
635
636
}

637
static void cros_ec_xfer_high_pri_work(struct kthread_work *work)
638
639
640
641
642
643
644
645
646
647
648
{
	struct cros_ec_xfer_work_params *params;

	params = container_of(work, struct cros_ec_xfer_work_params, work);
	params->ret = params->fn(params->ec_dev, params->ec_msg);
}

static int cros_ec_xfer_high_pri(struct cros_ec_device *ec_dev,
				 struct cros_ec_command *ec_msg,
				 cros_ec_xfer_fn_t fn)
{
649
650
651
652
653
654
655
656
	struct cros_ec_spi *ec_spi = ec_dev->priv;
	struct cros_ec_xfer_work_params params = {
		.work = KTHREAD_WORK_INIT(params.work,
					  cros_ec_xfer_high_pri_work),
		.ec_dev = ec_dev,
		.ec_msg = ec_msg,
		.fn = fn,
	};
657
658
659
660
661
662
663
664
665
666

	/*
	 * This looks a bit ridiculous.  Why do the work on a
	 * different thread if we're just going to block waiting for
	 * the thread to finish?  The key here is that the thread is
	 * running at high priority but the calling context might not
	 * be.  We need to be at high priority to avoid getting
	 * context switched out for too long and the EC giving up on
	 * the transfer.
	 */
667
668
	kthread_queue_work(ec_spi->high_pri_worker, &params.work);
	kthread_flush_work(&params.work);
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

	return params.ret;
}

static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
				struct cros_ec_command *ec_msg)
{
	return cros_ec_xfer_high_pri(ec_dev, ec_msg, do_cros_ec_pkt_xfer_spi);
}

static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
				struct cros_ec_command *ec_msg)
{
	return cros_ec_xfer_high_pri(ec_dev, ec_msg, do_cros_ec_cmd_xfer_spi);
}

685
686
687
688
689
690
static void cros_ec_spi_dt_probe(struct cros_ec_spi *ec_spi, struct device *dev)
{
	struct device_node *np = dev->of_node;
	u32 val;
	int ret;

691
692
693
694
	ret = of_property_read_u32(np, "google,cros-ec-spi-pre-delay", &val);
	if (!ret)
		ec_spi->start_of_msg_delay = val;

695
696
697
698
699
	ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val);
	if (!ret)
		ec_spi->end_of_msg_delay = val;
}

700
701
702
703
704
705
706
707
708
static void cros_ec_spi_high_pri_release(void *worker)
{
	kthread_destroy_worker(worker);
}

static int cros_ec_spi_devm_high_pri_alloc(struct device *dev,
					   struct cros_ec_spi *ec_spi)
{
	struct sched_param sched_priority = {
Peter Zijlstra's avatar
Peter Zijlstra committed
709
		.sched_priority = MAX_RT_PRIO / 2,
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
	};
	int err;

	ec_spi->high_pri_worker =
		kthread_create_worker(0, "cros_ec_spi_high_pri");

	if (IS_ERR(ec_spi->high_pri_worker)) {
		err = PTR_ERR(ec_spi->high_pri_worker);
		dev_err(dev, "Can't create cros_ec high pri worker: %d\n", err);
		return err;
	}

	err = devm_add_action_or_reset(dev, cros_ec_spi_high_pri_release,
				       ec_spi->high_pri_worker);
	if (err)
		return err;

	err = sched_setscheduler_nocheck(ec_spi->high_pri_worker->task,
					 SCHED_FIFO, &sched_priority);
	if (err)
		dev_err(dev, "Can't set cros_ec high pri priority: %d\n", err);
	return err;
}

734
static int cros_ec_spi_probe(struct spi_device *spi)
Simon Glass's avatar
Simon Glass committed
735
736
737
738
739
740
741
742
{
	struct device *dev = &spi->dev;
	struct cros_ec_device *ec_dev;
	struct cros_ec_spi *ec_spi;
	int err;

	spi->bits_per_word = 8;
	spi->mode = SPI_MODE_0;
743
	spi->rt = true;
Simon Glass's avatar
Simon Glass committed
744
745
746
747
748
749
750
751
752
753
754
755
	err = spi_setup(spi);
	if (err < 0)
		return err;

	ec_spi = devm_kzalloc(dev, sizeof(*ec_spi), GFP_KERNEL);
	if (ec_spi == NULL)
		return -ENOMEM;
	ec_spi->spi = spi;
	ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
	if (!ec_dev)
		return -ENOMEM;

756
757
758
	/* Check for any DT properties */
	cros_ec_spi_dt_probe(ec_spi, dev);

Simon Glass's avatar
Simon Glass committed
759
760
761
762
	spi_set_drvdata(spi, ec_dev);
	ec_dev->dev = dev;
	ec_dev->priv = ec_spi;
	ec_dev->irq = spi->irq;
763
	ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi;
764
	ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi;
Simon Glass's avatar
Simon Glass committed
765
	ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
766
767
768
769
	ec_dev->din_size = EC_MSG_PREAMBLE_COUNT +
			   sizeof(struct ec_host_response) +
			   sizeof(struct ec_response_get_protocol_info);
	ec_dev->dout_size = sizeof(struct ec_host_request);
Simon Glass's avatar
Simon Glass committed
770

771
	ec_spi->last_transfer_ns = ktime_get_ns();
772

773
774
775
776
	err = cros_ec_spi_devm_high_pri_alloc(dev, ec_spi);
	if (err)
		return err;

Simon Glass's avatar
Simon Glass committed
777
778
779
780
781
782
	err = cros_ec_register(ec_dev);
	if (err) {
		dev_err(dev, "cannot register EC\n");
		return err;
	}

783
784
	device_init_wakeup(&spi->dev, true);

Simon Glass's avatar
Simon Glass committed
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int cros_ec_spi_suspend(struct device *dev)
{
	struct cros_ec_device *ec_dev = dev_get_drvdata(dev);

	return cros_ec_suspend(ec_dev);
}

static int cros_ec_spi_resume(struct device *dev)
{
	struct cros_ec_device *ec_dev = dev_get_drvdata(dev);

	return cros_ec_resume(ec_dev);
}
#endif

static SIMPLE_DEV_PM_OPS(cros_ec_spi_pm_ops, cros_ec_spi_suspend,
			 cros_ec_spi_resume);

807
808
809
810
811
812
static const struct of_device_id cros_ec_spi_of_match[] = {
	{ .compatible = "google,cros-ec-spi", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, cros_ec_spi_of_match);

Simon Glass's avatar
Simon Glass committed
813
814
815
816
817
818
819
820
821
static const struct spi_device_id cros_ec_spi_id[] = {
	{ "cros-ec-spi", 0 },
	{ }
};
MODULE_DEVICE_TABLE(spi, cros_ec_spi_id);

static struct spi_driver cros_ec_driver_spi = {
	.driver	= {
		.name	= "cros-ec-spi",
822
		.of_match_table = cros_ec_spi_of_match,
Simon Glass's avatar
Simon Glass committed
823
824
		.pm	= &cros_ec_spi_pm_ops,
	},
825
	.probe		= cros_ec_spi_probe,
Simon Glass's avatar
Simon Glass committed
826
827
828
829
830
	.id_table	= cros_ec_spi_id,
};

module_spi_driver(cros_ec_driver_spi);

831
MODULE_LICENSE("GPL v2");
832
MODULE_DESCRIPTION("SPI interface for ChromeOS Embedded Controller");