Received: by 2002:a05:6602:18e:0:0:0:0 with SMTP id m14csp2064537ioo; Mon, 23 May 2022 09:18:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3fDeDXP6WFxUWnyDn9de76ka2LP1W28sb/CtTRduXLzZk+GegxZMcDefZo0veigYegsbv X-Received: by 2002:a17:90a:bb10:b0:1e0:383b:de80 with SMTP id u16-20020a17090abb1000b001e0383bde80mr9430490pjr.67.1653322710432; Mon, 23 May 2022 09:18:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1653322710; cv=none; d=google.com; s=arc-20160816; b=Ut3pW2Q+OqbXLzofkdDnAt4B3HsHb/1C7CO26CIilb/MZf9ARiKwCxsdpyFWIj8BwQ lHZqwZP5oCL3gTANBLRTjABvzXnCYd/rK4jxHSX6Kj2fk8MLX2mo59F+BvMEQih0HHf1 wl92I1bzAQhJRlatjBClvUig+xLID31+oR2O0ztihj2PHpNxqWd91L/hmB5OdZYlqiiZ Mgx2C5B67DHsnr631XFs/8yBsD4QMGVKT5e2qaxFj6H5COigG3yEODEU4ZVSJtDBoV+d ptpHrNK5YWTmHpJVJg8XyJvgE9aj0YsgX8jgz7vDSSDrg7PfnLbR3Z62EcehTKiQz/YS Z5Cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=2APSlLujdtpChdpBvkpG5jGkTHfodxSS48Z1TYvxXnE=; b=YZ1Q7plqCQd7ppzNkqaKR2ilE9n+rQer11f+Tz8dMpsOTJrmwsn3JWasUSPnKhiwce lJwTDI0S3b0rzaOG5dRxfJ3C7Qkxr4oMKIr/RuLYnYZX0FX2ZMAdtdH4mO+WFYT6532U 6FBBew6wifq2wiYHDcOV93vUxOsO9keoY2boPePbil7v4n8h85xI2isH7efJuxO95BiD oayIGF+hkoyXtaZc0IkdxF9Zg/pWLJLkArf4iH6+bjl5gW8b6Ufu2pHul8muYZ33vlZK 1kQ40QSsHcxRcK2WJi6+ksGg0HEdoQRaD/RuJVZjcIX/BHKzJmxe75N6bOwWqWF6tNUW lYlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=sjICK09w; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id b12-20020a170903228c00b001619aaf38casi11983816plh.63.2022.05.23.09.18.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 May 2022 09:18:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=sjICK09w; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 31A9E674CD; Mon, 23 May 2022 09:18:24 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238635AbiEWQRJ (ORCPT + 99 others); Mon, 23 May 2022 12:17:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59756 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238634AbiEWQQq (ORCPT ); Mon, 23 May 2022 12:16:46 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4872A6543B; Mon, 23 May 2022 09:16:45 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id F1955B8101B; Mon, 23 May 2022 16:16:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9CECFC385A9; Mon, 23 May 2022 16:16:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1653322602; bh=xfepUKvQ7sCLevxiv5+hN7CvEb5owQ3Fs6hC8vUBBNM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=sjICK09wvrS1+7OIscEQWeasa141fB+xn3ZgGjGq7lUEPFtbGf2/8kbaCYO4QAPsP J/wlOnhuvQFwBRVV+SDgmt2EhDY/IxYbLgq/YTbhIUjI7d6XRi18JIF3xCAESh7diQ vOzs4nJG9aNxPoJEATOHDjnHJbtPd38iGWldzc1lO1wZUZPwG/Z49Teh3ck4EQYMlD iav0fx1iHPoFQLBKlKc+kAHsWKqi8Z7W7syVEWaCzD+7Ju8KzDAPmztKYepllWagLs YH++IXRao9IagEoMO68hUikYn6OmcWvmCZEosWDRzjBGJyup4xdHXU9c32Dq7ke+EM 3guKsdcHoe8dQ== Received: from johan by xi.lan with local (Exim 4.94.2) (envelope-from ) id 1ntAjY-00083G-ND; Mon, 23 May 2022 18:16:40 +0200 Date: Mon, 23 May 2022 18:16:40 +0200 From: Johan Hovold To: frank zago Cc: Greg Kroah-Hartman , linux-kernel@vger.kernel.org, Bartosz Golaszewski , Wolfram Sang , linux-usb@vger.kernel.org, Lee Jones , Linus Walleij , linux-gpio@vger.kernel.org, linux-i2c@vger.kernel.org Subject: Re: [PATCH v5 2/3] gpio: ch341: add GPIO MFD cell driver for the CH341 Message-ID: References: <20220401023306.79532-1-frank@zago.net> <20220401023306.79532-3-frank@zago.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220401023306.79532-3-frank@zago.net> X-Spam-Status: No, score=-3.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 31, 2022 at 09:33:05PM -0500, frank zago wrote: > The GPIO interface offers 16 GPIOs. 6 are read/write, and 10 are > read-only. > > Signed-off-by: frank zago > --- > +struct ch341_gpio { > + struct gpio_chip gpio; > + struct mutex gpio_lock; > + u16 gpio_dir; /* 1 bit per pin, 0=IN, 1=OUT. */ > + u16 gpio_last_read; /* last GPIO values read */ > + u16 gpio_last_written; /* last GPIO values written */ > + union { > + u8 gpio_buf[SEG_SIZE]; > + __le16 gpio_buf_status; > + }; > + > + struct urb *irq_urb; > + struct usb_anchor irq_urb_out; > + u8 irq_buf[CH341_USB_MAX_INTR_SIZE]; > + struct irq_chip irq_chip; > + > + struct ch341_device *ch341; > +}; > +static void ch341_complete_intr_urb(struct urb *urb) > +{ > + struct ch341_gpio *dev = urb->context; > + int rc; > + > + if (urb->status) { > + usb_unanchor_urb(dev->irq_urb); URBs are unanchored by USB core on completion. > + } else { > + /* > + * Data is 8 bytes. Byte 0 might be the length of > + * significant data, which is 3 more bytes. Bytes 1 > + * and 2, and possibly 3, are the pin status. The byte > + * order is different than for the GET_STATUS > + * command. Byte 1 is GPIOs 8 to 15, and byte 2 is > + * GPIOs 0 to 7. > + */ > + > + handle_nested_irq(irq_find_mapping(dev->gpio.irq.domain, > + CH341_GPIO_INT_LINE)); > + > + rc = usb_submit_urb(dev->irq_urb, GFP_ATOMIC); > + if (rc) > + usb_unanchor_urb(dev->irq_urb); > + } > +} > +static void ch341_gpio_irq_enable(struct irq_data *data) > +{ > + struct ch341_gpio *dev = irq_data_get_irq_chip_data(data); > + int rc; > + > + /* > + * The URB might have just been unlinked in > + * ch341_gpio_irq_disable, but the completion handler hasn't > + * been called yet. > + */ > + if (!usb_wait_anchor_empty_timeout(&dev->irq_urb_out, 5000)) > + usb_kill_anchored_urbs(&dev->irq_urb_out); > + > + usb_anchor_urb(dev->irq_urb, &dev->irq_urb_out); > + rc = usb_submit_urb(dev->irq_urb, GFP_ATOMIC); > + if (rc) > + usb_unanchor_urb(dev->irq_urb); This looks confused and broken. usb_kill_anchored_urbs() can sleep so either calling it is broken or using GFP_ATOMIC is unnecessary. And isn't this function called multiple times when enabling more than one irq?! > +} > + > +static void ch341_gpio_irq_disable(struct irq_data *data) > +{ > + struct ch341_gpio *dev = irq_data_get_irq_chip_data(data); > + > + usb_unlink_urb(dev->irq_urb); Same here... > +} > + > +static int ch341_gpio_remove(struct platform_device *pdev) > +{ > + struct ch341_gpio *dev = platform_get_drvdata(pdev); > + > + usb_kill_anchored_urbs(&dev->irq_urb_out); You only have one URB... And what prevents it from being resubmitted here? > + gpiochip_remove(&dev->gpio); > + usb_free_urb(dev->irq_urb); > + > + return 0; > +} > + > +static int ch341_gpio_probe(struct platform_device *pdev) > +{ > + struct ch341_device *ch341 = dev_get_drvdata(pdev->dev.parent); > + struct gpio_irq_chip *girq; > + struct ch341_gpio *dev; > + struct gpio_chip *gpio; > + int rc; > + > + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); > + if (dev == NULL) > + return -ENOMEM; > + > + platform_set_drvdata(pdev, dev); > + dev->ch341 = ch341; > + mutex_init(&dev->gpio_lock); > + > + gpio = &dev->gpio; > + gpio->label = dev_name(&pdev->dev); > + gpio->parent = &pdev->dev; > + gpio->owner = THIS_MODULE; > + gpio->get_direction = ch341_gpio_get_direction; > + gpio->direction_input = ch341_gpio_direction_input; > + gpio->direction_output = ch341_gpio_direction_output; > + gpio->get = ch341_gpio_get; > + gpio->get_multiple = ch341_gpio_get_multiple; > + gpio->set = ch341_gpio_set; > + gpio->set_multiple = ch341_gpio_set_multiple; > + gpio->base = -1; > + gpio->ngpio = CH341_GPIO_NUM_PINS; > + gpio->can_sleep = true; > + > + dev->irq_chip.name = dev_name(&pdev->dev); > + dev->irq_chip.irq_set_type = ch341_gpio_irq_set_type; > + dev->irq_chip.irq_enable = ch341_gpio_irq_enable; > + dev->irq_chip.irq_disable = ch341_gpio_irq_disable; > + > + girq = &gpio->irq; > + girq->chip = &dev->irq_chip; > + girq->handler = handle_simple_irq; > + girq->default_type = IRQ_TYPE_NONE; > + > + /* Create an URB for handling interrupt */ > + dev->irq_urb = usb_alloc_urb(0, GFP_KERNEL); > + if (!dev->irq_urb) > + return dev_err_probe(&pdev->dev, -ENOMEM, "Cannot allocate the int URB\n"); > + > + usb_fill_int_urb(dev->irq_urb, ch341->usb_dev, > + usb_rcvintpipe(ch341->usb_dev, ch341->ep_intr), > + dev->irq_buf, CH341_USB_MAX_INTR_SIZE, > + ch341_complete_intr_urb, dev, ch341->ep_intr_interval); > + > + init_usb_anchor(&dev->irq_urb_out); > + > + rc = gpiochip_add_data(gpio, dev); > + if (rc) { > + rc = dev_err_probe(&pdev->dev, rc, "Could not add GPIO\n"); > + goto release_urb; > + } > + > + return 0; > + > +release_urb: > + usb_free_urb(dev->irq_urb); > + > + return rc; > +} Johan