Re: problem with twl4030 GPIO irqs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Fri, Dec 16, 2011 at 11:50:32AM +1100, NeilBrown wrote:
> On Fri, 16 Dec 2011 02:03:51 +0200 Grazvydas Ignotas <notasas@xxxxxxxxx>
> wrote:
> 
> > Hi,
> > 
> > I'm running 3.2-rc5 on pandora with Neil's twl patches on top, and
> > omap_hsmmc driver fails to probe:
> > [    3.491394] omap_hsmmc omap_hsmmc.0: context was not lost
> > [    3.497161] omap_hsmmc omap_hsmmc.0: enabled
> > [    3.715270] omap_hsmmc omap_hsmmc.0: Unable to grab MMC CD IRQ
> > 
> > Pandora is using twl4030 GPIOs for card detect. From what I tried to
> > debug, omap_hsmmc is failing after call to request_irq() on card
> > detect irq with -EINVAL, irq number is 384 which is in range of other
> > twl4030 irqs. It looks like request_irq() is calling
> > request_threaded_irq() on ARM with NULL thread_fn, which in turn calls
> > __setup_irq() that calls irq_settings_is_nested_thread() that results
> > with true. As this nested flag is set it checks thread_fn, but that is
> > NULL causing -EINVAL final result.
> > 
> > Could someone who knows irq code better look at this? I think this
> > should reproduce on beagle too.
> > 
> > 
> 
> Try this.
> 
> I wrote it for a slightly different reason, but I think it applies here.
> 
> NeilBrown
> 
> From f7f05b87364d0316f1f6ddad0d7387b25f5d21b9 Mon Sep 17 00:00:00 2001
> From: NeilBrown <neilb@xxxxxxx>
> Date: Fri, 2 Dec 2011 15:35:16 +1100
> Subject: [PATCH] omap_hsmmc - use threaded irq handler for card-detect.
> 
> The the card-detect irq handler just schedules work to be done by
> a thread, we can use request_threaded_irq to do much of the work for
> us.
> 
> Signed-off-by: NeilBrown <neilb@xxxxxxx>

Didn't test myself, but looks like the right approach:

Reviewed-by: Felipe Balbi <balbi@xxxxxx>

> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index 101cd31..d72c181 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -24,7 +24,6 @@
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/platform_device.h>
> -#include <linux/workqueue.h>
>  #include <linux/timer.h>
>  #include <linux/clk.h>
>  #include <linux/mmc/host.h>
> @@ -163,7 +162,6 @@ struct omap_hsmmc_host {
>  	 */
>  	struct	regulator	*vcc;
>  	struct	regulator	*vcc_aux;
> -	struct	work_struct	mmc_carddetect_work;
>  	void	__iomem		*base;
>  	resource_size_t		mapbase;
>  	spinlock_t		irq_lock; /* Prevent races with irq handler */
> @@ -1279,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
>  }
>  
>  /*
> - * Work Item to notify the core about card insertion/removal
> + * irq handler to notify the core about card insertion/removal
>   */
> -static void omap_hsmmc_detect(struct work_struct *work)
> +static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
>  {
> -	struct omap_hsmmc_host *host =
> -		container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
> +	struct omap_hsmmc_host *host = dev_id;
>  	struct omap_mmc_slot_data *slot = &mmc_slot(host);
>  	int carddetect;
>  
>  	if (host->suspended)
> -		return;
> +		return IRQ_HANDLED;
>  
>  	sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
>  
> @@ -1304,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
>  		mmc_detect_change(host->mmc, (HZ * 200) / 1000);
>  	else
>  		mmc_detect_change(host->mmc, (HZ * 50) / 1000);
> -}
> -
> -/*
> - * ISR for handling card insertion and removal
> - */
> -static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id)
> -{
> -	struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
> -
> -	if (host->suspended)
> -		return IRQ_HANDLED;
> -	schedule_work(&host->mmc_carddetect_work);
> -
>  	return IRQ_HANDLED;
>  }
>  
> @@ -1916,7 +1900,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
>  	host->next_data.cookie = 1;
>  
>  	platform_set_drvdata(pdev, host);
> -	INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
>  
>  	mmc->ops	= &omap_hsmmc_ops;
>  
> @@ -2044,10 +2027,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
>  
>  	/* Request IRQ for card detect */
>  	if ((mmc_slot(host).card_detect_irq)) {
> -		ret = request_irq(mmc_slot(host).card_detect_irq,
> -				  omap_hsmmc_cd_handler,
> -				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> -				  mmc_hostname(mmc), host);
> +		ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
> +					   NULL,
> +					   omap_hsmmc_detect,
> +					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> +					   mmc_hostname(mmc), host);
>  		if (ret) {
>  			dev_dbg(mmc_dev(host->mmc),
>  				"Unable to grab MMC CD IRQ\n");
> @@ -2126,7 +2110,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
>  		free_irq(host->irq, host);
>  		if (mmc_slot(host).card_detect_irq)
>  			free_irq(mmc_slot(host).card_detect_irq, host);
> -		flush_work_sync(&host->mmc_carddetect_work);
>  
>  		pm_runtime_put_sync(host->dev);
>  		pm_runtime_disable(host->dev);
> @@ -2173,7 +2156,6 @@ static int omap_hsmmc_suspend(struct device *dev)
>  				return ret;
>  			}
>  		}
> -		cancel_work_sync(&host->mmc_carddetect_work);
>  		ret = mmc_suspend_host(host->mmc);
>  
>  		if (ret == 0) {



-- 
balbi

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux