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

Commit f7365e43 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: lmh_lite: Enable interrupt inside critical section"

parents dee6cdb0 b82c5427
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -278,7 +278,8 @@ static int lmh_reset(struct lmh_sensor_ops *ops)
		trace_lmh_sensor_interrupt(lmh_sensor->sensor_name,
			lmh_sensor->last_read_value);
	} else {
		goto reset_exit;
		pr_err("Sensor:[%s] is already in reset state\n",
			lmh_sensor->sensor_name);
	}

	if (!lmh_data->intr_status_val) {
@@ -299,20 +300,21 @@ static int lmh_reset(struct lmh_sensor_ops *ops)
					lmh_iter_sensor->last_read_value);
			}
		}
		if (!lmh_data->intr_status_val)
			lmh_data->intr_state = LMH_ISR_MONITOR;
	}

reset_exit:
	up_write(&lmh_sensor_access);
		if (!lmh_data->intr_status_val) {
		/* cancel the poll work after releasing the lock to avoid
		** deadlock situation */
			lmh_data->intr_state = LMH_ISR_MONITOR;
			pr_debug("Zero throttling. Re-enabling interrupt\n");
		cancel_delayed_work_sync(&lmh_data->poll_work);
			/*
			 * Don't use cancel_delayed_work_sync as it will lead
			 * to deadlock because of the mutex
			 */
			cancel_delayed_work(&lmh_data->poll_work);
			trace_lmh_event_call("Lmh Interrupt Clear");
			enable_irq(lmh_data->irq_num);
		}
	}

reset_exit:
	up_write(&lmh_sensor_access);
	return ret;
}

@@ -446,10 +448,13 @@ static void lmh_trim_error(void)

static void lmh_notify(struct work_struct *work)
{
	struct lmh_driver_data *lmh_dat;
	struct lmh_driver_data *lmh_dat = container_of(work,
			struct lmh_driver_data, isr_work);

	/* Cancel any pending polling work event before scheduling new one */
	cancel_delayed_work_sync(&lmh_dat->poll_work);
	down_write(&lmh_sensor_access);
	lmh_dat = container_of(work, struct lmh_driver_data, isr_work);
	lmh_dat->intr_state = LMH_ISR_POLLING;
	if (!lmh_data->trim_err_disable) {
		lmh_dat->intr_reg_val = readl_relaxed(lmh_dat->intr_addr);
		pr_debug("Lmh hw interrupt:%d\n", lmh_dat->intr_reg_val);
@@ -480,13 +485,12 @@ notify_exit:

static irqreturn_t lmh_handle_isr(int irq, void *data)
{
	struct lmh_driver_data *lmh_dat = (struct lmh_driver_data *)data;
	struct lmh_driver_data *lmh_dat = data;

	pr_debug("LMH Interrupt triggered\n");
	trace_lmh_event_call("Lmh Interrupt");
	if (lmh_dat->intr_state == LMH_ISR_MONITOR) {
		disable_irq_nosync(lmh_dat->irq_num);
		lmh_dat->intr_state = LMH_ISR_POLLING;
		queue_work(lmh_dat->isr_wq, &lmh_dat->isr_work);
	}