mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
gpio fixes for v6.13-rc3
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAmdcOcIACgkQEacuoBRx 13Ky3g/+JZawOniCmm5vBEH5SS4lhjEMts0i0WkaH5oIhESxsLgfZO8e0ucQt4td AmVk7ingHaoY1GYL1bmhkZEELHhqrSYb0uCMMtK1AxvXOeMUdGRj2QYpdKLGdWL3 dCrWemJi8sx0UDWs4LLvR5HcoKAACB5Mu2NmOMTtuYiBB8qIfCWQ0+0Q09/yhJM8 WNhGComnuKPvVgndHrGcd5H7CTUJobyacYu3dwvzPjPC+PvC6YTrkos5xonbyx1E GQQ3bxgU/ZvuGp6OKKeugaMxJcWOcrBm7emYiCyYwcasrh3GghUAcQ8UAP9CLYSx U1AzWI1lDqNdh7a+pr+HYR43aJ8RJ8lWFKA5wlUHSZv97G4aZyFRPBIC0AI4C9os OvW/sS4IvJ/snY7dyQ7972RLEMzmSSpEDWyYdrwOCDAtRt6KGpK7GH6yQrxQJCUN 6g30wry+zzlybki0gyyQB53b8X5pth6VuDtpaPSwFPQo1JL+Z0abbIPjqJKrVZBt UoVLKAev5Jo6U5/aiPvddBMw31RPeAN2dQTuYxKI8fv9xtWMYrpa9y9Hzgt4s1HX F+Pl2cVUnM+cKWYQbk7m1s07jHMjsnaH0RCxPX54RnXaQ7hevXfBn0HeNkETN426 uZmlQIPgIB7cP2zdBDnJ6Jzgzv5mu+azIuTb11PL6JmL+DOXzhw= =nunS -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
243f750a2d
@ -482,8 +482,9 @@ config GPIO_MT7621
|
|||||||
Say yes here to support the Mediatek MT7621 SoC GPIO device.
|
Say yes here to support the Mediatek MT7621 SoC GPIO device.
|
||||||
|
|
||||||
config GPIO_MVEBU
|
config GPIO_MVEBU
|
||||||
def_bool y
|
bool "Marvell Orion and EBU GPIO support" if COMPILE_TEST
|
||||||
depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST
|
depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST
|
||||||
|
default PLAT_ORION || ARCH_MVEBU
|
||||||
select GENERIC_IRQ_CHIP
|
select GENERIC_IRQ_CHIP
|
||||||
select REGMAP_MMIO
|
select REGMAP_MMIO
|
||||||
|
|
||||||
|
@ -32,12 +32,14 @@
|
|||||||
#define GNR_PINS_PER_REG 32
|
#define GNR_PINS_PER_REG 32
|
||||||
#define GNR_NUM_REGS DIV_ROUND_UP(GNR_NUM_PINS, GNR_PINS_PER_REG)
|
#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_CFG_LOCK_OFFSET 0x04
|
||||||
#define GNR_GPI_STATUS_OFFSET 0x20
|
#define GNR_GPI_STATUS_OFFSET 0x14
|
||||||
#define GNR_GPI_ENABLE_OFFSET 0x24
|
#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_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_EDGE FIELD_PREP(GNR_CFG_DW_RX_MASK, 1)
|
||||||
#define GNR_CFG_DW_RX_LEVEL FIELD_PREP(GNR_CFG_DW_RX_MASK, 0)
|
#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
|
* struct gnr_gpio - Intel Granite Rapids-D vGPIO driver state
|
||||||
* @gc: GPIO controller interface
|
* @gc: GPIO controller interface
|
||||||
* @reg_base: base address of the GPIO registers
|
* @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
|
* @ro_bitmap: bitmap of read-only pins
|
||||||
* @lock: guard the registers
|
* @lock: guard the registers
|
||||||
* @pad_backup: backup of the register state for suspend
|
* @pad_backup: backup of the register state for suspend
|
||||||
@ -57,6 +60,7 @@
|
|||||||
struct gnr_gpio {
|
struct gnr_gpio {
|
||||||
struct gpio_chip gc;
|
struct gpio_chip gc;
|
||||||
void __iomem *reg_base;
|
void __iomem *reg_base;
|
||||||
|
void __iomem *pad_base;
|
||||||
DECLARE_BITMAP(ro_bitmap, GNR_NUM_PINS);
|
DECLARE_BITMAP(ro_bitmap, GNR_NUM_PINS);
|
||||||
raw_spinlock_t lock;
|
raw_spinlock_t lock;
|
||||||
u32 pad_backup[];
|
u32 pad_backup[];
|
||||||
@ -65,7 +69,7 @@ struct gnr_gpio {
|
|||||||
static void __iomem *gnr_gpio_get_padcfg_addr(const struct gnr_gpio *priv,
|
static void __iomem *gnr_gpio_get_padcfg_addr(const struct gnr_gpio *priv,
|
||||||
unsigned int gpio)
|
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,
|
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;
|
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)
|
static int gnr_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||||
{
|
{
|
||||||
const struct gnr_gpio *priv = gpiochip_get_data(gc);
|
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 = {
|
static const struct gpio_chip gnr_gpio_chip = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.request = gnr_gpio_request,
|
||||||
.get = gnr_gpio_get,
|
.get = gnr_gpio_get,
|
||||||
.set = gnr_gpio_set,
|
.set = gnr_gpio_set,
|
||||||
.get_direction = gnr_gpio_get_direction,
|
.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);
|
guard(raw_spinlock_irqsave)(&priv->lock);
|
||||||
|
|
||||||
reg = readl(addr);
|
reg = readl(addr);
|
||||||
reg &= ~BIT(bit_idx);
|
reg |= BIT(bit_idx);
|
||||||
writel(reg, addr);
|
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)
|
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);
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||||
irq_hw_number_t pin = irqd_to_hwirq(d);
|
struct gnr_gpio *priv = gpiochip_get_data(gc);
|
||||||
u32 mask = GNR_CFG_DW_RX_MASK;
|
irq_hw_number_t hwirq = irqd_to_hwirq(d);
|
||||||
|
u32 reg;
|
||||||
u32 set;
|
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 */
|
/* Falling edge and level low triggers not supported by the GPIO controller */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IRQ_TYPE_NONE:
|
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 -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 = {
|
static const struct irq_chip gnr_gpio_irq_chip = {
|
||||||
|
.name = "gpio-graniterapids",
|
||||||
.irq_ack = gnr_gpio_irq_ack,
|
.irq_ack = gnr_gpio_irq_ack,
|
||||||
.irq_mask = gnr_gpio_irq_mask,
|
.irq_mask = gnr_gpio_irq_mask,
|
||||||
.irq_unmask = gnr_gpio_irq_unmask,
|
.irq_unmask = gnr_gpio_irq_unmask,
|
||||||
@ -291,6 +319,7 @@ static int gnr_gpio_probe(struct platform_device *pdev)
|
|||||||
struct gnr_gpio *priv;
|
struct gnr_gpio *priv;
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
int irq, ret;
|
int irq, ret;
|
||||||
|
u32 offset;
|
||||||
|
|
||||||
priv = devm_kzalloc(dev, struct_size(priv, pad_backup, num_backup_pins), GFP_KERNEL);
|
priv = devm_kzalloc(dev, struct_size(priv, pad_backup, num_backup_pins), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
@ -302,6 +331,10 @@ static int gnr_gpio_probe(struct platform_device *pdev)
|
|||||||
if (IS_ERR(regs))
|
if (IS_ERR(regs))
|
||||||
return PTR_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);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
return irq;
|
return irq;
|
||||||
@ -311,8 +344,6 @@ static int gnr_gpio_probe(struct platform_device *pdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return dev_err_probe(dev, ret, "failed to request interrupt\n");
|
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,
|
gnr_gpio_init_pin_ro_bits(dev, priv->reg_base + GNR_CFG_LOCK_OFFSET,
|
||||||
priv->ro_bitmap);
|
priv->ro_bitmap);
|
||||||
|
|
||||||
@ -324,7 +355,6 @@ static int gnr_gpio_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
girq = &priv->gc.irq;
|
girq = &priv->gc.irq;
|
||||||
gpio_irq_chip_set_chip(girq, &gnr_gpio_irq_chip);
|
gpio_irq_chip_set_chip(girq, &gnr_gpio_irq_chip);
|
||||||
girq->chip->name = dev_name(dev);
|
|
||||||
girq->parent_handler = NULL;
|
girq->parent_handler = NULL;
|
||||||
girq->num_parents = 0;
|
girq->num_parents = 0;
|
||||||
girq->parents = NULL;
|
girq->parents = NULL;
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
* GPIO library for the ACCES IDIO-16 family
|
* GPIO library for the ACCES IDIO-16 family
|
||||||
* Copyright (C) 2022 William Breathitt Gray
|
* Copyright (C) 2022 William Breathitt Gray
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16"
|
||||||
|
|
||||||
#include <linux/bits.h>
|
#include <linux/bits.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
@ -14,8 +17,6 @@
|
|||||||
|
|
||||||
#include "gpio-idio-16.h"
|
#include "gpio-idio-16.h"
|
||||||
|
|
||||||
#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16"
|
|
||||||
|
|
||||||
#define IDIO_16_DAT_BASE 0x0
|
#define IDIO_16_DAT_BASE 0x0
|
||||||
#define IDIO_16_OUT_BASE IDIO_16_DAT_BASE
|
#define IDIO_16_OUT_BASE IDIO_16_DAT_BASE
|
||||||
#define IDIO_16_IN_BASE (IDIO_16_DAT_BASE + 1)
|
#define IDIO_16_IN_BASE (IDIO_16_DAT_BASE + 1)
|
||||||
|
@ -82,9 +82,9 @@ static int ljca_gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&ljca_gpio->trans_lock);
|
mutex_lock(&ljca_gpio->trans_lock);
|
||||||
|
packet->num = 1;
|
||||||
packet->item[0].index = gpio_id;
|
packet->item[0].index = gpio_id;
|
||||||
packet->item[0].value = config | ljca_gpio->connect_mode[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,
|
ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet,
|
||||||
struct_size(packet, item, packet->num), NULL, 0);
|
struct_size(packet, item, packet->num), NULL, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user