diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 09:35:29 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 09:35:29 -0800 | 
| commit | 4c8c225abf972ce422c241579ce1d4d27eaeb166 (patch) | |
| tree | 77bc67defdc53c494b20632e66b82ce9be3c06af /drivers/gpio/gpio-pca953x.c | |
| parent | 3eb05225ee8efb81fe50558f5f9d94e7477ade8f (diff) | |
| parent | 9170100ee46402af6d318134525c728027318d67 (diff) | |
| download | olio-linux-3.10-4c8c225abf972ce422c241579ce1d4d27eaeb166.tar.xz olio-linux-3.10-4c8c225abf972ce422c241579ce1d4d27eaeb166.zip  | |
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux
Pull GPIO changes from Grant Likely:
 "This branch contains the usual set of individual driver improvements
  and bug fixes, as well as updates to the core code.  The more notable
  changes include:
   - Internally add new API for referencing GPIOs by gpio_desc instead
     of number.  Eventually this will become a public API
   - ACPI GPIO binding support"
* tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux: (33 commits)
  arm64: select ARCH_WANT_OPTIONAL_GPIOLIB
  gpio: em: Use irq_domain_add_simple() to fix runtime error
  gpio: using common order: let 'static const' instead of 'const static'
  gpio/vt8500: memory cleanup missing
  gpiolib: Fix locking on gpio debugfs files
  gpiolib: let gpio_chip reference its descriptors
  gpiolib: use descriptors internally
  gpiolib: use gpio_chips list in gpiochip_find_base
  gpiolib: use gpio_chips list in sysfs ops
  gpiolib: use gpio_chips list in gpiochip_find
  gpiolib: use gpio_chips list in gpiolib_sysfs_init
  gpiolib: link all gpio_chips using a list
  gpio/langwell: cleanup driver
  gpio/langwell: Add Cloverview ids to pci device table
  gpio/lynxpoint: add chipset gpio driver.
  gpiolib: add missing braces in gpio_direction_show
  gpiolib-acpi: Fix error checks in interrupt requesting
  gpio: mpc8xxx: don't set IRQ_TYPE_NONE when creating irq mapping
  gpiolib: remove gpiochip_reserve()
  arm: pxa: tosa: do not use gpiochip_reserve()
  ...
Diffstat (limited to 'drivers/gpio/gpio-pca953x.c')
| -rw-r--r-- | drivers/gpio/gpio-pca953x.c | 376 | 
1 files changed, 211 insertions, 165 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index cc102d25ee2..24059462c87 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -46,6 +46,7 @@  #define PCA957X_TYPE		0x2000  static const struct i2c_device_id pca953x_id[] = { +	{ "pca9505", 40 | PCA953X_TYPE | PCA_INT, },  	{ "pca9534", 8  | PCA953X_TYPE | PCA_INT, },  	{ "pca9535", 16 | PCA953X_TYPE | PCA_INT, },  	{ "pca9536", 4  | PCA953X_TYPE, }, @@ -71,19 +72,23 @@ static const struct i2c_device_id pca953x_id[] = {  };  MODULE_DEVICE_TABLE(i2c, pca953x_id); +#define MAX_BANK 5 +#define BANK_SZ 8 + +#define NBANK(chip) (chip->gpio_chip.ngpio / BANK_SZ) +  struct pca953x_chip {  	unsigned gpio_start; -	u32 reg_output; -	u32 reg_direction; +	u8 reg_output[MAX_BANK]; +	u8 reg_direction[MAX_BANK];  	struct mutex i2c_lock;  #ifdef CONFIG_GPIO_PCA953X_IRQ  	struct mutex irq_lock; -	u32 irq_mask; -	u32 irq_stat; -	u32 irq_trig_raise; -	u32 irq_trig_fall; -	int	 irq_base; +	u8 irq_mask[MAX_BANK]; +	u8 irq_stat[MAX_BANK]; +	u8 irq_trig_raise[MAX_BANK]; +	u8 irq_trig_fall[MAX_BANK];  	struct irq_domain *domain;  #endif @@ -93,33 +98,69 @@ struct pca953x_chip {  	int	chip_type;  }; -static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) +static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, +				int off) +{ +	int ret; +	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); +	int offset = off / BANK_SZ; + +	ret = i2c_smbus_read_byte_data(chip->client, +				(reg << bank_shift) + offset); +	*val = ret; + +	if (ret < 0) { +		dev_err(&chip->client->dev, "failed reading register\n"); +		return ret; +	} + +	return 0; +} + +static int pca953x_write_single(struct pca953x_chip *chip, int reg, u32 val, +				int off) +{ +	int ret = 0; +	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); +	int offset = off / BANK_SZ; + +	ret = i2c_smbus_write_byte_data(chip->client, +					(reg << bank_shift) + offset, val); + +	if (ret < 0) { +		dev_err(&chip->client->dev, "failed writing register\n"); +		return ret; +	} + +	return 0; +} + +static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)  {  	int ret = 0;  	if (chip->gpio_chip.ngpio <= 8) -		ret = i2c_smbus_write_byte_data(chip->client, reg, val); -	else if (chip->gpio_chip.ngpio == 24) { -		cpu_to_le32s(&val); +		ret = i2c_smbus_write_byte_data(chip->client, reg, *val); +	else if (chip->gpio_chip.ngpio >= 24) { +		int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);  		ret = i2c_smbus_write_i2c_block_data(chip->client, -						(reg << 2) | REG_ADDR_AI, -						3, -						(u8 *) &val); +					(reg << bank_shift) | REG_ADDR_AI, +					NBANK(chip), val);  	}  	else {  		switch (chip->chip_type) {  		case PCA953X_TYPE:  			ret = i2c_smbus_write_word_data(chip->client, -							reg << 1, val); +							reg << 1, (u16) *val);  			break;  		case PCA957X_TYPE:  			ret = i2c_smbus_write_byte_data(chip->client, reg << 1, -							val & 0xff); +							val[0]);  			if (ret < 0)  				break;  			ret = i2c_smbus_write_byte_data(chip->client,  							(reg << 1) + 1, -							(val & 0xff00) >> 8); +							val[1]);  			break;  		}  	} @@ -132,26 +173,24 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val)  	return 0;  } -static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) +static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)  {  	int ret;  	if (chip->gpio_chip.ngpio <= 8) {  		ret = i2c_smbus_read_byte_data(chip->client, reg);  		*val = ret; -	} -	else if (chip->gpio_chip.ngpio == 24) { -		*val = 0; +	} else if (chip->gpio_chip.ngpio >= 24) { +		int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); +  		ret = i2c_smbus_read_i2c_block_data(chip->client, -						(reg << 2) | REG_ADDR_AI, -						3, -						(u8 *) val); -		le32_to_cpus(val); +					(reg << bank_shift) | REG_ADDR_AI, +					NBANK(chip), val);  	} else {  		ret = i2c_smbus_read_word_data(chip->client, reg << 1); -		*val = ret; +		val[0] = (u16)ret & 0xFF; +		val[1] = (u16)ret >> 8;  	} -  	if (ret < 0) {  		dev_err(&chip->client->dev, "failed reading register\n");  		return ret; @@ -163,13 +202,13 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val)  static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)  {  	struct pca953x_chip *chip; -	uint reg_val; +	u8 reg_val;  	int ret, offset = 0;  	chip = container_of(gc, struct pca953x_chip, gpio_chip);  	mutex_lock(&chip->i2c_lock); -	reg_val = chip->reg_direction | (1u << off); +	reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ));  	switch (chip->chip_type) {  	case PCA953X_TYPE: @@ -179,11 +218,11 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)  		offset = PCA957X_CFG;  		break;  	} -	ret = pca953x_write_reg(chip, offset, reg_val); +	ret = pca953x_write_single(chip, offset, reg_val, off);  	if (ret)  		goto exit; -	chip->reg_direction = reg_val; +	chip->reg_direction[off / BANK_SZ] = reg_val;  	ret = 0;  exit:  	mutex_unlock(&chip->i2c_lock); @@ -194,7 +233,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,  		unsigned off, int val)  {  	struct pca953x_chip *chip; -	uint reg_val; +	u8 reg_val;  	int ret, offset = 0;  	chip = container_of(gc, struct pca953x_chip, gpio_chip); @@ -202,9 +241,11 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,  	mutex_lock(&chip->i2c_lock);  	/* set output level */  	if (val) -		reg_val = chip->reg_output | (1u << off); +		reg_val = chip->reg_output[off / BANK_SZ] +			| (1u << (off % BANK_SZ));  	else -		reg_val = chip->reg_output & ~(1u << off); +		reg_val = chip->reg_output[off / BANK_SZ] +			& ~(1u << (off % BANK_SZ));  	switch (chip->chip_type) {  	case PCA953X_TYPE: @@ -214,14 +255,14 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,  		offset = PCA957X_OUT;  		break;  	} -	ret = pca953x_write_reg(chip, offset, reg_val); +	ret = pca953x_write_single(chip, offset, reg_val, off);  	if (ret)  		goto exit; -	chip->reg_output = reg_val; +	chip->reg_output[off / BANK_SZ] = reg_val;  	/* then direction */ -	reg_val = chip->reg_direction & ~(1u << off); +	reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ));  	switch (chip->chip_type) {  	case PCA953X_TYPE:  		offset = PCA953X_DIRECTION; @@ -230,11 +271,11 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,  		offset = PCA957X_CFG;  		break;  	} -	ret = pca953x_write_reg(chip, offset, reg_val); +	ret = pca953x_write_single(chip, offset, reg_val, off);  	if (ret)  		goto exit; -	chip->reg_direction = reg_val; +	chip->reg_direction[off / BANK_SZ] = reg_val;  	ret = 0;  exit:  	mutex_unlock(&chip->i2c_lock); @@ -258,7 +299,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)  		offset = PCA957X_IN;  		break;  	} -	ret = pca953x_read_reg(chip, offset, ®_val); +	ret = pca953x_read_single(chip, offset, ®_val, off);  	mutex_unlock(&chip->i2c_lock);  	if (ret < 0) {  		/* NOTE:  diagnostic already emitted; that's all we should @@ -274,16 +315,18 @@ 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; -	u32 reg_val; +	u8 reg_val;  	int ret, offset = 0;  	chip = container_of(gc, struct pca953x_chip, gpio_chip);  	mutex_lock(&chip->i2c_lock);  	if (val) -		reg_val = chip->reg_output | (1u << off); +		reg_val = chip->reg_output[off / BANK_SZ] +			| (1u << (off % BANK_SZ));  	else -		reg_val = chip->reg_output & ~(1u << off); +		reg_val = chip->reg_output[off / BANK_SZ] +			& ~(1u << (off % BANK_SZ));  	switch (chip->chip_type) {  	case PCA953X_TYPE: @@ -293,11 +336,11 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)  		offset = PCA957X_OUT;  		break;  	} -	ret = pca953x_write_reg(chip, offset, reg_val); +	ret = pca953x_write_single(chip, offset, reg_val, off);  	if (ret)  		goto exit; -	chip->reg_output = reg_val; +	chip->reg_output[off / BANK_SZ] = reg_val;  exit:  	mutex_unlock(&chip->i2c_lock);  } @@ -328,21 +371,21 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)  	struct pca953x_chip *chip;  	chip = container_of(gc, struct pca953x_chip, gpio_chip); -	return chip->irq_base + off; +	return irq_create_mapping(chip->domain, off);  }  static void pca953x_irq_mask(struct irq_data *d)  {  	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); -	chip->irq_mask &= ~(1 << d->hwirq); +	chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ));  }  static void pca953x_irq_unmask(struct irq_data *d)  {  	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); -	chip->irq_mask |= 1 << d->hwirq; +	chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ);  }  static void pca953x_irq_bus_lock(struct irq_data *d) @@ -355,17 +398,20 @@ static void pca953x_irq_bus_lock(struct irq_data *d)  static void pca953x_irq_bus_sync_unlock(struct irq_data *d)  {  	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); -	u32 new_irqs; -	u32 level; +	u8 new_irqs; +	int level, i;  	/* Look for any newly setup interrupt */ -	new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; -	new_irqs &= ~chip->reg_direction; +	for (i = 0; i < NBANK(chip); i++) { +		new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i]; +		new_irqs &= ~chip->reg_direction[i]; -	while (new_irqs) { -		level = __ffs(new_irqs); -		pca953x_gpio_direction_input(&chip->gpio_chip, level); -		new_irqs &= ~(1 << level); +		while (new_irqs) { +			level = __ffs(new_irqs); +			pca953x_gpio_direction_input(&chip->gpio_chip, +							level + (BANK_SZ * i)); +			new_irqs &= ~(1 << level); +		}  	}  	mutex_unlock(&chip->irq_lock); @@ -374,7 +420,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)  static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)  {  	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); -	u32 mask = 1 << d->hwirq; +	int bank_nb = d->hwirq / BANK_SZ; +	u8 mask = 1 << (d->hwirq % BANK_SZ);  	if (!(type & IRQ_TYPE_EDGE_BOTH)) {  		dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", @@ -383,14 +430,14 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)  	}  	if (type & IRQ_TYPE_EDGE_FALLING) -		chip->irq_trig_fall |= mask; +		chip->irq_trig_fall[bank_nb] |= mask;  	else -		chip->irq_trig_fall &= ~mask; +		chip->irq_trig_fall[bank_nb] &= ~mask;  	if (type & IRQ_TYPE_EDGE_RISING) -		chip->irq_trig_raise |= mask; +		chip->irq_trig_raise[bank_nb] |= mask;  	else -		chip->irq_trig_raise &= ~mask; +		chip->irq_trig_raise[bank_nb] &= ~mask;  	return 0;  } @@ -404,13 +451,13 @@ static struct irq_chip pca953x_irq_chip = {  	.irq_set_type		= pca953x_irq_set_type,  }; -static u32 pca953x_irq_pending(struct pca953x_chip *chip) +static u8 pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)  { -	u32 cur_stat; -	u32 old_stat; -	u32 pending; -	u32 trigger; -	int ret, offset = 0; +	u8 cur_stat[MAX_BANK]; +	u8 old_stat[MAX_BANK]; +	u8 pendings = 0; +	u8 trigger[MAX_BANK], triggers = 0; +	int ret, i, offset = 0;  	switch (chip->chip_type) {  	case PCA953X_TYPE: @@ -420,60 +467,88 @@ static u32 pca953x_irq_pending(struct pca953x_chip *chip)  		offset = PCA957X_IN;  		break;  	} -	ret = pca953x_read_reg(chip, offset, &cur_stat); +	ret = pca953x_read_regs(chip, offset, cur_stat);  	if (ret)  		return 0;  	/* Remove output pins from the equation */ -	cur_stat &= chip->reg_direction; +	for (i = 0; i < NBANK(chip); i++) +		cur_stat[i] &= chip->reg_direction[i]; -	old_stat = chip->irq_stat; -	trigger = (cur_stat ^ old_stat) & chip->irq_mask; +	memcpy(old_stat, chip->irq_stat, NBANK(chip)); + +	for (i = 0; i < NBANK(chip); i++) { +		trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i]; +		triggers += trigger[i]; +	} -	if (!trigger) +	if (!triggers)  		return 0; -	chip->irq_stat = cur_stat; +	memcpy(chip->irq_stat, cur_stat, NBANK(chip)); -	pending = (old_stat & chip->irq_trig_fall) | -		  (cur_stat & chip->irq_trig_raise); -	pending &= trigger; +	for (i = 0; i < NBANK(chip); i++) { +		pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) | +			(cur_stat[i] & chip->irq_trig_raise[i]); +		pending[i] &= trigger[i]; +		pendings += pending[i]; +	} -	return pending; +	return pendings;  }  static irqreturn_t pca953x_irq_handler(int irq, void *devid)  {  	struct pca953x_chip *chip = devid; -	u32 pending; -	u32 level; - -	pending = pca953x_irq_pending(chip); +	u8 pending[MAX_BANK]; +	u8 level; +	int i; -	if (!pending) +	if (!pca953x_irq_pending(chip, pending))  		return IRQ_HANDLED; -	do { -		level = __ffs(pending); -		handle_nested_irq(irq_find_mapping(chip->domain, level)); - -		pending &= ~(1 << level); -	} while (pending); +	for (i = 0; i < NBANK(chip); i++) { +		while (pending[i]) { +			level = __ffs(pending[i]); +			handle_nested_irq(irq_find_mapping(chip->domain, +							level + (BANK_SZ * i))); +			pending[i] &= ~(1 << level); +		} +	}  	return IRQ_HANDLED;  } +static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, +		       irq_hw_number_t hwirq) +{ +	irq_clear_status_flags(irq, IRQ_NOREQUEST); +	irq_set_chip_data(irq, d->host_data); +	irq_set_chip(irq, &pca953x_irq_chip); +	irq_set_nested_thread(irq, true); +#ifdef CONFIG_ARM +	set_irq_flags(irq, IRQF_VALID); +#else +	irq_set_noprobe(irq); +#endif + +	return 0; +} + +static const struct irq_domain_ops pca953x_irq_simple_ops = { +	.map = pca953x_gpio_irq_map, +	.xlate = irq_domain_xlate_twocell, +}; +  static int pca953x_irq_setup(struct pca953x_chip *chip,  			     const struct i2c_device_id *id,  			     int irq_base)  {  	struct i2c_client *client = chip->client; -	int ret, offset = 0; -	u32 temporary; +	int ret, i, offset = 0;  	if (irq_base != -1  			&& (id->driver_data & PCA_INT)) { -		int lvl;  		switch (chip->chip_type) {  		case PCA953X_TYPE: @@ -483,49 +558,29 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,  			offset = PCA957X_IN;  			break;  		} -		ret = pca953x_read_reg(chip, offset, &temporary); -		chip->irq_stat = temporary; +		ret = pca953x_read_regs(chip, offset, chip->irq_stat);  		if (ret) -			goto out_failed; +			return ret;  		/*  		 * There is no way to know which GPIO line generated the  		 * interrupt.  We have to rely on the previous read for  		 * this purpose.  		 */ -		chip->irq_stat &= chip->reg_direction; +		for (i = 0; i < NBANK(chip); i++) +			chip->irq_stat[i] &= chip->reg_direction[i];  		mutex_init(&chip->irq_lock); -		chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1); -		if (chip->irq_base < 0) -			goto out_failed; - -		chip->domain = irq_domain_add_legacy(client->dev.of_node, +		chip->domain = irq_domain_add_simple(client->dev.of_node,  						chip->gpio_chip.ngpio, -						chip->irq_base, -						0, -						&irq_domain_simple_ops, +						irq_base, +						&pca953x_irq_simple_ops,  						NULL); -		if (!chip->domain) { -			ret = -ENODEV; -			goto out_irqdesc_free; -		} - -		for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { -			int irq = lvl + chip->irq_base; - -			irq_clear_status_flags(irq, IRQ_NOREQUEST); -			irq_set_chip_data(irq, chip); -			irq_set_chip(irq, &pca953x_irq_chip); -			irq_set_nested_thread(irq, true); -#ifdef CONFIG_ARM -			set_irq_flags(irq, IRQF_VALID); -#else -			irq_set_noprobe(irq); -#endif -		} +		if (!chip->domain) +			return -ENODEV; -		ret = request_threaded_irq(client->irq, +		ret = devm_request_threaded_irq(&client->dev, +					client->irq,  					   NULL,  					   pca953x_irq_handler,  					   IRQF_TRIGGER_LOW | IRQF_ONESHOT, @@ -533,28 +588,15 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,  		if (ret) {  			dev_err(&client->dev, "failed to request irq %d\n",  				client->irq); -			goto out_irqdesc_free; +			return ret;  		}  		chip->gpio_chip.to_irq = pca953x_gpio_to_irq;  	}  	return 0; - -out_irqdesc_free: -	irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); -out_failed: -	chip->irq_base = -1; -	return ret;  } -static void pca953x_irq_teardown(struct pca953x_chip *chip) -{ -	if (chip->irq_base != -1) { -		irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); -		free_irq(chip->client->irq, chip); -	} -}  #else /* CONFIG_GPIO_PCA953X_IRQ */  static int pca953x_irq_setup(struct pca953x_chip *chip,  			     const struct i2c_device_id *id, @@ -567,10 +609,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,  	return 0;  } - -static void pca953x_irq_teardown(struct pca953x_chip *chip) -{ -}  #endif  /* @@ -619,18 +657,24 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert)  static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)  {  	int ret; +	u8 val[MAX_BANK]; -	ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); +	ret = pca953x_read_regs(chip, PCA953X_OUTPUT, chip->reg_output);  	if (ret)  		goto out; -	ret = pca953x_read_reg(chip, PCA953X_DIRECTION, -			       &chip->reg_direction); +	ret = pca953x_read_regs(chip, PCA953X_DIRECTION, +			       chip->reg_direction);  	if (ret)  		goto out;  	/* set platform specific polarity inversion */ -	ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); +	if (invert) +		memset(val, 0xFF, NBANK(chip)); +	else +		memset(val, 0, NBANK(chip)); + +	ret = pca953x_write_regs(chip, PCA953X_INVERT, val);  out:  	return ret;  } @@ -638,28 +682,36 @@ out:  static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)  {  	int ret; -	u32 val = 0; +	u8 val[MAX_BANK];  	/* Let every port in proper state, that could save power */ -	pca953x_write_reg(chip, PCA957X_PUPD, 0x0); -	pca953x_write_reg(chip, PCA957X_CFG, 0xffff); -	pca953x_write_reg(chip, PCA957X_OUT, 0x0); +	memset(val, 0, NBANK(chip)); +	pca953x_write_regs(chip, PCA957X_PUPD, val); +	memset(val, 0xFF, NBANK(chip)); +	pca953x_write_regs(chip, PCA957X_CFG, val); +	memset(val, 0, NBANK(chip)); +	pca953x_write_regs(chip, PCA957X_OUT, val); -	ret = pca953x_read_reg(chip, PCA957X_IN, &val); +	ret = pca953x_read_regs(chip, PCA957X_IN, val);  	if (ret)  		goto out; -	ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output); +	ret = pca953x_read_regs(chip, PCA957X_OUT, chip->reg_output);  	if (ret)  		goto out; -	ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction); +	ret = pca953x_read_regs(chip, PCA957X_CFG, chip->reg_direction);  	if (ret)  		goto out;  	/* set platform specific polarity inversion */ -	pca953x_write_reg(chip, PCA957X_INVRT, invert); +	if (invert) +		memset(val, 0xFF, NBANK(chip)); +	else +		memset(val, 0, NBANK(chip)); +	pca953x_write_regs(chip, PCA957X_INVRT, val);  	/* To enable register 6, 7 to controll pull up and pull down */ -	pca953x_write_reg(chip, PCA957X_BKEN, 0x202); +	memset(val, 0x02, NBANK(chip)); +	pca953x_write_regs(chip, PCA957X_BKEN, val);  	return 0;  out: @@ -675,7 +727,8 @@ static int pca953x_probe(struct i2c_client *client,  	int ret;  	u32 invert = 0; -	chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); +	chip = devm_kzalloc(&client->dev, +			sizeof(struct pca953x_chip), GFP_KERNEL);  	if (chip == NULL)  		return -ENOMEM; @@ -710,15 +763,15 @@ static int pca953x_probe(struct i2c_client *client,  	else  		ret = device_pca957x_init(chip, invert);  	if (ret) -		goto out_failed; +		return ret;  	ret = pca953x_irq_setup(chip, id, irq_base);  	if (ret) -		goto out_failed; +		return ret;  	ret = gpiochip_add(&chip->gpio_chip);  	if (ret) -		goto out_failed_irq; +		return ret;  	if (pdata && pdata->setup) {  		ret = pdata->setup(client, chip->gpio_chip.base, @@ -729,12 +782,6 @@ static int pca953x_probe(struct i2c_client *client,  	i2c_set_clientdata(client, chip);  	return 0; - -out_failed_irq: -	pca953x_irq_teardown(chip); -out_failed: -	kfree(chip); -	return ret;  }  static int pca953x_remove(struct i2c_client *client) @@ -760,12 +807,11 @@ static int pca953x_remove(struct i2c_client *client)  		return ret;  	} -	pca953x_irq_teardown(chip); -	kfree(chip);  	return 0;  }  static const struct of_device_id pca953x_dt_ids[] = { +	{ .compatible = "nxp,pca9505", },  	{ .compatible = "nxp,pca9534", },  	{ .compatible = "nxp,pca9535", },  	{ .compatible = "nxp,pca9536", },  |