From patchwork Tue May 10 23:43:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1428 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:51:55 -0000 Delivered-To: patches@linaro.org Received: by 10.224.61.3 with SMTP id r3cs38868qah; Tue, 10 May 2011 16:43:42 -0700 (PDT) Received: by 10.42.37.199 with SMTP id z7mr733070icd.110.1305071022421; Tue, 10 May 2011 16:43:42 -0700 (PDT) Received: from mail-iw0-f178.google.com (mail-iw0-f178.google.com [209.85.214.178]) by mx.google.com with ESMTPS id s1si21254351iba.87.2011.05.10.16.43.42 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 10 May 2011 16:43:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linus.ml.walleij@gmail.com designates 209.85.214.178 as permitted sender) client-ip=209.85.214.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linus.ml.walleij@gmail.com designates 209.85.214.178 as permitted sender) smtp.mail=linus.ml.walleij@gmail.com; dkim=pass (test mode) header.i=@gmail.com Received: by iwn9 with SMTP id 9so7264266iwn.37 for ; Tue, 10 May 2011 16:43:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type:content-transfer-encoding; bh=NqE/NXSpKB7hcBID03gYZzd1+shm6HrF/e4VxHSxKZs=; b=PFn7/zBx77ZM9+he8+Bmni9sNqK8sReb2caBjd4LyPSjwmdrUD7UnJOoaf9rl5/wyG 6yZIZNQs2jdMA0biGQ1AbLCwCT8ODw0crEtT4y6YCdBSEPK1pGwA0LkJT+KG+HAoLcZn KdB6RHxMH2HhycDo9dvpc+jxNxpmOUJ4g6U6s= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=wI+UbJOPwWAbpQDISgU/hQG3e7H10kmxKpdoa8mZCkVcw8ppA0xvnJDcp44w9x3lmS V4RXVdRF8Ut8RN/qpGSBUmLAq4NONwWGpH2KfPUWAPbKfGcp26T4bkAcrNaB0xBjCDjQ EL9SUK0FTT2bQtNzWtFiOvarPuU9KtXyBYhyg= MIME-Version: 1.0 Received: by 10.231.41.66 with SMTP id n2mr6155794ibe.76.1305071021646; Tue, 10 May 2011 16:43:41 -0700 (PDT) Received: by 10.231.20.3 with HTTP; Tue, 10 May 2011 16:43:41 -0700 (PDT) In-Reply-To: <1304976905-31405-1-git-send-email-linus.walleij@linaro.org> References: <1304976905-31405-1-git-send-email-linus.walleij@linaro.org> Date: Wed, 11 May 2011 01:43:41 +0200 Message-ID: Subject: Fwd: [PATCH 01/13] i2c/i2c-nomadik: add regulator support From: Linus Walleij To: patches@linaro.org ---------- Forwarded message ---------- From: Linus Walleij Date: 2011/5/9 Subject: [PATCH 01/13] i2c/i2c-nomadik: add regulator support To: Ben Dooks , linux-i2c@vger.kernel.org Kopia: Jonas Aberg , Linus Walleij From: Jonas Aberg This on-chip I2C controller needs to fetch the regulator representing its voltage domain so that it won't be switched off. Signed-off-by: Jonas Aberg Signed-off-by: Linus Walleij ---  drivers/i2c/busses/i2c-nomadik.c |   73 ++++++++++++++++++++++++++++++--------  1 files changed, 58 insertions(+), 15 deletions(-) @@ -860,6 +899,12 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)                goto err_irq;        } +       dev->regulator = regulator_get(&pdev->dev, "v-i2c"); +       if (IS_ERR(dev->regulator)) { +               dev_warn(&pdev->dev, "could not get i2c regulator\n"); +               dev->regulator = NULL; +       } +        dev->clk = clk_get(&pdev->dev, NULL);        if (IS_ERR(dev->clk)) {                dev_err(&pdev->dev, "could not get i2c clock\n"); @@ -887,12 +932,6 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)        i2c_set_adapdata(adap, dev); -       ret = init_hw(dev); -       if (ret != 0) { -               dev_err(&pdev->dev, "error in initializing i2c hardware\n"); -               goto err_init_hw; -       } -        dev_info(&pdev->dev, "initialize %s on virtual "                "base %p\n", adap->name, dev->virtbase); @@ -904,10 +943,11 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)        return 0; - err_init_hw:  err_add_adap:        clk_put(dev->clk);  err_no_clk: +       if (dev->regulator) +               regulator_put(dev->regulator);        free_irq(dev->irq, dev);  err_irq:        iounmap(dev->virtbase); @@ -938,6 +978,8 @@ static int __devexit nmk_i2c_remove(struct platform_device *pdev)        if (res)                release_mem_region(res->start, resource_size(res));        clk_put(dev->clk); +       if (dev->regulator) +               regulator_put(dev->regulator);        platform_set_drvdata(pdev, NULL);        kfree(dev); @@ -951,6 +993,7 @@ static struct platform_driver nmk_i2c_driver = {        },        .probe = nmk_i2c_probe,        .remove = __devexit_p(nmk_i2c_remove), +       .suspend = nmk_i2c_suspend,  };  static int __init nmk_i2c_init(void) -- 1.7.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@vger.kernel.org More majordomo info at  http://vger.kernel.org/majordomo-info.html diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index e10e5cf..182761e 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -22,6 +22,7 @@  #include  #include  #include +#include  #include @@ -151,6 +152,7 @@ struct i2c_nmk_client {  * @stop: stop condition  * @xfer_complete: acknowledge completion for a I2C message  * @result: controller propogated result + * @busy: Busy doing transfer  */  struct nmk_i2c_dev {        struct platform_device          *pdev; @@ -163,6 +165,8 @@ struct nmk_i2c_dev {        int                             stop;        struct completion               xfer_complete;        int                             result; +       struct regulator                *regulator; +       bool                            busy;  };  /* controller's abort causes */ @@ -257,7 +261,7 @@ static int init_hw(struct nmk_i2c_dev *dev)        stat = flush_i2c_fifo(dev);        if (stat) -               return stat; +               goto exit;        /* disable the controller */        i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE); @@ -268,10 +272,16 @@ static int init_hw(struct nmk_i2c_dev *dev)        dev->cli.operation = I2C_NO_OPERATION; +exit: +       /* TODO: Why disable clocks after init hw? */        clk_disable(dev->clk); - +       /* +        * TODO: What is this delay for? +        * Must be pretty pointless since the hw block +        * is frozen. Or? +        */        udelay(I2C_DELAY); -       return 0; +       return stat;  }  /* enable peripheral, master mode operation */ @@ -562,9 +572,14 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,        u32 cause;        struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap); +       dev->busy = true; + +       if (dev->regulator) +               regulator_enable(dev->regulator); +        status = init_hw(dev);        if (status) -               return status; +               goto out2;        clk_enable(dev->clk); @@ -575,7 +590,9 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,                if (unlikely(msgs[i].flags & I2C_M_TEN)) {                        dev_err(&dev->pdev->dev, "10 bit addressing"                                        "not supported\n"); -                       return -EINVAL; + +                       status = -EINVAL; +                       goto out;                }                dev->cli.slave_adr      = msgs[i].addr;                dev->cli.buffer         = msgs[i].buf; @@ -600,12 +617,19 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,                        dev_err(&dev->pdev->dev, "%s\n",                                cause >= ARRAY_SIZE(abort_causes)                                ? "unknown reason" : abort_causes[cause]); -                       clk_disable(dev->clk); -                       return status; + +                       goto out;                }                udelay(I2C_DELAY);        } + +out:        clk_disable(dev->clk); +out2: +       if (dev->regulator) +               regulator_disable(dev->regulator); + +       dev->busy = false;        /* return the no. messages processed */        if (status) @@ -805,6 +829,21 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)        return IRQ_HANDLED;  } + +#ifdef CONFIG_PM +static int nmk_i2c_suspend(struct platform_device *pdev, pm_message_t mesg) +{ +       struct nmk_i2c_dev *dev = platform_get_drvdata(pdev); + +       if (dev->busy) +               return -EBUSY; +       else +               return 0; +} +#else +#define nmk_i2c_suspend        NULL +#endif +  static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)  {        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; @@ -830,7 +869,7 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)                ret = -ENOMEM;                goto err_no_mem;        } - +       dev->busy = false;        dev->pdev = pdev;        platform_set_drvdata(pdev, dev);