* [PATCH 1/2] PM / OPP: Add support for 'boost' mode OPP
From: Nishanth Menon @ 2014-02-04 16:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJuA9aimVcxwKEQnSNpsEhZ7Rf-74+r8FOz09EpAZcoVEdi6GA@mail.gmail.com>
On 02/04/2014 09:59 AM, Thomas Abraham wrote:
> 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.
>
if we have
operating-points = < Fa Va
Fb Vb
Fc Vc
Fd Vd
>;
boost-frequencies = <Fc Fd>;
you can easily pick up the voltages from the table.
The point being - there does not seem to be a need to modify the
existing definitions to introduce new OPP definitions.
a way to flip this over is to consider iMX6(see
arch/arm/mach-imx/mach-imx6q.) where OPP tuple <Fd Vd> can only be
enabled *iff* efuse register x has bit y set.
Would we want to introduce efuse offsets into OPP definitions? into
something like additional field definition 'efuse_controlled'?
>>
>> 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].
The context of that discussion is to consider what is the data form we
consider OPP as? should we consider OPP as a data that is extensible
(as in phandle with properties that we add on) OR should we consider
key, value pair which provides a key (frequency) into another table
for other data (like efuse bit map, boost set etc..).
Both approaches I mentioned will work, and will take additional code
to make it happen. But having custom properties like this limits
extensibility - that is not scalable for other property definitions
we'd like to make in the future.
>
> 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
--
Regards,
Nishanth Menon
^ permalink raw reply
* [PATCH 1/2] arm64: atomics: fix use of acquire + release for full barrier semantics
From: Peter Zijlstra @ 2014-02-04 16:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391516953-14541-1-git-send-email-will.deacon@arm.com>
On Tue, Feb 04, 2014 at 12:29:12PM +0000, Will Deacon wrote:
> @@ -112,17 +114,20 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
> unsigned long tmp;
> int oldval;
>
> + smp_mb();
> +
> asm volatile("// atomic_cmpxchg\n"
> -"1: ldaxr %w1, %2\n"
> +"1: ldxr %w1, %2\n"
> " cmp %w1, %w3\n"
> " b.ne 2f\n"
> -" stlxr %w0, %w4, %2\n"
> +" stxr %w0, %w4, %2\n"
> " cbnz %w0, 1b\n"
> "2:"
> : "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter)
> : "Ir" (old), "r" (new)
> : "cc", "memory");
>
> + smp_mb();
> return oldval;
> }
>
Any particular reason atomic_cmpxchg() doesn't use the proposed rel + mb
scheme? It would be a waste to have atomic_cmpxchg() be more expensive
than it needs to be.
^ permalink raw reply
* [PATCH] arm64: Add architecture support for PCI
From: Catalin Marinas @ 2014-02-04 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3277167.UhkSU8Sf56@wuerfel>
On Tue, Feb 04, 2014 at 08:44:36AM +0000, Arnd Bergmann wrote:
> On Monday 03 February 2014 21:36:58 Liviu Dudau wrote:
> > On Mon, Feb 03, 2014 at 08:05:56PM +0000, Arnd Bergmann wrote:
> > > 2 MB was a compromise on arm32 to allow up to 32 PCI host bridges but not
> > > take up too much virtual space. On arm64 it should be at least as big.
> > > Could be more than that, although I don't see a reason why it should be,
> > > unless we expect to see systems with tons of host bridges, or buses
> > > that exceed 64KB of I/O space.
> >
> > I will increase the size to 2MB for v2.
>
> Thinking about this some more, I'd go a little higher. In case of
> pci_mv, we already register a 1MB region for one logical host
> (which has multiple I/O spaces behind an emulated bridge), so
> going to 16MB or more would let us handle multiple 1MB windows
> for some amount of future proofing.
>
> Maybe Catalin can assign us some virtual address space to use,
> with the constraints that it should be 16MB or more in an
> area that doesn't require additional kernel page table pages.
See below, 16MB and could be extended further if needed.
------------>8--------------------
>From 00521f109ac8a2589c9089a5feaaaa1be7f26108 Mon Sep 17 00:00:00 2001
From: Catalin Marinas <catalin.marinas@arm.com>
Date: Tue, 4 Feb 2014 16:37:59 +0000
Subject: [PATCH] arm64: Extend the PCI I/O space to 16MB
The patch moves the PCI I/O space (currently at 64K) before the
earlyprintk mapping and extends it to 16MB.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
Documentation/arm64/memory.txt | 16 ++++++++++------
arch/arm64/include/asm/io.h | 2 +-
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt
index 5e054bfe4dde..85e24c4f215c 100644
--- a/Documentation/arm64/memory.txt
+++ b/Documentation/arm64/memory.txt
@@ -35,11 +35,13 @@ ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
-ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
+ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space
+
+ffffffbffb000000 ffffffbffbbfffff 12MB [guard]
-ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
+ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
-ffffffbffbe10000 ffffffbcffffffff ~2MB [guard]
+ffffffbffbe00000 ffffffbffbffffff 2MB [guard]
ffffffbffc000000 ffffffbfffffffff 64MB modules
@@ -60,11 +62,13 @@ fffffdfc00000000 fffffdfdffffffff 8GB vmemmap
fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap]
-fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
+fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space
+
+fffffdfffb000000 fffffdfffbbfffff 12MB [guard]
-fffffdfffbe00000 fffffdfffbe0ffff 64KB PCI I/O space
+fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
-fffffdfffbe10000 fffffdfffbffffff ~2MB [guard]
+fffffdfffbe00000 fffffdfffbffffff 2MB [guard]
fffffdfffc000000 fffffdffffffffff 64MB modules
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 4cc813eddacb..7846a6bb0833 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -121,7 +121,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
* I/O port access primitives.
*/
#define IO_SPACE_LIMIT 0xffff
-#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
+#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M))
static inline u8 inb(unsigned long addr)
{
^ permalink raw reply related
* [RFC/RFT 1/2] ARM: mm: introduce arch hooks for dma address translation routines
From: Santosh Shilimkar @ 2014-02-04 16:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402041715.54538.arnd@arndb.de>
On Tuesday 04 February 2014 11:15 AM, Arnd Bergmann wrote:
> On Tuesday 04 February 2014, Santosh Shilimkar wrote:
>> Currently arch specific DMA address translation routines can be enabled
>> using only defines which makes impossible to use them in with
>> multi-platform builds.
>>
>> Hence, introduce arch specific hooks for DMA address translations
>> routines to be compatible with multi-platform builds:
>> dma_addr_t (*arch_pfn_to_dma)(struct device *dev, unsigned long pfn);
>> unsigned long (*arch_dma_to_pfn)(struct device *dev, dma_addr_t addr);
>> void* (*arch_dma_to_virt)(struct device *dev, dma_addr_t addr);
>> dma_addr_t (*arch_virt_to_dma)(struct device *dev, void *addr);
>>
>> In case if architecture won't use it - DMA address translation routines
>> will fall-back to existing implementation.
>> v
>> Also, modify machines omap1, ks8695, iop13xx to use new DMA hooks.
>
> I think this is going into a wrong direction. DMA translation is not
> at all a platform-specific thing, but rather bus specific. The most
> common scenario is that you have some 64-bit capable buses and some
> buses that are limited to 32-bit DMA (or less if you are unfortunate).
>
I may be wrong but you could have 64 bit bus but 32 bit DMA controllers.
That is one of the case I am dealing with.
> We also can't rely on {pfn,phys,virt}_to_{bus,dma} and the reverse
> to work anywhere outside of the dma_map_ops implementation, because
> of IOMMUs in-between.
>
> Of course we do need a proper solution for this problem, but we
> can't make it a per-platform decision, and whatever the solution is
> needs to take into account both nontrivial linear mappings (offset
> or cropped) and IOMMUs, and set the appropriate dma_map_ops for
> the device.
>
> I guess for the legacy cases (omap1, iop13xx, ks8695), we can
> hardcode dma_map_ops for all devices to get this right. For everything
> else, I'd suggest defaulting to the arm_dma_ops unless we get
> other information from DT. This means we have to create standardized
> properties to handle any combination of these:
>
Thats the case and the $subject series doesn't change that.
> 1. DMA is coherent
> 2. DMA space is offset from phys space
> 3. DMA space is smaller than 32-bit
> 4. DMA space is larger than 32-bit
> 5. DMA goes through an IOMMU
>
> The dma-ranges property can deal with 2-4. Highbank already introduced
> a "dma-coherent" flag for 1, and we can decide to generalize that.
> I don't know what the state of IOMMU support is, but we have to come
> up with something better than what we had on PowerPC, because we now
> have to deal with a combination of different IOMMUs in the same system,
> whereas the most complex case on PowerPC was some devices all going
> through one IOMMU and the other devices being linearly mapped.
>
Just to be clear, the patch set is not fiddling with dma_ops as such.
The dma_ops needs few accessors to convert addresses and these accessors
are different on few platforms. And hence needs to be patched.
We will try to look at "dma-ranges" to see if it can address my case.
Thanks for the pointer
Regards,
Santosh
^ permalink raw reply
* [ath9k-devel] [PATCH 1/3] ath9k: Fix build error on ARM
From: Joe Perches @ 2014-02-04 16:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOpc7mFQZ3efZda0cC28BLATqRDJ99BRNu=ezQq8wa+dyFyOvA@mail.gmail.com>
On Tue, 2014-02-04 at 08:03 +0100, Holger Schurig wrote:
> Joe, look in linux/arch/arm/include/asm/delay.h. The macro udelay
> cannot handle large values because of lost-of-precision.
>
> IMHO udelay on ARM is broken, because it also cannot work with fast
> ARM processors (where bogomips >= 3355, which is in sight now). It's
> just not broken enought that someone did something against it ... so
> the current kludge is good enought.
Maybe something like this would be better?
---
arch/arm/include/asm/delay.h | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index dff714d..ac33c56 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -15,6 +15,8 @@
#ifndef __ASSEMBLY__
+#include <linux/printk.h>
+
struct delay_timer {
unsigned long (*read_current_timer)(void);
unsigned long freq;
@@ -51,11 +53,34 @@ extern void __bad_udelay(void);
#define __udelay(n) arm_delay_ops.udelay(n)
#define __const_udelay(n) arm_delay_ops.const_udelay(n)
+#ifdef DEBUG
+#define __udelay_debug_max_delay(n) \
+do { \
+ if (n > MAX_UDELAY_MS * 1000) { \
+ pr_debug("udelay(%d) too large - Convert to mdelay\n", n); \
+ dump_stack(); \
+ } \
+} while (0)
+#else
+#define __udelay_debug_max_delay(n) \
+ do {} while (0)
+#endif
+
#define udelay(n) \
- (__builtin_constant_p(n) ? \
- ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
- __const_udelay((n) * UDELAY_MULT)) : \
- __udelay(n))
+({ \
+ if (__builtin_constant_p(n)) { \
+ typeof n _n = n; \
+ while (_n > MAX_UDELAY_MS * 1000) { \
+ __const_udelay(MAX_UDELAY_MS * 1000 * UDELAY_MULT); \
+ _n -= MAX_UDELAY_MS * 1000; \
+ } \
+ if (_n) \
+ __const_udelay(_n * 1000 * UDELAY_MULT); \
+ } else { \
+ __udelay_debug_max_delay(n); \
+ __udelay(n); \
+ } \
+})
/* Loop-based definitions for assembly code. */
extern void __loop_delay(unsigned long loops);
^ permalink raw reply related
* [PATCH v2 1/6] audit: Enable arm64 support
From: Richard Guy Briggs @ 2014-02-04 16:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140203160659.GA19292@madcap2.tricolour.ca>
On 14/02/03, Richard Guy Briggs wrote:
> On 14/02/03, AKASHI Takahiro wrote:
> > Richard,
>
> Takahiro,
Takahiro,
> > On 01/30/2014 07:36 AM, Richard Guy Briggs wrote:
> > >On 14/01/29, Richard Guy Briggs wrote:
> > >>On 14/01/27, AKASHI Takahiro wrote:
> > >>>[To audit maintainers]
> > >>>
> > >>>On 01/23/2014 11:18 PM, Catalin Marinas wrote:
> > >>>>On Fri, Jan 17, 2014 at 08:13:14AM +0000, AKASHI Takahiro wrote:
> > >>>>>--- a/include/uapi/linux/audit.h
> > >>>>>+++ b/include/uapi/linux/audit.h
> > >>>>>@@ -327,6 +327,8 @@ enum {
> > >>>>> /* distinguish syscall tables */
> > >>>>> #define __AUDIT_ARCH_64BIT 0x80000000
> > >>>>> #define __AUDIT_ARCH_LE 0x40000000
> > >>>>>+#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
> > >>>>>+#define AUDIT_ARCH_AARCH64EB (EM_AARCH64|__AUDIT_ARCH_64BIT)
> > >>>>> #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
> > >>>>> #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
> > >>>>> #define AUDIT_ARCH_ARMEB (EM_ARM)
> > >>>>>diff --git a/init/Kconfig b/init/Kconfig
> > >>>>>index 79383d3..3aae602 100644
> > >>>>>--- a/init/Kconfig
> > >>>>>+++ b/init/Kconfig
> > >>>>>@@ -284,7 +284,7 @@ config AUDIT
> > >>>>>
> > >>>>> config AUDITSYSCALL
> > >>>>> bool "Enable system-call auditing support"
> > >>>>>- depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
> > >>>>>+ depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT) || ARM64)
> > >>>>
> > >>>>The usual comment for such changes: could you please clean this up and
> > >>>>just use something like "depends on HAVE_ARCH_AUDITSYSCALL"?
> > >>>
> > >>>Do you agree to this change?
> > >>>
> > >>>If so, I can create a patch, but have some concerns:
> > >>>1) I can't verify it on other architectures than (arm &) arm64.
> > >>>2) Some architectures (microblaze, mips, openrisc) are not listed here, but
> > >>> their ptrace.c have a call to audit_syscall_entry/exit().
> > >>> (audit_syscall_entry/exit are null if !AUDITSYSCALL, though)
> > >>
> > >>I can try: ppc s390 x86_64 ppc64 i686 s390x
> > >
> > >These arches above all pass compile and basic tests with the following patches applied:
> > >
> > > audit: correct a type mismatch in audit_syscall_exit() pending (already upstream)
> > >
> > > audit: Modify a set of system calls in audit class definitions (already upstream)
> > >
> > > [PATCH v3] audit: Add generic compat syscall support
> > >
> > > [PATCH v2] audit: Enable arm64 support
> > > [PATCH v2] arm64: Add regs_return_value() in syscall.h
> > > [PATCH v2] arm64: Add audit support
> > > [PATCH v2] arm64: audit: Add 32-bit (compat) syscall support
> > > [PATCH v2] arm64: audit: Add makefile rule to create unistd_32.h for compat syscalls
> > > [PATCH v2] arm64: audit: Add audit hook in ptrace/syscall_trace
> >
> > I think that you missed Catalin's suggestion.
>
> I didn't miss his suggestions. I think they are a good way to go, but I
> wanted to make a test at referrable point in time to validate the work
> to that point and to avoid introducing errors by mis-interpreting ideas
> that were not yet fully-formed patches.
>
> > Please use the patch I will post after this message and try it again, please?
>
> I was certainly intending to do so.
I have tested the new sets from Catalin and you and everything passes ok.
> > Thanks,
> > -Takahiro AKASHI
> >
> > >>>So I'm afraid that the change might break someone's assumption.
> > >>>
> > >>>Thanks,
> > >>>-Takahiro AKASHI
> > >>
> > >>- RGB
> > >
> > >- RGB
>
> - RGB
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545
^ permalink raw reply
* [PATCH v4 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Thomas Gleixner @ 2014-02-04 16:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391513453-21140-2-git-send-email-ivan.khoronzhuk@ti.com>
On Tue, 4 Feb 2014, Ivan Khoronzhuk wrote:
> + keystone_timer_writel(off, TCR);
> + /* here we have to be sure the timer has been disabled */
> + wmb();
We have explicit writew_relaxed and writew. Why open coding the
barriers?
Thanks,
tglx
^ permalink raw reply
* [RFC/RFT 2/2] ARM: keystone: Install hooks for dma address translation routines
From: Olof Johansson @ 2014-02-04 16:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402041702.00039.arnd@arndb.de>
On Tue, Feb 4, 2014 at 8:01 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> 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.
Ah, that might very well be the case. And it looks like dma-ranges
handles this case already. At least based on the first draft proposal
for dma-ranges that I came across. :)
-Olof
^ permalink raw reply
* [PATCH] arm64: Add architecture support for PCI
From: Arnd Bergmann @ 2014-02-04 16:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPcvp5HN4pBysOdS5_ep_3Lp7GDDKw4YrgmKjYzBet7PtaOLUg@mail.gmail.com>
On Tuesday 04 February 2014, Andrew Murray wrote:
> On 4 February 2014 12:29, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > On Mon, Feb 03, 2014 at 10:34:40PM +0000, Andrew Murray wrote:
> >> On 3 February 2014 18:43, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >> > diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> >> > index 4cc813e..ce5bad2 100644
> >> > --- a/arch/arm64/include/asm/io.h
> >> > +++ b/arch/arm64/include/asm/io.h
> >> > @@ -120,9 +120,13 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
> >> > /*
> >> > * I/O port access primitives.
> >> > */
> >> > +#define arch_has_dev_port() (0)
> >> > #define IO_SPACE_LIMIT 0xffff
> >> > #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
> >> >
> >> > +#define ioport_map(port, nr) (PCI_IOBASE + ((port) & IO_SPACE_LIMIT))
> >> > +#define ioport_unmap(addr)
> >>
> >> I'm not sure that this will work. The in[bwl], out[bwl] macros in
> >> arch/arm64/include/asm/io.h already add the PCI_IOBASE offset.
> >>
> >> Instead of these two #defines, why not just enforce that
> >> GENERIC_PCI_IOMAP is enabled? Or at least wrap these defines with 'if
> >> (!config_enabled(CONFIG_GENERIC_PCI_IOMAP))' or similar.
> >
> > GENERIC_PCI_IOMAP is enabled for AArch64. We have select GENERIC_IOMAP in
> > arch/arm64/Kconfig which in turn selects GENERIC_PCI_IOMAP in lib/Kconfig.
>
> Sorry, it was intent to suggest using the ioport_[map|unmap] functions
> in lib/iomap.c instead of defining something similar here. I guess you
> will also need to also define CONFIG_HAS_IOPORT for this to happen.
We do want CONFIG_HAS_IOPORT, but I would say that we should not use
CONFIG_GENERIC_IOMAP. As I explained in another reply, enabling this
was probably a simple mistake, and we only need this if we want I/O
spaces that are /not/ memory mapped. IMHO any ARM64 system that doesn't
map its PCI I/O space into MMIO space can live without I/O port
access.
Arnd
^ permalink raw reply
* [RFC/RFT 1/2] ARM: mm: introduce arch hooks for dma address translation routines
From: Arnd Bergmann @ 2014-02-04 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391470107-15927-2-git-send-email-santosh.shilimkar@ti.com>
On Tuesday 04 February 2014, Santosh Shilimkar wrote:
> Currently arch specific DMA address translation routines can be enabled
> using only defines which makes impossible to use them in with
> multi-platform builds.
>
> Hence, introduce arch specific hooks for DMA address translations
> routines to be compatible with multi-platform builds:
> dma_addr_t (*arch_pfn_to_dma)(struct device *dev, unsigned long pfn);
> unsigned long (*arch_dma_to_pfn)(struct device *dev, dma_addr_t addr);
> void* (*arch_dma_to_virt)(struct device *dev, dma_addr_t addr);
> dma_addr_t (*arch_virt_to_dma)(struct device *dev, void *addr);
>
> In case if architecture won't use it - DMA address translation routines
> will fall-back to existing implementation.
> v
> Also, modify machines omap1, ks8695, iop13xx to use new DMA hooks.
I think this is going into a wrong direction. DMA translation is not
at all a platform-specific thing, but rather bus specific. The most
common scenario is that you have some 64-bit capable buses and some
buses that are limited to 32-bit DMA (or less if you are unfortunate).
We also can't rely on {pfn,phys,virt}_to_{bus,dma} and the reverse
to work anywhere outside of the dma_map_ops implementation, because
of IOMMUs in-between.
Of course we do need a proper solution for this problem, but we
can't make it a per-platform decision, and whatever the solution is
needs to take into account both nontrivial linear mappings (offset
or cropped) and IOMMUs, and set the appropriate dma_map_ops for
the device.
I guess for the legacy cases (omap1, iop13xx, ks8695), we can
hardcode dma_map_ops for all devices to get this right. For everything
else, I'd suggest defaulting to the arm_dma_ops unless we get
other information from DT. This means we have to create standardized
properties to handle any combination of these:
1. DMA is coherent
2. DMA space is offset from phys space
3. DMA space is smaller than 32-bit
4. DMA space is larger than 32-bit
5. DMA goes through an IOMMU
The dma-ranges property can deal with 2-4. Highbank already introduced
a "dma-coherent" flag for 1, and we can decide to generalize that.
I don't know what the state of IOMMU support is, but we have to come
up with something better than what we had on PowerPC, because we now
have to deal with a combination of different IOMMUs in the same system,
whereas the most complex case on PowerPC was some devices all going
through one IOMMU and the other devices being linearly mapped.
Arnd
^ permalink raw reply
* [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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox