Messages in this thread | | | Date | Tue, 11 Jan 2022 13:46:47 +0200 | From | Andy Shevchenko <> | Subject | Re: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq |
| |
On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote: > Add support for eint irq when MSDC is used as an SDIO host. This
IRQ
> feature requires SDIO device support async irq function. With this
IRQ
> feature,SDIO host can be awakened by SDIO card in suspend state,
feature, SDIO
> without additional pin. > > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during > resume, switch GPIO function back to DAT1 mode then turn on clock. > > Some device tree property should be added or modified in msdc node
MSDC
> to support SDIO eint irq. Pinctrls named state_dat1 and state_eint
IRQ
> are mandatory. And cap-sdio-async-irq flag is necessary since this > feature depends on asynchronous interrupt: > &mmcX { > ... > pinctrl-names = "default", "state_uhs", "state_eint", > "state_dat1"; > ... > pinctrl-2 = <&mmc2_pins_eint>; > pinctrl-3 = <&mmc2_pins_dat1>; > ... > cap-sdio-async-irq; > ... > };
...
> - * Copyright (c) 2014-2015 MediaTek Inc. > + * Copyright (c) 2014-2022 MediaTek Inc.
Shouldn't it be rather like
* Copyright (c) 2014-2015,2022 MediaTek Inc.
?
...
> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id) > +{ > + unsigned long flags; > + struct msdc_host *host = (struct msdc_host *)dev_id;
No casting is needed.
> + struct mmc_host *mmc = mmc_from_priv(host);
Perhaps reversed xmas tree order
struct msdc_host *host = dev_id; struct mmc_host *mmc = mmc_from_priv(host); unsigned long flags;
?
But hey, why do you need flags?
> + spin_lock_irqsave(&host->lock, flags); > + if (likely(host->sdio_irq_cnt > 0)) { > + disable_irq_nosync(host->eint_irq); > + disable_irq_wake(host->eint_irq); > + host->sdio_irq_cnt--; > + } > + spin_unlock_irqrestore(&host->lock, flags); > + > + sdio_signal_irq(mmc); > + > + return IRQ_HANDLED; > +}
...
> +static int msdc_request_dat1_eint_irq(struct msdc_host *host) > +{ > + struct gpio_desc *desc; > + int irq, ret; > + > + desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN); > + if (IS_ERR(desc)) > + return PTR_ERR(desc); > + > + ret = gpiod_to_irq(desc); > + if (ret < 0) > + return ret; > + > + irq = ret; > + ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq, > + IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN, > + "sdio-eint", host);
> +
Redundant blank line.
> + if (!ret) > + host->eint_irq = irq; > + > + return ret;
I guess I have already commented on this, i.e. use standard pattern
if (ret) return ret;
... return 0;
> +}
...
> + host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint"); > + if (IS_ERR(host->pins_eint)) {
> + dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
In debug mode of pin control this will bring a duplicate message.
> + } else { > + host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1"); > + if (IS_ERR(host->pins_dat1)) { > + ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1), > + "Cannot find pinctrl dat1!\n"); > + goto host_free; > + } > + > + host->sdio_eint_ready = true; > + } > + }
-- With Best Regards, Andy Shevchenko
| |