linux/drivers/pci/hotplug/ibmphp_hpc.c
<<
>>
Prefs
   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        u16 end_address;
 329        u8 data;
 330
 331        start_address = ctlr_ptr->u.isa_ctlr.io_start;
 332        end_address = ctlr_ptr->u.isa_ctlr.io_end;
 333        data = inb(start_address + offset);
 334        return data;
 335}
 336
 337//--------------------------------------------------------------
 338// Write to ISA type HPC
 339//--------------------------------------------------------------
 340static void isa_ctrl_write(struct controller *ctlr_ptr, u8 offset, u8 data)
 341{
 342        u16 start_address;
 343        u16 port_address;
 344
 345        start_address = ctlr_ptr->u.isa_ctlr.io_start;
 346        port_address = start_address + (u16) offset;
 347        outb(data, port_address);
 348}
 349
 350static u8 pci_ctrl_read(struct controller *ctrl, u8 offset)
 351{
 352        u8 data = 0x00;
 353        debug("inside pci_ctrl_read\n");
 354        if (ctrl->ctrl_dev)
 355                pci_read_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
 356        return data;
 357}
 358
 359static u8 pci_ctrl_write(struct controller *ctrl, u8 offset, u8 data)
 360{
 361        u8 rc = -ENODEV;
 362        debug("inside pci_ctrl_write\n");
 363        if (ctrl->ctrl_dev) {
 364                pci_write_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
 365                rc = 0;
 366        }
 367        return rc;
 368}
 369
 370static u8 ctrl_read(struct controller *ctlr, void __iomem *base, u8 offset)
 371{
 372        u8 rc;
 373        switch (ctlr->ctlr_type) {
 374        case 0:
 375                rc = isa_ctrl_read(ctlr, offset);
 376                break;
 377        case 1:
 378                rc = pci_ctrl_read(ctlr, offset);
 379                break;
 380        case 2:
 381        case 4:
 382                rc = i2c_ctrl_read(ctlr, base, offset);
 383                break;
 384        default:
 385                return -ENODEV;
 386        }
 387        return rc;
 388}
 389
 390static u8 ctrl_write(struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
 391{
 392        u8 rc = 0;
 393        switch (ctlr->ctlr_type) {
 394        case 0:
 395                isa_ctrl_write(ctlr, offset, data);
 396                break;
 397        case 1:
 398                rc = pci_ctrl_write(ctlr, offset, data);
 399                break;
 400        case 2:
 401        case 4:
 402                rc = i2c_ctrl_write(ctlr, base, offset, data);
 403                break;
 404        default:
 405                return -ENODEV;
 406        }
 407        return rc;
 408}
 409/*----------------------------------------------------------------------
 410* Name:    hpc_writecmdtoindex()
 411*
 412* Action:  convert a write command to proper index within a controller
 413*
 414* Return   index, HPC_ERROR
 415*---------------------------------------------------------------------*/
 416static u8 hpc_writecmdtoindex(u8 cmd, u8 index)
 417{
 418        u8 rc;
 419
 420        switch (cmd) {
 421        case HPC_CTLR_ENABLEIRQ:        // 0x00.N.15
 422        case HPC_CTLR_CLEARIRQ: // 0x06.N.15
 423        case HPC_CTLR_RESET:    // 0x07.N.15
 424        case HPC_CTLR_IRQSTEER: // 0x08.N.15
 425        case HPC_CTLR_DISABLEIRQ:       // 0x01.N.15
 426        case HPC_ALLSLOT_ON:    // 0x11.N.15
 427        case HPC_ALLSLOT_OFF:   // 0x12.N.15
 428                rc = 0x0F;
 429                break;
 430
 431        case HPC_SLOT_OFF:      // 0x02.Y.0-14
 432        case HPC_SLOT_ON:       // 0x03.Y.0-14
 433        case HPC_SLOT_ATTNOFF:  // 0x04.N.0-14
 434        case HPC_SLOT_ATTNON:   // 0x05.N.0-14
 435        case HPC_SLOT_BLINKLED: // 0x13.N.0-14
 436                rc = index;
 437                break;
 438
 439        case HPC_BUS_33CONVMODE:
 440        case HPC_BUS_66CONVMODE:
 441        case HPC_BUS_66PCIXMODE:
 442        case HPC_BUS_100PCIXMODE:
 443        case HPC_BUS_133PCIXMODE:
 444                rc = index + WPG_1ST_BUS_INDEX - 1;
 445                break;
 446
 447        default:
 448                err("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
 449                rc = HPC_ERROR;
 450        }
 451
 452        return rc;
 453}
 454
 455/*----------------------------------------------------------------------
 456* Name:    hpc_readcmdtoindex()
 457*
 458* Action:  convert a read command to proper index within a controller
 459*
 460* Return   index, HPC_ERROR
 461*---------------------------------------------------------------------*/
 462static u8 hpc_readcmdtoindex(u8 cmd, u8 index)
 463{
 464        u8 rc;
 465
 466        switch (cmd) {
 467        case READ_CTLRSTATUS:
 468                rc = 0x0F;
 469                break;
 470        case READ_SLOTSTATUS:
 471        case READ_ALLSTAT:
 472                rc = index;
 473                break;
 474        case READ_EXTSLOTSTATUS:
 475                rc = index + WPG_1ST_EXTSLOT_INDEX;
 476                break;
 477        case READ_BUSSTATUS:
 478                rc = index + WPG_1ST_BUS_INDEX - 1;
 479                break;
 480        case READ_SLOTLATCHLOWREG:
 481                rc = 0x28;
 482                break;
 483        case READ_REVLEVEL:
 484                rc = 0x25;
 485                break;
 486        case READ_HPCOPTIONS:
 487                rc = 0x27;
 488                break;
 489        default:
 490                rc = HPC_ERROR;
 491        }
 492        return rc;
 493}
 494
 495/*----------------------------------------------------------------------
 496* Name:    HPCreadslot()
 497*
 498* Action:  issue a READ command to HPC
 499*
 500* Input:   pslot   - cannot be NULL for READ_ALLSTAT
 501*          pstatus - can be NULL for READ_ALLSTAT
 502*
 503* Return   0 or error codes
 504*---------------------------------------------------------------------*/
 505int ibmphp_hpc_readslot(struct slot *pslot, u8 cmd, u8 *pstatus)
 506{
 507        void __iomem *wpg_bbar = NULL;
 508        struct controller *ctlr_ptr;
 509        u8 index, status;
 510        int rc = 0;
 511        int busindex;
 512
 513        debug_polling("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus);
 514
 515        if ((pslot == NULL)
 516            || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
 517                rc = -EINVAL;
 518                err("%s - Error invalid pointer, rc[%d]\n", __func__, rc);
 519                return rc;
 520        }
 521
 522        if (cmd == READ_BUSSTATUS) {
 523                busindex = ibmphp_get_bus_index(pslot->bus);
 524                if (busindex < 0) {
 525                        rc = -EINVAL;
 526                        err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
 527                        return rc;
 528                } else
 529                        index = (u8) busindex;
 530        } else
 531                index = pslot->ctlr_index;
 532
 533        index = hpc_readcmdtoindex(cmd, index);
 534
 535        if (index == HPC_ERROR) {
 536                rc = -EINVAL;
 537                err("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc);
 538                return rc;
 539        }
 540
 541        ctlr_ptr = pslot->ctrl;
 542
 543        get_hpc_access();
 544
 545        //--------------------------------------------------------------------
 546        // map physical address to logical address
 547        //--------------------------------------------------------------------
 548        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 549                wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 550
 551        //--------------------------------------------------------------------
 552        // check controller status before reading
 553        //--------------------------------------------------------------------
 554        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
 555        if (!rc) {
 556                switch (cmd) {
 557                case READ_ALLSTAT:
 558                        // update the slot structure
 559                        pslot->ctrl->status = status;
 560                        pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
 561                        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
 562                                                       &status);
 563                        if (!rc)
 564                                pslot->ext_status = ctrl_read(ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
 565
 566                        break;
 567
 568                case READ_SLOTSTATUS:
 569                        // DO NOT update the slot structure
 570                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 571                        break;
 572
 573                case READ_EXTSLOTSTATUS:
 574                        // DO NOT update the slot structure
 575                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 576                        break;
 577
 578                case READ_CTLRSTATUS:
 579                        // DO NOT update the slot structure
 580                        *pstatus = status;
 581                        break;
 582
 583                case READ_BUSSTATUS:
 584                        pslot->busstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 585                        break;
 586                case READ_REVLEVEL:
 587                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 588                        break;
 589                case READ_HPCOPTIONS:
 590                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 591                        break;
 592                case READ_SLOTLATCHLOWREG:
 593                        // DO NOT update the slot structure
 594                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 595                        break;
 596
 597                        // Not used
 598                case READ_ALLSLOT:
 599                        list_for_each_entry(pslot, &ibmphp_slot_head,
 600                                            ibm_slot_list) {
 601                                index = pslot->ctlr_index;
 602                                rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr,
 603                                                                wpg_bbar, &status);
 604                                if (!rc) {
 605                                        pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
 606                                        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT,
 607                                                                        ctlr_ptr, wpg_bbar, &status);
 608                                        if (!rc)
 609                                                pslot->ext_status =
 610                                                    ctrl_read(ctlr_ptr, wpg_bbar,
 611                                                                index + WPG_1ST_EXTSLOT_INDEX);
 612                                } else {
 613                                        err("%s - Error ctrl_read failed\n", __func__);
 614                                        rc = -EINVAL;
 615                                        break;
 616                                }
 617                        }
 618                        break;
 619                default:
 620                        rc = -EINVAL;
 621                        break;
 622                }
 623        }
 624        //--------------------------------------------------------------------
 625        // cleanup
 626        //--------------------------------------------------------------------
 627
 628        // remove physical to logical address mapping
 629        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 630                iounmap(wpg_bbar);
 631
 632        free_hpc_access();
 633
 634        debug_polling("%s - Exit rc[%d]\n", __func__, rc);
 635        return rc;
 636}
 637
 638/*----------------------------------------------------------------------
 639* Name:    ibmphp_hpc_writeslot()
 640*
 641* Action: issue a WRITE command to HPC
 642*---------------------------------------------------------------------*/
 643int ibmphp_hpc_writeslot(struct slot *pslot, u8 cmd)
 644{
 645        void __iomem *wpg_bbar = NULL;
 646        struct controller *ctlr_ptr;
 647        u8 index, status;
 648        int busindex;
 649        u8 done;
 650        int rc = 0;
 651        int timeout;
 652
 653        debug_polling("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd);
 654        if (pslot == NULL) {
 655                rc = -EINVAL;
 656                err("%s - Error Exit rc[%d]\n", __func__, rc);
 657                return rc;
 658        }
 659
 660        if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
 661                (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
 662                (cmd == HPC_BUS_133PCIXMODE)) {
 663                busindex = ibmphp_get_bus_index(pslot->bus);
 664                if (busindex < 0) {
 665                        rc = -EINVAL;
 666                        err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
 667                        return rc;
 668                } else
 669                        index = (u8) busindex;
 670        } else
 671                index = pslot->ctlr_index;
 672
 673        index = hpc_writecmdtoindex(cmd, index);
 674
 675        if (index == HPC_ERROR) {
 676                rc = -EINVAL;
 677                err("%s - Error Exit rc[%d]\n", __func__, rc);
 678                return rc;
 679        }
 680
 681        ctlr_ptr = pslot->ctrl;
 682
 683        get_hpc_access();
 684
 685        //--------------------------------------------------------------------
 686        // map physical address to logical address
 687        //--------------------------------------------------------------------
 688        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
 689                wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 690
 691                debug("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__,
 692                ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
 693                ctlr_ptr->u.wpeg_ctlr.i2c_addr);
 694        }
 695        //--------------------------------------------------------------------
 696        // check controller status before writing
 697        //--------------------------------------------------------------------
 698        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
 699        if (!rc) {
 700
 701                ctrl_write(ctlr_ptr, wpg_bbar, index, cmd);
 702
 703                //--------------------------------------------------------------------
 704                // check controller is still not working on the command
 705                //--------------------------------------------------------------------
 706                timeout = CMD_COMPLETE_TOUT_SEC;
 707                done = 0;
 708                while (!done) {
 709                        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
 710                                                        &status);
 711                        if (!rc) {
 712                                if (NEEDTOCHECK_CMDSTATUS(cmd)) {
 713                                        if (CTLR_FINISHED(status) == HPC_CTLR_FINISHED_YES)
 714                                                done = 1;
 715                                } else
 716                                        done = 1;
 717                        }
 718                        if (!done) {
 719                                msleep(1000);
 720                                if (timeout < 1) {
 721                                        done = 1;
 722                                        err("%s - Error command complete timeout\n", __func__);
 723                                        rc = -EFAULT;
 724                                } else
 725                                        timeout--;
 726                        }
 727                }
 728                ctlr_ptr->status = status;
 729        }
 730        // cleanup
 731
 732        // remove physical to logical address mapping
 733        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 734                iounmap(wpg_bbar);
 735        free_hpc_access();
 736
 737        debug_polling("%s - Exit rc[%d]\n", __func__, rc);
 738        return rc;
 739}
 740
 741/*----------------------------------------------------------------------
 742* Name:    get_hpc_access()
 743*
 744* Action: make sure only one process can access HPC at one time
 745*---------------------------------------------------------------------*/
 746static void get_hpc_access(void)
 747{
 748        mutex_lock(&sem_hpcaccess);
 749}
 750
 751/*----------------------------------------------------------------------
 752* Name:    free_hpc_access()
 753*---------------------------------------------------------------------*/
 754void free_hpc_access(void)
 755{
 756        mutex_unlock(&sem_hpcaccess);
 757}
 758
 759/*----------------------------------------------------------------------
 760* Name:    ibmphp_lock_operations()
 761*
 762* Action: make sure only one process can change the data structure
 763*---------------------------------------------------------------------*/
 764void ibmphp_lock_operations(void)
 765{
 766        mutex_lock(&operations_mutex);
 767        to_debug = 1;
 768}
 769
 770/*----------------------------------------------------------------------
 771* Name:    ibmphp_unlock_operations()
 772*---------------------------------------------------------------------*/
 773void ibmphp_unlock_operations(void)
 774{
 775        debug("%s - Entry\n", __func__);
 776        mutex_unlock(&operations_mutex);
 777        to_debug = 0;
 778        debug("%s - Exit\n", __func__);
 779}
 780
 781/*----------------------------------------------------------------------
 782* Name:    poll_hpc()
 783*---------------------------------------------------------------------*/
 784#define POLL_LATCH_REGISTER     0
 785#define POLL_SLOTS              1
 786#define POLL_SLEEP              2
 787static int poll_hpc(void *data)
 788{
 789        struct slot myslot;
 790        struct slot *pslot = NULL;
 791        int rc;
 792        int poll_state = POLL_LATCH_REGISTER;
 793        u8 oldlatchlow = 0x00;
 794        u8 curlatchlow = 0x00;
 795        int poll_count = 0;
 796        u8 ctrl_count = 0x00;
 797
 798        debug("%s - Entry\n", __func__);
 799
 800        while (!kthread_should_stop()) {
 801                /* try to get the lock to do some kind of hardware access */
 802                mutex_lock(&operations_mutex);
 803
 804                switch (poll_state) {
 805                case POLL_LATCH_REGISTER:
 806                        oldlatchlow = curlatchlow;
 807                        ctrl_count = 0x00;
 808                        list_for_each_entry(pslot, &ibmphp_slot_head,
 809                                            ibm_slot_list) {
 810                                if (ctrl_count >= ibmphp_get_total_controllers())
 811                                        break;
 812                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
 813                                        ctrl_count++;
 814                                        if (READ_SLOT_LATCH(pslot->ctrl)) {
 815                                                rc = ibmphp_hpc_readslot(pslot,
 816                                                                          READ_SLOTLATCHLOWREG,
 817                                                                          &curlatchlow);
 818                                                if (oldlatchlow != curlatchlow)
 819                                                        process_changeinlatch(oldlatchlow,
 820                                                                               curlatchlow,
 821                                                                               pslot->ctrl);
 822                                        }
 823                                }
 824                        }
 825                        ++poll_count;
 826                        poll_state = POLL_SLEEP;
 827                        break;
 828                case POLL_SLOTS:
 829                        list_for_each_entry(pslot, &ibmphp_slot_head,
 830                                            ibm_slot_list) {
 831                                // make a copy of the old status
 832                                memcpy((void *) &myslot, (void *) pslot,
 833                                        sizeof(struct slot));
 834                                rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
 835                                if ((myslot.status != pslot->status)
 836                                    || (myslot.ext_status != pslot->ext_status))
 837                                        process_changeinstatus(pslot, &myslot);
 838                        }
 839                        ctrl_count = 0x00;
 840                        list_for_each_entry(pslot, &ibmphp_slot_head,
 841                                            ibm_slot_list) {
 842                                if (ctrl_count >= ibmphp_get_total_controllers())
 843                                        break;
 844                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
 845                                        ctrl_count++;
 846                                        if (READ_SLOT_LATCH(pslot->ctrl))
 847                                                rc = ibmphp_hpc_readslot(pslot,
 848                                                                          READ_SLOTLATCHLOWREG,
 849                                                                          &curlatchlow);
 850                                }
 851                        }
 852                        ++poll_count;
 853                        poll_state = POLL_SLEEP;
 854                        break;
 855                case POLL_SLEEP:
 856                        /* don't sleep with a lock on the hardware */
 857                        mutex_unlock(&operations_mutex);
 858                        msleep(POLL_INTERVAL_SEC * 1000);
 859
 860                        if (kthread_should_stop())
 861                                goto out_sleep;
 862
 863                        mutex_lock(&operations_mutex);
 864
 865                        if (poll_count >= POLL_LATCH_CNT) {
 866                                poll_count = 0;
 867                                poll_state = POLL_SLOTS;
 868                        } else
 869                                poll_state = POLL_LATCH_REGISTER;
 870                        break;
 871                }
 872                /* give up the hardware semaphore */
 873                mutex_unlock(&operations_mutex);
 874                /* sleep for a short time just for good measure */
 875out_sleep:
 876                msleep(100);
 877        }
 878        complete(&exit_complete);
 879        debug("%s - Exit\n", __func__);
 880        return 0;
 881}
 882
 883
 884/*----------------------------------------------------------------------
 885* Name:    process_changeinstatus
 886*
 887* Action:  compare old and new slot status, process the change in status
 888*
 889* Input:   pointer to slot struct, old slot struct
 890*
 891* Return   0 or error codes
 892* Value:
 893*
 894* Side
 895* Effects: None.
 896*
 897* Notes:
 898*---------------------------------------------------------------------*/
 899static int process_changeinstatus(struct slot *pslot, struct slot *poldslot)
 900{
 901        u8 status;
 902        int rc = 0;
 903        u8 disable = 0;
 904        u8 update = 0;
 905
 906        debug("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
 907
 908        // bit 0 - HPC_SLOT_POWER
 909        if ((pslot->status & 0x01) != (poldslot->status & 0x01))
 910                update = 1;
 911
 912        // bit 1 - HPC_SLOT_CONNECT
 913        // ignore
 914
 915        // bit 2 - HPC_SLOT_ATTN
 916        if ((pslot->status & 0x04) != (poldslot->status & 0x04))
 917                update = 1;
 918
 919        // bit 3 - HPC_SLOT_PRSNT2
 920        // bit 4 - HPC_SLOT_PRSNT1
 921        if (((pslot->status & 0x08) != (poldslot->status & 0x08))
 922                || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
 923                update = 1;
 924
 925        // bit 5 - HPC_SLOT_PWRGD
 926        if ((pslot->status & 0x20) != (poldslot->status & 0x20))
 927                // OFF -> ON: ignore, ON -> OFF: disable slot
 928                if ((poldslot->status & 0x20) && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status)))
 929                        disable = 1;
 930
 931        // bit 6 - HPC_SLOT_BUS_SPEED
 932        // ignore
 933
 934        // bit 7 - HPC_SLOT_LATCH
 935        if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
 936                update = 1;
 937                // OPEN -> CLOSE
 938                if (pslot->status & 0x80) {
 939                        if (SLOT_PWRGD(pslot->status)) {
 940                                // power goes on and off after closing latch
 941                                // check again to make sure power is still ON
 942                                msleep(1000);
 943                                rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &status);
 944                                if (SLOT_PWRGD(status))
 945                                        update = 1;
 946                                else    // overwrite power in pslot to OFF
 947                                        pslot->status &= ~HPC_SLOT_POWER;
 948                        }
 949                }
 950                // CLOSE -> OPEN
 951                else if ((SLOT_PWRGD(poldslot->status) == HPC_SLOT_PWRGD_GOOD)
 952                        && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status))) {
 953                        disable = 1;
 954                }
 955                // else - ignore
 956        }
 957        // bit 4 - HPC_SLOT_BLINK_ATTN
 958        if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
 959                update = 1;
 960
 961        if (disable) {
 962                debug("process_changeinstatus - disable slot\n");
 963                pslot->flag = 0;
 964                rc = ibmphp_do_disable_slot(pslot);
 965        }
 966
 967        if (update || disable)
 968                ibmphp_update_slot_info(pslot);
 969
 970        debug("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);
 971
 972        return rc;
 973}
 974
 975/*----------------------------------------------------------------------
 976* Name:    process_changeinlatch
 977*
 978* Action:  compare old and new latch reg status, process the change
 979*
 980* Input:   old and current latch register status
 981*
 982* Return   0 or error codes
 983* Value:
 984*---------------------------------------------------------------------*/
 985static int process_changeinlatch(u8 old, u8 new, struct controller *ctrl)
 986{
 987        struct slot myslot, *pslot;
 988        u8 i;
 989        u8 mask;
 990        int rc = 0;
 991
 992        debug("%s - Entry old[%x], new[%x]\n", __func__, old, new);
 993        // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
 994
 995        for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
 996                mask = 0x01 << i;
 997                if ((mask & old) != (mask & new)) {
 998                        pslot = ibmphp_get_slot_from_physical_num(i);
 999                        if (pslot) {
1000                                memcpy((void *) &myslot, (void *) pslot, sizeof(struct slot));
1001                                rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
1002                                debug("%s - call process_changeinstatus for slot[%d]\n", __func__, i);
1003                                process_changeinstatus(pslot, &myslot);
1004                        } else {
1005                                rc = -EINVAL;
1006                                err("%s - Error bad pointer for slot[%d]\n", __func__, i);
1007                        }
1008                }
1009        }
1010        debug("%s - Exit rc[%d]\n", __func__, rc);
1011        return rc;
1012}
1013
1014/*----------------------------------------------------------------------
1015* Name:    ibmphp_hpc_start_poll_thread
1016*
1017* Action:  start polling thread
1018*---------------------------------------------------------------------*/
1019int __init ibmphp_hpc_start_poll_thread(void)
1020{
1021        debug("%s - Entry\n", __func__);
1022
1023        ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll");
1024        if (IS_ERR(ibmphp_poll_thread)) {
1025                err("%s - Error, thread not started\n", __func__);
1026                return PTR_ERR(ibmphp_poll_thread);
1027        }
1028        return 0;
1029}
1030
1031/*----------------------------------------------------------------------
1032* Name:    ibmphp_hpc_stop_poll_thread
1033*
1034* Action:  stop polling thread and cleanup
1035*---------------------------------------------------------------------*/
1036void __exit ibmphp_hpc_stop_poll_thread(void)
1037{
1038        debug("%s - Entry\n", __func__);
1039
1040        kthread_stop(ibmphp_poll_thread);
1041        debug("before locking operations\n");
1042        ibmphp_lock_operations();
1043        debug("after locking operations\n");
1044
1045        // wait for poll thread to exit
1046        debug("before exit_complete down\n");
1047        wait_for_completion(&exit_complete);
1048        debug("after exit_completion down\n");
1049
1050        // cleanup
1051        debug("before free_hpc_access\n");
1052        free_hpc_access();
1053        debug("after free_hpc_access\n");
1054        ibmphp_unlock_operations();
1055        debug("after unlock operations\n");
1056
1057        debug("%s - Exit\n", __func__);
1058}
1059
1060/*----------------------------------------------------------------------
1061* Name:    hpc_wait_ctlr_notworking
1062*
1063* Action:  wait until the controller is in a not working state
1064*
1065* Return   0, HPC_ERROR
1066* Value:
1067*---------------------------------------------------------------------*/
1068static int hpc_wait_ctlr_notworking(int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
1069                                    u8 *pstatus)
1070{
1071        int rc = 0;
1072        u8 done = 0;
1073
1074        debug_polling("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1075
1076        while (!done) {
1077                *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1078                if (*pstatus == HPC_ERROR) {
1079                        rc = HPC_ERROR;
1080                        done = 1;
1081                }
1082                if (CTLR_WORKING(*pstatus) == HPC_CTLR_WORKING_NO)
1083                        done = 1;
1084                if (!done) {
1085                        msleep(1000);
1086                        if (timeout < 1) {
1087                                done = 1;
1088                                err("HPCreadslot - Error ctlr timeout\n");
1089                                rc = HPC_ERROR;
1090                        } else
1091                                timeout--;
1092                }
1093        }
1094        debug_polling("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1095        return rc;
1096}
1097