From patchwork Fri May 9 11:35:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 29886 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qg0-f72.google.com (mail-qg0-f72.google.com [209.85.192.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C60AC202FE for ; Fri, 9 May 2014 11:35:51 +0000 (UTC) Received: by mail-qg0-f72.google.com with SMTP id q108sf8034197qgd.3 for ; Fri, 09 May 2014 04:35:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=PxLFvWePx8EOauhKuroo1honRTHEqkzqBozZ0348BvM=; b=al1g+nx9quoBGr5X0Kpj4Ff1ZM5cB5Y4Q0iwWTAMp6+ENwsi08W169V0ONFJQnw30P zusHvfP0I6vTeOsndNLLai9NeNEUXKVy4ACD8bS/YxpCKYhczf8YjqePNpkGUfbrKz7l eecuBiS5x8MNt3VOPQer6Rt4Qu5MN5i9XgR7sfp4llpPAargUGcLm4wyzFkcnM7CFy2U qdEBxX2Yjsyhaeq4EcJBf5T/1YAmmWjg1a70UPhbXUwAafRJ4SS8V1ckjY1U8xIe1Ex6 BNggH3Y13Nx2kDJGGKSahEi10X1/kl1t8PJIeA8kgcknCgkKvrUNlxu2rjSqx2iqgsQT b5uA== X-Gm-Message-State: ALoCoQkXrdLwLYs5m1QtjhjrxKC149en9ONbhnaSzeD7akzMXXr8KoclIbxS694t290wrIyGDOZq X-Received: by 10.236.138.113 with SMTP id z77mr3998634yhi.25.1399635351511; Fri, 09 May 2014 04:35:51 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.107.97 with SMTP id g88ls252522qgf.40.gmail; Fri, 09 May 2014 04:35:51 -0700 (PDT) X-Received: by 10.58.39.129 with SMTP id p1mr65077vek.69.1399635351381; Fri, 09 May 2014 04:35:51 -0700 (PDT) Received: from mail-ve0-f175.google.com (mail-ve0-f175.google.com [209.85.128.175]) by mx.google.com with ESMTPS id sc7si680362vdc.67.2014.05.09.04.35.51 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 09 May 2014 04:35:51 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.175 as permitted sender) client-ip=209.85.128.175; Received: by mail-ve0-f175.google.com with SMTP id jw12so4984585veb.20 for ; Fri, 09 May 2014 04:35:51 -0700 (PDT) X-Received: by 10.53.1.69 with SMTP id be5mr6681229vdd.27.1399635351272; Fri, 09 May 2014 04:35:51 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp71715vcb; Fri, 9 May 2014 04:35:50 -0700 (PDT) X-Received: by 10.66.221.4 with SMTP id qa4mr19646429pac.138.1399635349913; Fri, 09 May 2014 04:35:49 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bg4si406682pbb.364.2014.05.09.04.35.49; Fri, 09 May 2014 04:35:49 -0700 (PDT) Received-SPF: none (google.com: linux-gpio-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754599AbaEILfs (ORCPT + 1 other); Fri, 9 May 2014 07:35:48 -0400 Received: from mail-wi0-f177.google.com ([209.85.212.177]:54815 "EHLO mail-wi0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754716AbaEILfr (ORCPT ); Fri, 9 May 2014 07:35:47 -0400 Received: by mail-wi0-f177.google.com with SMTP id f8so1166619wiw.4 for ; Fri, 09 May 2014 04:35:45 -0700 (PDT) X-Received: by 10.194.92.7 with SMTP id ci7mr8133238wjb.7.1399635345804; Fri, 09 May 2014 04:35:45 -0700 (PDT) Received: from localhost.localdomain ([85.235.11.236]) by mx.google.com with ESMTPSA id fu10sm4636074wib.11.2014.05.09.04.35.43 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 May 2014 04:35:44 -0700 (PDT) From: Linus Walleij To: linux-gpio@vger.kernel.org, Toby Smith , Aaron Sierra , Graeme Smecher , Andrew Ruder , Gregory CLEMENT , Maxime Ripard Cc: Alexandre Courbot , Linus Walleij Subject: [PATCH] RFT: gpio: pca953x: use gpiolib irqchip helpers Date: Fri, 9 May 2014 13:35:39 +0200 Message-Id: <1399635339-16812-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.9.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-gpio@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.175 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This switches the PCA953x driver over to using the gpiolib irqchip helpers to handle the threaded interrups cascaded off this GPIO chip. Signed-off-by: Linus Walleij --- PCA953x users: please! help testing this. It is just compile-tested but I'm sure this or something close to it will work just fine. The patch depends on the GPIO tree devel branch, so I have set up a branch you can test: git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git#pca953-irqchip-helpers The branch is on top of Toby's changes. Please help to provide Tested-by tags. --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-pca953x.c | 93 ++++++++++++++++----------------------------- 2 files changed, 33 insertions(+), 61 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 664df4d08459..b29427cc7f44 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -519,6 +519,7 @@ config GPIO_PCA953X config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" depends on GPIO_PCA953X=y + select GPIOLIB_IRQCHIP help Say yes here to enable the pca953x to be used as an interrupt controller. It requires the driver to be built in the kernel. diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 6398f8a0f40c..e721a37c3473 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include #include @@ -91,7 +89,6 @@ struct pca953x_chip { u8 irq_stat[MAX_BANK]; u8 irq_trig_raise[MAX_BANK]; u8 irq_trig_fall[MAX_BANK]; - struct irq_domain *domain; #endif struct i2c_client *client; @@ -100,6 +97,11 @@ struct pca953x_chip { int chip_type; }; +static inline struct pca953x_chip *to_pca(struct gpio_chip *gc) +{ + return container_of(gc, struct pca953x_chip, gpio_chip); +} + static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, int off) { @@ -202,12 +204,10 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val) static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); 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[off / BANK_SZ] | (1u << (off % BANK_SZ)); @@ -233,12 +233,10 @@ exit: static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; - chip = container_of(gc, struct pca953x_chip, gpio_chip); - mutex_lock(&chip->i2c_lock); /* set output level */ if (val) @@ -285,12 +283,10 @@ exit: static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); u32 reg_val; int ret, offset = 0; - chip = container_of(gc, struct pca953x_chip, gpio_chip); - mutex_lock(&chip->i2c_lock); switch (chip->chip_type) { case PCA953X_TYPE: @@ -315,12 +311,10 @@ 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; + struct pca953x_chip *chip = to_pca(gc); 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[off / BANK_SZ] @@ -367,38 +361,34 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) } #ifdef CONFIG_GPIO_PCA953X_IRQ -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 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); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); 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); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ); } static void pca953x_irq_bus_lock(struct irq_data *d) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); mutex_lock(&chip->irq_lock); } static void pca953x_irq_bus_sync_unlock(struct irq_data *d) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); u8 new_irqs; int level, i; @@ -420,7 +410,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); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); int bank_nb = d->hwirq / BANK_SZ; u8 mask = 1 << (d->hwirq % BANK_SZ); @@ -512,7 +503,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) for (i = 0; i < NBANK(chip); i++) { while (pending[i]) { level = __ffs(pending[i]); - handle_nested_irq(irq_find_mapping(chip->domain, + handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, level + (BANK_SZ * i))); pending[i] &= ~(1 << level); nhandled++; @@ -522,27 +513,6 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE; } -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) @@ -574,14 +544,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->irq_stat[i] &= chip->reg_direction[i]; mutex_init(&chip->irq_lock); - chip->domain = irq_domain_add_simple(client->dev.of_node, - chip->gpio_chip.ngpio, - irq_base, - &pca953x_irq_simple_ops, - chip); - if (!chip->domain) - return -ENODEV; - ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, @@ -595,7 +557,16 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return ret; } - chip->gpio_chip.to_irq = pca953x_gpio_to_irq; + ret = gpiochip_irqchip_add(&chip->gpio_chip, + &pca953x_irq_chip, + irq_base, + handle_simple_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(&client->dev, + "could not connect irqchip to gpiochip\n"); + return ret; + } } return 0; @@ -759,11 +730,11 @@ static int pca953x_probe(struct i2c_client *client, if (ret) return ret; - ret = pca953x_irq_setup(chip, id, irq_base); + ret = gpiochip_add(&chip->gpio_chip); if (ret) return ret; - ret = gpiochip_add(&chip->gpio_chip); + ret = pca953x_irq_setup(chip, id, irq_base); if (ret) return ret;