aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2019-02-21 15:20:22 +1030
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2019-03-04 21:31:37 +0530
commit381a7e6553d7307dc4fe84b5c27bc7693ac274ea (patch)
tree20acf99d0ab41dc410fba446d3b57de1ab14ae62
parent2d8b0043aa9dad9555e3070c4cc82389bbde9339 (diff)
downloadskiboot-381a7e6553d7307dc4fe84b5c27bc7693ac274ea.zip
skiboot-381a7e6553d7307dc4fe84b5c27bc7693ac274ea.tar.gz
skiboot-381a7e6553d7307dc4fe84b5c27bc7693ac274ea.tar.bz2
ast-io: Rework ast_sio_is_enabled() test sequence
[ Upstream commit 6a4db4c249a14b11e237e5824fcb434309aff138 ] The postcondition of probing with a lock sequence is easier to make correct than with unlock. The original implementation left SuperIO locked after execution which broke an assumption of some callers. Tested on Garrison, Palmetto without HIOMAP, Palmetto with HIOMAP and Witherspoon. Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Signed-off-by: Stewart Smith <stewart@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
-rw-r--r--hw/ast-bmc/ast-io.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/hw/ast-bmc/ast-io.c b/hw/ast-bmc/ast-io.c
index 38ca86c..a9da06b 100644
--- a/hw/ast-bmc/ast-io.c
+++ b/hw/ast-bmc/ast-io.c
@@ -323,20 +323,41 @@ static void ast_setup_sio_irq_polarity(void)
bool ast_sio_is_enabled(void)
{
+ bool enabled;
int64_t rc;
- /* Begin the unlock sequence with a probe to establish presence */
- rc = lpc_probe_write(OPAL_LPC_IO, 0x2e, 0xa5, 1);
- if (rc)
- return false;
+ lock(&bmc_sio_lock);
+ /*
+ * Probe by attempting to lock the SIO device, this way the
+ * post-condition is that the SIO device is locked or not able to be
+ * unlocked. This turns out neater than trying to use the unlock code.
+ */
+ rc = lpc_probe_write(OPAL_LPC_IO, 0x2e, 0xaa, 1);
+ if (rc) {
+ enabled = false;
+ /* If we can't lock it, then we can't unlock it either */
+ goto out;
+ }
+
+ /*
+ * Now that we know that is locked and able to be unlocked, unlock it
+ * if skiboot's recorded device state indicates it was previously
+ * unlocked.
+ */
+ if (bmc_sio_cur_dev != BMC_SIO_DEV_NONE) {
+ /* Send SuperIO password */
+ lpc_outb(0xa5, 0x2e);
+ lpc_outb(0xa5, 0x2e);
- /* Complete the unlock sequence if the device is present */
- lpc_outb(0xa5, 0x2e);
+ /* Ensure the previously selected logical dev is selected */
+ bmc_sio_outb(bmc_sio_cur_dev, 0x07);
+ }
- /* Re-lock to return to a known state */
- lpc_outb(0xaa, 0x2e);
+ enabled = true;
+out:
+ unlock(&bmc_sio_lock);
- return true;
+ return enabled;
}
bool ast_sio_init(void)