cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ibmphp_hpc.c (31949B)


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