summaryrefslogtreecommitdiff
path: root/drivers/hotplug/ibmphp_hpc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2002-06-06 23:27:01 -0700
committerGreg Kroah-Hartman <greg@kroah.com>2002-06-06 23:27:01 -0700
commit0c6df6a6523e468e2bb161132382cab2811b497f (patch)
tree0b9a29d2a96c53931215ec6c0d9424ebd553ac12 /drivers/hotplug/ibmphp_hpc.c
parent3da9cf2895a490d8c7a1a8d78130f66a88e93efa (diff)
IBM PCI Hotplug driver: polling thread locking cleanup
removed a lot of bizzare polling locking logic, causing the driver to not sleep for 2 seconds with some locks held. This improves userspace interaction by a few orders of magnitude :)
Diffstat (limited to 'drivers/hotplug/ibmphp_hpc.c')
-rw-r--r--drivers/hotplug/ibmphp_hpc.c114
1 files changed, 54 insertions, 60 deletions
diff --git a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c
index a4338b48af1e..b3150aea49ff 100644
--- a/drivers/hotplug/ibmphp_hpc.c
+++ b/drivers/hotplug/ibmphp_hpc.c
@@ -3,7 +3,7 @@
*
* Written By: Jyoti Shah, IBM Corporation
*
- * Copyright (c) 2001,2001 IBM Corp.
+ * Copyright (c) 2001-2002 IBM Corp.
*
* All rights reserved.
*
@@ -27,7 +27,6 @@
*
*/
-//#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/module.h>
@@ -35,9 +34,6 @@
#include <linux/smp_lock.h>
#include "ibmphp.h"
-#define POLL_NO 0x01
-#define POLL_YES 0x00
-
static int to_debug = FALSE;
#define debug_polling(fmt, arg...) do { if (to_debug) debug (fmt, arg); } while (0)
@@ -98,19 +94,15 @@ static int to_debug = FALSE;
// if bits 20,22,25,26,27,29,30 are OFF return TRUE
#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE))
-// return code 0:poll slots, 1-POLL_LATCH_CNT:poll latch register
-#define INCREMENT_POLLCNT(i) ((i < POLL_LATCH_CNT) ? i++ : (i=0))
//----------------------------------------------------------------------------
// global variables
//----------------------------------------------------------------------------
static int ibmphp_shutdown;
static int tid_poll;
-static int stop_polling; // 2 values: poll, don't poll
static struct semaphore sem_hpcaccess; // lock access to HPC
static struct semaphore semOperations; // lock all operations and
// access to data structures
static struct semaphore sem_exit; // make sure polling thread goes away
-static struct semaphore sem_poll; // make sure poll is idle
//----------------------------------------------------------------------------
// local function prototypes
//----------------------------------------------------------------------------
@@ -141,8 +133,6 @@ void ibmphp_hpc_initvars (void)
init_MUTEX (&sem_hpcaccess);
init_MUTEX (&semOperations);
init_MUTEX_LOCKED (&sem_exit);
- init_MUTEX_LOCKED (&sem_poll);
- stop_polling = POLL_YES;
to_debug = FALSE;
ibmphp_shutdown = FALSE;
tid_poll = 0;
@@ -710,11 +700,6 @@ void free_hpc_access (void)
void ibmphp_lock_operations (void)
{
down (&semOperations);
- stop_polling = POLL_NO;
- to_debug = TRUE;
-
- /* waiting for polling to actually stop */
- down (&sem_poll);
}
/*----------------------------------------------------------------------
@@ -723,8 +708,6 @@ void ibmphp_lock_operations (void)
void ibmphp_unlock_operations (void)
{
debug ("%s - Entry\n", __FUNCTION__);
- stop_polling = POLL_YES;
- to_debug = FALSE;
up (&semOperations);
debug ("%s - Exit\n", __FUNCTION__);
}
@@ -732,34 +715,30 @@ void ibmphp_unlock_operations (void)
/*----------------------------------------------------------------------
* Name: poll_hpc()
*---------------------------------------------------------------------*/
+#define POLL_LATCH_REGISTER 0
+#define POLL_SLOTS 1
+#define POLL_SLEEP 2
static void poll_hpc (void)
{
- struct slot myslot, *pslot = NULL;
+ struct slot myslot;
+ struct slot *pslot = NULL;
struct list_head *pslotlist;
int rc;
+ int poll_state = POLL_LATCH_REGISTER;
u8 oldlatchlow = 0x00;
u8 curlatchlow = 0x00;
- int pollcnt = 0;
+ int poll_count = 0;
u8 ctrl_count = 0x00;
- debug ("poll_hpc - Entry\n");
+ debug ("%s - Entry\n", __FUNCTION__);
while (!ibmphp_shutdown) {
- if (stop_polling) {
- debug ("poll_hpc - stop_polling\n");
- up (&sem_poll);
- /* to prevent deadlock */
- if (ibmphp_shutdown)
- break;
- /* to make the thread sleep */
- down (&semOperations);
- up (&semOperations);
- debug ("poll_hpc - after stop_polling sleep\n");
- } else {
- if (pollcnt) {
- // only poll the latch register
- oldlatchlow = curlatchlow;
+ /* try to get the lock to do some kind of harware access */
+ down (&semOperations);
+ switch (poll_state) {
+ case POLL_LATCH_REGISTER:
+ oldlatchlow = curlatchlow;
ctrl_count = 0x00;
list_for_each (pslotlist, &ibmphp_slot_head) {
if (ctrl_count >= ibmphp_get_total_controllers())
@@ -773,14 +752,16 @@ static void poll_hpc (void)
&curlatchlow);
if (oldlatchlow != curlatchlow)
process_changeinlatch (oldlatchlow,
- curlatchlow, pslot->ctrl);
+ curlatchlow,
+ pslot->ctrl);
}
}
}
- } else {
+ poll_state = POLL_SLOTS;
+ break;
+
+ case POLL_SLOTS:
list_for_each (pslotlist, &ibmphp_slot_head) {
- if (stop_polling)
- break;
pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
// make a copy of the old status
memcpy ((void *) &myslot, (void *) pslot,
@@ -791,31 +772,45 @@ static void poll_hpc (void)
process_changeinstatus (pslot, &myslot);
}
- if (!stop_polling) {
- ctrl_count = 0x00;
- list_for_each (pslotlist, &ibmphp_slot_head) {
- if (ctrl_count >= ibmphp_get_total_controllers())
- break;
- pslot =
- list_entry (pslotlist, struct slot,
- ibm_slot_list);
- if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
- ctrl_count++;
- if (READ_SLOT_LATCH (pslot->ctrl))
- rc = ibmphp_hpc_readslot (pslot,
- READ_SLOTLATCHLOWREG,
- &curlatchlow);
- }
+ ctrl_count = 0x00;
+ list_for_each (pslotlist, &ibmphp_slot_head) {
+ if (ctrl_count >= ibmphp_get_total_controllers())
+ break;
+ pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+ if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+ ctrl_count++;
+ if (READ_SLOT_LATCH (pslot->ctrl))
+ rc = ibmphp_hpc_readslot (pslot,
+ READ_SLOTLATCHLOWREG,
+ &curlatchlow);
}
}
- }
- INCREMENT_POLLCNT (pollcnt);
- long_delay (POLL_INTERVAL_SEC * HZ); // snooze
+ ++poll_count;
+ if (poll_count >= POLL_LATCH_CNT) {
+ poll_count = 0;
+ poll_state = POLL_SLEEP;
+ }
+ break;
+
+ case POLL_SLEEP:
+ /* don't sleep with a lock on the hardware */
+ up (&semOperations);
+ long_delay (POLL_INTERVAL_SEC * HZ);
+ down (&semOperations);
+ poll_state = POLL_LATCH_REGISTER;
+ break;
}
+
+ /* give up the harware semaphore */
+ up (&semOperations);
+
+ /* sleep for a short time just for good measure */
+ set_current_state (TASK_INTERRUPTIBLE);
+ schedule_timeout (HZ/10);
}
- up (&sem_poll);
+
up (&sem_exit);
- debug ("poll_hpc - Exit\n");
+ debug ("%s - Exit\n", __FUNCTION__);
}
@@ -1083,7 +1078,6 @@ void ibmphp_hpc_stop_poll_thread (void)
// cleanup
free_hpc_access ();
ibmphp_unlock_operations ();
- up (&sem_poll);
up (&sem_exit);
debug ("ibmphp_hpc_stop_poll_thread - Exit\n");