Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V5 2/4] DRIVERS: IRQCHIP: CROSSBAR: Add support for Crossbar IP
From: Thomas Gleixner @ 2014-02-04 16:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52EF7D85.5070705@ti.com>

On Mon, 3 Feb 2014, Sricharan R wrote:
> > I already have your reviewed-by tag for the first patch in this series.
> > 
> > Kevin was pointing out that irqchip maintainer tag is needed for this patch as well
> > to be merged. We are planning to take this series through arm-soc tree.
> > 
> > Can i please have your tag for this patch as well ?

Acked-by-me

^ permalink raw reply

* [RFC/RFT 2/2] ARM: keystone: Install hooks for dma address translation routines
From: Arnd Bergmann @ 2014-02-04 16:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F0F979.2090505@ti.com>

On Tuesday 04 February 2014, Santosh Shilimkar wrote:
> > PPC servers use "ibm,dma-window" to describe the assigned dma address
> > space for busses/devices, but the window itself doesn't contain any
> > information about the physical address mapping (since it goes through
> > an iommu after that). It likely doesn't fit this particular use case,
> > but it's something we should look at as a base in case we need to
> > start looking at bindings for this instead of coding it per SoC. We'll
> > know more once we've seen what a few of the implementations out there
> > are.
> > 
> Understood.

I think you are looking for the "dma-ranges" property, which describes
how a device DMA address space maps into the parent bus address space
for inbound translations. It's not used much in Linux, but it is clearly
specified. The "ibm,dma-window" property OTOH is for the corner case
that you have a small per-partition DMA address space section, which is
not how things are done on most systems these days.

	Arnd

^ permalink raw reply

* [PATCH 1/2] PM / OPP: Add support for 'boost' mode OPP
From: Thomas Abraham @ 2014-02-04 15:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F10418.4040806@ti.com>

On Tue, Feb 4, 2014 at 8:45 PM, Nishanth Menon <nm@ti.com> wrote:
> On 02/04/2014 03:41 AM, Thomas Abraham wrote:
>> From: Thomas Abraham <thomas.ab@samsung.com>
>>
>> Commit 6f19efc0 ("cpufreq: Add boost frequency support in core") adds
>> support for CPU boost mode. This patch adds support for finding available
>> boost OPPs from device tree and marking them as usable in boost mode.
>>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: Lukasz Majewski <l.majewski@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>> ---
>
> Why is a cpufreq feature being pushed on to OPP library? you can very
> well have a property boot-frequencies = < a b c > and be done with the
> job.

The boost-opp was not limited to be a cpu/cpufreq only feature. Any
device (such as a bus) which has OPPs and if it can support optional
boost OPPs, can utilize this feature. The boost OPPs also require a
voltage to be associated with the frequency and hence the binding
boost-frequencies would not be suffice. The code changes in this patch
also do not have anything that is cpufreq specific.

>
> I agree with Rob's comment that this is something we have to discuss
> in wider "add features to an OPP" discussion[1].

Okay. I have read through the discussion in [1]. Thanks for the link.
Assuming that the current OPP tuple format will not change, I do not
feel the code changes in this patch will be hinder the outcome of the
discussion in [1].

Regards,
Thomas.

>
>
> [1] http://marc.info/?t=139108946400001&r=1&w=2
>
>>  drivers/base/power/opp.c |   69 +++++++++++++++++++++++++++++++++++++---------
>>  1 file changed, 56 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
>> index 2553867..de4d52d 100644
>> --- a/drivers/base/power/opp.c
>> +++ b/drivers/base/power/opp.c
>> @@ -62,6 +62,7 @@ struct dev_pm_opp {
>>       struct list_head node;
>>
>>       bool available;
>> +     bool boost;
>>       unsigned long rate;
>>       unsigned long u_volt;
>>
>> @@ -380,10 +381,12 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
>>  EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
>>
>>  /**
>> - * dev_pm_opp_add()  - Add an OPP table from a table definitions
>> + * dev_pm_opp_add_flags()  - Add an OPP to device OPP list with flags
>>   * @dev:     device for which we do this operation
>>   * @freq:    Frequency in Hz for this OPP
>>   * @u_volt:  Voltage in uVolts for this OPP
>> + * @available:       initial availability of the OPP with adding it to the list.
>> + * @boost:   availability of this opp in controller's boost operating mode.
>>   *
>>   * This function adds an opp definition to the opp list and returns status.
>>   * The opp is made available by default and it can be controlled using
>> @@ -395,7 +398,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
>>   * that this function is *NOT* called under RCU protection or in contexts where
>>   * mutex cannot be locked.
>>   */
>> -int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>> +static int dev_pm_opp_add_flags(struct device *dev, unsigned long freq,
>> +                     unsigned long u_volt, bool available, bool boost)
>>  {
>>       struct device_opp *dev_opp = NULL;
>>       struct dev_pm_opp *opp, *new_opp;
>> @@ -441,7 +445,8 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>>       new_opp->dev_opp = dev_opp;
>>       new_opp->rate = freq;
>>       new_opp->u_volt = u_volt;
>> -     new_opp->available = true;
>> +     new_opp->available = available;
>> +     new_opp->boost = boost;
>>
>>       /* Insert new OPP in order of increasing frequency */
>>       head = &dev_opp->opp_list;
>> @@ -462,6 +467,27 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>>       srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp);
>>       return 0;
>>  }
>> +
>> +/**
>> + * dev_pm_opp_add()  - Add an OPP table from a table definitions
>> + * @dev:     device for which we do this operation
>> + * @freq:    Frequency in Hz for this OPP
>> + * @u_volt:  Voltage in uVolts for this OPP
>> + *
>> + * This function adds an opp definition to the opp list and returns status.
>> + * The opp is made available by default and it can be controlled using
>> + * dev_pm_opp_enable/disable functions.
>> + *
>> + * Locking: The internal device_opp and opp structures are RCU protected.
>> + * Hence this function internally uses RCU updater strategy with mutex locks
>> + * to keep the integrity of the internal data structures. Callers should ensure
>> + * that this function is *NOT* called under RCU protection or in contexts where
>> + * mutex cannot be locked.
>> + */
>> +int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>> +{
>> +     return dev_pm_opp_add_flags(dev, freq, u_volt, true, false);
>> +}
>>  EXPORT_SYMBOL_GPL(dev_pm_opp_add);
>>
>>  /**
>> @@ -651,7 +677,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
>>
>>       list_for_each_entry(opp, &dev_opp->opp_list, node) {
>>               if (opp->available) {
>> -                     freq_table[i].driver_data = i;
>> +                     freq_table[i].driver_data =
>> +                             opp->boost ? CPUFREQ_BOOST_FREQ : i;
>>                       freq_table[i].frequency = opp->rate / 1000;
>>                       i++;
>>               }
>> @@ -701,19 +728,14 @@ struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev)
>>  }
>>
>>  #ifdef CONFIG_OF
>> -/**
>> - * of_init_opp_table() - Initialize opp table from device tree
>> - * @dev:     device pointer used to lookup device OPPs.
>> - *
>> - * Register the initial OPP table with the OPP library for given device.
>> - */
>> -int of_init_opp_table(struct device *dev)
>> +static int of_parse_opp_table(struct device *dev, const char *prop_name,
>> +                                     bool boost)
>>  {
>>       const struct property *prop;
>>       const __be32 *val;
>>       int nr;
>>
>> -     prop = of_find_property(dev->of_node, "operating-points", NULL);
>> +     prop = of_find_property(dev->of_node, prop_name, NULL);
>>       if (!prop)
>>               return -ENODEV;
>>       if (!prop->value)
>> @@ -734,7 +756,7 @@ int of_init_opp_table(struct device *dev)
>>               unsigned long freq = be32_to_cpup(val++) * 1000;
>>               unsigned long volt = be32_to_cpup(val++);
>>
>> -             if (dev_pm_opp_add(dev, freq, volt)) {
>> +             if (dev_pm_opp_add_flags(dev, freq, volt, true, boost)) {
>>                       dev_warn(dev, "%s: Failed to add OPP %ld\n",
>>                                __func__, freq);
>>                       continue;
>> @@ -744,5 +766,26 @@ int of_init_opp_table(struct device *dev)
>>
>>       return 0;
>>  }
>> +
>> +/**
>> + * of_init_opp_table() - Initialize opp table from device tree
>> + * @dev:     device pointer used to lookup device OPPs.
>> + *
>> + * Register the initial OPP table with the OPP library for given device.
>> + * Additional "boost" operating points of the controller, if any, are
>> + * specified with "boost-opp" property.
>> + */
>> +int of_init_opp_table(struct device *dev)
>> +{
>> +     int ret;
>> +
>> +     ret = of_parse_opp_table(dev, "operating-points", false);
>> +     if (!ret) {
>> +             ret = of_parse_opp_table(dev, "boost-opp", true);
>> +             if (ret == -ENODEV)
>> +                     ret = 0;
>> +     }
>> +     return ret;
>> +}
>>  EXPORT_SYMBOL_GPL(of_init_opp_table);
>>  #endif
>>
>
>
> --
> Regards,
> Nishanth Menon

^ permalink raw reply

* [PATCH 17/17] i2c: nomadik: Fixup system suspend
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

For !CONFIG_PM_RUNTIME, the device were never put back into active
state while resuming.

For CONFIG_PM_RUNTIME, we blindly trusted the device to be inactive
while we were about to handle it at suspend late, which is just too
optimistic.

Even if the driver uses pm_runtime_put_sync() after each tranfer to
return it's runtime PM resources, there are no guarantees this will
actually mean the device will inactivated. The reason is that the PM
core will prevent runtime suspend during system suspend, and thus when
a transfer occurs during the early phases of system suspend the device
will be kept active after the transfer.

To handle both issues above, we need to re-use the runtime PM callbacks
and check the runtime PM state of the device before proceeding with our
operations for system suspend.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |   29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 2004eea..e6dbe66 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -887,21 +887,36 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 #ifdef CONFIG_PM_SLEEP
 static int nmk_i2c_suspend_late(struct device *dev)
 {
-	struct amba_device *adev = to_amba_device(dev);
-	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+	if (!pm_runtime_status_suspended(dev)) {
+		int ret = 0;
+		if (dev->pm_domain && dev->pm_domain->ops.runtime_suspend)
+			ret = dev->pm_domain->ops.runtime_suspend(dev);
+		else
+			ret = dev->bus->pm->runtime_suspend(dev);
+		if (ret)
+			return ret;
+
+		pm_runtime_set_suspended(dev);
+	}
 
 	pinctrl_pm_select_sleep_state(dev);
-
 	return 0;
 }
 
 static int nmk_i2c_resume_early(struct device *dev)
 {
-	/* First go to the default state */
-	pinctrl_pm_select_default_state(dev);
-	/* Then let's idle the pins until the next transfer happens */
-	pinctrl_pm_select_idle_state(dev);
+	int ret = 0;
+
+	if (dev->pm_domain && dev->pm_domain->ops.runtime_resume)
+		ret = dev->pm_domain->ops.runtime_resume(dev);
+	else
+		ret = dev->bus->pm->runtime_resume(dev);
+	if (ret) {
+		dev_err(dev, "problem resuming\n");
+		return ret;
+	}
 
+	pm_runtime_set_active(dev);
 	return 0;
 }
 #endif
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 16/17] i2c: nomadik: Remove busy check for transfers at suspend late
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

We should never be busy performing transfers at suspend late, thus
there are no reason to check for it.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |   10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index eda4f0d..2004eea 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -179,7 +179,6 @@ 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 i2c_vendor_data		*vendor;
@@ -193,7 +192,6 @@ struct nmk_i2c_dev {
 	int				stop;
 	struct completion		xfer_complete;
 	int				result;
-	bool				busy;
 };
 
 /* controller's abort causes */
@@ -679,8 +677,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 	struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
 	int j;
 
-	dev->busy = true;
-
 	pm_runtime_get_sync(&dev->adev->dev);
 
 	/* Attempt three times to send the message queue */
@@ -705,8 +701,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
 	pm_runtime_put_sync(&dev->adev->dev);
 
-	dev->busy = false;
-
 	/* return the no. messages processed */
 	if (status)
 		return status;
@@ -896,9 +890,6 @@ static int nmk_i2c_suspend_late(struct device *dev)
 	struct amba_device *adev = to_amba_device(dev);
 	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
 
-	if (nmk_i2c->busy)
-		return -EBUSY;
-
 	pinctrl_pm_select_sleep_state(dev);
 
 	return 0;
@@ -1019,7 +1010,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 		goto err_no_mem;
 	}
 	dev->vendor = vendor;
-	dev->busy = false;
 	dev->adev = adev;
 	amba_set_drvdata(adev, dev);
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 15/17] i2c: nomadik: Convert to late and early system PM callbacks
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

At system suspend_late, runtime PM has been disabled by the PM core
which means we can safely operate on these resources. Consequentially
we no longer have to wait until the noirq phase of the system suspend.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |   18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 2d7dbc9..eda4f0d 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -890,9 +890,8 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-
-#ifdef CONFIG_PM
-static int nmk_i2c_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int nmk_i2c_suspend_late(struct device *dev)
 {
 	struct amba_device *adev = to_amba_device(dev);
 	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
@@ -905,7 +904,7 @@ static int nmk_i2c_suspend(struct device *dev)
 	return 0;
 }
 
-static int nmk_i2c_resume(struct device *dev)
+static int nmk_i2c_resume_early(struct device *dev)
 {
 	/* First go to the default state */
 	pinctrl_pm_select_default_state(dev);
@@ -914,9 +913,6 @@ static int nmk_i2c_resume(struct device *dev)
 
 	return 0;
 }
-#else
-#define nmk_i2c_suspend	NULL
-#define nmk_i2c_resume	NULL
 #endif
 
 #if CONFIG_PM
@@ -942,14 +938,8 @@ static int nmk_i2c_runtime_resume(struct device *dev)
 }
 #endif
 
-/*
- * We use noirq so that we suspend late and resume before the wakeup interrupt
- * to ensure that we do the !pm_runtime_suspended() check in resume before
- * there has been a regular pm runtime resume (via pm_runtime_get_sync()).
- */
 static const struct dev_pm_ops nmk_i2c_pm = {
-	.suspend_noirq	= nmk_i2c_suspend,
-	.resume_noirq	= nmk_i2c_resume,
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(nmk_i2c_suspend_late, nmk_i2c_resume_early)
 	SET_PM_RUNTIME_PM_OPS(nmk_i2c_runtime_suspend,
 			nmk_i2c_runtime_resume,
 			NULL)
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 14/17] i2c: nomadik: Fixup deployment of runtime PM
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Since the device is active while a successful probe has been completed,
the reference counting for the clock will be screwed up and never reach
zero.

The issue is resolved by implementing runtime PM callbacks and let them
handle the resources accordingly, including the clock.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |   47 ++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 0caa8ea..2d7dbc9 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -674,7 +674,7 @@ static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
 static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 		struct i2c_msg msgs[], int num_msgs)
 {
-	int status;
+	int status = 0;
 	int i;
 	struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
 	int j;
@@ -683,19 +683,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
 	pm_runtime_get_sync(&dev->adev->dev);
 
-	status = clk_prepare_enable(dev->clk);
-	if (status) {
-		dev_err(&dev->adev->dev, "can't prepare_enable clock\n");
-		goto out_clk;
-	}
-
-	/* Optionaly enable pins to be muxed in and configured */
-	pinctrl_pm_select_default_state(&dev->adev->dev);
-
-	status = init_hw(dev);
-	if (status)
-		goto out;
-
 	/* Attempt three times to send the message queue */
 	for (j = 0; j < 3; j++) {
 		/* setup the i2c controller */
@@ -716,12 +703,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 			break;
 	}
 
-out:
-	clk_disable_unprepare(dev->clk);
-out_clk:
-	/* Optionally let pins go into idle state */
-	pinctrl_pm_select_idle_state(&dev->adev->dev);
-
 	pm_runtime_put_sync(&dev->adev->dev);
 
 	dev->busy = false;
@@ -938,6 +919,29 @@ static int nmk_i2c_resume(struct device *dev)
 #define nmk_i2c_resume	NULL
 #endif
 
+#if CONFIG_PM
+static int nmk_i2c_runtime_suspend(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+
+	clk_disable_unprepare(nmk_i2c->clk);
+	pinctrl_pm_select_idle_state(dev);
+	return 0;
+}
+
+static int nmk_i2c_runtime_resume(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+
+	clk_prepare_enable(nmk_i2c->clk);
+	pinctrl_pm_select_default_state(dev);
+	init_hw(nmk_i2c);
+	return 0;
+}
+#endif
+
 /*
  * We use noirq so that we suspend late and resume before the wakeup interrupt
  * to ensure that we do the !pm_runtime_suspended() check in resume before
@@ -946,6 +950,9 @@ static int nmk_i2c_resume(struct device *dev)
 static const struct dev_pm_ops nmk_i2c_pm = {
 	.suspend_noirq	= nmk_i2c_suspend,
 	.resume_noirq	= nmk_i2c_resume,
+	SET_PM_RUNTIME_PM_OPS(nmk_i2c_runtime_suspend,
+			nmk_i2c_runtime_resume,
+			NULL)
 };
 
 static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 13/17] i2c: nomadik: Leave probe with the device in active state
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Since the runtime PM state is expected to be active according to the
amba bus, we must align our behaviour while probing to it.

Moreover, this is needed to be able to have the driver fully functional
without depending on CONFIG_RUNTIME_PM.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 42c9e51..0caa8ea 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -1026,11 +1026,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 	dev->adev = adev;
 	amba_set_drvdata(adev, dev);
 
-	/* Select default pin state */
-	pinctrl_pm_select_default_state(&adev->dev);
-	/* If possible, let's go to idle until the first transfer */
-	pinctrl_pm_select_idle_state(&adev->dev);
-
 	dev->virtbase = devm_ioremap(&adev->dev, adev->res.start,
 				resource_size(&adev->res));
 	if (!dev->virtbase) {
@@ -1055,6 +1050,14 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 		goto err_no_mem;
 	}
 
+	ret = clk_prepare_enable(dev->clk);
+	if (ret) {
+		dev_err(&adev->dev, "can't prepare_enable clock\n");
+		goto err_no_mem;
+	}
+
+	init_hw(dev);
+
 	adap = &dev->adap;
 	adap->dev.of_node = np;
 	adap->dev.parent = &adev->dev;
@@ -1080,13 +1083,15 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 	ret = i2c_add_adapter(adap);
 	if (ret) {
 		dev_err(&adev->dev, "failed to add adapter\n");
-		goto err_no_mem;
+		goto err_no_adap;
 	}
 
 	pm_runtime_put(&adev->dev);
 
 	return 0;
 
+ err_no_adap:
+	clk_disable_unprepare(dev->clk);
  err_no_mem:
 
 	return ret;
@@ -1103,6 +1108,7 @@ static int nmk_i2c_remove(struct amba_device *adev)
 	clear_all_interrupts(dev);
 	/* disable the controller */
 	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+	clk_disable_unprepare(dev->clk);
 	if (res)
 		release_mem_region(res->start, resource_size(res));
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 12/17] i2c: nomadik: Remove redundant call to pm_runtime_disable
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

The amba bus are responsible for pm_runtime_enable|disable, remove the
redundant pm_runtime_disable at driver removal.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 840bcf9..42c9e51 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -1105,7 +1105,6 @@ static int nmk_i2c_remove(struct amba_device *adev)
 	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
 	if (res)
 		release_mem_region(res->start, resource_size(res));
-	pm_runtime_disable(&adev->dev);
 
 	return 0;
 }
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 11/17] i2c: nomadik: Convert to devm functions
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Use devm_* functions to simplify code and error handling.

Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/busses/i2c-nomadik.c |   29 +++++++++--------------------
 1 file changed, 9 insertions(+), 20 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 4443613..840bcf9 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -1015,7 +1015,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 		pdata->rft = max_fifo_threshold;
 	}
 
-	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
+	dev = devm_kzalloc(&adev->dev, sizeof(struct nmk_i2c_dev), GFP_KERNEL);
 	if (!dev) {
 		dev_err(&adev->dev, "cannot allocate memory\n");
 		ret = -ENOMEM;
@@ -1031,27 +1031,28 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 	/* If possible, let's go to idle until the first transfer */
 	pinctrl_pm_select_idle_state(&adev->dev);
 
-	dev->virtbase = ioremap(adev->res.start, resource_size(&adev->res));
+	dev->virtbase = devm_ioremap(&adev->dev, adev->res.start,
+				resource_size(&adev->res));
 	if (!dev->virtbase) {
 		ret = -ENOMEM;
-		goto err_no_ioremap;
+		goto err_no_mem;
 	}
 
 	dev->irq = adev->irq[0];
-	ret = request_irq(dev->irq, i2c_irq_handler, 0,
+	ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0,
 				DRIVER_NAME, dev);
 	if (ret) {
 		dev_err(&adev->dev, "cannot claim the irq %d\n", dev->irq);
-		goto err_irq;
+		goto err_no_mem;
 	}
 
 	pm_suspend_ignore_children(&adev->dev, true);
 
-	dev->clk = clk_get(&adev->dev, NULL);
+	dev->clk = devm_clk_get(&adev->dev, NULL);
 	if (IS_ERR(dev->clk)) {
 		dev_err(&adev->dev, "could not get i2c clock\n");
 		ret = PTR_ERR(dev->clk);
-		goto err_no_clk;
+		goto err_no_mem;
 	}
 
 	adap = &dev->adap;
@@ -1079,21 +1080,13 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 	ret = i2c_add_adapter(adap);
 	if (ret) {
 		dev_err(&adev->dev, "failed to add adapter\n");
-		goto err_add_adap;
+		goto err_no_mem;
 	}
 
 	pm_runtime_put(&adev->dev);
 
 	return 0;
 
- err_add_adap:
-	clk_put(dev->clk);
- err_no_clk:
-	free_irq(dev->irq, dev);
- err_irq:
-	iounmap(dev->virtbase);
- err_no_ioremap:
-	kfree(dev);
  err_no_mem:
 
 	return ret;
@@ -1110,13 +1103,9 @@ static int nmk_i2c_remove(struct amba_device *adev)
 	clear_all_interrupts(dev);
 	/* disable the controller */
 	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
-	free_irq(dev->irq, dev);
-	iounmap(dev->virtbase);
 	if (res)
 		release_mem_region(res->start, resource_size(res));
-	clk_put(dev->clk);
 	pm_runtime_disable(&adev->dev);
-	kfree(dev);
 
 	return 0;
 }
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 10/17] spi: pl022: Remove redundant pinctrl to default state in probe
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

The driver core is now taking care of putting our pins into default
state at probe. Thus we can remove the redundant call for it in probe.

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi-pl022.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2f44c81..3ddd8da 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2109,8 +2109,6 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 	pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
 					  GFP_KERNEL);
 
-	pinctrl_pm_select_default_state(dev);
-
 	/*
 	 * Bus Number Which has been Assigned to this SSP controller
 	 * on this board
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 09/17] spi: pl022: Simplify clock handling
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Make use of clk_prepare_enable and clk_disable_unprepare to simplify
code. No functional change.

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi-pl022.c |   15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2bb238f..2f44c81 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2183,13 +2183,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 		goto err_no_clk;
 	}
 
-	status = clk_prepare(pl022->clk);
-	if (status) {
-		dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
-		goto  err_clk_prep;
-	}
-
-	status = clk_enable(pl022->clk);
+	status = clk_prepare_enable(pl022->clk);
 	if (status) {
 		dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
 		goto err_no_clk_en;
@@ -2250,10 +2244,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 	if (platform_info->enable_dma)
 		pl022_dma_remove(pl022);
  err_no_irq:
-	clk_disable(pl022->clk);
+	clk_disable_unprepare(pl022->clk);
  err_no_clk_en:
-	clk_unprepare(pl022->clk);
- err_clk_prep:
  err_no_clk:
  err_no_ioremap:
 	amba_release_regions(adev);
@@ -2281,8 +2273,7 @@ pl022_remove(struct amba_device *adev)
 	if (pl022->master_info->enable_dma)
 		pl022_dma_remove(pl022);
 
-	clk_disable(pl022->clk);
-	clk_unprepare(pl022->clk);
+	clk_disable_unprepare(pl022->clk);
 	amba_release_regions(adev);
 	tasklet_disable(&pl022->pump_transfers);
 	return 0;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 08/17] spi: pl022: Fully gate clocks at request inactivity
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Use clk_disable_unprepare and clk_prepare_enable from the runtime PM
callbacks, to fully gate|ungate clocks. Potentially this will save more
power, depending on the clock tree for the current SOC.

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi-pl022.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index db829a1..2bb238f 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2355,7 +2355,7 @@ static int pl022_runtime_suspend(struct device *dev)
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 
-	clk_disable(pl022->clk);
+	clk_disable_unprepare(pl022->clk);
 	pinctrl_pm_select_idle_state(dev);
 
 	return 0;
@@ -2366,7 +2366,7 @@ static int pl022_runtime_resume(struct device *dev)
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 
 	pinctrl_pm_select_default_state(dev);
-	clk_enable(pl022->clk);
+	clk_prepare_enable(pl022->clk);
 
 	return 0;
 }
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 07/17] spi: pl022: Don't ignore power domain and amba bus at system suspend
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Due to the available runtime PM callbacks for CONFIG_PM, we are now
able to put the device into complete low power state at system suspend.

Previously only the resources controlled by the driver were put into
low power state at system suspend. Both the amba bus and a potential
power domain were ignored, which now isn't the case any more.

Moreover, putting the device into low power state couldn't be done
without first bringing it back to full power. This constraint don't
exists any more.

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi-pl022.c |   74 +++++++++++++++++++++++------------------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 70fa907..db829a1 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2288,35 +2288,7 @@ pl022_remove(struct amba_device *adev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * These two functions are used from both suspend/resume and
- * the runtime counterparts to handle external resources like
- * clocks, pins and regulators when going to sleep.
- */
-static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
-{
-	clk_disable(pl022->clk);
-
-	if (runtime)
-		pinctrl_pm_select_idle_state(&pl022->adev->dev);
-	else
-		pinctrl_pm_select_sleep_state(&pl022->adev->dev);
-}
-
-static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
-{
-	/* First go to the default state */
-	pinctrl_pm_select_default_state(&pl022->adev->dev);
-	if (!runtime)
-		/* Then let's idle the pins until the next transfer happens */
-		pinctrl_pm_select_idle_state(&pl022->adev->dev);
-
-	clk_enable(pl022->clk);
-}
-#endif
-
-#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_PM_SLEEP
 static int pl022_suspend(struct device *dev)
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2328,8 +2300,23 @@ static int pl022_suspend(struct device *dev)
 		return ret;
 	}
 
-	pm_runtime_get_sync(dev);
-	pl022_suspend_resources(pl022, false);
+	pm_runtime_disable(dev);
+
+	if (!pm_runtime_status_suspended(dev)) {
+		if (dev->pm_domain && dev->pm_domain->ops.runtime_suspend)
+			ret = dev->pm_domain->ops.runtime_suspend(dev);
+		else
+			ret = dev->bus->pm->runtime_suspend(dev);
+
+		if (ret) {
+			pm_runtime_enable(dev);
+			return ret;
+		}
+
+		pm_runtime_set_suspended(dev);
+	}
+
+	pinctrl_pm_select_sleep_state(dev);
 
 	dev_dbg(dev, "suspended\n");
 	return 0;
@@ -2338,10 +2325,19 @@ static int pl022_suspend(struct device *dev)
 static int pl022_resume(struct device *dev)
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
-	int ret;
+	int ret = 0;
 
-	pl022_resume_resources(pl022, false);
-	pm_runtime_put(dev);
+	if (dev->pm_domain && dev->pm_domain->ops.runtime_resume)
+		ret = dev->pm_domain->ops.runtime_resume(dev);
+	else
+		ret = dev->bus->pm->runtime_resume(dev);
+
+	if (ret)
+		dev_err(dev, "problem resuming\n");
+	else
+		pm_runtime_set_active(dev);
+
+	pm_runtime_enable(dev);
 
 	/* Start the queue running */
 	ret = spi_master_resume(pl022->master);
@@ -2352,14 +2348,16 @@ static int pl022_resume(struct device *dev)
 
 	return ret;
 }
-#endif	/* CONFIG_PM */
+#endif
 
 #ifdef CONFIG_PM
 static int pl022_runtime_suspend(struct device *dev)
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 
-	pl022_suspend_resources(pl022, true);
+	clk_disable(pl022->clk);
+	pinctrl_pm_select_idle_state(dev);
+
 	return 0;
 }
 
@@ -2367,7 +2365,9 @@ static int pl022_runtime_resume(struct device *dev)
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 
-	pl022_resume_resources(pl022, true);
+	pinctrl_pm_select_default_state(dev);
+	clk_enable(pl022->clk);
+
 	return 0;
 }
 #endif
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 06/17] spi: pl022: Let runtime PM callbacks be available for CONFIG_PM
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Convert to the SET_PM_RUNTIME_PM macro while defining the runtime PM
callbacks. This means the callbacks becomes available for both
CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME, which is needed to handle the
combinations of these scenarios.

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi-pl022.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2789b45..70fa907 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2288,7 +2288,7 @@ pl022_remove(struct amba_device *adev)
 	return 0;
 }
 
-#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME)
+#ifdef CONFIG_PM
 /*
  * These two functions are used from both suspend/resume and
  * the runtime counterparts to handle external resources like
@@ -2354,7 +2354,7 @@ static int pl022_resume(struct device *dev)
 }
 #endif	/* CONFIG_PM */
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static int pl022_runtime_suspend(struct device *dev)
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2374,7 +2374,7 @@ static int pl022_runtime_resume(struct device *dev)
 
 static const struct dev_pm_ops pl022_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
-	SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
+	SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
 };
 
 static struct vendor_data vendor_arm = {
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 05/17] mmc: mmci: Put the device into low power state at system suspend
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Due to the available runtime PM callbacks, we are now able to put our
device into low power state at system suspend.

Earlier we could not accomplish this without trusting a power domain
for the device to take care of it. Now we are able to cope with
scenarios both with and without a power domain.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/host/mmci.c |   45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index c88da1c..074e0cb 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1723,33 +1723,38 @@ static int mmci_remove(struct amba_device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_SUSPEND
-static int mmci_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int mmci_suspend_late(struct device *dev)
 {
-	struct amba_device *adev = to_amba_device(dev);
-	struct mmc_host *mmc = amba_get_drvdata(adev);
+	int ret = 0;
 
-	if (mmc) {
-		struct mmci_host *host = mmc_priv(mmc);
-		pm_runtime_get_sync(dev);
-		writel(0, host->base + MMCIMASK0);
-	}
+	if (pm_runtime_status_suspended(dev))
+		return 0;
 
-	return 0;
+	if (dev->pm_domain && dev->pm_domain->ops.runtime_suspend)
+		ret = dev->pm_domain->ops.runtime_suspend(dev);
+	else
+		ret = dev->bus->pm->runtime_suspend(dev);
+
+	if (!ret)
+		pm_runtime_set_suspended(dev);
+
+	return ret;
 }
 
-static int mmci_resume(struct device *dev)
+static int mmci_resume_early(struct device *dev)
 {
-	struct amba_device *adev = to_amba_device(dev);
-	struct mmc_host *mmc = amba_get_drvdata(adev);
+	int ret = 0;
 
-	if (mmc) {
-		struct mmci_host *host = mmc_priv(mmc);
-		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
-		pm_runtime_put(dev);
-	}
+	if (pm_runtime_status_suspended(dev))
+		return 0;
 
-	return 0;
+	if (dev->pm_domain && dev->pm_domain->ops.runtime_resume)
+		ret = dev->pm_domain->ops.runtime_resume(dev);
+	else
+		ret = dev->bus->pm->runtime_resume(dev);
+
+	return ret;
 }
 #endif
 
@@ -1820,7 +1825,7 @@ static int mmci_runtime_resume(struct device *dev)
 #endif
 
 static const struct dev_pm_ops mmci_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(mmci_suspend_late, mmci_resume_early)
 	SET_PM_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
 };
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 04/17] mmc: mmci: Let runtime PM callbacks be available for CONFIG_PM
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Convert to the SET_PM_RUNTIME_PM macro while defining the runtime PM
callbacks. This means the callbacks becomes available for both
CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME, which is needed to handle the
combinations of these scenarios.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/host/mmci.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 178868a..c88da1c 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1753,7 +1753,7 @@ static int mmci_resume(struct device *dev)
 }
 #endif
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static void mmci_save(struct mmci_host *host)
 {
 	unsigned long flags;
@@ -1821,7 +1821,7 @@ static int mmci_runtime_resume(struct device *dev)
 
 static const struct dev_pm_ops mmci_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
-	SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
+	SET_PM_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
 };
 
 static struct amba_id mmci_ids[] = {
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 03/17] mmc: mmci: Mask IRQs for all variants during runtime suspend
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

In runtime suspended state, we are not expecting IRQs and thus we can
safely mask them, not only for pwrreg_nopower variants but for all.

Obviously we then also need to make sure we restore the IRQ mask while
becoming runtime resumed.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/host/mmci.c |   23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index b931226..178868a 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1758,35 +1758,34 @@ static void mmci_save(struct mmci_host *host)
 {
 	unsigned long flags;
 
-	if (host->variant->pwrreg_nopower) {
-		spin_lock_irqsave(&host->lock, flags);
+	spin_lock_irqsave(&host->lock, flags);
 
-		writel(0, host->base + MMCIMASK0);
+	writel(0, host->base + MMCIMASK0);
+	if (host->variant->pwrreg_nopower) {
 		writel(0, host->base + MMCIDATACTRL);
 		writel(0, host->base + MMCIPOWER);
 		writel(0, host->base + MMCICLOCK);
-		mmci_reg_delay(host);
-
-		spin_unlock_irqrestore(&host->lock, flags);
 	}
+	mmci_reg_delay(host);
 
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static void mmci_restore(struct mmci_host *host)
 {
 	unsigned long flags;
 
-	if (host->variant->pwrreg_nopower) {
-		spin_lock_irqsave(&host->lock, flags);
+	spin_lock_irqsave(&host->lock, flags);
 
+	if (host->variant->pwrreg_nopower) {
 		writel(host->clk_reg, host->base + MMCICLOCK);
 		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
 		writel(host->pwr_reg, host->base + MMCIPOWER);
-		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
-		mmci_reg_delay(host);
-
-		spin_unlock_irqrestore(&host->lock, flags);
 	}
+	writel(MCI_IRQENABLE, host->base + MMCIMASK0);
+	mmci_reg_delay(host);
+
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static int mmci_runtime_suspend(struct device *dev)
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 02/17] amba: Add late and early PM callbacks
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

To give provision for amba drivers to make use of the late|early PM
callbacks, we point the amba bus PM callbacks to the generic versions
of these.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/amba/bus.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 3cf61a1..c255d62 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -123,6 +123,12 @@ static const struct dev_pm_ops amba_pm = {
 	.thaw		= pm_generic_thaw,
 	.poweroff	= pm_generic_poweroff,
 	.restore	= pm_generic_restore,
+	.suspend_late	= pm_generic_suspend_late,
+	.resume_early	= pm_generic_resume_early,
+	.freeze_late	= pm_generic_freeze_late,
+	.thaw_early	= pm_generic_thaw_early,
+	.poweroff_late	= pm_generic_poweroff_late,
+	.restore_early	= pm_generic_restore_early,
 	SET_PM_RUNTIME_PM_OPS(
 		amba_pm_runtime_suspend,
 		amba_pm_runtime_resume,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 01/17] amba: Let runtime PM callbacks be available for CONFIG_PM
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391529538-21685-1-git-send-email-ulf.hansson@linaro.org>

Convert to the SET_PM_RUNTIME_PM macro while defining the runtime PM
callbacks. This means the callbacks becomes available for both
CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME, which is needed by drivers and
power domains.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/amba/bus.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 9e60291..3cf61a1 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -83,7 +83,7 @@ static struct device_attribute amba_dev_attrs[] = {
 	__ATTR_NULL,
 };
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
  * enable/disable the bus clock at runtime PM suspend/resume as this
@@ -123,7 +123,7 @@ static const struct dev_pm_ops amba_pm = {
 	.thaw		= pm_generic_thaw,
 	.poweroff	= pm_generic_poweroff,
 	.restore	= pm_generic_restore,
-	SET_RUNTIME_PM_OPS(
+	SET_PM_RUNTIME_PM_OPS(
 		amba_pm_runtime_suspend,
 		amba_pm_runtime_resume,
 		NULL
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 00/17] amba: PM fixups for amba bus and some amba drivers
From: Ulf Hansson @ 2014-02-04 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset fixes the PM problems you yet when combining CONFIG_PM_SLEEP and
CONFIG_PM_RUNTIME. In principle these drivers did not manage to put it's devices
into low power state at system suspend, which then this patchset intend to fix.

Both the drivers and the amba bus converts to the new SET_PM_RUNTIME_PM_OPS
macro while setting up the runtime PM callbacks, which is intended to be used
for solving these kind of issues.

The fixes for the amba bus needs to be merged prior to the other, thus I think
it could make sense to merge this complete patchset through Russell's tree,
if he and the other maintainers think this is okay.

Ulf Hansson (17):
  amba: Let runtime PM callbacks be available for CONFIG_PM
  amba: Add late and early PM callbacks
  mmc: mmci: Mask IRQs for all variants during runtime suspend
  mmc: mmci: Let runtime PM callbacks be available for CONFIG_PM
  mmc: mmci: Put the device into low power state at system suspend
  spi: pl022: Let runtime PM callbacks be available for CONFIG_PM
  spi: pl022: Don't ignore power domain and amba bus at system suspend
  spi: pl022: Fully gate clocks at request inactivity
  spi: pl022: Simplify clock handling
  spi: pl022: Remove redundant pinctrl to default state in probe
  i2c: nomadik: Convert to devm functions
  i2c: nomadik: Remove redundant call to pm_runtime_disable
  i2c: nomadik: Leave probe with the device in active state
  i2c: nomadik: Fixup deployment of runtime PM
  i2c: nomadik: Convert to late and early system PM callbacks
  i2c: nomadik: Remove busy check for transfers at suspend late
  i2c: nomadik: Fixup system suspend

 drivers/amba/bus.c               |   10 ++-
 drivers/i2c/busses/i2c-nomadik.c |  146 ++++++++++++++++++--------------------
 drivers/mmc/host/mmci.c          |   72 ++++++++++---------
 drivers/spi/spi-pl022.c          |   95 +++++++++++--------------
 4 files changed, 159 insertions(+), 164 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH] pci: Add support for creating a generic host_bridge from device tree
From: Arnd Bergmann @ 2014-02-04 15:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140204120801.GB27975@e106497-lin.cambridge.arm.com>

On Tuesday 04 February 2014, Liviu Dudau wrote:
> On Tue, Feb 04, 2014 at 10:09:44AM +0000, Arnd Bergmann wrote:
> > On Monday 03 February 2014 22:17:44 Liviu Dudau wrote:
> > > On Mon, Feb 03, 2014 at 07:31:31PM +0000, Arnd Bergmann wrote:
> > > > The aperture here reflects the subset of the
> > > > 4GB bus I/O space that is actually mapped into a CPU visible "physical
> > > > I/O aperture" using an inbound mapping of the host bridge. The physical
> > > > I/O aperture in turn gets mapped to the virtual I/O space using
> > > > pci_ioremap_io.
> > >
> > > Agree.
> > >
> > > > The difference between a bus I/O address and a logical
> > > > I/O address is stored in the io_offset.
> > >
> > > Not exactly. If that would be true that means that for an I/O range that
> > > start at bus I/O address zero but physical I/O apperture starts at
> > > 0x40000000 the io_offset is zero. For me, the io_offset should be 0x40000000.
> >
> > That's not how we do it on any of the existing host controllers.
> > Typically the io_offset is zero for the first one, and may be
> > either zero for all the others (meaning BARs get > 64KB values
> > for secondary buses) or between 64KB and 2MB (meaning each bus
> > starts at I/O port number 0).
> 
> In that case it is probably worth to rename my variable into phys_io_offset.
> 
> I need to go back over my driver code. My assumptions were probably wrong
> wrt to meaning of the io_offset.

Ok. I'd still call it 'base' rather than 'offset', although the meaning
isn't all that different.

> > But there should never be an IORESOURCE_IO resource structure that is
> > not in IO space, i.e. within ioport_resource. Doing an "adjustment"
> > is not an operation defined on this structure. What I meant above is that
> > the pci range parser gets this right and gives you a resource that looks
> > like { .flags = IORESOURCE_MEM, .start = phys_base, .end = phys_base +
> > size - 1}, while the resource we want to register is { .flags = IORESOURCE_IO,
> > .start = log_base, .end = log_base + size -1}. In the of_pci_range struct for
> > the I/O space, the "pci_space" is IORESOURCE_IO (for the pci_addr), while the
> > "flags" are IORESOURCE_MEM, to go along with the cpu_addr.
> 
> The pci range parser gives me a range with .flags = IORESOURCE_IO for IO space. It
> does not convert it to IORESOURCE_MEM. Hence the need for adjustment.

Ah, I see that now in the code too. This seems to be a bug in the range parser
though: range->flags should not be initialized to
of_bus_pci_get_flags(parser->range).

	Arnd

^ permalink raw reply

* [PATCH v2 2/2] ARM: shmobile: Koelsch: pass Ether PHY IRQ
From: Sergei Shtylyov @ 2014-02-04 15:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201402041851.47198.sergei.shtylyov@cogentembedded.com>

Pass Ether's PHY IRQ (which is IRQC's IRQ0) to the 'sh_eth' driver. Set the IRQ
trigger type to be low-level as per the Micrel PHY driver's setup.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- refreshed the patch.

 arch/arm/mach-shmobile/board-koelsch.c |    4 ++++
 1 file changed, 4 insertions(+)

Index: renesas/arch/arm/mach-shmobile/board-koelsch.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-koelsch.c
+++ renesas/arch/arm/mach-shmobile/board-koelsch.c
@@ -23,6 +23,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/leds.h>
 #include <linux/phy.h>
@@ -92,6 +93,7 @@ static void __init koelsch_add_du_device
 /* Ether */
 static const struct sh_eth_plat_data ether_pdata __initconst = {
 	.phy			= 0x1,
+	.phy_irq		= irq_pin(0),
 	.edmac_endian		= EDMAC_LITTLE_ENDIAN,
 	.phy_interface		= PHY_INTERFACE_MODE_RMII,
 	.ether_link_active_low	= 1,
@@ -232,6 +234,8 @@ static void __init koelsch_init(void)
 {
 	koelsch_add_standard_devices();
 
+	irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
+
 	if (IS_ENABLED(CONFIG_PHYLIB))
 		phy_register_fixup_for_id("r8a7791-ether-ff:01",
 					  koelsch_ksz8041_fixup);

^ permalink raw reply

* [PATCH v2 1/2] ARM: shmobile: Lager: pass Ether PHY IRQ
From: Sergei Shtylyov @ 2014-02-04 15:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201402041851.47198.sergei.shtylyov@cogentembedded.com>

Pass Ether's PHY IRQ (which is IRQC's IRQ0) to the 'sh_eth' driver. Set the IRQ
trigger type to be low-level as per the Micrel PHY driver's setup.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- refreshed the patch.

 arch/arm/mach-shmobile/board-lager.c |    4 ++++
 1 file changed, 4 insertions(+)

Index: renesas/arch/arm/mach-shmobile/board-lager.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-lager.c
+++ renesas/arch/arm/mach-shmobile/board-lager.c
@@ -22,6 +22,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/leds.h>
 #include <linux/mmc/host.h>
@@ -233,6 +234,7 @@ static const struct resource mmcif1_reso
 /* Ether */
 static const struct sh_eth_plat_data ether_pdata __initconst = {
 	.phy			= 0x1,
+	.phy_irq		= irq_pin(0),
 	.edmac_endian		= EDMAC_LITTLE_ENDIAN,
 	.phy_interface		= PHY_INTERFACE_MODE_RMII,
 	.ether_link_active_low	= 1,
@@ -618,6 +620,8 @@ static void __init lager_init(void)
 {
 	lager_add_standard_devices();
 
+	irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
+
 	if (IS_ENABLED(CONFIG_PHYLIB))
 		phy_register_fixup_for_id("r8a7790-ether-ff:01",
 					  lager_ksz8041_fixup);

^ permalink raw reply

* [PATCH 0/2] Add Ether's PHY IRQ support for Lager/Koelsh boards
From: Sergei Shtylyov @ 2014-02-04 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
'renesas-devel-v3.14-rc1-20130204' tag. Here we add support for the Ether's PHY
IRQ to the R8A7790/Lager and R8A7791/Koelsch boards.

[1/2] ARM: shmobile: Lager: pass Ether PHY IRQ
[1/2] ARM: shmobile: Koelsch: pass Ether PHY IRQ

PS: Sorry for the previous mail, I've hit Ctrl-Enter unexpectedly.

WBR, Sergei

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox