Select defaults such that a PERST causes flash image reload.  Select which
image based on what the card is set up to load.

CXL_VSEC_PERST_LOADS_IMAGE selects whether PERST assertion causes flash image
load.

CXL_VSEC_PERST_SELECT_USER selects which image is loaded on the next PERST.

cxl_update_image_control writes these bits into the VSEC.
---
 drivers/misc/cxl/cxl.h |  1 +
 drivers/misc/cxl/pci.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 0df0438..518c4c6 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -488,6 +488,7 @@ void cxl_release_one_irq(struct cxl *adapter, int hwirq);
 int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, 
unsigned int num);
 void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter);
 int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq);
+int cxl_update_image_control(struct cxl *adapter);
 
 /* common == phyp + powernv */
 struct cxl_process_element_common {
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index f801c28..5e71ef9 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -362,6 +362,41 @@ int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq,
        return pnv_cxl_ioda_msi_setup(dev, hwirq, virq);
 }
 
+int cxl_update_image_control(struct cxl *adapter)
+{
+       struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
+       int rc;
+       int vsec;
+       u8 image_state;
+
+       if (!(vsec = find_cxl_vsec(dev))) {
+               dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
+               return -ENODEV;
+       }
+
+       if ((rc = CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state))) {
+               dev_err(&dev->dev, "failed to read image state: %i\n", rc);
+               return rc;
+       }
+
+       if (adapter->perst_loads_image)
+               image_state |= CXL_VSEC_PERST_LOADS_IMAGE;
+       else
+               image_state &= ~CXL_VSEC_PERST_LOADS_IMAGE;
+
+       if (adapter->perst_select_user)
+               image_state |= CXL_VSEC_PERST_SELECT_USER;
+       else
+               image_state &= ~CXL_VSEC_PERST_SELECT_USER;
+
+       if ((rc = CXL_WRITE_VSEC_IMAGE_STATE(dev, vsec, image_state))) {
+               dev_err(&dev->dev, "failed to update image control: %i\n", rc);
+               return rc;
+       }
+
+       return 0;
+}
+
 int cxl_alloc_one_irq(struct cxl *adapter)
 {
        struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
@@ -771,8 +806,8 @@ static int cxl_read_vsec(struct cxl *adapter, struct 
pci_dev *dev)
        CXL_READ_VSEC_BASE_IMAGE(dev, vsec, &adapter->base_image);
        CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state);
        adapter->user_image_loaded = !!(image_state & 
CXL_VSEC_USER_IMAGE_LOADED);
-       adapter->perst_loads_image = !!(image_state & 
CXL_VSEC_PERST_LOADS_IMAGE);
-       adapter->perst_select_user = !!(image_state & 
CXL_VSEC_PERST_SELECT_USER);
+       adapter->perst_loads_image = true;
+       adapter->perst_select_user = !!(image_state & 
CXL_VSEC_USER_IMAGE_LOADED);
 
        CXL_READ_VSEC_NAFUS(dev, vsec, &adapter->slices);
        CXL_READ_VSEC_AFU_DESC_OFF(dev, vsec, &afu_desc_off);
@@ -880,6 +915,9 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
        if ((rc = cxl_vsec_looks_ok(adapter, dev)))
                goto err2;
 
+       if ((rc = cxl_update_image_control(adapter)))
+               goto err2;
+
        if ((rc = cxl_map_adapter_regs(adapter, dev)))
                goto err2;
 
-- 
1.9.1

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to