[PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq

Andy Shevchenko andriy.shevchenko at linux.intel.com
Tue Jan 11 03:46:47 PST 2022


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





More information about the Linux-mediatek mailing list