diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2020-11-11 17:38:21 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2020-11-11 17:38:21 +0100 |
commit | 27b5ea2fcb90d2dbc3be03e3a171bc28117eef14 (patch) | |
tree | 01a7b287f11ce55e20200571594a21cbb3863e7e /drivers/gpio | |
parent | gpio: sifive: Fix SiFive gpio probe (diff) | |
parent | gpio: 104-idi-48: improve code indentation (diff) | |
download | linux-27b5ea2fcb90d2dbc3be03e3a171bc28117eef14.tar.xz linux-27b5ea2fcb90d2dbc3be03e3a171bc28117eef14.zip |
Merge branch 'devel' into for-next
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/TODO | 49 | ||||
-rw-r--r-- | drivers/gpio/gpio-104-idi-48.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-stmpe.c | 10 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-cdev.c | 24 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 168 |
5 files changed, 19 insertions, 238 deletions
diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO index e560e45e84f8..cd04e0b60159 100644 --- a/drivers/gpio/TODO +++ b/drivers/gpio/TODO @@ -129,58 +129,9 @@ GPIOLIB irqchip The GPIOLIB irqchip is a helper irqchip for "simple cases" that should try to cover any generic kind of irqchip cascaded from a GPIO. -- Convert all the GPIOLIB_IRQCHIP users to pass an irqchip template, - parent and flags before calling [devm_]gpiochip_add[_data](). - Currently we set up the irqchip after setting up the gpiochip - using gpiochip_irqchip_add() and gpiochip_set_[chained|nested]_irqchip(). - This is too complex, so convert all users over to just set up - the irqchip before registering the gpio_chip, typical example: - - /* Typical state container with dynamic irqchip */ - struct my_gpio { - struct gpio_chip gc; - struct irq_chip irq; - }; - - int irq; /* from platform etc */ - struct my_gpio *g; - struct gpio_irq_chip *girq; - - /* Set up the irqchip dynamically */ - g->irq.name = "my_gpio_irq"; - g->irq.irq_ack = my_gpio_ack_irq; - g->irq.irq_mask = my_gpio_mask_irq; - g->irq.irq_unmask = my_gpio_unmask_irq; - g->irq.irq_set_type = my_gpio_set_irq_type; - - /* Get a pointer to the gpio_irq_chip */ - girq = &g->gc.irq; - girq->chip = &g->irq; - girq->parent_handler = ftgpio_gpio_irq_handler; - girq->num_parents = 1; - girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_bad_irq; - girq->parents[0] = irq; - - When this is done, we will delete the old APIs for instatiating - GPIOLIB_IRQCHIP and simplify the code. - - Look over and identify any remaining easily converted drivers and dry-code conversions to gpiolib irqchip for maintainers to test -- Drop gpiochip_set_chained_irqchip() when all the chained irqchips - have been converted to the above infrastructure. - -- Add more infrastructure to make it possible to also pass a threaded - irqchip in struct gpio_irq_chip. - -- Drop gpiochip_irqchip_add_nested() when all the chained irqchips - have been converted to the above infrastructure. - Increase integration with pin control diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index 94c3a9bc4e75..b132afaf7d99 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -132,8 +132,7 @@ static void idi_48_irq_mask(struct irq_data *data) outb(idi48gpio->cos_enb, idi48gpio->base + 7); - raw_spin_unlock_irqrestore(&idi48gpio->lock, - flags); + raw_spin_unlock_irqrestore(&idi48gpio->lock, flags); } return; @@ -166,8 +165,7 @@ static void idi_48_irq_unmask(struct irq_data *data) outb(idi48gpio->cos_enb, idi48gpio->base + 7); - raw_spin_unlock_irqrestore(&idi48gpio->lock, - flags); + raw_spin_unlock_irqrestore(&idi48gpio->lock, flags); } return; diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index b0155d6007c8..b94ef8181428 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -474,15 +474,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->chip.parent = &pdev->dev; stmpe_gpio->chip.of_node = np; stmpe_gpio->chip.base = -1; - /* - * REVISIT: this makes sure the valid mask gets allocated and - * filled in when adding the gpio_chip, but the rest of the - * gpio_irqchip is still filled in using the old method - * in gpiochip_irqchip_add_nested() so clean this up once we - * get the gpio_irqchip to initialize while adding the - * gpio_chip also for threaded irqchips. - */ - stmpe_gpio->chip.irq.init_valid_mask = stmpe_init_irq_valid_mask; if (IS_ENABLED(CONFIG_DEBUG_FS)) stmpe_gpio->chip.dbg_show = stmpe_dbg_show; @@ -520,6 +511,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_simple_irq; girq->threaded = true; + girq->init_valid_mask = stmpe_init_irq_valid_mask; } ret = gpiochip_add_data(&stmpe_gpio->chip, stmpe_gpio); diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index e9faeaf65d14..192721f829a3 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1479,21 +1479,10 @@ static __poll_t lineevent_poll(struct file *file, return events; } -static ssize_t lineevent_get_size(void) -{ -#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) - /* i386 has no padding after 'id' */ - if (in_ia32_syscall()) { - struct compat_gpioeevent_data { - compat_u64 timestamp; - u32 id; - }; - - return sizeof(struct compat_gpioeevent_data); - } -#endif - return sizeof(struct gpioevent_data); -} +struct compat_gpioeevent_data { + compat_u64 timestamp; + u32 id; +}; static ssize_t lineevent_read(struct file *file, char __user *buf, @@ -1515,7 +1504,10 @@ static ssize_t lineevent_read(struct file *file, * actual sizeof() and pass this as an argument to copy_to_user() to * drop unneeded bytes from the output. */ - ge_size = lineevent_get_size(); + if (compat_need_64bit_alignment_fixup()) + ge_size = sizeof(struct compat_gpioeevent_data); + else + ge_size = sizeof(struct gpioevent_data); if (count < ge_size) return -EINVAL; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 089ddcaa9bc6..c980ddcda833 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -936,67 +936,6 @@ bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc, } EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid); -/** - * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip - * @gc: the gpiochip to set the irqchip chain to - * @parent_irq: the irq number corresponding to the parent IRQ for this - * cascaded irqchip - * @parent_handler: the parent interrupt handler for the accumulated IRQ - * coming out of the gpiochip. If the interrupt is nested rather than - * cascaded, pass NULL in this handler argument - */ -static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gc, - unsigned int parent_irq, - irq_flow_handler_t parent_handler) -{ - struct gpio_irq_chip *girq = &gc->irq; - struct device *dev = &gc->gpiodev->dev; - - if (!girq->domain) { - chip_err(gc, "called %s before setting up irqchip\n", - __func__); - return; - } - - if (parent_handler) { - if (gc->can_sleep) { - chip_err(gc, - "you cannot have chained interrupts on a chip that may sleep\n"); - return; - } - girq->parents = devm_kcalloc(dev, 1, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) { - chip_err(gc, "out of memory allocating parent IRQ\n"); - return; - } - girq->parents[0] = parent_irq; - girq->num_parents = 1; - /* - * The parent irqchip is already using the chip_data for this - * irqchip, so our callbacks simply use the handler_data. - */ - irq_set_chained_handler_and_data(parent_irq, parent_handler, - gc); - } -} - -/** - * gpiochip_set_nested_irqchip() - connects a nested irqchip to a gpiochip - * @gc: the gpiochip to set the irqchip nested handler to - * @irqchip: the irqchip to nest to the gpiochip - * @parent_irq: the irq number corresponding to the parent IRQ for this - * nested irqchip - */ -void gpiochip_set_nested_irqchip(struct gpio_chip *gc, - struct irq_chip *irqchip, - unsigned int parent_irq) -{ - gpiochip_set_cascaded_irqchip(gc, parent_irq, NULL); -} -EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip); - #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY /** @@ -1648,98 +1587,6 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc) } /** - * gpiochip_irqchip_add_key() - adds an irqchip to a gpiochip - * @gc: the gpiochip to add the irqchip to - * @irqchip: the irqchip to add to the gpiochip - * @first_irq: if not dynamically assigned, the base (first) IRQ to - * allocate gpiochip irqs from - * @handler: the irq handler to use (often a predefined irq core function) - * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE - * to have the core avoid setting up any default type in the hardware. - * @threaded: whether this irqchip uses a nested thread handler - * @lock_key: lockdep class for IRQ lock - * @request_key: lockdep class for IRQ request - * - * This function closely associates a certain irqchip with a certain - * gpiochip, providing an irq domain to translate the local IRQs to - * global irqs in the gpiolib core, and making sure that the gpiochip - * is passed as chip data to all related functions. Driver callbacks - * need to use gpiochip_get_data() to get their local state containers back - * from the gpiochip passed as chip data. An irqdomain will be stored - * in the gpiochip that shall be used by the driver to handle IRQ number - * translation. The gpiochip will need to be initialized and registered - * before calling this function. - * - * This function will handle two cell:ed simple IRQs and assumes all - * the pins on the gpiochip can generate a unique IRQ. Everything else - * need to be open coded. - */ -int gpiochip_irqchip_add_key(struct gpio_chip *gc, - struct irq_chip *irqchip, - unsigned int first_irq, - irq_flow_handler_t handler, - unsigned int type, - bool threaded, - struct lock_class_key *lock_key, - struct lock_class_key *request_key) -{ - struct device_node *of_node; - - if (!gc || !irqchip) - return -EINVAL; - - if (!gc->parent) { - chip_err(gc, "missing gpiochip .dev parent pointer\n"); - return -EINVAL; - } - gc->irq.threaded = threaded; - of_node = gc->parent->of_node; -#ifdef CONFIG_OF_GPIO - /* - * If the gpiochip has an assigned OF node this takes precedence - * FIXME: get rid of this and use gc->parent->of_node - * everywhere - */ - if (gc->of_node) - of_node = gc->of_node; -#endif - /* - * Specifying a default trigger is a terrible idea if DT or ACPI is - * used to configure the interrupts, as you may end-up with - * conflicting triggers. Tell the user, and reset to NONE. - */ - if (WARN(of_node && type != IRQ_TYPE_NONE, - "%pOF: Ignoring %d default trigger\n", of_node, type)) - type = IRQ_TYPE_NONE; - if (has_acpi_companion(gc->parent) && type != IRQ_TYPE_NONE) { - acpi_handle_warn(ACPI_HANDLE(gc->parent), - "Ignoring %d default trigger\n", type); - type = IRQ_TYPE_NONE; - } - - gc->irq.chip = irqchip; - gc->irq.handler = handler; - gc->irq.default_type = type; - gc->to_irq = gpiochip_to_irq; - gc->irq.lock_key = lock_key; - gc->irq.request_key = request_key; - gc->irq.domain = irq_domain_add_simple(of_node, - gc->ngpio, first_irq, - &gpiochip_domain_ops, gc); - if (!gc->irq.domain) { - gc->irq.chip = NULL; - return -EINVAL; - } - - gpiochip_set_irq_hooks(gc); - - acpi_gpiochip_request_interrupts(gc); - - return 0; -} -EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key); - -/** * gpiochip_irqchip_add_domain() - adds an irqdomain to a gpiochip * @gc: the gpiochip to add the irqchip to * @domain: the irqdomain to add to the gpiochip @@ -2268,8 +2115,8 @@ static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode) static int gpio_set_bias(struct gpio_desc *desc) { - int bias = 0; - int ret = 0; + enum pin_config_param bias; + int ret; if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) bias = PIN_CONFIG_BIAS_DISABLE; @@ -2277,12 +2124,13 @@ static int gpio_set_bias(struct gpio_desc *desc) bias = PIN_CONFIG_BIAS_PULL_UP; else if (test_bit(FLAG_PULL_DOWN, &desc->flags)) bias = PIN_CONFIG_BIAS_PULL_DOWN; + else + return 0; + + ret = gpio_set_config(desc, bias); + if (ret != -ENOTSUPP) + return ret; - if (bias) { - ret = gpio_set_config(desc, bias); - if (ret != -ENOTSUPP) - return ret; - } return 0; } |