Commit 243f750a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'gpio-fixes-for-v6.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - fix several low-level issues in gpio-graniterapids

 - fix an initialization order issue that manifests itself with
   __counted_by() checks in gpio-ljca

 - don't default to y for CONFIG_GPIO_MVEBU with COMPILE_TEST enabled

 - move the DEFAULT_SYMBOL_NAMESPACE define before the export.h include
   in gpio-idio-16

* tag 'gpio-fixes-for-v6.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: idio-16: Actually make use of the GPIO_IDIO_16 symbol namespace
  gpio: graniterapids: Fix GPIO Ack functionality
  gpio: graniterapids: Check if GPIO line can be used for IRQs
  gpio: graniterapids: Determine if GPIO pad can be used by driver
  gpio: graniterapids: Fix invalid RXEVCFG register bitmask
  gpio: graniterapids: Fix invalid GPI_IS register offset
  gpio: graniterapids: Fix incorrect BAR assignment
  gpio: graniterapids: Fix vGPIO driver crash
  gpio: ljca: Initialize num before accessing item in ljca_gpio_config
  gpio: GPIO_MVEBU should not default to y when compile-testing
parents de20dc2b 9ac4b58f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -482,8 +482,9 @@ config GPIO_MT7621
	  Say yes here to support the Mediatek MT7621 SoC GPIO device.

config GPIO_MVEBU
	def_bool y
	bool "Marvell Orion and EBU GPIO support" if COMPILE_TEST
	depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST
	default PLAT_ORION || ARCH_MVEBU
	select GENERIC_IRQ_CHIP
	select REGMAP_MMIO

+41 −11
Original line number Diff line number Diff line
@@ -32,12 +32,14 @@
#define GNR_PINS_PER_REG 32
#define GNR_NUM_REGS DIV_ROUND_UP(GNR_NUM_PINS, GNR_PINS_PER_REG)

#define GNR_CFG_BAR		0x00
#define GNR_CFG_PADBAR		0x00
#define GNR_CFG_LOCK_OFFSET	0x04
#define GNR_GPI_STATUS_OFFSET	0x20
#define GNR_GPI_STATUS_OFFSET	0x14
#define GNR_GPI_ENABLE_OFFSET	0x24

#define GNR_CFG_DW_RX_MASK	GENMASK(25, 22)
#define GNR_CFG_DW_HOSTSW_MODE	BIT(27)
#define GNR_CFG_DW_RX_MASK	GENMASK(23, 22)
#define GNR_CFG_DW_INTSEL_MASK	GENMASK(21, 14)
#define GNR_CFG_DW_RX_DISABLE	FIELD_PREP(GNR_CFG_DW_RX_MASK, 2)
#define GNR_CFG_DW_RX_EDGE	FIELD_PREP(GNR_CFG_DW_RX_MASK, 1)
#define GNR_CFG_DW_RX_LEVEL	FIELD_PREP(GNR_CFG_DW_RX_MASK, 0)
@@ -50,6 +52,7 @@
 * struct gnr_gpio - Intel Granite Rapids-D vGPIO driver state
 * @gc: GPIO controller interface
 * @reg_base: base address of the GPIO registers
 * @pad_base: base address of the vGPIO pad configuration registers
 * @ro_bitmap: bitmap of read-only pins
 * @lock: guard the registers
 * @pad_backup: backup of the register state for suspend
@@ -57,6 +60,7 @@
struct gnr_gpio {
	struct gpio_chip gc;
	void __iomem *reg_base;
	void __iomem *pad_base;
	DECLARE_BITMAP(ro_bitmap, GNR_NUM_PINS);
	raw_spinlock_t lock;
	u32 pad_backup[];
@@ -65,7 +69,7 @@ struct gnr_gpio {
static void __iomem *gnr_gpio_get_padcfg_addr(const struct gnr_gpio *priv,
					      unsigned int gpio)
{
	return priv->reg_base + gpio * sizeof(u32);
	return priv->pad_base + gpio * sizeof(u32);
}

static int gnr_gpio_configure_line(struct gpio_chip *gc, unsigned int gpio,
@@ -88,6 +92,20 @@ static int gnr_gpio_configure_line(struct gpio_chip *gc, unsigned int gpio,
	return 0;
}

static int gnr_gpio_request(struct gpio_chip *gc, unsigned int gpio)
{
	struct gnr_gpio *priv = gpiochip_get_data(gc);
	u32 dw;

	dw = readl(gnr_gpio_get_padcfg_addr(priv, gpio));
	if (!(dw & GNR_CFG_DW_HOSTSW_MODE)) {
		dev_warn(gc->parent, "GPIO %u is not owned by host", gpio);
		return -EBUSY;
	}

	return 0;
}

static int gnr_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
	const struct gnr_gpio *priv = gpiochip_get_data(gc);
@@ -139,6 +157,7 @@ static int gnr_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio, in

static const struct gpio_chip gnr_gpio_chip = {
	.owner		  = THIS_MODULE,
	.request	  = gnr_gpio_request,
	.get		  = gnr_gpio_get,
	.set		  = gnr_gpio_set,
	.get_direction    = gnr_gpio_get_direction,
@@ -166,7 +185,7 @@ static void gnr_gpio_irq_ack(struct irq_data *d)
	guard(raw_spinlock_irqsave)(&priv->lock);

	reg = readl(addr);
	reg &= ~BIT(bit_idx);
	reg |= BIT(bit_idx);
	writel(reg, addr);
}

@@ -209,10 +228,18 @@ static void gnr_gpio_irq_unmask(struct irq_data *d)
static int gnr_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t pin = irqd_to_hwirq(d);
	u32 mask = GNR_CFG_DW_RX_MASK;
	struct gnr_gpio *priv = gpiochip_get_data(gc);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	u32 reg;
	u32 set;

	/* Allow interrupts only if Interrupt Select field is non-zero */
	reg = readl(gnr_gpio_get_padcfg_addr(priv, hwirq));
	if (!(reg & GNR_CFG_DW_INTSEL_MASK)) {
		dev_dbg(gc->parent, "GPIO %lu cannot be used as IRQ", hwirq);
		return -EPERM;
	}

	/* Falling edge and level low triggers not supported by the GPIO controller */
	switch (type) {
	case IRQ_TYPE_NONE:
@@ -230,10 +257,11 @@ static int gnr_gpio_irq_set_type(struct irq_data *d, unsigned int type)
		return -EINVAL;
	}

	return gnr_gpio_configure_line(gc, pin, mask, set);
	return gnr_gpio_configure_line(gc, hwirq, GNR_CFG_DW_RX_MASK, set);
}

static const struct irq_chip gnr_gpio_irq_chip = {
	.name		= "gpio-graniterapids",
	.irq_ack	= gnr_gpio_irq_ack,
	.irq_mask	= gnr_gpio_irq_mask,
	.irq_unmask	= gnr_gpio_irq_unmask,
@@ -291,6 +319,7 @@ static int gnr_gpio_probe(struct platform_device *pdev)
	struct gnr_gpio *priv;
	void __iomem *regs;
	int irq, ret;
	u32 offset;

	priv = devm_kzalloc(dev, struct_size(priv, pad_backup, num_backup_pins), GFP_KERNEL);
	if (!priv)
@@ -302,6 +331,10 @@ static int gnr_gpio_probe(struct platform_device *pdev)
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	priv->reg_base = regs;
	offset = readl(priv->reg_base + GNR_CFG_PADBAR);
	priv->pad_base = priv->reg_base + offset;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;
@@ -311,8 +344,6 @@ static int gnr_gpio_probe(struct platform_device *pdev)
	if (ret)
		return dev_err_probe(dev, ret, "failed to request interrupt\n");

	priv->reg_base = regs + readl(regs + GNR_CFG_BAR);

	gnr_gpio_init_pin_ro_bits(dev, priv->reg_base + GNR_CFG_LOCK_OFFSET,
				  priv->ro_bitmap);

@@ -324,7 +355,6 @@ static int gnr_gpio_probe(struct platform_device *pdev)

	girq = &priv->gc.irq;
	gpio_irq_chip_set_chip(girq, &gnr_gpio_irq_chip);
	girq->chip->name	= dev_name(dev);
	girq->parent_handler	= NULL;
	girq->num_parents	= 0;
	girq->parents		= NULL;
+3 −2
Original line number Diff line number Diff line
@@ -3,6 +3,9 @@
 * GPIO library for the ACCES IDIO-16 family
 * Copyright (C) 2022 William Breathitt Gray
 */

#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16"

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -14,8 +17,6 @@

#include "gpio-idio-16.h"

#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16"

#define IDIO_16_DAT_BASE 0x0
#define IDIO_16_OUT_BASE IDIO_16_DAT_BASE
#define IDIO_16_IN_BASE (IDIO_16_DAT_BASE + 1)
+1 −1
Original line number Diff line number Diff line
@@ -82,9 +82,9 @@ static int ljca_gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id,
	int ret;

	mutex_lock(&ljca_gpio->trans_lock);
	packet->num = 1;
	packet->item[0].index = gpio_id;
	packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id];
	packet->num = 1;

	ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet,
			    struct_size(packet, item, packet->num), NULL, 0);