mirror of https://gitee.com/openkylin/linux.git
gpio updates for v5.5
- only get the second IRQ when there is more than one IRQ in mxc - move the code around in lineevent_create() for some shrinkage - fix formatting for GPIO docs - add DT binding for r8a774b1 - convert drivers that prevously used nocache ioremap() to using regular devm_platform_ioremap_resource() - remove some redundant error messages - shrink object code in 104-idi-48e - drop an unneeded warning from gpiolib-of -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAl2u/9UACgkQEacuoBRx 13J5NBAAglp/gJDyOdmOz+4u8sv0BqOR/01+gOFljuQkV4rUytjb2PXQ+g5aVrfe l4Iqq0vWU16jUGp3WG48ITrYepSx0x4PaS3y/6r7cPTXrl6Ki4RLzR2a4yVSD6LD XfKjhuLNV5T2L99tltzgIPihSn60a0gpIUc6/KlJQ8pmzuzgyyTMXWqjr128j9S0 qnIexsQNBl5dSvi8HolRmie5i3FScAQXwD3EnZPV6hb5FaDkhGrbyvGAGl7Uqz83 KekGOHlhPvvVLP/NnLoJn94UfD5p5kSlA1Ey9vEahzqj/IOQYwUubPs22bL8bIIB UA3iJ/CKiWNAH6/W4NxxmwblIyENnA5Njeop32quXE8Jkttx42ZWuKwVl1UL6seP E0Xv5r9xQmO4ZGuSR3G2JWJM0NiFBS7+dpIj/aBYw96eM7TO5Knfjq3LOPURyVNa RViWhmA245PxtcNJBEo51CFYNnOvcBvwLcXkKvqIJipQTaYrZgWmpdI6YFRYoZ2Z tWiBSVRZwyfRQuwsUs5vGTKmsq2X2LF91m/wsriNZGEdR8cZ+Ig14Stx94K8iM8U p5xw0jCYSFoswvMjkV+pFFX/mlWwqebUSs38yuX8G+OMWctmjq+amcKMenDtwkEm vYZe4/VgC6UZ4o3FVo34nOZg0rU9Pqvh0GMnJPcqiZvgS2beQLk= =mQ1k -----END PGP SIGNATURE----- Merge tag 'gpio-v5.5-updates-for-linus-part-1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel gpio updates for v5.5 - only get the second IRQ when there is more than one IRQ in mxc - move the code around in lineevent_create() for some shrinkage - fix formatting for GPIO docs - add DT binding for r8a774b1 - convert drivers that prevously used nocache ioremap() to using regular devm_platform_ioremap_resource() - remove some redundant error messages - shrink object code in 104-idi-48e - drop an unneeded warning from gpiolib-of
This commit is contained in:
commit
fe12e94375
|
@ -8,6 +8,7 @@ Required Properties:
|
|||
- "renesas,gpio-r8a7745": for R8A7745 (RZ/G1E) compatible GPIO controller.
|
||||
- "renesas,gpio-r8a77470": for R8A77470 (RZ/G1C) compatible GPIO controller.
|
||||
- "renesas,gpio-r8a774a1": for R8A774A1 (RZ/G2M) compatible GPIO controller.
|
||||
- "renesas,gpio-r8a774b1": for R8A774B1 (RZ/G2N) compatible GPIO controller.
|
||||
- "renesas,gpio-r8a774c0": for R8A774C0 (RZ/G2E) compatible GPIO controller.
|
||||
- "renesas,gpio-r8a7778": for R8A7778 (R-Car M1) compatible GPIO controller.
|
||||
- "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller.
|
||||
|
|
|
@ -415,6 +415,8 @@ If you do this, the additional irq_chip will be set up by gpiolib at the
|
|||
same time as setting up the rest of the GPIO functionality. The following
|
||||
is a typical example of a cascaded interrupt handler using gpio_irq_chip:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* Typical state container with dynamic irqchip */
|
||||
struct my_gpio {
|
||||
struct gpio_chip gc;
|
||||
|
@ -450,6 +452,8 @@ is a typical example of a cascaded interrupt handler using gpio_irq_chip:
|
|||
The helper support using hierarchical interrupt controllers as well.
|
||||
In this case the typical set-up will look like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* Typical state container with dynamic irqchip */
|
||||
struct my_gpio {
|
||||
struct gpio_chip gc;
|
||||
|
|
|
@ -65,7 +65,7 @@ static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|||
{
|
||||
struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
|
||||
unsigned i;
|
||||
const unsigned register_offset[6] = { 0, 1, 2, 4, 5, 6 };
|
||||
static const unsigned int register_offset[6] = { 0, 1, 2, 4, 5, 6 };
|
||||
unsigned base_offset;
|
||||
unsigned mask;
|
||||
|
||||
|
|
|
@ -226,7 +226,6 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
|||
struct device_node *np = dev->of_node;
|
||||
struct ath79_gpio_ctrl *ctrl;
|
||||
struct gpio_irq_chip *girq;
|
||||
struct resource *res;
|
||||
u32 ath79_gpio_count;
|
||||
bool oe_inverted;
|
||||
int err;
|
||||
|
@ -256,12 +255,9 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
ctrl->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
|
||||
if (!ctrl->base)
|
||||
return -ENOMEM;
|
||||
ctrl->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ctrl->base))
|
||||
return PTR_ERR(ctrl->base);
|
||||
|
||||
raw_spin_lock_init(&ctrl->lock);
|
||||
err = bgpio_init(&ctrl->gc, dev, 4,
|
||||
|
|
|
@ -269,7 +269,7 @@ static void em_gio_irq_domain_remove(void *data)
|
|||
static int em_gio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct em_gio_priv *p;
|
||||
struct resource *io[2], *irq[2];
|
||||
struct resource *irq[2];
|
||||
struct gpio_chip *gpio_chip;
|
||||
struct irq_chip *irq_chip;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -285,25 +285,21 @@ static int em_gio_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, p);
|
||||
spin_lock_init(&p->sense_lock);
|
||||
|
||||
io[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
io[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
|
||||
|
||||
if (!io[0] || !io[1] || !irq[0] || !irq[1]) {
|
||||
if (!irq[0] || !irq[1]) {
|
||||
dev_err(dev, "missing IRQ or IOMEM\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p->base0 = devm_ioremap_nocache(dev, io[0]->start,
|
||||
resource_size(io[0]));
|
||||
if (!p->base0)
|
||||
return -ENOMEM;
|
||||
p->base0 = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(p->base0))
|
||||
return PTR_ERR(p->base0);
|
||||
|
||||
p->base1 = devm_ioremap_nocache(dev, io[1]->start,
|
||||
resource_size(io[1]));
|
||||
if (!p->base1)
|
||||
return -ENOMEM;
|
||||
p->base1 = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(p->base1))
|
||||
return PTR_ERR(p->base1);
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) {
|
||||
dev_err(dev, "Missing ngpios OF property\n");
|
||||
|
|
|
@ -265,7 +265,6 @@ static int __init egpio_probe(struct platform_device *pdev)
|
|||
struct gpio_chip *chip;
|
||||
unsigned int irq, irq_end;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
/* Initialize ei data structure. */
|
||||
ei = devm_kzalloc(&pdev->dev, sizeof(*ei), GFP_KERNEL);
|
||||
|
@ -275,28 +274,24 @@ static int __init egpio_probe(struct platform_device *pdev)
|
|||
spin_lock_init(&ei->lock);
|
||||
|
||||
/* Find chained irq */
|
||||
ret = -EINVAL;
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (res)
|
||||
ei->chained_irq = res->start;
|
||||
|
||||
/* Map egpio chip into virtual address space. */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
goto fail;
|
||||
ei->base_addr = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!ei->base_addr)
|
||||
goto fail;
|
||||
pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr);
|
||||
ei->base_addr = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ei->base_addr))
|
||||
return PTR_ERR(ei->base_addr);
|
||||
|
||||
if ((pdata->bus_width != 16) && (pdata->bus_width != 32))
|
||||
goto fail;
|
||||
return -EINVAL;
|
||||
|
||||
ei->bus_shift = fls(pdata->bus_width - 1) - 3;
|
||||
pr_debug("bus_shift = %d\n", ei->bus_shift);
|
||||
|
||||
if ((pdata->reg_width != 8) && (pdata->reg_width != 16))
|
||||
goto fail;
|
||||
return -EINVAL;
|
||||
|
||||
ei->reg_shift = fls(pdata->reg_width - 1);
|
||||
pr_debug("reg_shift = %d\n", ei->reg_shift);
|
||||
|
||||
|
@ -308,10 +303,9 @@ static int __init egpio_probe(struct platform_device *pdev)
|
|||
ei->chip = devm_kcalloc(&pdev->dev,
|
||||
ei->nchips, sizeof(struct egpio_chip),
|
||||
GFP_KERNEL);
|
||||
if (!ei->chip) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
if (!ei->chip)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ei->nchips; i++) {
|
||||
ei->chip[i].reg_start = pdata->chip[i].reg_start;
|
||||
ei->chip[i].cached_values = pdata->chip[i].initial_values;
|
||||
|
@ -321,10 +315,9 @@ static int __init egpio_probe(struct platform_device *pdev)
|
|||
chip->label = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"htc-egpio-%d",
|
||||
i);
|
||||
if (!chip->label) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
if (!chip->label)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->parent = &pdev->dev;
|
||||
chip->owner = THIS_MODULE;
|
||||
chip->get = egpio_get;
|
||||
|
@ -366,10 +359,6 @@ static int __init egpio_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
printk(KERN_ERR "EGPIO failed to setup\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -411,6 +411,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct mxc_gpio_port *port;
|
||||
int irq_count;
|
||||
int irq_base;
|
||||
int err;
|
||||
|
||||
|
@ -426,9 +427,15 @@ static int mxc_gpio_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(port->base))
|
||||
return PTR_ERR(port->base);
|
||||
|
||||
port->irq_high = platform_get_irq(pdev, 1);
|
||||
if (port->irq_high < 0)
|
||||
port->irq_high = 0;
|
||||
irq_count = platform_irq_count(pdev);
|
||||
if (irq_count < 0)
|
||||
return irq_count;
|
||||
|
||||
if (irq_count > 1) {
|
||||
port->irq_high = platform_get_irq(pdev, 1);
|
||||
if (port->irq_high < 0)
|
||||
port->irq_high = 0;
|
||||
}
|
||||
|
||||
port->irq = platform_get_irq(pdev, 0);
|
||||
if (port->irq < 0)
|
||||
|
|
|
@ -155,28 +155,16 @@ static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume);
|
|||
|
||||
static int xgene_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct xgene_gpio *gpio;
|
||||
int err = 0;
|
||||
|
||||
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
|
||||
if (!gpio) {
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (!gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
gpio->base = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!gpio->base) {
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
gpio->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(gpio->base))
|
||||
return PTR_ERR(gpio->base);
|
||||
|
||||
gpio->chip.ngpio = XGENE_MAX_GPIOS;
|
||||
|
||||
|
@ -196,14 +184,11 @@ static int xgene_gpio_probe(struct platform_device *pdev)
|
|||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to register gpiochip.\n");
|
||||
goto err;
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "X-Gene GPIO driver registered.\n");
|
||||
return 0;
|
||||
err:
|
||||
dev_err(&pdev->dev, "X-Gene GPIO driver registration failed.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id xgene_gpio_of_match[] = {
|
||||
|
|
|
@ -135,18 +135,20 @@ static void of_gpio_flags_quirks(struct device_node *np,
|
|||
(!(strcmp(propname, "enable-gpio") &&
|
||||
strcmp(propname, "enable-gpios")) &&
|
||||
of_device_is_compatible(np, "regulator-gpio")))) {
|
||||
bool active_low = !of_property_read_bool(np,
|
||||
"enable-active-high");
|
||||
/*
|
||||
* The regulator GPIO handles are specified such that the
|
||||
* presence or absence of "enable-active-high" solely controls
|
||||
* the polarity of the GPIO line. Any phandle flags must
|
||||
* be actively ignored.
|
||||
*/
|
||||
if (*flags & OF_GPIO_ACTIVE_LOW) {
|
||||
if ((*flags & OF_GPIO_ACTIVE_LOW) && !active_low) {
|
||||
pr_warn("%s GPIO handle specifies active low - ignored\n",
|
||||
of_node_full_name(np));
|
||||
*flags &= ~OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
if (!of_property_read_bool(np, "enable-active-high"))
|
||||
if (active_low)
|
||||
*flags |= OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -900,6 +900,24 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
|
|||
if (copy_from_user(&eventreq, ip, sizeof(eventreq)))
|
||||
return -EFAULT;
|
||||
|
||||
offset = eventreq.lineoffset;
|
||||
lflags = eventreq.handleflags;
|
||||
eflags = eventreq.eventflags;
|
||||
|
||||
if (offset >= gdev->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
/* Return an error if a unknown flag is set */
|
||||
if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
|
||||
(eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS))
|
||||
return -EINVAL;
|
||||
|
||||
/* This is just wrong: we don't look for events on output lines */
|
||||
if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
|
||||
(lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
|
||||
(lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
|
||||
return -EINVAL;
|
||||
|
||||
le = kzalloc(sizeof(*le), GFP_KERNEL);
|
||||
if (!le)
|
||||
return -ENOMEM;
|
||||
|
@ -917,30 +935,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
|
|||
}
|
||||
}
|
||||
|
||||
offset = eventreq.lineoffset;
|
||||
lflags = eventreq.handleflags;
|
||||
eflags = eventreq.eventflags;
|
||||
|
||||
if (offset >= gdev->ngpio) {
|
||||
ret = -EINVAL;
|
||||
goto out_free_label;
|
||||
}
|
||||
|
||||
/* Return an error if a unknown flag is set */
|
||||
if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
|
||||
(eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) {
|
||||
ret = -EINVAL;
|
||||
goto out_free_label;
|
||||
}
|
||||
|
||||
/* This is just wrong: we don't look for events on output lines */
|
||||
if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
|
||||
(lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
|
||||
(lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)) {
|
||||
ret = -EINVAL;
|
||||
goto out_free_label;
|
||||
}
|
||||
|
||||
desc = &gdev->descs[offset];
|
||||
ret = gpiod_request(desc, le->label);
|
||||
if (ret)
|
||||
|
|
Loading…
Reference in New Issue