On Thu, Jun 25, 2020 at 10:59 AM Sungbo Eo <mans0n@xxxxxxxxxx> wrote: > > NXP PCA9570 is 4-bit I2C GPO expander without interrupt functionality. > Its ports are controlled only by a data byte without register address. > > As there is no other driver similar enough to be adapted for it, a new > driver is introduced here. Thanks for an update. I'll look at them later, so please defer the next version a bit (perhaps for one week). My comments below. ... > +static void pca9570_set_mask_bits(struct gpio_chip *chip, u8 mask, u8 bits) > +{ > + struct pca9570 *gpio = gpiochip_get_data(chip); > + u8 buffer; > + int err; > + > + mutex_lock(&gpio->lock); > + buffer = gpio->buffer & ~mask; > + buffer |= (mask & bits); Usual pattern is to put this on one line buffer = (gpio->buffer & ~mask) | (bits & mask); > + err = i2c_smbus_write_byte(gpio->client, buffer); > + if (!err) > + gpio->buffer = buffer; I'm not sure I understand why this is under lock. > + > + mutex_unlock(&gpio->lock); Can't you simple do it here like if (err) return; ... = buffer; ? > +} ... > +static int pca9570_probe(struct i2c_client *client, > + const struct i2c_device_id *id) Can't you use ->probe_new() instead? > +{ > + struct pca9570 *gpio; > + int ret; > + > + gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL); > + if (!gpio) > + return -ENOMEM; > + > + i2c_set_clientdata(client, gpio); Either move this before return 0; or... > + gpio->chip = template_chip; > + gpio->chip.parent = &client->dev; > + > + gpio->client = client; > + > + mutex_init(&gpio->lock); > + > + ret = devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio); > + if (ret < 0) { (What is the meaning of ' < 0' ? > + dev_err(&client->dev, "Unable to register gpiochip\n"); > + return ret; > + } > + > + return 0; ...simple return devm_...(...); > +} -- With Best Regards, Andy Shevchenko