@@ -891,6 +891,8 @@ static int parse_config(struct mhi_controller *mhi_cntrl,
if (config->m2_no_db)
mhi_cntrl->db_access &= ~MHI_PM_M2;
+ mhi_cntrl->quirks = config->quirks;
+
return 0;
error_ev_cfg:
@@ -982,10 +984,13 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
}
/* Read the MHI device info */
- ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs,
- SOC_HW_VERSION_OFFS, &soc_info);
- if (ret)
- goto err_destroy_wq;
+ if (mhi_cntrl->quirks & MHI_QUIRK_SOC_HW_VERSION_UNRELIABLE) {
+ soc_info = 0;
+ } else {
+ ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs, SOC_HW_VERSION_OFFS, &soc_info);
+ if (ret)
+ goto err_destroy_wq;
+ }
mhi_cntrl->family_number = FIELD_GET(SOC_HW_VERSION_FAM_NUM_BMSK, soc_info);
mhi_cntrl->device_number = FIELD_GET(SOC_HW_VERSION_DEV_NUM_BMSK, soc_info);
@@ -17,6 +17,20 @@
#define MHI_MAX_OEM_PK_HASH_SEGMENTS 16
+/*
+ * List of workarounds for devices that require behavior not specified in
+ * the standard.
+ */
+enum mhi_quirks {
+ /*
+ * Some devices do not properly initialize the SOC_HW_VERSION register
+ * in the BHI space. In some instances, the value is 0xFFFFFFFF which
+ * may hold special meaning. In the case of such devices, do not read
+ * the register.
+ */
+ MHI_QUIRK_SOC_HW_VERSION_UNRELIABLE = BIT(0),
+};
+
struct mhi_chan;
struct mhi_event;
struct mhi_ctxt;
@@ -273,6 +287,7 @@ struct mhi_event_config {
* @event_cfg: Array of defined event rings
* @use_bounce_buf: Use a bounce buffer pool due to limited DDR access
* @m2_no_db: Host is not allowed to ring DB in M2 state
+ * @quirks: Workarounds for devices that require non-standard behavior
*/
struct mhi_controller_config {
u32 max_channels;
@@ -284,6 +299,7 @@ struct mhi_controller_config {
struct mhi_event_config *event_cfg;
bool use_bounce_buf;
bool m2_no_db;
+ u32 quirks;
};
/**
@@ -358,6 +374,7 @@ struct mhi_controller_config {
* @wake_set: Device wakeup set flag
* @irq_flags: irq flags passed to request_irq (optional)
* @mru: the default MRU for the MHI device
+ * @quirks: Workarounds for devices that require non-standard behavior
*
* Fields marked as (required) need to be populated by the controller driver
* before calling mhi_register_controller(). For the fields marked as (optional)
@@ -452,6 +469,7 @@ struct mhi_controller {
bool wake_set;
unsigned long irq_flags;
u32 mru;
+ u32 quirks;
};
/**