xref: /openbmc/linux/drivers/pci/hotplug/ibmphp_hpc.c (revision e3d786a3)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * IBM Hot Plug Controller Driver
4  *
5  * Written By: Jyoti Shah, IBM Corporation
6  *
7  * Copyright (C) 2001-2003 IBM Corp.
8  *
9  * All rights reserved.
10  *
11  * Send feedback to <gregkh@us.ibm.com>
12  *                  <jshah@us.ibm.com>
13  *
14  */
15 
16 #include <linux/wait.h>
17 #include <linux/time.h>
18 #include <linux/delay.h>
19 #include <linux/module.h>
20 #include <linux/pci.h>
21 #include <linux/init.h>
22 #include <linux/mutex.h>
23 #include <linux/sched.h>
24 #include <linux/semaphore.h>
25 #include <linux/kthread.h>
26 #include "ibmphp.h"
27 
28 static int to_debug = 0;
29 #define debug_polling(fmt, arg...)	do { if (to_debug) debug(fmt, arg); } while (0)
30 
31 //----------------------------------------------------------------------------
32 // timeout values
33 //----------------------------------------------------------------------------
34 #define CMD_COMPLETE_TOUT_SEC	60	// give HPC 60 sec to finish cmd
35 #define HPC_CTLR_WORKING_TOUT	60	// give HPC 60 sec to finish cmd
36 #define HPC_GETACCESS_TIMEOUT	60	// seconds
37 #define POLL_INTERVAL_SEC	2	// poll HPC every 2 seconds
38 #define POLL_LATCH_CNT		5	// poll latch 5 times, then poll slots
39 
40 //----------------------------------------------------------------------------
41 // Winnipeg Architected Register Offsets
42 //----------------------------------------------------------------------------
43 #define WPG_I2CMBUFL_OFFSET	0x08	// I2C Message Buffer Low
44 #define WPG_I2CMOSUP_OFFSET	0x10	// I2C Master Operation Setup Reg
45 #define WPG_I2CMCNTL_OFFSET	0x20	// I2C Master Control Register
46 #define WPG_I2CPARM_OFFSET	0x40	// I2C Parameter Register
47 #define WPG_I2CSTAT_OFFSET	0x70	// I2C Status Register
48 
49 //----------------------------------------------------------------------------
50 // Winnipeg Store Type commands (Add this commands to the register offset)
51 //----------------------------------------------------------------------------
52 #define WPG_I2C_AND		0x1000	// I2C AND operation
53 #define WPG_I2C_OR		0x2000	// I2C OR operation
54 
55 //----------------------------------------------------------------------------
56 // Command set for I2C Master Operation Setup Register
57 //----------------------------------------------------------------------------
58 #define WPG_READATADDR_MASK	0x00010000	// read,bytes,I2C shifted,index
59 #define WPG_WRITEATADDR_MASK	0x40010000	// write,bytes,I2C shifted,index
60 #define WPG_READDIRECT_MASK	0x10010000
61 #define WPG_WRITEDIRECT_MASK	0x60010000
62 
63 
64 //----------------------------------------------------------------------------
65 // bit masks for I2C Master Control Register
66 //----------------------------------------------------------------------------
67 #define WPG_I2CMCNTL_STARTOP_MASK	0x00000002	// Start the Operation
68 
69 //----------------------------------------------------------------------------
70 //
71 //----------------------------------------------------------------------------
72 #define WPG_I2C_IOREMAP_SIZE	0x2044	// size of linear address interval
73 
74 //----------------------------------------------------------------------------
75 // command index
76 //----------------------------------------------------------------------------
77 #define WPG_1ST_SLOT_INDEX	0x01	// index - 1st slot for ctlr
78 #define WPG_CTLR_INDEX		0x0F	// index - ctlr
79 #define WPG_1ST_EXTSLOT_INDEX	0x10	// index - 1st ext slot for ctlr
80 #define WPG_1ST_BUS_INDEX	0x1F	// index - 1st bus for ctlr
81 
82 //----------------------------------------------------------------------------
83 // macro utilities
84 //----------------------------------------------------------------------------
85 // if bits 20,22,25,26,27,29,30 are OFF return 1
86 #define HPC_I2CSTATUS_CHECK(s)	((u8)((s & 0x00000A76) ? 0 : 1))
87 
88 //----------------------------------------------------------------------------
89 // global variables
90 //----------------------------------------------------------------------------
91 static struct mutex sem_hpcaccess;	// lock access to HPC
92 static struct semaphore semOperations;	// lock all operations and
93 					// access to data structures
94 static struct semaphore sem_exit;	// make sure polling thread goes away
95 static struct task_struct *ibmphp_poll_thread;
96 //----------------------------------------------------------------------------
97 // local function prototypes
98 //----------------------------------------------------------------------------
99 static u8 i2c_ctrl_read(struct controller *, void __iomem *, u8);
100 static u8 i2c_ctrl_write(struct controller *, void __iomem *, u8, u8);
101 static u8 hpc_writecmdtoindex(u8, u8);
102 static u8 hpc_readcmdtoindex(u8, u8);
103 static void get_hpc_access(void);
104 static void free_hpc_access(void);
105 static int poll_hpc(void *data);
106 static int process_changeinstatus(struct slot *, struct slot *);
107 static int process_changeinlatch(u8, u8, struct controller *);
108 static int hpc_wait_ctlr_notworking(int, struct controller *, void __iomem *, u8 *);
109 //----------------------------------------------------------------------------
110 
111 
112 /*----------------------------------------------------------------------
113 * Name:    ibmphp_hpc_initvars
114 *
115 * Action:  initialize semaphores and variables
116 *---------------------------------------------------------------------*/
117 void __init ibmphp_hpc_initvars(void)
118 {
119 	debug("%s - Entry\n", __func__);
120 
121 	mutex_init(&sem_hpcaccess);
122 	sema_init(&semOperations, 1);
123 	sema_init(&sem_exit, 0);
124 	to_debug = 0;
125 
126 	debug("%s - Exit\n", __func__);
127 }
128 
129 /*----------------------------------------------------------------------
130 * Name:    i2c_ctrl_read
131 *
132 * Action:  read from HPC over I2C
133 *
134 *---------------------------------------------------------------------*/
135 static u8 i2c_ctrl_read(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
136 {
137 	u8 status;
138 	int i;
139 	void __iomem *wpg_addr;	// base addr + offset
140 	unsigned long wpg_data;	// data to/from WPG LOHI format
141 	unsigned long ultemp;
142 	unsigned long data;	// actual data HILO format
143 
144 	debug_polling("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index);
145 
146 	//--------------------------------------------------------------------
147 	// READ - step 1
148 	// read at address, byte length, I2C address (shifted), index
149 	// or read direct, byte length, index
150 	if (ctlr_ptr->ctlr_type == 0x02) {
151 		data = WPG_READATADDR_MASK;
152 		// fill in I2C address
153 		ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
154 		ultemp = ultemp >> 1;
155 		data |= (ultemp << 8);
156 
157 		// fill in index
158 		data |= (unsigned long)index;
159 	} else if (ctlr_ptr->ctlr_type == 0x04) {
160 		data = WPG_READDIRECT_MASK;
161 
162 		// fill in index
163 		ultemp = (unsigned long)index;
164 		ultemp = ultemp << 8;
165 		data |= ultemp;
166 	} else {
167 		err("this controller type is not supported \n");
168 		return HPC_ERROR;
169 	}
170 
171 	wpg_data = swab32(data);	// swap data before writing
172 	wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
173 	writel(wpg_data, wpg_addr);
174 
175 	//--------------------------------------------------------------------
176 	// READ - step 2 : clear the message buffer
177 	data = 0x00000000;
178 	wpg_data = swab32(data);
179 	wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
180 	writel(wpg_data, wpg_addr);
181 
182 	//--------------------------------------------------------------------
183 	// READ - step 3 : issue start operation, I2C master control bit 30:ON
184 	//                 2020 : [20] OR operation at [20] offset 0x20
185 	data = WPG_I2CMCNTL_STARTOP_MASK;
186 	wpg_data = swab32(data);
187 	wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
188 	writel(wpg_data, wpg_addr);
189 
190 	//--------------------------------------------------------------------
191 	// READ - step 4 : wait until start operation bit clears
192 	i = CMD_COMPLETE_TOUT_SEC;
193 	while (i) {
194 		msleep(10);
195 		wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
196 		wpg_data = readl(wpg_addr);
197 		data = swab32(wpg_data);
198 		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
199 			break;
200 		i--;
201 	}
202 	if (i == 0) {
203 		debug("%s - Error : WPG timeout\n", __func__);
204 		return HPC_ERROR;
205 	}
206 	//--------------------------------------------------------------------
207 	// READ - step 5 : read I2C status register
208 	i = CMD_COMPLETE_TOUT_SEC;
209 	while (i) {
210 		msleep(10);
211 		wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
212 		wpg_data = readl(wpg_addr);
213 		data = swab32(wpg_data);
214 		if (HPC_I2CSTATUS_CHECK(data))
215 			break;
216 		i--;
217 	}
218 	if (i == 0) {
219 		debug("ctrl_read - Exit Error:I2C timeout\n");
220 		return HPC_ERROR;
221 	}
222 
223 	//--------------------------------------------------------------------
224 	// READ - step 6 : get DATA
225 	wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
226 	wpg_data = readl(wpg_addr);
227 	data = swab32(wpg_data);
228 
229 	status = (u8) data;
230 
231 	debug_polling("%s - Exit index[%x] status[%x]\n", __func__, index, status);
232 
233 	return (status);
234 }
235 
236 /*----------------------------------------------------------------------
237 * Name:    i2c_ctrl_write
238 *
239 * Action:  write to HPC over I2C
240 *
241 * Return   0 or error codes
242 *---------------------------------------------------------------------*/
243 static u8 i2c_ctrl_write(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
244 {
245 	u8 rc;
246 	void __iomem *wpg_addr;	// base addr + offset
247 	unsigned long wpg_data;	// data to/from WPG LOHI format
248 	unsigned long ultemp;
249 	unsigned long data;	// actual data HILO format
250 	int i;
251 
252 	debug_polling("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __func__, WPGBbar, index, cmd);
253 
254 	rc = 0;
255 	//--------------------------------------------------------------------
256 	// WRITE - step 1
257 	// write at address, byte length, I2C address (shifted), index
258 	// or write direct, byte length, index
259 	data = 0x00000000;
260 
261 	if (ctlr_ptr->ctlr_type == 0x02) {
262 		data = WPG_WRITEATADDR_MASK;
263 		// fill in I2C address
264 		ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
265 		ultemp = ultemp >> 1;
266 		data |= (ultemp << 8);
267 
268 		// fill in index
269 		data |= (unsigned long)index;
270 	} else if (ctlr_ptr->ctlr_type == 0x04) {
271 		data = WPG_WRITEDIRECT_MASK;
272 
273 		// fill in index
274 		ultemp = (unsigned long)index;
275 		ultemp = ultemp << 8;
276 		data |= ultemp;
277 	} else {
278 		err("this controller type is not supported \n");
279 		return HPC_ERROR;
280 	}
281 
282 	wpg_data = swab32(data);	// swap data before writing
283 	wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
284 	writel(wpg_data, wpg_addr);
285 
286 	//--------------------------------------------------------------------
287 	// WRITE - step 2 : clear the message buffer
288 	data = 0x00000000 | (unsigned long)cmd;
289 	wpg_data = swab32(data);
290 	wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
291 	writel(wpg_data, wpg_addr);
292 
293 	//--------------------------------------------------------------------
294 	// WRITE - step 3 : issue start operation,I2C master control bit 30:ON
295 	//                 2020 : [20] OR operation at [20] offset 0x20
296 	data = WPG_I2CMCNTL_STARTOP_MASK;
297 	wpg_data = swab32(data);
298 	wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
299 	writel(wpg_data, wpg_addr);
300 
301 	//--------------------------------------------------------------------
302 	// WRITE - step 4 : wait until start operation bit clears
303 	i = CMD_COMPLETE_TOUT_SEC;
304 	while (i) {
305 		msleep(10);
306 		wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
307 		wpg_data = readl(wpg_addr);
308 		data = swab32(wpg_data);
309 		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
310 			break;
311 		i--;
312 	}
313 	if (i == 0) {
314 		debug("%s - Exit Error:WPG timeout\n", __func__);
315 		rc = HPC_ERROR;
316 	}
317 
318 	//--------------------------------------------------------------------
319 	// WRITE - step 5 : read I2C status register
320 	i = CMD_COMPLETE_TOUT_SEC;
321 	while (i) {
322 		msleep(10);
323 		wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
324 		wpg_data = readl(wpg_addr);
325 		data = swab32(wpg_data);
326 		if (HPC_I2CSTATUS_CHECK(data))
327 			break;
328 		i--;
329 	}
330 	if (i == 0) {
331 		debug("ctrl_read - Error : I2C timeout\n");
332 		rc = HPC_ERROR;
333 	}
334 
335 	debug_polling("%s Exit rc[%x]\n", __func__, rc);
336 	return (rc);
337 }
338 
339 //------------------------------------------------------------
340 //  Read from ISA type HPC
341 //------------------------------------------------------------
342 static u8 isa_ctrl_read(struct controller *ctlr_ptr, u8 offset)
343 {
344 	u16 start_address;
345 	u16 end_address;
346 	u8 data;
347 
348 	start_address = ctlr_ptr->u.isa_ctlr.io_start;
349 	end_address = ctlr_ptr->u.isa_ctlr.io_end;
350 	data = inb(start_address + offset);
351 	return data;
352 }
353 
354 //--------------------------------------------------------------
355 // Write to ISA type HPC
356 //--------------------------------------------------------------
357 static void isa_ctrl_write(struct controller *ctlr_ptr, u8 offset, u8 data)
358 {
359 	u16 start_address;
360 	u16 port_address;
361 
362 	start_address = ctlr_ptr->u.isa_ctlr.io_start;
363 	port_address = start_address + (u16) offset;
364 	outb(data, port_address);
365 }
366 
367 static u8 pci_ctrl_read(struct controller *ctrl, u8 offset)
368 {
369 	u8 data = 0x00;
370 	debug("inside pci_ctrl_read\n");
371 	if (ctrl->ctrl_dev)
372 		pci_read_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
373 	return data;
374 }
375 
376 static u8 pci_ctrl_write(struct controller *ctrl, u8 offset, u8 data)
377 {
378 	u8 rc = -ENODEV;
379 	debug("inside pci_ctrl_write\n");
380 	if (ctrl->ctrl_dev) {
381 		pci_write_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
382 		rc = 0;
383 	}
384 	return rc;
385 }
386 
387 static u8 ctrl_read(struct controller *ctlr, void __iomem *base, u8 offset)
388 {
389 	u8 rc;
390 	switch (ctlr->ctlr_type) {
391 	case 0:
392 		rc = isa_ctrl_read(ctlr, offset);
393 		break;
394 	case 1:
395 		rc = pci_ctrl_read(ctlr, offset);
396 		break;
397 	case 2:
398 	case 4:
399 		rc = i2c_ctrl_read(ctlr, base, offset);
400 		break;
401 	default:
402 		return -ENODEV;
403 	}
404 	return rc;
405 }
406 
407 static u8 ctrl_write(struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
408 {
409 	u8 rc = 0;
410 	switch (ctlr->ctlr_type) {
411 	case 0:
412 		isa_ctrl_write(ctlr, offset, data);
413 		break;
414 	case 1:
415 		rc = pci_ctrl_write(ctlr, offset, data);
416 		break;
417 	case 2:
418 	case 4:
419 		rc = i2c_ctrl_write(ctlr, base, offset, data);
420 		break;
421 	default:
422 		return -ENODEV;
423 	}
424 	return rc;
425 }
426 /*----------------------------------------------------------------------
427 * Name:    hpc_writecmdtoindex()
428 *
429 * Action:  convert a write command to proper index within a controller
430 *
431 * Return   index, HPC_ERROR
432 *---------------------------------------------------------------------*/
433 static u8 hpc_writecmdtoindex(u8 cmd, u8 index)
434 {
435 	u8 rc;
436 
437 	switch (cmd) {
438 	case HPC_CTLR_ENABLEIRQ:	// 0x00.N.15
439 	case HPC_CTLR_CLEARIRQ:	// 0x06.N.15
440 	case HPC_CTLR_RESET:	// 0x07.N.15
441 	case HPC_CTLR_IRQSTEER:	// 0x08.N.15
442 	case HPC_CTLR_DISABLEIRQ:	// 0x01.N.15
443 	case HPC_ALLSLOT_ON:	// 0x11.N.15
444 	case HPC_ALLSLOT_OFF:	// 0x12.N.15
445 		rc = 0x0F;
446 		break;
447 
448 	case HPC_SLOT_OFF:	// 0x02.Y.0-14
449 	case HPC_SLOT_ON:	// 0x03.Y.0-14
450 	case HPC_SLOT_ATTNOFF:	// 0x04.N.0-14
451 	case HPC_SLOT_ATTNON:	// 0x05.N.0-14
452 	case HPC_SLOT_BLINKLED:	// 0x13.N.0-14
453 		rc = index;
454 		break;
455 
456 	case HPC_BUS_33CONVMODE:
457 	case HPC_BUS_66CONVMODE:
458 	case HPC_BUS_66PCIXMODE:
459 	case HPC_BUS_100PCIXMODE:
460 	case HPC_BUS_133PCIXMODE:
461 		rc = index + WPG_1ST_BUS_INDEX - 1;
462 		break;
463 
464 	default:
465 		err("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
466 		rc = HPC_ERROR;
467 	}
468 
469 	return rc;
470 }
471 
472 /*----------------------------------------------------------------------
473 * Name:    hpc_readcmdtoindex()
474 *
475 * Action:  convert a read command to proper index within a controller
476 *
477 * Return   index, HPC_ERROR
478 *---------------------------------------------------------------------*/
479 static u8 hpc_readcmdtoindex(u8 cmd, u8 index)
480 {
481 	u8 rc;
482 
483 	switch (cmd) {
484 	case READ_CTLRSTATUS:
485 		rc = 0x0F;
486 		break;
487 	case READ_SLOTSTATUS:
488 	case READ_ALLSTAT:
489 		rc = index;
490 		break;
491 	case READ_EXTSLOTSTATUS:
492 		rc = index + WPG_1ST_EXTSLOT_INDEX;
493 		break;
494 	case READ_BUSSTATUS:
495 		rc = index + WPG_1ST_BUS_INDEX - 1;
496 		break;
497 	case READ_SLOTLATCHLOWREG:
498 		rc = 0x28;
499 		break;
500 	case READ_REVLEVEL:
501 		rc = 0x25;
502 		break;
503 	case READ_HPCOPTIONS:
504 		rc = 0x27;
505 		break;
506 	default:
507 		rc = HPC_ERROR;
508 	}
509 	return rc;
510 }
511 
512 /*----------------------------------------------------------------------
513 * Name:    HPCreadslot()
514 *
515 * Action:  issue a READ command to HPC
516 *
517 * Input:   pslot   - cannot be NULL for READ_ALLSTAT
518 *          pstatus - can be NULL for READ_ALLSTAT
519 *
520 * Return   0 or error codes
521 *---------------------------------------------------------------------*/
522 int ibmphp_hpc_readslot(struct slot *pslot, u8 cmd, u8 *pstatus)
523 {
524 	void __iomem *wpg_bbar = NULL;
525 	struct controller *ctlr_ptr;
526 	u8 index, status;
527 	int rc = 0;
528 	int busindex;
529 
530 	debug_polling("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus);
531 
532 	if ((pslot == NULL)
533 	    || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
534 		rc = -EINVAL;
535 		err("%s - Error invalid pointer, rc[%d]\n", __func__, rc);
536 		return rc;
537 	}
538 
539 	if (cmd == READ_BUSSTATUS) {
540 		busindex = ibmphp_get_bus_index(pslot->bus);
541 		if (busindex < 0) {
542 			rc = -EINVAL;
543 			err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
544 			return rc;
545 		} else
546 			index = (u8) busindex;
547 	} else
548 		index = pslot->ctlr_index;
549 
550 	index = hpc_readcmdtoindex(cmd, index);
551 
552 	if (index == HPC_ERROR) {
553 		rc = -EINVAL;
554 		err("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc);
555 		return rc;
556 	}
557 
558 	ctlr_ptr = pslot->ctrl;
559 
560 	get_hpc_access();
561 
562 	//--------------------------------------------------------------------
563 	// map physical address to logical address
564 	//--------------------------------------------------------------------
565 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
566 		wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
567 
568 	//--------------------------------------------------------------------
569 	// check controller status before reading
570 	//--------------------------------------------------------------------
571 	rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
572 	if (!rc) {
573 		switch (cmd) {
574 		case READ_ALLSTAT:
575 			// update the slot structure
576 			pslot->ctrl->status = status;
577 			pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
578 			rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
579 						       &status);
580 			if (!rc)
581 				pslot->ext_status = ctrl_read(ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
582 
583 			break;
584 
585 		case READ_SLOTSTATUS:
586 			// DO NOT update the slot structure
587 			*pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
588 			break;
589 
590 		case READ_EXTSLOTSTATUS:
591 			// DO NOT update the slot structure
592 			*pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
593 			break;
594 
595 		case READ_CTLRSTATUS:
596 			// DO NOT update the slot structure
597 			*pstatus = status;
598 			break;
599 
600 		case READ_BUSSTATUS:
601 			pslot->busstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
602 			break;
603 		case READ_REVLEVEL:
604 			*pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
605 			break;
606 		case READ_HPCOPTIONS:
607 			*pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
608 			break;
609 		case READ_SLOTLATCHLOWREG:
610 			// DO NOT update the slot structure
611 			*pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
612 			break;
613 
614 			// Not used
615 		case READ_ALLSLOT:
616 			list_for_each_entry(pslot, &ibmphp_slot_head,
617 					    ibm_slot_list) {
618 				index = pslot->ctlr_index;
619 				rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr,
620 								wpg_bbar, &status);
621 				if (!rc) {
622 					pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
623 					rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT,
624 									ctlr_ptr, wpg_bbar, &status);
625 					if (!rc)
626 						pslot->ext_status =
627 						    ctrl_read(ctlr_ptr, wpg_bbar,
628 								index + WPG_1ST_EXTSLOT_INDEX);
629 				} else {
630 					err("%s - Error ctrl_read failed\n", __func__);
631 					rc = -EINVAL;
632 					break;
633 				}
634 			}
635 			break;
636 		default:
637 			rc = -EINVAL;
638 			break;
639 		}
640 	}
641 	//--------------------------------------------------------------------
642 	// cleanup
643 	//--------------------------------------------------------------------
644 
645 	// remove physical to logical address mapping
646 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
647 		iounmap(wpg_bbar);
648 
649 	free_hpc_access();
650 
651 	debug_polling("%s - Exit rc[%d]\n", __func__, rc);
652 	return rc;
653 }
654 
655 /*----------------------------------------------------------------------
656 * Name:    ibmphp_hpc_writeslot()
657 *
658 * Action: issue a WRITE command to HPC
659 *---------------------------------------------------------------------*/
660 int ibmphp_hpc_writeslot(struct slot *pslot, u8 cmd)
661 {
662 	void __iomem *wpg_bbar = NULL;
663 	struct controller *ctlr_ptr;
664 	u8 index, status;
665 	int busindex;
666 	u8 done;
667 	int rc = 0;
668 	int timeout;
669 
670 	debug_polling("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd);
671 	if (pslot == NULL) {
672 		rc = -EINVAL;
673 		err("%s - Error Exit rc[%d]\n", __func__, rc);
674 		return rc;
675 	}
676 
677 	if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
678 		(cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
679 		(cmd == HPC_BUS_133PCIXMODE)) {
680 		busindex = ibmphp_get_bus_index(pslot->bus);
681 		if (busindex < 0) {
682 			rc = -EINVAL;
683 			err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
684 			return rc;
685 		} else
686 			index = (u8) busindex;
687 	} else
688 		index = pslot->ctlr_index;
689 
690 	index = hpc_writecmdtoindex(cmd, index);
691 
692 	if (index == HPC_ERROR) {
693 		rc = -EINVAL;
694 		err("%s - Error Exit rc[%d]\n", __func__, rc);
695 		return rc;
696 	}
697 
698 	ctlr_ptr = pslot->ctrl;
699 
700 	get_hpc_access();
701 
702 	//--------------------------------------------------------------------
703 	// map physical address to logical address
704 	//--------------------------------------------------------------------
705 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
706 		wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
707 
708 		debug("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__,
709 		ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
710 		ctlr_ptr->u.wpeg_ctlr.i2c_addr);
711 	}
712 	//--------------------------------------------------------------------
713 	// check controller status before writing
714 	//--------------------------------------------------------------------
715 	rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
716 	if (!rc) {
717 
718 		ctrl_write(ctlr_ptr, wpg_bbar, index, cmd);
719 
720 		//--------------------------------------------------------------------
721 		// check controller is still not working on the command
722 		//--------------------------------------------------------------------
723 		timeout = CMD_COMPLETE_TOUT_SEC;
724 		done = 0;
725 		while (!done) {
726 			rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
727 							&status);
728 			if (!rc) {
729 				if (NEEDTOCHECK_CMDSTATUS(cmd)) {
730 					if (CTLR_FINISHED(status) == HPC_CTLR_FINISHED_YES)
731 						done = 1;
732 				} else
733 					done = 1;
734 			}
735 			if (!done) {
736 				msleep(1000);
737 				if (timeout < 1) {
738 					done = 1;
739 					err("%s - Error command complete timeout\n", __func__);
740 					rc = -EFAULT;
741 				} else
742 					timeout--;
743 			}
744 		}
745 		ctlr_ptr->status = status;
746 	}
747 	// cleanup
748 
749 	// remove physical to logical address mapping
750 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
751 		iounmap(wpg_bbar);
752 	free_hpc_access();
753 
754 	debug_polling("%s - Exit rc[%d]\n", __func__, rc);
755 	return rc;
756 }
757 
758 /*----------------------------------------------------------------------
759 * Name:    get_hpc_access()
760 *
761 * Action: make sure only one process can access HPC at one time
762 *---------------------------------------------------------------------*/
763 static void get_hpc_access(void)
764 {
765 	mutex_lock(&sem_hpcaccess);
766 }
767 
768 /*----------------------------------------------------------------------
769 * Name:    free_hpc_access()
770 *---------------------------------------------------------------------*/
771 void free_hpc_access(void)
772 {
773 	mutex_unlock(&sem_hpcaccess);
774 }
775 
776 /*----------------------------------------------------------------------
777 * Name:    ibmphp_lock_operations()
778 *
779 * Action: make sure only one process can change the data structure
780 *---------------------------------------------------------------------*/
781 void ibmphp_lock_operations(void)
782 {
783 	down(&semOperations);
784 	to_debug = 1;
785 }
786 
787 /*----------------------------------------------------------------------
788 * Name:    ibmphp_unlock_operations()
789 *---------------------------------------------------------------------*/
790 void ibmphp_unlock_operations(void)
791 {
792 	debug("%s - Entry\n", __func__);
793 	up(&semOperations);
794 	to_debug = 0;
795 	debug("%s - Exit\n", __func__);
796 }
797 
798 /*----------------------------------------------------------------------
799 * Name:    poll_hpc()
800 *---------------------------------------------------------------------*/
801 #define POLL_LATCH_REGISTER	0
802 #define POLL_SLOTS		1
803 #define POLL_SLEEP		2
804 static int poll_hpc(void *data)
805 {
806 	struct slot myslot;
807 	struct slot *pslot = NULL;
808 	int rc;
809 	int poll_state = POLL_LATCH_REGISTER;
810 	u8 oldlatchlow = 0x00;
811 	u8 curlatchlow = 0x00;
812 	int poll_count = 0;
813 	u8 ctrl_count = 0x00;
814 
815 	debug("%s - Entry\n", __func__);
816 
817 	while (!kthread_should_stop()) {
818 		/* try to get the lock to do some kind of hardware access */
819 		down(&semOperations);
820 
821 		switch (poll_state) {
822 		case POLL_LATCH_REGISTER:
823 			oldlatchlow = curlatchlow;
824 			ctrl_count = 0x00;
825 			list_for_each_entry(pslot, &ibmphp_slot_head,
826 					    ibm_slot_list) {
827 				if (ctrl_count >= ibmphp_get_total_controllers())
828 					break;
829 				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
830 					ctrl_count++;
831 					if (READ_SLOT_LATCH(pslot->ctrl)) {
832 						rc = ibmphp_hpc_readslot(pslot,
833 									  READ_SLOTLATCHLOWREG,
834 									  &curlatchlow);
835 						if (oldlatchlow != curlatchlow)
836 							process_changeinlatch(oldlatchlow,
837 									       curlatchlow,
838 									       pslot->ctrl);
839 					}
840 				}
841 			}
842 			++poll_count;
843 			poll_state = POLL_SLEEP;
844 			break;
845 		case POLL_SLOTS:
846 			list_for_each_entry(pslot, &ibmphp_slot_head,
847 					    ibm_slot_list) {
848 				// make a copy of the old status
849 				memcpy((void *) &myslot, (void *) pslot,
850 					sizeof(struct slot));
851 				rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
852 				if ((myslot.status != pslot->status)
853 				    || (myslot.ext_status != pslot->ext_status))
854 					process_changeinstatus(pslot, &myslot);
855 			}
856 			ctrl_count = 0x00;
857 			list_for_each_entry(pslot, &ibmphp_slot_head,
858 					    ibm_slot_list) {
859 				if (ctrl_count >= ibmphp_get_total_controllers())
860 					break;
861 				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
862 					ctrl_count++;
863 					if (READ_SLOT_LATCH(pslot->ctrl))
864 						rc = ibmphp_hpc_readslot(pslot,
865 									  READ_SLOTLATCHLOWREG,
866 									  &curlatchlow);
867 				}
868 			}
869 			++poll_count;
870 			poll_state = POLL_SLEEP;
871 			break;
872 		case POLL_SLEEP:
873 			/* don't sleep with a lock on the hardware */
874 			up(&semOperations);
875 			msleep(POLL_INTERVAL_SEC * 1000);
876 
877 			if (kthread_should_stop())
878 				goto out_sleep;
879 
880 			down(&semOperations);
881 
882 			if (poll_count >= POLL_LATCH_CNT) {
883 				poll_count = 0;
884 				poll_state = POLL_SLOTS;
885 			} else
886 				poll_state = POLL_LATCH_REGISTER;
887 			break;
888 		}
889 		/* give up the hardware semaphore */
890 		up(&semOperations);
891 		/* sleep for a short time just for good measure */
892 out_sleep:
893 		msleep(100);
894 	}
895 	up(&sem_exit);
896 	debug("%s - Exit\n", __func__);
897 	return 0;
898 }
899 
900 
901 /*----------------------------------------------------------------------
902 * Name:    process_changeinstatus
903 *
904 * Action:  compare old and new slot status, process the change in status
905 *
906 * Input:   pointer to slot struct, old slot struct
907 *
908 * Return   0 or error codes
909 * Value:
910 *
911 * Side
912 * Effects: None.
913 *
914 * Notes:
915 *---------------------------------------------------------------------*/
916 static int process_changeinstatus(struct slot *pslot, struct slot *poldslot)
917 {
918 	u8 status;
919 	int rc = 0;
920 	u8 disable = 0;
921 	u8 update = 0;
922 
923 	debug("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
924 
925 	// bit 0 - HPC_SLOT_POWER
926 	if ((pslot->status & 0x01) != (poldslot->status & 0x01))
927 		update = 1;
928 
929 	// bit 1 - HPC_SLOT_CONNECT
930 	// ignore
931 
932 	// bit 2 - HPC_SLOT_ATTN
933 	if ((pslot->status & 0x04) != (poldslot->status & 0x04))
934 		update = 1;
935 
936 	// bit 3 - HPC_SLOT_PRSNT2
937 	// bit 4 - HPC_SLOT_PRSNT1
938 	if (((pslot->status & 0x08) != (poldslot->status & 0x08))
939 		|| ((pslot->status & 0x10) != (poldslot->status & 0x10)))
940 		update = 1;
941 
942 	// bit 5 - HPC_SLOT_PWRGD
943 	if ((pslot->status & 0x20) != (poldslot->status & 0x20))
944 		// OFF -> ON: ignore, ON -> OFF: disable slot
945 		if ((poldslot->status & 0x20) && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status)))
946 			disable = 1;
947 
948 	// bit 6 - HPC_SLOT_BUS_SPEED
949 	// ignore
950 
951 	// bit 7 - HPC_SLOT_LATCH
952 	if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
953 		update = 1;
954 		// OPEN -> CLOSE
955 		if (pslot->status & 0x80) {
956 			if (SLOT_PWRGD(pslot->status)) {
957 				// power goes on and off after closing latch
958 				// check again to make sure power is still ON
959 				msleep(1000);
960 				rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &status);
961 				if (SLOT_PWRGD(status))
962 					update = 1;
963 				else	// overwrite power in pslot to OFF
964 					pslot->status &= ~HPC_SLOT_POWER;
965 			}
966 		}
967 		// CLOSE -> OPEN
968 		else if ((SLOT_PWRGD(poldslot->status) == HPC_SLOT_PWRGD_GOOD)
969 			&& (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status))) {
970 			disable = 1;
971 		}
972 		// else - ignore
973 	}
974 	// bit 4 - HPC_SLOT_BLINK_ATTN
975 	if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
976 		update = 1;
977 
978 	if (disable) {
979 		debug("process_changeinstatus - disable slot\n");
980 		pslot->flag = 0;
981 		rc = ibmphp_do_disable_slot(pslot);
982 	}
983 
984 	if (update || disable)
985 		ibmphp_update_slot_info(pslot);
986 
987 	debug("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);
988 
989 	return rc;
990 }
991 
992 /*----------------------------------------------------------------------
993 * Name:    process_changeinlatch
994 *
995 * Action:  compare old and new latch reg status, process the change
996 *
997 * Input:   old and current latch register status
998 *
999 * Return   0 or error codes
1000 * Value:
1001 *---------------------------------------------------------------------*/
1002 static int process_changeinlatch(u8 old, u8 new, struct controller *ctrl)
1003 {
1004 	struct slot myslot, *pslot;
1005 	u8 i;
1006 	u8 mask;
1007 	int rc = 0;
1008 
1009 	debug("%s - Entry old[%x], new[%x]\n", __func__, old, new);
1010 	// bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
1011 
1012 	for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
1013 		mask = 0x01 << i;
1014 		if ((mask & old) != (mask & new)) {
1015 			pslot = ibmphp_get_slot_from_physical_num(i);
1016 			if (pslot) {
1017 				memcpy((void *) &myslot, (void *) pslot, sizeof(struct slot));
1018 				rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
1019 				debug("%s - call process_changeinstatus for slot[%d]\n", __func__, i);
1020 				process_changeinstatus(pslot, &myslot);
1021 			} else {
1022 				rc = -EINVAL;
1023 				err("%s - Error bad pointer for slot[%d]\n", __func__, i);
1024 			}
1025 		}
1026 	}
1027 	debug("%s - Exit rc[%d]\n", __func__, rc);
1028 	return rc;
1029 }
1030 
1031 /*----------------------------------------------------------------------
1032 * Name:    ibmphp_hpc_start_poll_thread
1033 *
1034 * Action:  start polling thread
1035 *---------------------------------------------------------------------*/
1036 int __init ibmphp_hpc_start_poll_thread(void)
1037 {
1038 	debug("%s - Entry\n", __func__);
1039 
1040 	ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll");
1041 	if (IS_ERR(ibmphp_poll_thread)) {
1042 		err("%s - Error, thread not started\n", __func__);
1043 		return PTR_ERR(ibmphp_poll_thread);
1044 	}
1045 	return 0;
1046 }
1047 
1048 /*----------------------------------------------------------------------
1049 * Name:    ibmphp_hpc_stop_poll_thread
1050 *
1051 * Action:  stop polling thread and cleanup
1052 *---------------------------------------------------------------------*/
1053 void __exit ibmphp_hpc_stop_poll_thread(void)
1054 {
1055 	debug("%s - Entry\n", __func__);
1056 
1057 	kthread_stop(ibmphp_poll_thread);
1058 	debug("before locking operations\n");
1059 	ibmphp_lock_operations();
1060 	debug("after locking operations\n");
1061 
1062 	// wait for poll thread to exit
1063 	debug("before sem_exit down\n");
1064 	down(&sem_exit);
1065 	debug("after sem_exit down\n");
1066 
1067 	// cleanup
1068 	debug("before free_hpc_access\n");
1069 	free_hpc_access();
1070 	debug("after free_hpc_access\n");
1071 	ibmphp_unlock_operations();
1072 	debug("after unlock operations\n");
1073 	up(&sem_exit);
1074 	debug("after sem exit up\n");
1075 
1076 	debug("%s - Exit\n", __func__);
1077 }
1078 
1079 /*----------------------------------------------------------------------
1080 * Name:    hpc_wait_ctlr_notworking
1081 *
1082 * Action:  wait until the controller is in a not working state
1083 *
1084 * Return   0, HPC_ERROR
1085 * Value:
1086 *---------------------------------------------------------------------*/
1087 static int hpc_wait_ctlr_notworking(int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
1088 				    u8 *pstatus)
1089 {
1090 	int rc = 0;
1091 	u8 done = 0;
1092 
1093 	debug_polling("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1094 
1095 	while (!done) {
1096 		*pstatus = ctrl_read(ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1097 		if (*pstatus == HPC_ERROR) {
1098 			rc = HPC_ERROR;
1099 			done = 1;
1100 		}
1101 		if (CTLR_WORKING(*pstatus) == HPC_CTLR_WORKING_NO)
1102 			done = 1;
1103 		if (!done) {
1104 			msleep(1000);
1105 			if (timeout < 1) {
1106 				done = 1;
1107 				err("HPCreadslot - Error ctlr timeout\n");
1108 				rc = HPC_ERROR;
1109 			} else
1110 				timeout--;
1111 		}
1112 	}
1113 	debug_polling("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1114 	return rc;
1115 }
1116