Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be3a1adb authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: ope: Handle reset IRQ delay" into camera-kernel.lnx.3.1

parents 7ce0928a db1e8beb
Loading
Loading
Loading
Loading
+58 −21
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ static int cam_ope_top_reset(struct ope_hw *ope_hw_info,
	struct cam_ope_top_reg *top_reg;
	struct cam_ope_top_reg_val *top_reg_val;
	uint32_t irq_mask, irq_status;
	unsigned long flags;

	if (!ope_hw_info) {
		CAM_ERR(CAM_OPE, "Invalid ope_hw_info");
@@ -72,21 +73,37 @@ static int cam_ope_top_reset(struct ope_hw *ope_hw_info,

	rc = wait_for_completion_timeout(
			&ope_top_info.reset_complete,
			msecs_to_jiffies(30));
			msecs_to_jiffies(60));

	cam_io_w_mb(top_reg_val->debug_cfg_val,
		top_reg->base + top_reg->debug_cfg);

	if (!rc || rc < 0) {
		CAM_ERR(CAM_OPE, "reset error result = %d", rc);
		spin_lock_irqsave(&ope_top_info.hw_lock, flags);
		if (!completion_done(&ope_top_info.reset_complete)) {
			CAM_DBG(CAM_OPE,
				"IRQ delayed, checking the status registers");
			irq_mask = cam_io_r_mb(ope_hw_info->top_reg->base +
				top_reg->irq_mask);
			irq_status = cam_io_r_mb(ope_hw_info->top_reg->base +
				top_reg->irq_status);
		CAM_ERR(CAM_OPE, "irq mask 0x%x irq status 0x%x",
			if (irq_status & top_reg_val->rst_done) {
				CAM_DBG(CAM_OPE, "ope reset done");
				cam_io_w_mb(irq_status,
					top_reg->base + top_reg->irq_clear);
				cam_io_w_mb(top_reg_val->irq_set_clear,
					top_reg->base + top_reg->irq_cmd);
			} else {
				CAM_ERR(CAM_OPE,
					"irq mask 0x%x irq status 0x%x",
					irq_mask, irq_status);
				cam_ope_top_dump_debug_reg(ope_hw_info);
				rc = -ETIMEDOUT;
			}
		} else {
			rc = 0;
		}
		spin_unlock_irqrestore(&ope_top_info.hw_lock, flags);
	} else {
		rc = 0;
	}
@@ -137,6 +154,7 @@ static int cam_ope_top_init(struct ope_hw *ope_hw_info,
	struct cam_ope_top_reg_val *top_reg_val;
	struct cam_ope_dev_init *dev_init = data;
	uint32_t irq_mask, irq_status;
	unsigned long flags;

	if (!ope_hw_info) {
		CAM_ERR(CAM_OPE, "Invalid ope_hw_info");
@@ -160,25 +178,41 @@ static int cam_ope_top_init(struct ope_hw *ope_hw_info,

	rc = wait_for_completion_timeout(
			&ope_top_info.reset_complete,
			msecs_to_jiffies(30));
			msecs_to_jiffies(60));

	cam_io_w_mb(top_reg_val->debug_cfg_val,
		top_reg->base + top_reg->debug_cfg);

	if (!rc || rc < 0) {
		CAM_ERR(CAM_OPE, "reset error result = %d", rc);
		spin_lock_irqsave(&ope_top_info.hw_lock, flags);
		if (!completion_done(&ope_top_info.reset_complete)) {
			CAM_DBG(CAM_OPE,
				"IRQ delayed, checking the status registers");
			irq_mask = cam_io_r_mb(ope_hw_info->top_reg->base +
				top_reg->irq_mask);
			irq_status = cam_io_r_mb(ope_hw_info->top_reg->base +
				top_reg->irq_status);
		CAM_ERR(CAM_OPE, "irq mask 0x%x irq status 0x%x",
			if (irq_status & top_reg_val->rst_done) {
				CAM_DBG(CAM_OPE, "ope reset done");
				cam_io_w_mb(irq_status,
					top_reg->base + top_reg->irq_clear);
				cam_io_w_mb(top_reg_val->irq_set_clear,
					top_reg->base + top_reg->irq_cmd);
			} else {
				CAM_ERR(CAM_OPE,
					"irq mask 0x%x irq status 0x%x",
					irq_mask, irq_status);
				cam_ope_top_dump_debug_reg(ope_hw_info);
				rc = -ETIMEDOUT;
			}
		} else {
			CAM_DBG(CAM_OPE, "reset done");
			rc = 0;
		}
		spin_unlock_irqrestore(&ope_top_info.hw_lock, flags);
	} else {
		rc = 0;
	}

	/* enable interrupt mask */
	cam_io_w_mb(top_reg_val->irq_mask,
		ope_hw_info->top_reg->base + top_reg->irq_mask);
@@ -197,6 +231,7 @@ static int cam_ope_top_probe(struct ope_hw *ope_hw_info,
	}

	ope_top_info.ope_hw_info = ope_hw_info;
	spin_lock_init(&ope_top_info.hw_lock);

	return rc;
}
@@ -219,6 +254,7 @@ static int cam_ope_top_isr(struct ope_hw *ope_hw_info,
	top_reg = ope_hw_info->top_reg;
	top_reg_val = ope_hw_info->top_reg_val;

	spin_lock(&ope_top_info.hw_lock);
	/* Read and Clear Top Interrupt status */
	irq_status = cam_io_r_mb(top_reg->base + top_reg->irq_status);
	cam_io_w_mb(irq_status,
@@ -238,6 +274,7 @@ static int cam_ope_top_isr(struct ope_hw *ope_hw_info,
		irq_data->error = 1;
		CAM_ERR(CAM_OPE, "ope violation: %x", violation_status);
	}
	spin_unlock(&ope_top_info.hw_lock);

	return rc;
}
+2 −0
Original line number Diff line number Diff line
@@ -33,11 +33,13 @@ struct ope_top_ctx {
 * @top_ctx:        OPE top context
 * @reset_complete: Reset complete flag
 * @ope_mutex:      OPE hardware mutex
 * @hw_lock:        OPE hardware spinlock
 */
struct ope_top {
	struct ope_hw *ope_hw_info;
	struct ope_top_ctx top_ctx[OPE_CTX_MAX];
	struct completion reset_complete;
	struct mutex      ope_hw_mutex;
	spinlock_t        hw_lock;
};
#endif /* OPE_TOP_H */