diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2015-11-12 18:41:32 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-11-13 15:57:13 +1100 |
commit | a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3 (patch) | |
tree | dca05d627e2a7c1d022952f580348e4fd03795c2 /core | |
parent | ad1aa4b81a1add6a3ac2e100dcc73aa0ed33d611 (diff) | |
download | skiboot-a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3.zip skiboot-a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3.tar.gz skiboot-a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3.tar.bz2 |
occ: hbrt: Change the OCC reset order
Modify the OCC reset order such that master OCC is reset after the
slave OCCs are reset. In Tuleta/Alpine systems 'proc0' will always be
the master OCC, which has to be stopped last when FSP sends OCC_RESET
command to Opal.
This fixes BZ 119718, SW289036
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/hostservices.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/core/hostservices.c b/core/hostservices.c index 815654d..672b57f 100644 --- a/core/hostservices.c +++ b/core/hostservices.c @@ -826,9 +826,8 @@ int host_services_occ_start(void) int host_services_occ_stop(void) { - struct proc_chip *chip; - int i, rc = 0, nr_chips=0; - uint64_t chipids[MAX_CHIPS]; + int i, rc = 0, nr_slaves = 0, nr_masters = 0; + uint64_t *master_chipids = NULL, *slave_chipids = NULL; prlog(PR_INFO, "HBRT: OCC Stop requested\n"); @@ -837,22 +836,39 @@ int host_services_occ_stop(void) return -ENOENT; } - for_each_chip(chip) { - chipids[nr_chips++] = chip->id; - } + rc = find_master_and_slave_occ(&master_chipids, &slave_chipids, + &nr_masters, &nr_slaves); + if (rc) + goto out; - for (i = 0; i < nr_chips; i++) + for (i = 0; i < nr_slaves; i++) prlog(PR_TRACE, "HBRT: Calling stopOCC() for %04llx ", - chipids[i]); + slave_chipids[i]); + + if (!nr_slaves) + goto master; + + /* Lets STOP all the slave OCC */ + rc = hservice_runtime->stopOCCs(slave_chipids, nr_slaves); + prlog(PR_DEBUG, "HBRT: stopOCCs() slave rc = %d\n", rc); + +master: + for (i = 0; i < nr_masters; i++) + prlog(PR_TRACE, "HBRT: Calling stopOCC() for %04llx ", + master_chipids[i]); + + /* Lets STOP all the master OCC */ + rc = hservice_runtime->stopOCCs(master_chipids, nr_masters); - /* Lets STOP all OCC */ - rc = hservice_runtime->stopOCCs(chipids, nr_chips); hservice_mark(); - prlog(PR_DEBUG, "HBRT: stopOCCs() rc = %d\n", rc); + prlog(PR_DEBUG, "HBRT: stopOCCs() master rc = %d\n", rc); + +out: + free(master_chipids); + free(slave_chipids); return rc; } - void host_services_occ_base_setup(void) { struct proc_chip *chip; |