Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59300
b: refs/heads/master
c: 17b2eb9
h: refs/heads/master
v: v3
  • Loading branch information
Michael Albaugh authored and Roland Dreier committed Jul 10, 2007
1 parent 29cf3b0 commit 131ba8c
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 82466f00ec6ef0a5ca7ea8991c731af2ec561c7d
refs/heads/master: 17b2eb9fe6bfadcb3ece308ed50193d10b71ba6e
68 changes: 40 additions & 28 deletions trunk/drivers/infiniband/hw/ipath/ipath_eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,37 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
enum i2c_type line,
enum i2c_state new_line_state)
{
u64 read_val, write_val, mask, *gpioval;
u64 out_mask, dir_mask, *gpioval;
unsigned long flags = 0;

gpioval = &dd->ipath_gpio_out;
read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
if (line == i2c_line_scl)
mask = dd->ipath_gpio_scl;
else
mask = dd->ipath_gpio_sda;

if (new_line_state == i2c_line_high)
if (line == i2c_line_scl) {
dir_mask = dd->ipath_gpio_scl;
out_mask = (1UL << dd->ipath_gpio_scl_num);
} else {
dir_mask = dd->ipath_gpio_sda;
out_mask = (1UL << dd->ipath_gpio_sda_num);
}

spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
if (new_line_state == i2c_line_high) {
/* tri-state the output rather than force high */
write_val = read_val & ~mask;
else
dd->ipath_extctrl &= ~dir_mask;
} else {
/* config line to be an output */
write_val = read_val | mask;
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);
dd->ipath_extctrl |= dir_mask;
}
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, dd->ipath_extctrl);

/* set high and verify */
/* set output as well (no real verify) */
if (new_line_state == i2c_line_high)
write_val = 0x1UL;
*gpioval |= out_mask;
else
write_val = 0x0UL;
*gpioval &= ~out_mask;

if (line == i2c_line_scl) {
write_val <<= dd->ipath_gpio_scl_num;
*gpioval = *gpioval & ~(1UL << dd->ipath_gpio_scl_num);
*gpioval |= write_val;
} else {
write_val <<= dd->ipath_gpio_sda_num;
*gpioval = *gpioval & ~(1UL << dd->ipath_gpio_sda_num);
*gpioval |= write_val;
}
ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_out, *gpioval);
spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);

return 0;
}
Expand All @@ -145,24 +143,31 @@ static int i2c_gpio_get(struct ipath_devdata *dd,
enum i2c_type line,
enum i2c_state *curr_statep)
{
u64 read_val, write_val, mask;
u64 read_val, mask;
int ret;
unsigned long flags = 0;

/* check args */
if (curr_statep == NULL) {
ret = 1;
goto bail;
}

read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
/* config line to be an input */
if (line == i2c_line_scl)
mask = dd->ipath_gpio_scl;
else
mask = dd->ipath_gpio_sda;
write_val = read_val & ~mask;
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);

spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
dd->ipath_extctrl &= ~mask;
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, dd->ipath_extctrl);
/*
* Below is very unlikely to reflect true input state if Output
* Enable actually changed.
*/
read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);
spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);

if (read_val & mask)
*curr_statep = i2c_line_high;
Expand Down Expand Up @@ -192,6 +197,7 @@ static void i2c_wait_for_writes(struct ipath_devdata *dd)

static void scl_out(struct ipath_devdata *dd, u8 bit)
{
udelay(1);
i2c_gpio_set(dd, i2c_line_scl, bit ? i2c_line_high : i2c_line_low);

i2c_wait_for_writes(dd);
Expand Down Expand Up @@ -314,12 +320,18 @@ static int eeprom_reset(struct ipath_devdata *dd)
int clock_cycles_left = 9;
u64 *gpioval = &dd->ipath_gpio_out;
int ret;
unsigned long flags;

eeprom_init = 1;
spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
/* Make sure shadows are consistent */
dd->ipath_extctrl = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
*gpioval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_out);
spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);

ipath_cdbg(VERBOSE, "Resetting i2c eeprom; initial gpioout reg "
"is %llx\n", (unsigned long long) *gpioval);

eeprom_init = 1;
/*
* This is to get the i2c into a known state, by first going low,
* then tristate sda (and then tristate scl as first thing
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
u64 lst, u64 ltst)
{
u64 extctl;
unsigned long flags = 0;

/* the diags use the LED to indicate diag info, so we leave
* the external LED alone when the diags are running */
Expand All @@ -1075,6 +1076,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
: INFINIPATH_IBCS_L_STATE_DOWN;
}

spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
/*
* start by setting both LED control bits to off, then turn
* on the appropriate bit(s).
Expand Down Expand Up @@ -1103,6 +1105,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
}
dd->ipath_extctrl = extctl;
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
}

static void ipath_init_ht_variables(struct ipath_devdata *dd)
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
u64 ltst)
{
u64 extctl;
unsigned long flags = 0;

/* the diags use the LED to indicate diag info, so we leave
* the external LED alone when the diags are running */
Expand All @@ -807,6 +808,7 @@ static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
: INFINIPATH_IBCS_L_STATE_DOWN;
}

spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
extctl = dd->ipath_extctrl & ~(INFINIPATH_EXTC_LED1PRIPORT_ON |
INFINIPATH_EXTC_LED2PRIPORT_ON);

Expand All @@ -816,6 +818,7 @@ static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON;
dd->ipath_extctrl = extctl;
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/infiniband/hw/ipath/ipath_init_chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ static int init_chip_first(struct ipath_devdata *dd,

spin_lock_init(&dd->ipath_tid_lock);

spin_lock_init(&dd->ipath_gpio_lock);

done:
*pdp = pd;
return ret;
Expand Down
7 changes: 5 additions & 2 deletions trunk/drivers/infiniband/hw/ipath/ipath_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ struct ipath_devdata {
u64 ipath_gpio_out;
/* shadow the gpio mask register */
u64 ipath_gpio_mask;
/* shadow the gpio output enable, etc... */
u64 ipath_extctrl;
/* kr_revision shadow */
u64 ipath_revision;
/*
Expand Down Expand Up @@ -473,8 +475,6 @@ struct ipath_devdata {
u32 ipath_cregbase;
/* shadow the control register contents */
u32 ipath_control;
/* shadow the gpio output contents */
u32 ipath_extctrl;
/* PCI revision register (HTC rev on FPGA) */
u32 ipath_pcirev;

Expand Down Expand Up @@ -576,6 +576,9 @@ struct ipath_devdata {
u64 ipath_gpio_sda;
u64 ipath_gpio_scl;

/* lock for doing RMW of shadows/regs for ExtCtrl and GPIO */
spinlock_t ipath_gpio_lock;

/* used to override LED behavior */
u8 ipath_led_override; /* Substituted for normal value, if non-zero */
u16 ipath_led_override_timeoff; /* delta to next timer event */
Expand Down

0 comments on commit 131ba8c

Please sign in to comment.