Commit 29f9f8e1 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'gpio-updates-for-v5.8-part1' of...

Merge tag 'gpio-updates-for-v5.8-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel

gpio updates for v5.8-rc1 - part1

- correct the IRQ type used in to_irq() in gpio-xgene-sb
- add new item to the TODO list
- support building gpio-pl061 as module
- improve pull-up/down support on GPIO expanders in device-tree
- several improvements in gpio-pca953x
- emit a warning for too long GPIO line names
- add MODULE_DEVICE_TABLE to gpio-tegra186
- add support for new variant to gpio-f7188x
- lsgpio can now display bias flags
parents 8d091012 3831c051
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ config GPIO_OMAP
	  Say yes here to enable GPIO support for TI OMAP SoCs.

config GPIO_PL061
	bool "PrimeCell PL061 GPIO support"
	tristate "PrimeCell PL061 GPIO support"
	depends on ARM_AMBA
	select IRQ_DOMAIN
	select GPIOLIB_IRQCHIP
+4 −0
Original line number Diff line number Diff line
@@ -99,6 +99,10 @@ similar and probe a proper driver in the gpiolib subsystem.
In some cases it makes sense to create a GPIO chip from the local driver
for a few GPIOs. Those should stay where they are.

At the same time it makes sense to get rid of code duplication in existing or
new coming drivers. For example, gpio-ml-ioh should be incorporated into
gpio-pch. In similar way gpio-intel-mid into gpio-pxa.


Generic MMIO GPIO

+30 −3
Original line number Diff line number Diff line
@@ -36,9 +36,19 @@
#define SIO_F71889A_ID		0x1005	/* F71889A chipset ID */
#define SIO_F81866_ID		0x1010	/* F81866 chipset ID */
#define SIO_F81804_ID		0x1502  /* F81804 chipset ID, same for f81966 */


enum chips { f71869, f71869a, f71882fg, f71889a, f71889f, f81866, f81804 };
#define SIO_F81865_ID		0x0704	/* F81865 chipset ID */


enum chips {
	f71869,
	f71869a,
	f71882fg,
	f71889a,
	f71889f,
	f81866,
	f81804,
	f81865,
};

static const char * const f7188x_names[] = {
	"f71869",
@@ -48,6 +58,7 @@ static const char * const f7188x_names[] = {
	"f71889f",
	"f81866",
	"f81804",
	"f81865",
};

struct f7188x_sio {
@@ -233,6 +244,15 @@ static struct f7188x_gpio_bank f81804_gpio_bank[] = {
	F7188X_GPIO_BANK(90, 8, 0x98),
};

static struct f7188x_gpio_bank f81865_gpio_bank[] = {
	F7188X_GPIO_BANK(0, 8, 0xF0),
	F7188X_GPIO_BANK(10, 8, 0xE0),
	F7188X_GPIO_BANK(20, 8, 0xD0),
	F7188X_GPIO_BANK(30, 8, 0xC0),
	F7188X_GPIO_BANK(40, 8, 0xB0),
	F7188X_GPIO_BANK(50, 8, 0xA0),
	F7188X_GPIO_BANK(60, 5, 0x90),
};

static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
@@ -425,6 +445,10 @@ static int f7188x_gpio_probe(struct platform_device *pdev)
		data->nr_bank = ARRAY_SIZE(f81804_gpio_bank);
		data->bank = f81804_gpio_bank;
		break;
	case f81865:
		data->nr_bank = ARRAY_SIZE(f81865_gpio_bank);
		data->bank = f81865_gpio_bank;
		break;
	default:
		return -ENODEV;
	}
@@ -490,6 +514,9 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio)
	case SIO_F81804_ID:
		sio->type = f81804;
		break;
	case SIO_F81865_ID:
		sio->type = f81865;
		break;
	default:
		pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid);
		goto err;
+58 −36
Original line number Diff line number Diff line
@@ -306,37 +306,39 @@ static const struct regmap_config pca953x_i2c_regmap = {
	.writeable_reg = pca953x_writeable_register,
	.volatile_reg = pca953x_volatile_register,

	.disable_locking = true,
	.cache_type = REGCACHE_RBTREE,
	/* REVISIT: should be 0x7f but some 24 bit chips use REG_ADDR_AI */
	.max_register = 0xff,
	.max_register = 0x7f,
};

static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off,
			      bool write, bool addrinc)
static const struct regmap_config pca953x_ai_i2c_regmap = {
	.reg_bits = 8,
	.val_bits = 8,

	.read_flag_mask = REG_ADDR_AI,
	.write_flag_mask = REG_ADDR_AI,

	.readable_reg = pca953x_readable_register,
	.writeable_reg = pca953x_writeable_register,
	.volatile_reg = pca953x_volatile_register,

	.cache_type = REGCACHE_RBTREE,
	.max_register = 0x7f,
};

static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off)
{
	int bank_shift = pca953x_bank_shift(chip);
	int addr = (reg & PCAL_GPIO_MASK) << bank_shift;
	int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;
	u8 regaddr = pinctrl | addr | (off / BANK_SZ);

	/* Single byte read doesn't need AI bit set. */
	if (!addrinc)
		return regaddr;

	/* Chips with 24 and more GPIOs always support Auto Increment */
	if (write && NBANK(chip) > 2)
		regaddr |= REG_ADDR_AI;

	/* PCA9575 needs address-increment on multi-byte writes */
	if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE)
		regaddr |= REG_ADDR_AI;

	return regaddr;
}

static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
{
	u8 regaddr = pca953x_recalc_addr(chip, reg, 0, true, true);
	u8 regaddr = pca953x_recalc_addr(chip, reg, 0);
	u8 value[MAX_BANK];
	int i, ret;

@@ -354,7 +356,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long

static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
{
	u8 regaddr = pca953x_recalc_addr(chip, reg, 0, false, true);
	u8 regaddr = pca953x_recalc_addr(chip, reg, 0);
	u8 value[MAX_BANK];
	int i, ret;

@@ -373,8 +375,7 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *
static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
					true, false);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off);
	u8 bit = BIT(off % BANK_SZ);
	int ret;

@@ -388,10 +389,8 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
		unsigned off, int val)
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
					true, false);
	u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off,
					true, false);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off);
	u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off);
	u8 bit = BIT(off % BANK_SZ);
	int ret;

@@ -411,8 +410,7 @@ exit:
static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 inreg = pca953x_recalc_addr(chip, chip->regs->input, off,
				       true, false);
	u8 inreg = pca953x_recalc_addr(chip, chip->regs->input, off);
	u8 bit = BIT(off % BANK_SZ);
	u32 reg_val;
	int ret;
@@ -436,8 +434,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off,
					true, false);
	u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off);
	u8 bit = BIT(off % BANK_SZ);

	mutex_lock(&chip->i2c_lock);
@@ -448,8 +445,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
					true, false);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off);
	u8 bit = BIT(off % BANK_SZ);
	u32 reg_val;
	int ret;
@@ -466,6 +462,23 @@ static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
	return GPIO_LINE_DIRECTION_OUT;
}

static int pca953x_gpio_get_multiple(struct gpio_chip *gc,
				     unsigned long *mask, unsigned long *bits)
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	DECLARE_BITMAP(reg_val, MAX_LINE);
	int ret;

	mutex_lock(&chip->i2c_lock);
	ret = pca953x_read_regs(chip, chip->regs->input, reg_val);
	mutex_unlock(&chip->i2c_lock);
	if (ret)
		return ret;

	bitmap_replace(bits, bits, reg_val, mask, gc->ngpio);
	return 0;
}

static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
				      unsigned long *mask, unsigned long *bits)
{
@@ -489,10 +502,8 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip,
					 unsigned int offset,
					 unsigned long config)
{
	u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset,
					     true, false);
	u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset,
					      true, false);
	u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset);
	u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset);
	u8 bit = BIT(offset % BANK_SZ);
	int ret;

@@ -551,6 +562,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
	gc->get = pca953x_gpio_get_value;
	gc->set = pca953x_gpio_set_value;
	gc->get_direction = pca953x_gpio_get_direction;
	gc->get_multiple = pca953x_gpio_get_multiple;
	gc->set_multiple = pca953x_gpio_set_multiple;
	gc->set_config = pca953x_gpio_set_config;
	gc->can_sleep = true;
@@ -863,6 +875,7 @@ static int pca953x_probe(struct i2c_client *client,
	int ret;
	u32 invert = 0;
	struct regulator *reg;
	const struct regmap_config *regmap_config;

	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
@@ -925,7 +938,17 @@ static int pca953x_probe(struct i2c_client *client,

	i2c_set_clientdata(client, chip);

	chip->regmap = devm_regmap_init_i2c(client, &pca953x_i2c_regmap);
	pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK);

	if (NBANK(chip) > 2 || PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) {
		dev_info(&client->dev, "using AI\n");
		regmap_config = &pca953x_ai_i2c_regmap;
	} else {
		dev_info(&client->dev, "using no AI\n");
		regmap_config = &pca953x_i2c_regmap;
	}

	chip->regmap = devm_regmap_init_i2c(client, regmap_config);
	if (IS_ERR(chip->regmap)) {
		ret = PTR_ERR(chip->regmap);
		goto err_exit;
@@ -956,7 +979,6 @@ static int pca953x_probe(struct i2c_client *client,
	/* initialize cached registers from their original values.
	 * we can't share this chip with another i2c master.
	 */
	pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK);

	if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) {
		chip->regs = &pca953x_regs;
+4 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/gpio/driver.h>
#include <linux/device.h>
@@ -408,6 +409,7 @@ static const struct amba_id pl061_ids[] = {
	},
	{ 0, 0 },
};
MODULE_DEVICE_TABLE(amba, pl061_ids);

static struct amba_driver pl061_gpio_driver = {
	.drv = {
@@ -419,9 +421,6 @@ static struct amba_driver pl061_gpio_driver = {
	.id_table	= pl061_ids,
	.probe		= pl061_probe,
};
module_amba_driver(pl061_gpio_driver);

static int __init pl061_gpio_init(void)
{
	return amba_driver_register(&pl061_gpio_driver);
}
device_initcall(pl061_gpio_init);
MODULE_LICENSE("GPL v2");
Loading