浏览代码

Merge "msm: camera: common: Add wrapper for presil locking" into camera-kernel.lnx.5.0

Camera Software Integration 3 年之前
父节点
当前提交
21d78e35c1

+ 13 - 12
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -1423,10 +1423,10 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 	CAM_DBG(CAM_CDM, "Got irq hw_version 0x%x from %s%u",
 		cdm_core->hw_version, soc_info->label_name,
 		soc_info->index);
-	spin_lock(&cdm_hw->hw_lock);
+	cam_hw_util_hw_lock(cdm_hw);
 	if (cdm_hw->hw_state == CAM_HW_STATE_POWER_DOWN) {
 		CAM_DBG(CAM_CDM, "CDM is in power down state");
-		spin_unlock(&cdm_hw->hw_lock);
+		cam_hw_util_hw_unlock(cdm_hw);
 		return IRQ_HANDLED;
 	}
 	if (cdm_core->hw_version >= CAM_CDM_VERSION_2_1) {
@@ -1467,7 +1467,8 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 		CAM_ERR(CAM_CDM, "Failed to read %s%u HW IRQ data",
 				soc_info->label_name,
 				soc_info->index);
-	spin_unlock(&cdm_hw->hw_lock);
+
+	cam_hw_util_hw_unlock(cdm_hw);
 
 	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo_irq; i++) {
 		if (!irq_status[i])
@@ -1983,7 +1984,7 @@ int cam_hw_cdm_init(void *hw_priv,
 	struct cam_hw_soc_info *soc_info = NULL;
 	struct cam_cdm *cdm_core = NULL;
 	int rc, i, reset_hw_hdl = 0x0;
-	unsigned long flags;
+	unsigned long flags = 0;
 
 	if (!hw_priv)
 		return -EINVAL;
@@ -1998,9 +1999,9 @@ int cam_hw_cdm_init(void *hw_priv,
 			soc_info->label_name, soc_info->index);
 		goto end;
 	}
-	spin_lock_irqsave(&cdm_hw->hw_lock, flags);
+	flags = cam_hw_util_hw_lock_irqsave(cdm_hw);
 	cdm_hw->hw_state = CAM_HW_STATE_POWER_UP;
-	spin_unlock_irqrestore(&cdm_hw->hw_lock, flags);
+	cam_hw_util_hw_unlock_irqrestore(cdm_hw, flags);
 
 	CAM_DBG(CAM_CDM, "Enable soc done for %s%d",
 		soc_info->label_name, soc_info->index);
@@ -2041,9 +2042,9 @@ int cam_hw_cdm_init(void *hw_priv,
 
 disable_return:
 	rc = -EIO;
-	spin_lock_irqsave(&cdm_hw->hw_lock, flags);
+	flags = cam_hw_util_hw_lock_irqsave(cdm_hw);
 	cdm_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
-	spin_unlock_irqrestore(&cdm_hw->hw_lock, flags);
+	cam_hw_util_hw_unlock_irqrestore(cdm_hw, flags);
 	cam_soc_util_disable_platform_resource(soc_info, true, true);
 end:
 	return rc;
@@ -2059,7 +2060,7 @@ int cam_hw_cdm_deinit(void *hw_priv,
 	int rc = 0, i;
 	uint32_t reset_val = 1;
 	long time_left;
-	unsigned long                             flags;
+	unsigned long flags = 0;
 
 	if (!hw_priv)
 		return -EINVAL;
@@ -2121,9 +2122,9 @@ int cam_hw_cdm_deinit(void *hw_priv,
 	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
 		mutex_unlock(&cdm_core->bl_fifo[i].fifo_lock);
 
-	spin_lock_irqsave(&cdm_hw->hw_lock, flags);
+	flags = cam_hw_util_hw_lock_irqsave(cdm_hw);
 	cdm_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
-	spin_unlock_irqrestore(&cdm_hw->hw_lock, flags);
+	cam_hw_util_hw_unlock_irqrestore(cdm_hw, flags);
 	rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
 	if (rc) {
 		CAM_ERR(CAM_CDM, "disable platform failed for %s%u",
@@ -2177,7 +2178,7 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 	cdm_hw_intf->hw_type = CAM_HW_CDM;
 	cdm_hw->open_count = 0;
 	mutex_init(&cdm_hw->hw_mutex);
-	spin_lock_init(&cdm_hw->hw_lock);
+	cam_hw_util_init_hw_lock(cdm_hw);
 	init_completion(&cdm_hw->hw_complete);
 
 	rc = cam_hw_cdm_soc_get_dt_properties(cdm_hw, msm_cam_hw_cdm_dt_match);

+ 7 - 1
drivers/cam_core/cam_hw.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_HW_H_
@@ -30,6 +30,8 @@ enum cam_hw_state {
  * @soc_info:              Platform SOC properties for hardware
  * @node_info:             Private HW data related to nodes
  * @core_info:             Private HW data related to core logic
+ * @presil_hw_lock:        Mutex lock used for presil in place of hw_lock,
+ *                         for drivers like CDM
  *
  */
 struct cam_hw_info {
@@ -41,6 +43,10 @@ struct cam_hw_info {
 	struct cam_hw_soc_info          soc_info;
 	void                           *node_info;
 	void                           *core_info;
+
+#ifdef CONFIG_CAM_PRESIL
+	struct mutex                    presil_hw_lock;
+#endif
 };
 
 #endif /* _CAM_HW_H_ */

+ 63 - 0
drivers/cam_core/cam_hw_intf.h

@@ -7,6 +7,7 @@
 #define _CAM_HW_INTF_H_
 
 #include <linux/types.h>
+#include "cam_hw.h"
 
 /*
  * This file declares Constants, Enums, Structures and APIs to be used as
@@ -86,4 +87,66 @@ struct cam_hw_intf {
 typedef int (*cam_hw_mgr_event_cb_func)(void *priv, uint32_t evt_id,
 	void *evt_data);
 
+#ifdef CONFIG_CAM_PRESIL
+static inline void cam_hw_util_init_hw_lock(struct cam_hw_info *hw_info)
+{
+	mutex_init(&hw_info->presil_hw_lock);
+}
+
+static inline unsigned long cam_hw_util_hw_lock_irqsave(struct cam_hw_info *hw_info)
+{
+	mutex_lock(&hw_info->presil_hw_lock);
+
+	return 0;
+}
+
+static inline void cam_hw_util_hw_unlock_irqrestore(struct cam_hw_info *hw_info,
+	unsigned long flags)
+{
+	mutex_unlock(&hw_info->presil_hw_lock);
+}
+
+static inline void cam_hw_util_hw_lock(struct cam_hw_info *hw_info)
+{
+	mutex_lock(&hw_info->presil_hw_lock);
+}
+
+static inline void cam_hw_util_hw_unlock(struct cam_hw_info *hw_info)
+{
+	mutex_unlock(&hw_info->presil_hw_lock);
+}
+#else
+static inline void cam_hw_util_init_hw_lock(struct cam_hw_info *hw_info)
+{
+	spin_lock_init(&hw_info->hw_lock);
+}
+
+static inline unsigned long cam_hw_util_hw_lock_irqsave(struct cam_hw_info *hw_info)
+{
+	unsigned long flags = 0;
+
+	if (!in_irq())
+		spin_lock_irqsave(&hw_info->hw_lock, flags);
+
+	return flags;
+}
+
+static inline void cam_hw_util_hw_unlock_irqrestore(struct cam_hw_info *hw_info,
+	unsigned long flags)
+{
+	if (!in_irq())
+		spin_unlock_irqrestore(&hw_info->hw_lock, flags);
+}
+
+static inline void cam_hw_util_hw_lock(struct cam_hw_info *hw_info)
+{
+	spin_lock(&hw_info->hw_lock);
+}
+
+static inline void cam_hw_util_hw_unlock(struct cam_hw_info *hw_info)
+{
+	spin_unlock(&hw_info->hw_lock);
+}
+#endif /* CONFIG_CAM_PRESIL */
+
 #endif /* _CAM_HW_INTF_H_ */

+ 93 - 36
drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c

@@ -11,6 +11,7 @@
 #include "cam_io_util.h"
 #include "cam_irq_controller.h"
 #include "cam_debug_util.h"
+#include "cam_common_util.h"
 
 /**
  * struct cam_irq_evt_handler:
@@ -94,12 +95,13 @@ struct cam_irq_register_obj {
  * @th_list_head:           List of handlers sorted by priority
  * @hdl_idx:                Unique identity of handler assigned on Subscribe.
  *                          Used to Unsubscribe.
- * @lock:                   Lock for use by controller
  * @th_payload:             Payload structure to be passed to top half handler
  * @is_dependent:           Flag to indicate is this controller is dependent on another controller
  * @dependent_controller:   Array of controllers that depend on this controller
  * @delayed_global_clear:   Flag to indicate if this controller issues global clear after dependent
  *                          controllers are handled
+ * @lock:                   Lock to be used by controller, Use mutex lock in presil mode,
+ *                          and spinlock in regular case
  */
 struct cam_irq_controller {
 	const char                     *name;
@@ -113,13 +115,84 @@ struct cam_irq_controller {
 	struct list_head                evt_handler_list_head;
 	struct list_head                th_list_head[CAM_IRQ_PRIORITY_MAX];
 	uint32_t                        hdl_idx;
-	spinlock_t                      lock;
 	struct cam_irq_th_payload       th_payload;
 	bool                            is_dependent;
 	struct cam_irq_controller      *dependent_controller[CAM_IRQ_MAX_DEPENDENTS];
 	bool                            delayed_global_clear;
+
+#ifdef CONFIG_CAM_PRESIL
+	struct mutex                    lock;
+#else
+	spinlock_t                      lock;
+#endif
 };
 
+#ifdef CONFIG_CAM_PRESIL
+static inline void cam_irq_controller_lock_init(struct cam_irq_controller *controller)
+{
+	mutex_init(&controller->lock);
+}
+
+static inline unsigned long cam_irq_controller_lock_irqsave(
+	struct cam_irq_controller *controller)
+{
+	mutex_lock(&controller->lock);
+
+	return 0;
+}
+
+static inline void cam_irq_controller_unlock_irqrestore(
+	struct cam_irq_controller *controller, unsigned long flags)
+{
+	mutex_unlock(&controller->lock);
+}
+
+static inline void cam_irq_controller_lock(struct cam_irq_controller *controller)
+{
+	mutex_lock(&controller->lock);
+}
+
+static inline void cam_irq_controller_unlock(struct cam_irq_controller *controller)
+{
+	mutex_unlock(&controller->lock);
+}
+#else
+static inline void cam_irq_controller_lock_init(struct cam_irq_controller *controller)
+{
+	spin_lock_init(&controller->lock);
+}
+
+static inline unsigned long cam_irq_controller_lock_irqsave(
+	struct cam_irq_controller *controller)
+{
+	unsigned long flags = 0;
+
+	if (!in_irq())
+		spin_lock_irqsave(&controller->lock, flags);
+
+	return flags;
+}
+
+static inline void cam_irq_controller_unlock_irqrestore(
+	struct cam_irq_controller *controller, unsigned long flags)
+{
+	if (!in_irq())
+		spin_unlock_irqrestore(&controller->lock, flags);
+}
+
+static inline void cam_irq_controller_lock(struct cam_irq_controller *controller)
+{
+	spin_lock(&controller->lock);
+}
+
+static inline void cam_irq_controller_unlock(struct cam_irq_controller *controller)
+{
+	spin_unlock(&controller->lock);
+}
+#endif
+
+
+
 int cam_irq_controller_unregister_dependent(void *primary_controller, void *secondary_controller)
 {
 	struct cam_irq_controller *ctrl_primary, *ctrl_secondary;
@@ -200,25 +273,6 @@ int cam_irq_controller_register_dependent(void *primary_controller, void *second
 	return 0;
 }
 
-static inline unsigned long cam_irq_controller_lock(
-	struct cam_irq_controller *controller)
-{
-	unsigned long flags = 0;
-
-	if (!in_irq())
-		spin_lock_irqsave(&controller->lock, flags);
-
-	return flags;
-}
-
-static inline void cam_irq_controller_unlock(
-	struct cam_irq_controller *controller,
-	unsigned long flags)
-{
-	if (!in_irq())
-		spin_unlock_irqrestore(&controller->lock, flags);
-}
-
 static inline void cam_irq_controller_clear_irq(
 	struct cam_irq_controller  *controller,
 	struct cam_irq_evt_handler *evt_handler)
@@ -358,7 +412,7 @@ int cam_irq_controller_init(const char       *name,
 	for (i = 0; i < CAM_IRQ_PRIORITY_MAX; i++)
 		INIT_LIST_HEAD(&controller->th_list_head[i]);
 
-	spin_lock_init(&controller->lock);
+	cam_irq_controller_lock_init(controller);
 
 	controller->hdl_idx = 1;
 	*irq_controller = controller;
@@ -506,7 +560,7 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 	if (controller->hdl_idx > 0x3FFFFFFF)
 		controller->hdl_idx = 1;
 
-	flags = cam_irq_controller_lock(controller);
+	flags = cam_irq_controller_lock_irqsave(controller);
 
 	__cam_irq_controller_enable_irq(controller, evt_handler);
 
@@ -515,7 +569,7 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 	list_add_tail(&evt_handler->th_list_node,
 		&controller->th_list_head[priority]);
 
-	cam_irq_controller_unlock(controller, flags);
+	cam_irq_controller_unlock_irqrestore(controller, flags);
 
 	return evt_handler->index;
 
@@ -554,7 +608,7 @@ int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
 	if (!controller)
 		return rc;
 
-	flags = cam_irq_controller_lock(controller);
+	flags = cam_irq_controller_lock_irqsave(controller);
 
 	rc = cam_irq_controller_find_event_handle(controller, handle,
 		&evt_handler);
@@ -565,7 +619,7 @@ int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
 	__cam_irq_controller_enable_irq(controller, evt_handler);
 
 end:
-	cam_irq_controller_unlock(controller, flags);
+	cam_irq_controller_unlock_irqrestore(controller, flags);
 
 	return rc;
 }
@@ -580,7 +634,7 @@ int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
 	if (!controller)
 		return rc;
 
-	flags = cam_irq_controller_lock(controller);
+	flags = cam_irq_controller_lock_irqsave(controller);
 
 	rc = cam_irq_controller_find_event_handle(controller, handle,
 		&evt_handler);
@@ -592,7 +646,7 @@ int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
 	cam_irq_controller_clear_irq(controller, evt_handler);
 
 end:
-	cam_irq_controller_unlock(controller, flags);
+	cam_irq_controller_unlock_irqrestore(controller, flags);
 
 	return rc;
 }
@@ -605,7 +659,7 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
 	unsigned long               flags = 0;
 	int                         rc = 0;
 
-	flags = cam_irq_controller_lock(controller);
+	flags = cam_irq_controller_lock_irqsave(controller);
 
 
 	rc = cam_irq_controller_find_event_handle(controller, handle,
@@ -623,7 +677,7 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
 	kfree(evt_handler);
 
 end:
-	cam_irq_controller_unlock(controller, flags);
+	cam_irq_controller_unlock_irqrestore(controller, flags);
 
 	return rc;
 }
@@ -824,9 +878,9 @@ static void cam_irq_controller_read_registers(struct cam_irq_controller *control
 			dep_controller = controller->dependent_controller[j];
 			CAM_DBG(CAM_IRQ_CTRL, "Reading dependent registers for %s",
 				dep_controller->name);
-			spin_lock(&dep_controller->lock);
+			cam_irq_controller_lock(dep_controller);
 			__cam_irq_controller_read_registers(dep_controller);
-			spin_unlock(&dep_controller->lock);
+			cam_irq_controller_unlock(dep_controller);
 		}
 	}
 
@@ -875,11 +929,14 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv, int evt_grp)
 	CAM_DBG(CAM_IRQ_CTRL,
 		"Locking: %s IRQ Controller: [%pK], lock handle: %pK",
 		controller->name, controller, &controller->lock);
-	spin_lock(&controller->lock);
+	cam_irq_controller_lock(controller);
+
 	if (!controller->is_dependent)
 		cam_irq_controller_read_registers(controller);
+
 	cam_irq_controller_process_th(controller, evt_grp);
-	spin_unlock(&controller->lock);
+
+	cam_irq_controller_unlock(controller);
 	CAM_DBG(CAM_IRQ_CTRL,
 		"Unlocked: %s IRQ Controller: %pK, lock handle: %pK",
 		controller->name, controller, &controller->lock);
@@ -899,7 +956,7 @@ int cam_irq_controller_update_irq(void *irq_controller, uint32_t handle,
 	if (!controller)
 		return rc;
 
-	flags = cam_irq_controller_lock(controller);
+	flags = cam_irq_controller_lock_irqsave(controller);
 
 	rc = cam_irq_controller_find_event_handle(controller, handle,
 		&evt_handler);
@@ -918,7 +975,7 @@ int cam_irq_controller_update_irq(void *irq_controller, uint32_t handle,
 	cam_irq_controller_clear_irq(controller, evt_handler);
 
 end:
-	cam_irq_controller_unlock(controller, flags);
+	cam_irq_controller_unlock_irqrestore(controller, flags);
 
 	return rc;
 }