Commit 7219b824 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

Merge tag 'intel-gpio-v5.19-2' of...

Merge tag 'intel-gpio-v5.19-2' of gitolite.kernel.org:pub/scm/linux/kernel/git/andy/linux-gpio-intel into gpio/for-current

intel-gpio for v5.19-2

* Convert IRQ chips in Diolan and Intel GPIO drivers to be immutable
parents f2906aa8 b93a8b2c
Loading
Loading
Loading
Loading
+37 −33
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>
#include <linux/types.h>

#define CRYSTALCOVE_GPIO_NUM	16
#define CRYSTALCOVE_VGPIO_NUM	95
@@ -110,8 +111,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)
	return reg + gpio % 8;
}

static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg,
					int gpio)
static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, int gpio)
{
	u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0;
	int mask = BIT(gpio % 8);
@@ -140,8 +140,7 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)
	return regmap_write(cg->regmap, reg, CTLO_INPUT_SET);
}

static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio,
				    int value)
static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, int value)
{
	struct crystalcove_gpio *cg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);
@@ -168,8 +167,7 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
	return val & 0x1;
}

static void crystalcove_gpio_set(struct gpio_chip *chip,
				 unsigned int gpio, int value)
static void crystalcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
{
	struct crystalcove_gpio *cg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);
@@ -185,10 +183,10 @@ static void crystalcove_gpio_set(struct gpio_chip *chip,

static int crystalcove_irq_type(struct irq_data *data, unsigned int type)
{
	struct crystalcove_gpio *cg =
		gpiochip_get_data(irq_data_get_irq_chip_data(data));
	struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));
	irq_hw_number_t hwirq = irqd_to_hwirq(data);

	if (data->hwirq >= CRYSTALCOVE_GPIO_NUM)
	if (hwirq >= CRYSTALCOVE_GPIO_NUM)
		return 0;

	switch (type) {
@@ -215,22 +213,20 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned int type)

static void crystalcove_bus_lock(struct irq_data *data)
{
	struct crystalcove_gpio *cg =
		gpiochip_get_data(irq_data_get_irq_chip_data(data));
	struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));

	mutex_lock(&cg->buslock);
}

static void crystalcove_bus_sync_unlock(struct irq_data *data)
{
	struct crystalcove_gpio *cg =
		gpiochip_get_data(irq_data_get_irq_chip_data(data));
	int gpio = data->hwirq;
	struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));
	irq_hw_number_t hwirq = irqd_to_hwirq(data);

	if (cg->update & UPDATE_IRQ_TYPE)
		crystalcove_update_irq_ctrl(cg, gpio);
		crystalcove_update_irq_ctrl(cg, hwirq);
	if (cg->update & UPDATE_IRQ_MASK)
		crystalcove_update_irq_mask(cg, gpio);
		crystalcove_update_irq_mask(cg, hwirq);
	cg->update = 0;

	mutex_unlock(&cg->buslock);
@@ -238,34 +234,43 @@ static void crystalcove_bus_sync_unlock(struct irq_data *data)

static void crystalcove_irq_unmask(struct irq_data *data)
{
	struct crystalcove_gpio *cg =
		gpiochip_get_data(irq_data_get_irq_chip_data(data));
	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
	struct crystalcove_gpio *cg = gpiochip_get_data(gc);
	irq_hw_number_t hwirq = irqd_to_hwirq(data);

	if (hwirq >= CRYSTALCOVE_GPIO_NUM)
		return;

	gpiochip_enable_irq(gc, hwirq);

	if (data->hwirq < CRYSTALCOVE_GPIO_NUM) {
	cg->set_irq_mask = false;
	cg->update |= UPDATE_IRQ_MASK;
}
}

static void crystalcove_irq_mask(struct irq_data *data)
{
	struct crystalcove_gpio *cg =
		gpiochip_get_data(irq_data_get_irq_chip_data(data));
	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
	struct crystalcove_gpio *cg = gpiochip_get_data(gc);
	irq_hw_number_t hwirq = irqd_to_hwirq(data);

	if (hwirq >= CRYSTALCOVE_GPIO_NUM)
		return;

	if (data->hwirq < CRYSTALCOVE_GPIO_NUM) {
	cg->set_irq_mask = true;
	cg->update |= UPDATE_IRQ_MASK;
	}

	gpiochip_disable_irq(gc, hwirq);
}

static struct irq_chip crystalcove_irqchip = {
static const struct irq_chip crystalcove_irqchip = {
	.name			= "Crystal Cove",
	.irq_mask		= crystalcove_irq_mask,
	.irq_unmask		= crystalcove_irq_unmask,
	.irq_set_type		= crystalcove_irq_type,
	.irq_bus_lock		= crystalcove_bus_lock,
	.irq_bus_sync_unlock	= crystalcove_bus_sync_unlock,
	.flags			= IRQCHIP_SKIP_SET_WAKE,
	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
@@ -293,8 +298,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
	return IRQ_HANDLED;
}

static void crystalcove_gpio_dbg_show(struct seq_file *s,
				      struct gpio_chip *chip)
static void crystalcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
	struct crystalcove_gpio *cg = gpiochip_get_data(chip);
	int gpio, offset;
@@ -353,7 +357,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
	cg->regmap = pmic->regmap;

	girq = &cg->chip.irq;
	girq->chip = &crystalcove_irqchip;
	gpio_irq_chip_set_chip(girq, &crystalcove_irqchip);
	/* This will let us handle the parent IRQ in the driver */
	girq->parent_handler = NULL;
	girq->num_parents = 0;
+14 −9
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@
struct dln2_gpio {
	struct platform_device *pdev;
	struct gpio_chip gpio;
	struct irq_chip irqchip;

	/*
	 * Cache pin direction to save us one transfer, since the hardware has
@@ -306,6 +305,7 @@ static void dln2_irq_unmask(struct irq_data *irqd)
	struct dln2_gpio *dln2 = gpiochip_get_data(gc);
	int pin = irqd_to_hwirq(irqd);

	gpiochip_enable_irq(gc, pin);
	set_bit(pin, dln2->unmasked_irqs);
}

@@ -316,6 +316,7 @@ static void dln2_irq_mask(struct irq_data *irqd)
	int pin = irqd_to_hwirq(irqd);

	clear_bit(pin, dln2->unmasked_irqs);
	gpiochip_disable_irq(gc, pin);
}

static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
@@ -384,6 +385,17 @@ static void dln2_irq_bus_unlock(struct irq_data *irqd)
	mutex_unlock(&dln2->irq_lock);
}

static const struct irq_chip dln2_irqchip = {
	.name = "dln2-irq",
	.irq_mask = dln2_irq_mask,
	.irq_unmask = dln2_irq_unmask,
	.irq_set_type = dln2_irq_set_type,
	.irq_bus_lock = dln2_irq_bus_lock,
	.irq_bus_sync_unlock = dln2_irq_bus_unlock,
	.flags = IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
			    const void *data, int len)
{
@@ -465,15 +477,8 @@ static int dln2_gpio_probe(struct platform_device *pdev)
	dln2->gpio.direction_output = dln2_gpio_direction_output;
	dln2->gpio.set_config = dln2_gpio_set_config;

	dln2->irqchip.name = "dln2-irq",
	dln2->irqchip.irq_mask = dln2_irq_mask,
	dln2->irqchip.irq_unmask = dln2_irq_unmask,
	dln2->irqchip.irq_set_type = dln2_irq_set_type,
	dln2->irqchip.irq_bus_lock = dln2_irq_bus_lock,
	dln2->irqchip.irq_bus_sync_unlock = dln2_irq_bus_unlock,

	girq = &dln2->gpio.irq;
	girq->chip = &dln2->irqchip;
	gpio_irq_chip_set_chip(girq, &dln2_irqchip);
	/* The event comes from the outside so no parent handler */
	girq->parent_handler = NULL;
	girq->num_parents = 0;
+15 −7
Original line number Diff line number Diff line
@@ -220,10 +220,8 @@ static void mrfld_irq_ack(struct irq_data *d)
	raw_spin_unlock_irqrestore(&priv->lock, flags);
}

static void mrfld_irq_unmask_mask(struct irq_data *d, bool unmask)
static void mrfld_irq_unmask_mask(struct mrfld_gpio *priv, u32 gpio, bool unmask)
{
	struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d);
	u32 gpio = irqd_to_hwirq(d);
	void __iomem *gimr = gpio_reg(&priv->chip, gpio, GIMR);
	unsigned long flags;
	u32 value;
@@ -241,12 +239,20 @@ static void mrfld_irq_unmask_mask(struct irq_data *d, bool unmask)

static void mrfld_irq_mask(struct irq_data *d)
{
	mrfld_irq_unmask_mask(d, false);
	struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d);
	u32 gpio = irqd_to_hwirq(d);

	mrfld_irq_unmask_mask(priv, gpio, false);
	gpiochip_disable_irq(&priv->chip, gpio);
}

static void mrfld_irq_unmask(struct irq_data *d)
{
	mrfld_irq_unmask_mask(d, true);
	struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d);
	u32 gpio = irqd_to_hwirq(d);

	gpiochip_enable_irq(&priv->chip, gpio);
	mrfld_irq_unmask_mask(priv, gpio, true);
}

static int mrfld_irq_set_type(struct irq_data *d, unsigned int type)
@@ -329,13 +335,15 @@ static int mrfld_irq_set_wake(struct irq_data *d, unsigned int on)
	return 0;
}

static struct irq_chip mrfld_irqchip = {
static const struct irq_chip mrfld_irqchip = {
	.name		= "gpio-merrifield",
	.irq_ack	= mrfld_irq_ack,
	.irq_mask	= mrfld_irq_mask,
	.irq_unmask	= mrfld_irq_unmask,
	.irq_set_type	= mrfld_irq_set_type,
	.irq_set_wake	= mrfld_irq_set_wake,
	.flags		= IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static void mrfld_irq_handler(struct irq_desc *desc)
@@ -482,7 +490,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
		return retval;

	girq = &priv->chip.irq;
	girq->chip = &mrfld_irqchip;
	gpio_irq_chip_set_chip(girq, &mrfld_irqchip);
	girq->init_hw = mrfld_irq_init_hw;
	girq->parent_handler = mrfld_irq_handler;
	girq->num_parents = 1;
+22 −13
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@

struct sch_gpio {
	struct gpio_chip chip;
	struct irq_chip irqchip;
	spinlock_t lock;
	unsigned short iobase;
	unsigned short resume_base;
@@ -218,11 +217,9 @@ static void sch_irq_ack(struct irq_data *d)
	spin_unlock_irqrestore(&sch->lock, flags);
}

static void sch_irq_mask_unmask(struct irq_data *d, int val)
static void sch_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t gpio_num, int val)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct sch_gpio *sch = gpiochip_get_data(gc);
	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
	unsigned long flags;

	spin_lock_irqsave(&sch->lock, flags);
@@ -232,14 +229,32 @@ static void sch_irq_mask_unmask(struct irq_data *d, int val)

static void sch_irq_mask(struct irq_data *d)
{
	sch_irq_mask_unmask(d, 0);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t gpio_num = irqd_to_hwirq(d);

	sch_irq_mask_unmask(gc, gpio_num, 0);
	gpiochip_disable_irq(gc, gpio_num);
}

static void sch_irq_unmask(struct irq_data *d)
{
	sch_irq_mask_unmask(d, 1);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t gpio_num = irqd_to_hwirq(d);

	gpiochip_enable_irq(gc, gpio_num);
	sch_irq_mask_unmask(gc, gpio_num, 1);
}

static const struct irq_chip sch_irqchip = {
	.name = "sch_gpio",
	.irq_ack = sch_irq_ack,
	.irq_mask = sch_irq_mask,
	.irq_unmask = sch_irq_unmask,
	.irq_set_type = sch_irq_type,
	.flags = IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context)
{
	struct sch_gpio *sch = context;
@@ -367,14 +382,8 @@ static int sch_gpio_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, sch);

	sch->irqchip.name = "sch_gpio";
	sch->irqchip.irq_ack = sch_irq_ack;
	sch->irqchip.irq_mask = sch_irq_mask;
	sch->irqchip.irq_unmask = sch_irq_unmask;
	sch->irqchip.irq_set_type = sch_irq_type;

	girq = &sch->chip.irq;
	girq->chip = &sch->irqchip;
	gpio_irq_chip_set_chip(girq, &sch_irqchip);
	girq->num_parents = 0;
	girq->parents = NULL;
	girq->parent_handler = NULL;
+8 −2
Original line number Diff line number Diff line
@@ -299,6 +299,8 @@ static void wcove_irq_unmask(struct irq_data *data)
	if (gpio >= WCOVE_GPIO_NUM)
		return;

	gpiochip_enable_irq(chip, gpio);

	wg->set_irq_mask = false;
	wg->update |= UPDATE_IRQ_MASK;
}
@@ -314,15 +316,19 @@ static void wcove_irq_mask(struct irq_data *data)

	wg->set_irq_mask = true;
	wg->update |= UPDATE_IRQ_MASK;

	gpiochip_disable_irq(chip, gpio);
}

static struct irq_chip wcove_irqchip = {
static const struct irq_chip wcove_irqchip = {
	.name			= "Whiskey Cove",
	.irq_mask		= wcove_irq_mask,
	.irq_unmask		= wcove_irq_unmask,
	.irq_set_type		= wcove_irq_type,
	.irq_bus_lock		= wcove_bus_lock,
	.irq_bus_sync_unlock	= wcove_bus_sync_unlock,
	.flags			= IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
@@ -452,7 +458,7 @@ static int wcove_gpio_probe(struct platform_device *pdev)
	}

	girq = &wg->chip.irq;
	girq->chip = &wcove_irqchip;
	gpio_irq_chip_set_chip(girq, &wcove_irqchip);
	/* This will let us handle the parent IRQ in the driver */
	girq->parent_handler = NULL;
	girq->num_parents = 0;