Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758480Ab1EZUY4 (ORCPT ); Thu, 26 May 2011 16:24:56 -0400 Received: from mail-pz0-f46.google.com ([209.85.210.46]:33495 "EHLO mail-pz0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755990Ab1EZUYz (ORCPT ); Thu, 26 May 2011 16:24:55 -0400 Date: Thu, 26 May 2011 14:24:52 -0600 From: Grant Likely To: Alan Cox Cc: linux-kernel@vger.kernel.org Subject: Re: [PATCH] langwell_gpio: add runtime pm support Message-ID: <20110526202452.GE29060@ponder.secretlab.ca> References: <20110510132318.31013.78989.stgit@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110510132318.31013.78989.stgit@localhost.localdomain> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5084 Lines: 184 On Tue, May 10, 2011 at 02:23:45PM +0100, Alan Cox wrote: > From: Kristen Carlson Accardi > > While this is essentially a no-op for this driver, it has the > side effect of letting the PMU driver snoop D3 requests from > the PCI core for this driver. > > This is only for langwell, not for whitney point. > > Signed-off-by: Kristen Carlson Accardi > Signed-off-by: Alan Cox > Signed-off-by: Dirk Brandewie > > [This went me->Dirk->me->upstream before the signed off confuses] Applied, thanks g. > --- > > drivers/gpio/langwell_gpio.c | 65 ++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 65 insertions(+), 0 deletions(-) > > diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c > index 560ab64..6f88e37 100644 > --- a/drivers/gpio/langwell_gpio.c > +++ b/drivers/gpio/langwell_gpio.c > @@ -33,6 +33,7 @@ > #include > #include > #include > +#include > > /* > * Langwell chip has 64 pins and thus there are 2 32bit registers to control > @@ -63,6 +64,7 @@ struct lnw_gpio { > void *reg_base; > spinlock_t lock; > unsigned irq_base; > + struct pci_dev *pdev; > }; > > static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, > @@ -104,11 +106,18 @@ static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset) > u32 value; > unsigned long flags; > > + if (lnw->pdev) > + pm_runtime_get(&lnw->pdev->dev); > + > spin_lock_irqsave(&lnw->lock, flags); > value = readl(gpdr); > value &= ~BIT(offset % 32); > writel(value, gpdr); > spin_unlock_irqrestore(&lnw->lock, flags); > + > + if (lnw->pdev) > + pm_runtime_put(&lnw->pdev->dev); > + > return 0; > } > > @@ -120,11 +129,19 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, > unsigned long flags; > > lnw_gpio_set(chip, offset, value); > + > + if (lnw->pdev) > + pm_runtime_get(&lnw->pdev->dev); > + > spin_lock_irqsave(&lnw->lock, flags); > value = readl(gpdr); > value |= BIT(offset % 32);; > writel(value, gpdr); > spin_unlock_irqrestore(&lnw->lock, flags); > + > + if (lnw->pdev) > + pm_runtime_put(&lnw->pdev->dev); > + > return 0; > } > > @@ -145,6 +162,10 @@ static int lnw_irq_type(struct irq_data *d, unsigned type) > > if (gpio >= lnw->chip.ngpio) > return -EINVAL; > + > + if (lnw->pdev) > + pm_runtime_get(&lnw->pdev->dev); > + > spin_lock_irqsave(&lnw->lock, flags); > if (type & IRQ_TYPE_EDGE_RISING) > value = readl(grer) | BIT(gpio % 32); > @@ -159,6 +180,9 @@ static int lnw_irq_type(struct irq_data *d, unsigned type) > writel(value, gfer); > spin_unlock_irqrestore(&lnw->lock, flags); > > + if (lnw->pdev) > + pm_runtime_put(&lnw->pdev->dev); > + > return 0; > } > > @@ -211,6 +235,39 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) > chip->irq_eoi(data); > } > > +#ifdef CONFIG_PM > +static int lnw_gpio_runtime_resume(struct device *dev) > +{ > + return 0; > +} > + > +static int lnw_gpio_runtime_suspend(struct device *dev) > +{ > + return 0; > +} > + > +static int lnw_gpio_runtime_idle(struct device *dev) > +{ > + int err = pm_schedule_suspend(dev, 500); > + > + if (!err) > + return 0; > + > + return -EBUSY; > +} > + > +#else > +#define lnw_gpio_runtime_suspend NULL > +#define lnw_gpio_runtime_resume NULL > +#define lnw_gpio_runtime_idle NULL > +#endif > + > +static const struct dev_pm_ops lnw_gpio_pm_ops = { > + .runtime_suspend = lnw_gpio_runtime_suspend, > + .runtime_resume = lnw_gpio_runtime_resume, > + .runtime_idle = lnw_gpio_runtime_idle, > +}; > + > static int __devinit lnw_gpio_probe(struct pci_dev *pdev, > const struct pci_device_id *id) > { > @@ -270,6 +327,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, > lnw->chip.base = gpio_base; > lnw->chip.ngpio = id->driver_data; > lnw->chip.can_sleep = 0; > + lnw->pdev = pdev; > pci_set_drvdata(pdev, lnw); > retval = gpiochip_add(&lnw->chip); > if (retval) { > @@ -285,6 +343,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, > } > > spin_lock_init(&lnw->lock); > + > + pm_runtime_put_noidle(&pdev->dev); > + pm_runtime_allow(&pdev->dev); > + > goto done; > err5: > kfree(lnw); > @@ -302,6 +364,9 @@ static struct pci_driver lnw_gpio_driver = { > .name = "langwell_gpio", > .id_table = lnw_gpio_ids, > .probe = lnw_gpio_probe, > + .driver = { > + .pm = &lnw_gpio_pm_ops, > + }, > }; > > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/