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

Commit e0a55832 authored by Maulik Shah's avatar Maulik Shah
Browse files

pinctrl: qcom: Add irq_enable callback for msmgpio-dc



Introduce the irq_enable callback which will be same as irq_unmask
except that it will also clear the pending irq before unmask.

This will help in clearing any erroneous interrupts that would
have gotten latched when the interrupt is not in use.

Change-Id: Ie97b017a0731f1616845b9c54c3a6d3ba0d5a666
Signed-off-by: default avatarMaulik Shah <mkshah@codeaurora.org>
parent 6293e143
Loading
Loading
Loading
Loading
+18 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
@@ -95,6 +96,20 @@ static inline int pdc_enable_intr(struct irq_data *d, bool on)
	return 0;
	return 0;
}
}


static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d,
		enum irqchip_irq_state which, bool *state)
{
	return d->parent_data->chip->irq_get_irqchip_state(d,
		which, state);
}

static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d,
		enum irqchip_irq_state which, bool value)
{
	return d->parent_data->chip->irq_set_irqchip_state(d,
		which, value);
}

static void qcom_pdc_gic_mask(struct irq_data *d)
static void qcom_pdc_gic_mask(struct irq_data *d)
{
{
	pdc_enable_intr(d, false);
	pdc_enable_intr(d, false);
@@ -220,6 +235,8 @@ static struct irq_chip qcom_pdc_gic_chip = {
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	.irq_set_affinity	= irq_chip_set_affinity_parent,
	.irq_set_affinity	= irq_chip_set_affinity_parent,
#endif
#endif
	.irq_get_irqchip_state	= qcom_pdc_gic_get_irqchip_state,
	.irq_set_irqchip_state	= qcom_pdc_gic_set_irqchip_state,
};
};


static int qcom_pdc_translate(struct irq_domain *d,
static int qcom_pdc_translate(struct irq_domain *d,
+34 −1
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2013, Sony Mobile Communications AB.
 * Copyright (c) 2013, Sony Mobile Communications AB.
 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -821,6 +821,38 @@ static void msm_dirconn_irq_mask(struct irq_data *d)
		parent_data->chip->irq_mask(parent_data);
		parent_data->chip->irq_mask(parent_data);
}
}


static void msm_dirconn_irq_enable(struct irq_data *d)
{
	struct irq_desc *desc = irq_data_to_desc(d);
	struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
	irq_hw_number_t dir_conn_irq = 0;

	if (!parent_data)
		return;

	if (is_gpio_dual_edge(d, &dir_conn_irq)) {
		struct irq_data *dir_conn_data =
			irq_get_irq_data(irq_find_mapping(parent_data->domain,
						dir_conn_irq));

		if (dir_conn_data &&
				dir_conn_data->chip->irq_set_irqchip_state)
			dir_conn_data->chip->irq_set_irqchip_state(
					dir_conn_data,
					IRQCHIP_STATE_PENDING, 0);

		if (dir_conn_data && dir_conn_data->chip->irq_unmask)
			dir_conn_data->chip->irq_unmask(dir_conn_data);
	}

	if (parent_data->chip->irq_set_irqchip_state)
		parent_data->chip->irq_set_irqchip_state(parent_data,
						IRQCHIP_STATE_PENDING, 0);

	if (parent_data->chip->irq_unmask)
		parent_data->chip->irq_unmask(parent_data);
}

static void msm_dirconn_irq_unmask(struct irq_data *d)
static void msm_dirconn_irq_unmask(struct irq_data *d)
{
{
	struct irq_desc *desc = irq_data_to_desc(d);
	struct irq_desc *desc = irq_data_to_desc(d);
@@ -1058,6 +1090,7 @@ static int msm_dirconn_irq_set_type(struct irq_data *d, unsigned int type)
static struct irq_chip msm_dirconn_irq_chip = {
static struct irq_chip msm_dirconn_irq_chip = {
	.name			= "msmgpio-dc",
	.name			= "msmgpio-dc",
	.irq_mask		= msm_dirconn_irq_mask,
	.irq_mask		= msm_dirconn_irq_mask,
	.irq_enable		= msm_dirconn_irq_enable,
	.irq_unmask		= msm_dirconn_irq_unmask,
	.irq_unmask		= msm_dirconn_irq_unmask,
	.irq_eoi		= msm_dirconn_irq_eoi,
	.irq_eoi		= msm_dirconn_irq_eoi,
	.irq_ack		= msm_dirconn_irq_ack,
	.irq_ack		= msm_dirconn_irq_ack,