Commit 36eccdb5 authored by Linus Walleij's avatar Linus Walleij

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

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

gpio updates for v5.10 - part 1

- automatically drive GPHY leds in gpio-stp-xway
- refactor ->{get, set}_multiple() in gpio-aggregator
- add support for a new model in rcar-gpio DT bindings
- simplify several GPIO drivers with dev_err_probe()
- disable Direct KBD interrupts in gpio-tc35894
- use DEFINE_SEQ_ATTRIBUTE() in GPIO chardev to shrink code
- switch to using a simpler IDA API in gpiolib
- make devprop_gpiochip_set_names() more generic by using device properties
  instead of using fwnode helpers
parents 0a2d411b 587823d3
...@@ -37,6 +37,7 @@ properties: ...@@ -37,6 +37,7 @@ properties:
- renesas,gpio-r8a774a1 # RZ/G2M - renesas,gpio-r8a774a1 # RZ/G2M
- renesas,gpio-r8a774b1 # RZ/G2N - renesas,gpio-r8a774b1 # RZ/G2N
- renesas,gpio-r8a774c0 # RZ/G2E - renesas,gpio-r8a774c0 # RZ/G2E
- renesas,gpio-r8a774e1 # RZ/G2H
- renesas,gpio-r8a7795 # R-Car H3 - renesas,gpio-r8a7795 # R-Car H3
- renesas,gpio-r8a7796 # R-Car M3-W - renesas,gpio-r8a7796 # R-Car M3-W
- renesas,gpio-r8a77961 # R-Car M3-W+ - renesas,gpio-r8a77961 # R-Car M3-W+
......
...@@ -6,7 +6,6 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG ...@@ -6,7 +6,6 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_GPIOLIB) += gpiolib.o obj-$(CONFIG_GPIOLIB) += gpiolib.o
obj-$(CONFIG_GPIOLIB) += gpiolib-devres.o obj-$(CONFIG_GPIOLIB) += gpiolib-devres.o
obj-$(CONFIG_GPIOLIB) += gpiolib-legacy.o obj-$(CONFIG_GPIOLIB) += gpiolib-legacy.o
obj-$(CONFIG_GPIOLIB) += gpiolib-devprop.o
obj-$(CONFIG_GPIOLIB) += gpiolib-cdev.o obj-$(CONFIG_GPIOLIB) += gpiolib-cdev.o
obj-$(CONFIG_OF_GPIO) += gpiolib-of.o obj-$(CONFIG_OF_GPIO) += gpiolib-of.o
obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o
......
...@@ -333,20 +333,14 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset) ...@@ -333,20 +333,14 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset)
return gpiod_get_value(fwd->descs[offset]); return gpiod_get_value(fwd->descs[offset]);
} }
static int gpio_fwd_get_multiple(struct gpio_chip *chip, unsigned long *mask, static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
unsigned long *bits) unsigned long *bits)
{ {
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
unsigned long *values, flags = 0;
struct gpio_desc **descs; struct gpio_desc **descs;
unsigned long *values;
unsigned int i, j = 0; unsigned int i, j = 0;
int error; int error;
if (chip->can_sleep)
mutex_lock(&fwd->mlock);
else
spin_lock_irqsave(&fwd->slock, flags);
/* Both values bitmap and desc pointers are stored in tmp[] */ /* Both values bitmap and desc pointers are stored in tmp[] */
values = &fwd->tmp[0]; values = &fwd->tmp[0];
descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)]; descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)];
...@@ -356,16 +350,32 @@ static int gpio_fwd_get_multiple(struct gpio_chip *chip, unsigned long *mask, ...@@ -356,16 +350,32 @@ static int gpio_fwd_get_multiple(struct gpio_chip *chip, unsigned long *mask,
descs[j++] = fwd->descs[i]; descs[j++] = fwd->descs[i];
error = gpiod_get_array_value(j, descs, NULL, values); error = gpiod_get_array_value(j, descs, NULL, values);
if (!error) { if (error)
j = 0; return error;
for_each_set_bit(i, mask, fwd->chip.ngpio)
__assign_bit(i, bits, test_bit(j++, values));
}
if (chip->can_sleep) j = 0;
for_each_set_bit(i, mask, fwd->chip.ngpio)
__assign_bit(i, bits, test_bit(j++, values));
return 0;
}
static int gpio_fwd_get_multiple_locked(struct gpio_chip *chip,
unsigned long *mask, unsigned long *bits)
{
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
unsigned long flags;
int error;
if (chip->can_sleep) {
mutex_lock(&fwd->mlock);
error = gpio_fwd_get_multiple(fwd, mask, bits);
mutex_unlock(&fwd->mlock); mutex_unlock(&fwd->mlock);
else } else {
spin_lock_irqsave(&fwd->slock, flags);
error = gpio_fwd_get_multiple(fwd, mask, bits);
spin_unlock_irqrestore(&fwd->slock, flags); spin_unlock_irqrestore(&fwd->slock, flags);
}
return error; return error;
} }
...@@ -377,19 +387,13 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value) ...@@ -377,19 +387,13 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value)
gpiod_set_value(fwd->descs[offset], value); gpiod_set_value(fwd->descs[offset], value);
} }
static void gpio_fwd_set_multiple(struct gpio_chip *chip, unsigned long *mask, static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
unsigned long *bits) unsigned long *bits)
{ {
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
unsigned long *values, flags = 0;
struct gpio_desc **descs; struct gpio_desc **descs;
unsigned long *values;
unsigned int i, j = 0; unsigned int i, j = 0;
if (chip->can_sleep)
mutex_lock(&fwd->mlock);
else
spin_lock_irqsave(&fwd->slock, flags);
/* Both values bitmap and desc pointers are stored in tmp[] */ /* Both values bitmap and desc pointers are stored in tmp[] */
values = &fwd->tmp[0]; values = &fwd->tmp[0];
descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)]; descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)];
...@@ -400,11 +404,23 @@ static void gpio_fwd_set_multiple(struct gpio_chip *chip, unsigned long *mask, ...@@ -400,11 +404,23 @@ static void gpio_fwd_set_multiple(struct gpio_chip *chip, unsigned long *mask,
} }
gpiod_set_array_value(j, descs, NULL, values); gpiod_set_array_value(j, descs, NULL, values);
}
if (chip->can_sleep) static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip,
unsigned long *mask, unsigned long *bits)
{
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
unsigned long flags;
if (chip->can_sleep) {
mutex_lock(&fwd->mlock);
gpio_fwd_set_multiple(fwd, mask, bits);
mutex_unlock(&fwd->mlock); mutex_unlock(&fwd->mlock);
else } else {
spin_lock_irqsave(&fwd->slock, flags);
gpio_fwd_set_multiple(fwd, mask, bits);
spin_unlock_irqrestore(&fwd->slock, flags); spin_unlock_irqrestore(&fwd->slock, flags);
}
} }
static int gpio_fwd_set_config(struct gpio_chip *chip, unsigned int offset, static int gpio_fwd_set_config(struct gpio_chip *chip, unsigned int offset,
...@@ -470,9 +486,9 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, ...@@ -470,9 +486,9 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev,
chip->direction_input = gpio_fwd_direction_input; chip->direction_input = gpio_fwd_direction_input;
chip->direction_output = gpio_fwd_direction_output; chip->direction_output = gpio_fwd_direction_output;
chip->get = gpio_fwd_get; chip->get = gpio_fwd_get;
chip->get_multiple = gpio_fwd_get_multiple; chip->get_multiple = gpio_fwd_get_multiple_locked;
chip->set = gpio_fwd_set; chip->set = gpio_fwd_set;
chip->set_multiple = gpio_fwd_set_multiple; chip->set_multiple = gpio_fwd_set_multiple_locked;
chip->base = -1; chip->base = -1;
chip->ngpio = ngpios; chip->ngpio = ngpios;
fwd->descs = descs; fwd->descs = descs;
......
...@@ -590,10 +590,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) ...@@ -590,10 +590,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev)
dev_err(dev, "Couldn't determine # GPIO banks\n"); dev_err(dev, "Couldn't determine # GPIO banks\n");
return -ENOENT; return -ENOENT;
} else if (ret < 0) { } else if (ret < 0) {
if (ret != -EPROBE_DEFER) return dev_err_probe(dev, ret, "Couldn't determine GPIO banks\n");
dev_err(dev, "Couldn't determine GPIO banks: (%pe)\n",
ERR_PTR(ret));
return ret;
} }
kona_gpio->num_bank = ret; kona_gpio->num_bank = ret;
......
...@@ -237,12 +237,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) ...@@ -237,12 +237,8 @@ static int davinci_gpio_probe(struct platform_device *pdev)
for (i = 0; i < nirq; i++) { for (i = 0; i < nirq; i++) {
chips->irqs[i] = platform_get_irq(pdev, i); chips->irqs[i] = platform_get_irq(pdev, i);
if (chips->irqs[i] < 0) { if (chips->irqs[i] < 0)
if (chips->irqs[i] != -EPROBE_DEFER) return dev_err_probe(dev, chips->irqs[i], "IRQ not populated\n");
dev_info(dev, "IRQ not populated, err = %d\n",
chips->irqs[i]);
return chips->irqs[i];
}
} }
chips->chip.label = dev_name(dev); chips->chip.label = dev_name(dev);
......
...@@ -1394,10 +1394,7 @@ static int omap_gpio_probe(struct platform_device *pdev) ...@@ -1394,10 +1394,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
if (bank->irq <= 0) { if (bank->irq <= 0) {
if (!bank->irq) if (!bank->irq)
bank->irq = -ENXIO; bank->irq = -ENXIO;
if (bank->irq != -EPROBE_DEFER) return dev_err_probe(dev, bank->irq, "can't get irq resource\n");
dev_err(dev,
"can't get irq resource ret=%d\n", bank->irq);
return bank->irq;
} }
bank->chip.parent = dev; bank->chip.parent = dev;
......
...@@ -1000,12 +1000,9 @@ static int pca953x_probe(struct i2c_client *client, ...@@ -1000,12 +1000,9 @@ static int pca953x_probe(struct i2c_client *client,
chip->client = client; chip->client = client;
reg = devm_regulator_get(&client->dev, "vcc"); reg = devm_regulator_get(&client->dev, "vcc");
if (IS_ERR(reg)) { if (IS_ERR(reg))
ret = PTR_ERR(reg); return dev_err_probe(&client->dev, PTR_ERR(reg), "reg get err\n");
if (ret != -EPROBE_DEFER)
dev_err(&client->dev, "reg get err: %d\n", ret);
return ret;
}
ret = regulator_enable(reg); ret = regulator_enable(reg);
if (ret) { if (ret) {
dev_err(&client->dev, "reg en err: %d\n", ret); dev_err(&client->dev, "reg en err: %d\n", ret);
......
...@@ -148,12 +148,9 @@ static int pisosr_gpio_probe(struct spi_device *spi) ...@@ -148,12 +148,9 @@ static int pisosr_gpio_probe(struct spi_device *spi)
return -ENOMEM; return -ENOMEM;
gpio->load_gpio = devm_gpiod_get_optional(dev, "load", GPIOD_OUT_LOW); gpio->load_gpio = devm_gpiod_get_optional(dev, "load", GPIOD_OUT_LOW);
if (IS_ERR(gpio->load_gpio)) { if (IS_ERR(gpio->load_gpio))
ret = PTR_ERR(gpio->load_gpio); return dev_err_probe(dev, PTR_ERR(gpio->load_gpio),
if (ret != -EPROBE_DEFER) "Unable to allocate load GPIO\n");
dev_err(dev, "Unable to allocate load GPIO\n");
return ret;
}
mutex_init(&gpio->lock); mutex_init(&gpio->lock);
......
...@@ -41,7 +41,10 @@ ...@@ -41,7 +41,10 @@
#define XWAY_STP_4HZ BIT(23) #define XWAY_STP_4HZ BIT(23)
#define XWAY_STP_8HZ BIT(24) #define XWAY_STP_8HZ BIT(24)
#define XWAY_STP_10HZ (BIT(24) | BIT(23)) #define XWAY_STP_10HZ (BIT(24) | BIT(23))
#define XWAY_STP_SPEED_MASK (0xf << 23) #define XWAY_STP_SPEED_MASK (BIT(23) | BIT(24) | BIT(25) | BIT(26) | BIT(27))
#define XWAY_STP_FPIS_VALUE BIT(21)
#define XWAY_STP_FPIS_MASK (BIT(20) | BIT(21))
/* clock source for automatic update */ /* clock source for automatic update */
#define XWAY_STP_UPD_FPI BIT(31) #define XWAY_STP_UPD_FPI BIT(31)
...@@ -54,7 +57,9 @@ ...@@ -54,7 +57,9 @@
/* 2 groups of 3 bits can be driven by the phys */ /* 2 groups of 3 bits can be driven by the phys */
#define XWAY_STP_PHY_MASK 0x7 #define XWAY_STP_PHY_MASK 0x7
#define XWAY_STP_PHY1_SHIFT 27 #define XWAY_STP_PHY1_SHIFT 27
#define XWAY_STP_PHY2_SHIFT 15 #define XWAY_STP_PHY2_SHIFT 3
#define XWAY_STP_PHY3_SHIFT 6
#define XWAY_STP_PHY4_SHIFT 15
/* STP has 3 groups of 8 bits */ /* STP has 3 groups of 8 bits */
#define XWAY_STP_GROUP0 BIT(0) #define XWAY_STP_GROUP0 BIT(0)
...@@ -80,6 +85,8 @@ struct xway_stp { ...@@ -80,6 +85,8 @@ struct xway_stp {
u8 dsl; /* the 2 LSBs can be driven by the dsl core */ u8 dsl; /* the 2 LSBs can be driven by the dsl core */
u8 phy1; /* 3 bits can be driven by phy1 */ u8 phy1; /* 3 bits can be driven by phy1 */
u8 phy2; /* 3 bits can be driven by phy2 */ u8 phy2; /* 3 bits can be driven by phy2 */
u8 phy3; /* 3 bits can be driven by phy3 */
u8 phy4; /* 3 bits can be driven by phy4 */
u8 reserved; /* mask out the hw driven bits in gpio_request */ u8 reserved; /* mask out the hw driven bits in gpio_request */
}; };
...@@ -114,7 +121,8 @@ static void xway_stp_set(struct gpio_chip *gc, unsigned gpio, int val) ...@@ -114,7 +121,8 @@ static void xway_stp_set(struct gpio_chip *gc, unsigned gpio, int val)
else else
chip->shadow &= ~BIT(gpio); chip->shadow &= ~BIT(gpio);
xway_stp_w32(chip->virt, chip->shadow, XWAY_STP_CPU0); xway_stp_w32(chip->virt, chip->shadow, XWAY_STP_CPU0);
xway_stp_w32_mask(chip->virt, 0, XWAY_STP_CON_SWU, XWAY_STP_CON0); if (!chip->reserved)
xway_stp_w32_mask(chip->virt, 0, XWAY_STP_CON_SWU, XWAY_STP_CON0);
} }
/** /**
...@@ -188,16 +196,37 @@ static void xway_stp_hw_init(struct xway_stp *chip) ...@@ -188,16 +196,37 @@ static void xway_stp_hw_init(struct xway_stp *chip)
chip->phy2 << XWAY_STP_PHY2_SHIFT, chip->phy2 << XWAY_STP_PHY2_SHIFT,
XWAY_STP_CON1); XWAY_STP_CON1);
if (of_machine_is_compatible("lantiq,grx390")
|| of_machine_is_compatible("lantiq,ar10")) {
xway_stp_w32_mask(chip->virt,
XWAY_STP_PHY_MASK << XWAY_STP_PHY3_SHIFT,
chip->phy3 << XWAY_STP_PHY3_SHIFT,
XWAY_STP_CON1);
}
if (of_machine_is_compatible("lantiq,grx390")) {
xway_stp_w32_mask(chip->virt,
XWAY_STP_PHY_MASK << XWAY_STP_PHY4_SHIFT,
chip->phy4 << XWAY_STP_PHY4_SHIFT,
XWAY_STP_CON1);
}
/* mask out the hw driven bits in gpio_request */ /* mask out the hw driven bits in gpio_request */
chip->reserved = (chip->phy2 << 5) | (chip->phy1 << 2) | chip->dsl; chip->reserved = (chip->phy4 << 11) | (chip->phy3 << 8) | (chip->phy2 << 5)
| (chip->phy1 << 2) | chip->dsl;
/* /*
* if we have pins that are driven by hw, we need to tell the stp what * if we have pins that are driven by hw, we need to tell the stp what
* clock to use as a timer. * clock to use as a timer.
*/ */
if (chip->reserved) if (chip->reserved) {
xway_stp_w32_mask(chip->virt, XWAY_STP_UPD_MASK, xway_stp_w32_mask(chip->virt, XWAY_STP_UPD_MASK,
XWAY_STP_UPD_FPI, XWAY_STP_CON1); XWAY_STP_UPD_FPI, XWAY_STP_CON1);
xway_stp_w32_mask(chip->virt, XWAY_STP_SPEED_MASK,
XWAY_STP_10HZ, XWAY_STP_CON1);
xway_stp_w32_mask(chip->virt, XWAY_STP_FPIS_MASK,
XWAY_STP_FPIS_VALUE, XWAY_STP_CON1);
}
} }
static int xway_stp_probe(struct platform_device *pdev) static int xway_stp_probe(struct platform_device *pdev)
...@@ -242,13 +271,26 @@ static int xway_stp_probe(struct platform_device *pdev) ...@@ -242,13 +271,26 @@ static int xway_stp_probe(struct platform_device *pdev)
/* find out which gpios are controlled by the phys */ /* find out which gpios are controlled by the phys */
if (of_machine_is_compatible("lantiq,ar9") || if (of_machine_is_compatible("lantiq,ar9") ||
of_machine_is_compatible("lantiq,gr9") || of_machine_is_compatible("lantiq,gr9") ||
of_machine_is_compatible("lantiq,vr9")) { of_machine_is_compatible("lantiq,vr9") ||
of_machine_is_compatible("lantiq,ar10") ||
of_machine_is_compatible("lantiq,grx390")) {
if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy1", &phy)) if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy1", &phy))
chip->phy1 = phy & XWAY_STP_PHY_MASK; chip->phy1 = phy & XWAY_STP_PHY_MASK;
if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy2", &phy)) if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy2", &phy))
chip->phy2 = phy & XWAY_STP_PHY_MASK; chip->phy2 = phy & XWAY_STP_PHY_MASK;
} }
if (of_machine_is_compatible("lantiq,ar10") ||
of_machine_is_compatible("lantiq,grx390")) {
if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy3", &phy))
chip->phy3 = phy & XWAY_STP_PHY_MASK;
}
if (of_machine_is_compatible("lantiq,grx390")) {
if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy4", &phy))
chip->phy4 = phy & XWAY_STP_PHY_MASK;
}
/* check which edge trigger we should use, default to a falling edge */ /* check which edge trigger we should use, default to a falling edge */
if (!of_find_property(pdev->dev.of_node, "lantiq,rising", NULL)) if (!of_find_property(pdev->dev.of_node, "lantiq,rising", NULL))
chip->edge = XWAY_STP_FALLING; chip->edge = XWAY_STP_FALLING;
......
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
* These registers are modified under the irq bus lock and cached to avoid * These registers are modified under the irq bus lock and cached to avoid
* unnecessary writes in bus_sync_unlock. * unnecessary writes in bus_sync_unlock.
*/ */
enum { REG_IBE, REG_IEV, REG_IS, REG_IE }; enum { REG_IBE, REG_IEV, REG_IS, REG_IE, REG_DIRECT };
#define CACHE_NR_REGS 4 #define CACHE_NR_REGS 5
#define CACHE_NR_BANKS 3 #define CACHE_NR_BANKS 3
struct tc3589x_gpio { struct tc3589x_gpio {
...@@ -200,6 +200,7 @@ static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d) ...@@ -200,6 +200,7 @@ static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d)
[REG_IEV] = TC3589x_GPIOIEV0, [REG_IEV] = TC3589x_GPIOIEV0,
[REG_IS] = TC3589x_GPIOIS0, [REG_IS] = TC3589x_GPIOIS0,
[REG_IE] = TC3589x_GPIOIE0, [REG_IE] = TC3589x_GPIOIE0,
[REG_DIRECT] = TC3589x_DIRECT0,
}; };
int i, j; int i, j;
...@@ -228,6 +229,7 @@ static void tc3589x_gpio_irq_mask(struct irq_data *d) ...@@ -228,6 +229,7 @@ static void tc3589x_gpio_irq_mask(struct irq_data *d)
int mask = BIT(offset % 8); int mask = BIT(offset % 8);
tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask; tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask;
tc3589x_gpio->regs[REG_DIRECT][regoffset] |= mask;
} }
static void tc3589x_gpio_irq_unmask(struct irq_data *d) static void tc3589x_gpio_irq_unmask(struct irq_data *d)
...@@ -239,6 +241,7 @@ static void tc3589x_gpio_irq_unmask(struct irq_data *d) ...@@ -239,6 +241,7 @@ static void tc3589x_gpio_irq_unmask(struct irq_data *d)
int mask = BIT(offset % 8); int mask = BIT(offset % 8);
tc3589x_gpio->regs[REG_IE][regoffset] |= mask; tc3589x_gpio->regs[REG_IE][regoffset] |= mask;
tc3589x_gpio->regs[REG_DIRECT][regoffset] &= ~mask;
} }
static struct irq_chip tc3589x_gpio_irq_chip = { static struct irq_chip tc3589x_gpio_irq_chip = {
...@@ -334,6 +337,17 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) ...@@ -334,6 +337,17 @@ static int tc3589x_gpio_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
return ret; return ret;
/* For tc35894, have to disable Direct KBD interrupts,
* else IRQST will always be 0x20, IRQN low level, can't
* clear the irq status.
* TODO: need more test on other tc3589x chip.
*
*/
ret = tc3589x_reg_write(tc3589x, TC3589x_DKBDMSK,
TC3589x_DKBDMSK_ELINT | TC3589x_DKBDMSK_EINT);
if (ret < 0)
return ret;
ret = devm_request_threaded_irq(&pdev->dev, ret = devm_request_threaded_irq(&pdev->dev,
irq, NULL, tc3589x_gpio_irq, irq, NULL, tc3589x_gpio_irq,
IRQF_ONESHOT, "tc3589x-gpio", IRQF_ONESHOT, "tc3589x-gpio",
......
...@@ -929,11 +929,9 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -929,11 +929,9 @@ static int zynq_gpio_probe(struct platform_device *pdev)
/* Retrieve GPIO clock */ /* Retrieve GPIO clock */
gpio->clk = devm_clk_get(&pdev->dev, NULL); gpio->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(gpio->clk)) { if (IS_ERR(gpio->clk))
if (PTR_ERR(gpio->clk) != -EPROBE_DEFER) return dev_err_probe(&pdev->dev, PTR_ERR(gpio->clk), "input clock not found.\n");
dev_err(&pdev->dev, "input clock not found.\n");
return PTR_ERR(gpio->clk);
}
ret = clk_prepare_enable(gpio->clk); ret = clk_prepare_enable(gpio->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to enable clock.\n"); dev_err(&pdev->dev, "Unable to enable clock.\n");
......
...@@ -1221,9 +1221,6 @@ void acpi_gpiochip_add(struct gpio_chip *chip) ...@@ -1221,9 +1221,6 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
return; return;
} }
if (!chip->names)
devprop_gpiochip_set_names(chip, dev_fwnode(chip->parent));
acpi_gpiochip_request_regions(acpi_gpio); acpi_gpiochip_request_regions(acpi_gpio);
acpi_gpiochip_scan_gpios(acpi_gpio); acpi_gpiochip_scan_gpios(acpi_gpio);
acpi_walk_dep_device_list(handle); acpi_walk_dep_device_list(handle);
......
// SPDX-License-Identifier: GPL-2.0
/*
* Device property helpers for GPIO chips.
*
* Copyright (C) 2016, Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/export.h>
#include "gpiolib.h"
/**
* devprop_gpiochip_set_names - Set GPIO line names using device properties
* @chip: GPIO chip whose lines should be named, if possible
* @fwnode: Property Node containing the gpio-line-names property
*
* Looks for device property "gpio-line-names" and if it exists assigns
* GPIO line names for the chip. The memory allocated for the assigned
* names belong to the underlying firmware node and should not be released
* by the caller.
*/
void devprop_gpiochip_set_names(struct gpio_chip *chip,
const struct fwnode_handle *fwnode)
{
struct gpio_device *gdev = chip->gpiodev;
const char **names;
int ret, i;
int count;
count = fwnode_property_read_string_array(fwnode, "gpio-line-names",
NULL, 0);
if (count < 0)
return;
if (count > gdev->ngpio) {
dev_warn(&gdev->dev, "gpio-line-names is length %d but should be at most length %d",
count, gdev->ngpio);
count = gdev->ngpio;
}
names = kcalloc(count, sizeof(*names), GFP_KERNEL);
if (!names)
return;
ret = fwnode_property_read_string_array(fwnode, "gpio-line-names",
names, count);
if (ret < 0) {
dev_warn(&gdev->dev, "failed to read GPIO line names\n");
kfree(names);
return;
}
for (i = 0; i < count; i++)
gdev->descs[i].name = names[i];
kfree(names);
}
EXPORT_SYMBOL_GPL(devprop_gpiochip_set_names);
...@@ -1026,11 +1026,6 @@ int of_gpiochip_add(struct gpio_chip *chip) ...@@ -1026,11 +1026,6 @@ int of_gpiochip_add(struct gpio_chip *chip)
if (ret) if (ret)
return ret; return ret;
/* If the chip defines names itself, these take precedence */
if (!chip->names)
devprop_gpiochip_set_names(chip,
of_fwnode_handle(chip->of_node));
of_node_get(chip->of_node); of_node_get(chip->of_node);
ret = of_gpiochip_scan_gpios(chip); ret = of_gpiochip_scan_gpios(chip);
......
...@@ -340,9 +340,6 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) ...@@ -340,9 +340,6 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc)
struct gpio_device *gdev = gc->gpiodev; struct gpio_device *gdev = gc->gpiodev;
int i; int i;
if (!gc->names)
return 0;
/* First check all names if they are unique */ /* First check all names if they are unique */
for (i = 0; i != gc->ngpio; ++i) { for (i = 0; i != gc->ngpio; ++i) {
struct gpio_desc *gpio; struct gpio_desc *gpio;
...@@ -361,6 +358,57 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) ...@@ -361,6 +358,57 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc)
return 0; return 0;
} }
/*
* devprop_gpiochip_set_names - Set GPIO line names using device properties
* @chip: GPIO chip whose lines should be named, if possible
*
* Looks for device property "gpio-line-names" and if it exists assigns
* GPIO line names for the chip. The memory allocated for the assigned
* names belong to the underlying software node and should not be released
* by the caller.
*/
static int devprop_gpiochip_set_names(struct gpio_chip *chip)
{
struct gpio_device *gdev = chip->gpiodev;
struct device *dev = chip->parent;
const char **names;
int ret, i;
int count;
/* GPIO chip may not have a parent device whose properties we inspect. */
if (!dev)
return 0;
count = device_property_string_array_count(dev, "gpio-line-names");
if (count < 0)
return 0;
if (count > gdev->ngpio) {
dev_warn(&gdev->dev, "gpio-line-names is length %d but should be at most length %d",
count, gdev->ngpio);
count = gdev->ngpio;
}
names = kcalloc(count, sizeof(*names), GFP_KERNEL);
if (!names)
return -ENOMEM;
ret = device_property_read_string_array(dev, "gpio-line-names",
names, count);
if (ret < 0) {
dev_warn(&gdev->dev, "failed to read GPIO line names\n");
kfree(names);
return ret;
}
for (i = 0; i < count; i++)
gdev->descs[i].name = names[i];
kfree(names);
return 0;
}
static unsigned long *gpiochip_allocate_mask(struct gpio_chip *gc) static unsigned long *gpiochip_allocate_mask(struct gpio_chip *gc)
{ {
unsigned long *p; unsigned long *p;
...@@ -426,7 +474,7 @@ static void gpiodevice_release(struct device *dev) ...@@ -426,7 +474,7 @@ static void gpiodevice_release(struct device *dev)
struct gpio_device *gdev = dev_get_drvdata(dev); struct gpio_device *gdev = dev_get_drvdata(dev);
list_del(&gdev->list); list_del(&gdev->list);
ida_simple_remove(&gpio_ida, gdev->id); ida_free(&gpio_ida, gdev->id);
kfree_const(gdev->label); kfree_const(gdev->label);
kfree(gdev->descs); kfree(gdev->descs);
kfree(gdev); kfree(gdev);
...@@ -537,7 +585,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -537,7 +585,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gc->of_node = gdev->dev.of_node; gc->of_node = gdev->dev.of_node;
#endif #endif
gdev->id = ida_simple_get(&gpio_ida, 0, 0, GFP_KERNEL); gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
if (gdev->id < 0) { if (gdev->id < 0) {
ret = gdev->id; ret = gdev->id;
goto err_free_gdev; goto err_free_gdev;
...@@ -621,7 +669,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -621,7 +669,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
INIT_LIST_HEAD(&gdev->pin_ranges); INIT_LIST_HEAD(&gdev->pin_ranges);
#endif #endif
ret = gpiochip_set_desc_names(gc); if (gc->names)
ret = gpiochip_set_desc_names(gc);
else
ret = devprop_gpiochip_set_names(gc);
if (ret) if (ret)
goto err_remove_from_list; goto err_remove_from_list;
...@@ -705,7 +756,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -705,7 +756,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
err_free_descs: err_free_descs:
kfree(gdev->descs); kfree(gdev->descs);
err_free_ida: err_free_ida:
ida_simple_remove(&gpio_ida, gdev->id); ida_free(&gpio_ida, gdev->id);
err_free_gdev: err_free_gdev:
/* failures here can mean systems won't boot... */ /* failures here can mean systems won't boot... */
pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__, pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
...@@ -4402,31 +4453,18 @@ static int gpiolib_seq_show(struct seq_file *s, void *v) ...@@ -4402,31 +4453,18 @@ static int gpiolib_seq_show(struct seq_file *s, void *v)
return 0; return 0;
} }
static const struct seq_operations gpiolib_seq_ops = { static const struct seq_operations gpiolib_sops = {
.start = gpiolib_seq_start, .start = gpiolib_seq_start,
.next = gpiolib_seq_next, .next = gpiolib_seq_next,
.stop = gpiolib_seq_stop, .stop = gpiolib_seq_stop,
.show = gpiolib_seq_show, .show = gpiolib_seq_show,
}; };
DEFINE_SEQ_ATTRIBUTE(gpiolib);
static int gpiolib_open(struct inode *inode, struct file *file)
{
return seq_open(file, &gpiolib_seq_ops);
}
static const struct file_operations gpiolib_operations = {
.owner = THIS_MODULE,
.open = gpiolib_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static int __init gpiolib_debugfs_init(void) static int __init gpiolib_debugfs_init(void)
{ {
/* /sys/kernel/debug/gpio */ /* /sys/kernel/debug/gpio */
debugfs_create_file("gpio", S_IFREG | S_IRUGO, NULL, NULL, debugfs_create_file("gpio", 0444, NULL, NULL, &gpiolib_fops);
&gpiolib_operations);
return 0; return 0;
} }
subsys_initcall(gpiolib_debugfs_init); subsys_initcall(gpiolib_debugfs_init);
......
...@@ -756,9 +756,6 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc, ...@@ -756,9 +756,6 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
enum gpiod_flags dflags); enum gpiod_flags dflags);
void gpiochip_free_own_desc(struct gpio_desc *desc); void gpiochip_free_own_desc(struct gpio_desc *desc);
void devprop_gpiochip_set_names(struct gpio_chip *gc,
const struct fwnode_handle *fwnode);
#ifdef CONFIG_GPIOLIB #ifdef CONFIG_GPIOLIB
/* lock/unlock as IRQ */ /* lock/unlock as IRQ */
......
...@@ -19,6 +19,9 @@ enum tx3589x_block { ...@@ -19,6 +19,9 @@ enum tx3589x_block {
#define TC3589x_RSTCTRL_KBDRST (1 << 1) #define TC3589x_RSTCTRL_KBDRST (1 << 1)
#define TC3589x_RSTCTRL_GPIRST (1 << 0) #define TC3589x_RSTCTRL_GPIRST (1 << 0)
#define TC3589x_DKBDMSK_ELINT (1 << 1)
#define TC3589x_DKBDMSK_EINT (1 << 0)
/* Keyboard Configuration Registers */ /* Keyboard Configuration Registers */
#define TC3589x_KBDSETTLE_REG 0x01 #define TC3589x_KBDSETTLE_REG 0x01
#define TC3589x_KBDBOUNCE 0x02 #define TC3589x_KBDBOUNCE 0x02
...@@ -101,6 +104,9 @@ enum tx3589x_block { ...@@ -101,6 +104,9 @@ enum tx3589x_block {
#define TC3589x_GPIOODM2 0xE4 #define TC3589x_GPIOODM2 0xE4
#define TC3589x_GPIOODE2 0xE5 #define TC3589x_GPIOODE2 0xE5
#define TC3589x_DIRECT0 0xEC
#define TC3589x_DKBDMSK 0xF3
#define TC3589x_INT_GPIIRQ 0 #define TC3589x_INT_GPIIRQ 0
#define TC3589x_INT_TI0IRQ 1 #define TC3589x_INT_TI0IRQ 1
#define TC3589x_INT_TI1IRQ 2 #define TC3589x_INT_TI1IRQ 2
......
...@@ -170,6 +170,12 @@ static inline int device_property_count_u64(struct device *dev, const char *prop ...@@ -170,6 +170,12 @@ static inline int device_property_count_u64(struct device *dev, const char *prop
return device_property_read_u64_array(dev, propname, NULL, 0); return device_property_read_u64_array(dev, propname, NULL, 0);
} }
static inline int device_property_string_array_count(struct device *dev,
const char *propname)
{
return device_property_read_string_array(dev, propname, NULL, 0);
}
static inline bool fwnode_property_read_bool(const struct fwnode_handle *fwnode, static inline bool fwnode_property_read_bool(const struct fwnode_handle *fwnode,
const char *propname) const char *propname)
{ {
...@@ -224,6 +230,13 @@ static inline int fwnode_property_count_u64(const struct fwnode_handle *fwnode, ...@@ -224,6 +230,13 @@ static inline int fwnode_property_count_u64(const struct fwnode_handle *fwnode,
return fwnode_property_read_u64_array(fwnode, propname, NULL, 0); return fwnode_property_read_u64_array(fwnode, propname, NULL, 0);
} }
static inline int
fwnode_property_string_array_count(const struct fwnode_handle *fwnode,
const char *propname)
{
return fwnode_property_read_string_array(fwnode, propname, NULL, 0);
}
struct software_node; struct software_node;
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment