Hi,
This patch adds support for PCI to AArch64. It is based on my v7 patch
that adds support for creating generic host bridge structure from
device tree. With that in place, I was able to boot a platform that
has PCIe host bridge support and use a PCIe network card.
I have dropped the RFC tag from the subject as I now have the ambitious goal
of trying to get it mainlined.
Changes from v6:
- Guard the pci_domain_nr() inline implementation with #ifdef CONFIG_PCI as
to avoid conflict with default empty version present in include/linux/pci.h.
Thanks to Jingoo Han for catching this.
Changes from v5:
- Removed pcibios_fixup_bridge_ranges() as the week default version is fine.
- Removed the ALIGN() call in pcibios_align_resource()
- Stopped exporting pcibios_align_resource()
Changes from v4:
- Fixed the pci_domain_nr() implementation for arm64. Now we use
find_pci_host_bride() to find the host bridge before we retrieve
the domain number.
Changes from v3:
- Added Acks accumulated so far ;)
- Still carrying Catalin's patch for moving the PCI_IO_BASE until it
lands in linux-next or mainline, in order to ease applying the series
Changes from v2:
- Implement an arch specific version of pci_register_io_range() and
pci_address_to_pio().
- Return 1 from pci_proc_domain().
Changes from v1:
- Added Catalin's patch for moving the PCI_IO_BASE location and extend
its size to 16MB
- Integrated Arnd's version of pci_ioremap_io that uses a bitmap for
keeping track of assigned IO space and returns an io_offset. At the
moment the code is added in arch/arm64 but it can be moved in drivers/pci.
- Added a fix for the generic ioport_map() function when !CONFIG_GENERIC_IOMAP
as suggested by Arnd.
v6 thread here: https://lkml.org/lkml/2014/3/5/41
v5 thread here: https://lkml.org/lkml/2014/3/4/307
v4 thread here: https://lkml.org/lkml/2014/3/3/298
v3 thread here: https://lkml.org/lkml/2014/2/28/211
v2 thread here: https://lkml.org/lkml/2014/2/27/255
v1 thread here: https://lkml.org/lkml/2014/2/3/389
The API used is different from the one used by ARM architecture. There is
no pci_common_init_dev() function and no hw_pci structure, as that is no
longer needed. Once the last signature is added to the legal agreement, I
will post the host bridge driver code that I am using. Meanwhile, here
is an example of what the probe function looks like, posted as an example:
static int myhostbridge_probe(struct platform_device *pdev)
{
int err;
struct device_node *dev;
struct pci_host_bridge *bridge;
struct myhostbridge_port *pp;
resource_size_t lastbus;
dev = pdev->dev.of_node;
if (!of_device_is_available(dev)) {
pr_warn("%s: disabled\n", dev->full_name);
return -ENODEV;
}
pp = kzalloc(sizeof(struct myhostbridge_port), GFP_KERNEL);
if (!pp)
return -ENOMEM;
bridge = of_create_pci_host_bridge(&pdev->dev, &myhostbridge_ops, pp);
if (IS_ERR(bridge)) {
err = PTR_ERR(bridge);
goto bridge_create_fail;
}
err = myhostbridge_setup(bridge->bus);
if (err)
goto bridge_setup_fail;
/* We always enable PCI domains and we keep domain 0 backward
* compatible in /proc for video cards
*/
pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
lastbus = pci_scan_child_bus(bridge->bus);
pci_bus_update_busn_res_end(bridge->bus, lastbus);
pci_assign_unassigned_bus_resources(bridge->bus);
pci_bus_add_devices(bridge->bus);
return 0;
bridge_setup_fail:
put_device(&bridge->dev);
device_unregister(&bridge->dev);
bridge_create_fail:
kfree(pp);
return err;
}
Best regards,
Liviu
Catalin Marinas (1):
arm64: Extend the PCI I/O space to 16MB
Liviu Dudau (2):
Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
arm64: Add architecture support for PCI
Documentation/arm64/memory.txt | 16 +--
arch/arm64/Kconfig | 19 +++-
arch/arm64/include/asm/Kbuild | 1 +
arch/arm64/include/asm/io.h | 5 +-
arch/arm64/include/asm/pci.h | 51 +++++++++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/pci.c | 173 +++++++++++++++++++++++++++++++
include/asm-generic/io.h | 2 +-
8 files changed, 258 insertions(+), 10 deletions(-)
create mode 100644 arch/arm64/include/asm/pci.h
create mode 100644 arch/arm64/kernel/pci.c
--
1.9.0
Kevin,
As we discussed at ELC, it would be nice to test ARM big endian in the
board farm. Here are some instructions on how to get this running:
1 Take the Buildroot branch at
http://git.free-electrons.com/users/thomas-petazzoni/buildroot/log/?h=for-k….
It is Buildroot 2014.02 + one patch for the AArch64 symlink + one
patch for the ARM big endian Linaro toolchain.
2 Build a Buildroot configuration such as:
BR2_armeb=y
BR2_cortex_a8=y
BR2_ARM_EABIHF=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TARGET_ROOTFS_CPIO=y
# BR2_TARGET_ROOTFS_TAR is not set
3 Build mvebu_v7_defconfig or multi_v7_defconfig with
CONFIG_CPU_BIG_ENDIAN=y (no other change is needed, except your own
configuration stuff maybe, like initrd support, devtmpfs and so on).
4 Boot
I've tested this right now on Armada XP OpenBlocks AX3-4. It is worth
noting that in BE mode, the ATAGS are not used, so if your OpenBlocks
has only 1 GB of RAM, the boot will crash (with some weird tty related
panic). That's because the Device Tree for the OpenBlocks AX3-4 encodes
a memory size of 3 GB, which some OpenBlocks have. If you fall into this
issue, then change the memory node in the DT to use 1 GB only.
Normally, this should also work on Armada 370 Mirabox, though I haven't
tested right now.
Do you think you could add this big endian test to the board farm?
In addition to this, it would be interesting if you could also test
LPAE on Armada XP OpenBlocks AX3-4 (it should work on little endian,
however I have never tested LPAE/big-endian).
Thanks a lot!
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
Douglas Anderson, recently pointed out an interesting problem due to which
udelay() was expiring earlier than it should.
While transitioning between frequencies few platforms may temporarily switch to
a stable frequency, waiting for the main PLL to stabilize.
For example: When we transition between very low frequencies on exynos, like
between 200MHz and 300MHz, we may temporarily switch to a PLL running at 800MHz.
No CPUFREQ notification is sent for that. That means there's a period of time
when we're running at 800MHz but loops_per_jiffy is calibrated at between 200MHz
and 300MHz. And so udelay behaves badly.
To get this fixed in a generic way, lets introduce another set of callbacks
get_intermediate() and target_intermediate(), only for drivers with
target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.
get_intermediate should return a stable intermediate frequency platform wants to
switch to, and target_intermediate() should set CPU to to that frequency, before
jumping to the frequency corresponding to 'index'. Core will take care of
sending notifications and driver doesn't have to handle them in
target_intermediate() or target_index().
This patchset also update Tegra to use this new infrastructure and is already
tested by Stephen.
NOTE: Once set to intermediate frequency, driver isn't expected to fail for the
following ->target_index() call, if it fails core will issue a WARN().
V2-V3:
- Fix spelling error: s/Uset/Used
- Update tegra with the changes Stephen suggested
- Include a dependency patch sent separately earlier (3/4)
V1-V2: Almost changed completely, V1 was here: https://lkml.org/lkml/2014/5/15/40
Viresh Kumar (4):
cpufreq: handle calls to ->target_index() in separate routine
cpufreq: add support for intermediate (stable) frequencies
cpufreq: Tegra: drop wrapper around tegra_update_cpu_speed()
cpufreq: Tegra: implement intermediate frequency callbacks
Documentation/cpu-freq/cpu-drivers.txt | 19 +++++++-
drivers/cpufreq/cpufreq.c | 82 ++++++++++++++++++++++++----------
drivers/cpufreq/tegra-cpufreq.c | 80 ++++++++++++++++-----------------
include/linux/cpufreq.h | 15 +++++++
4 files changed, 129 insertions(+), 67 deletions(-)
--
2.0.0.rc2
From: Arnd Bergmann <arnd(a)arndb.de>
As we are moving the mmp platform towards multiplatform support,
we have to stop including platform header files.
This changes the pxa-ssp sound driver file to no longer depend
on mach/hardware.h and mach/dma.h. The code using the definitions
from those headers is actually gone already, the only thing
that was still being used was the pxa_dma_desc typedef, which
we can easily work around by using the normal 'struct pxa_dma_desc'
name.
The pxa2xx-dma driver still uses this header, so we include it
explicitly there, which is ok because that is only used on pxa,
not on mmp.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Xia Kaixu <kaixu.xia(a)linaro.org>
Cc: Liam Girdwood <lgirdwood(a)gmail.com>
Cc: Mark Brown <broonie(a)kernel.org>
Cc: Eric Miao <eric.y.miao(a)gmail.com>
Cc: Russell King <linux(a)arm.linux.org.uk>
Cc: Haojian Zhuang <haojian.zhuang(a)gmail.com>
Cc: linux-arm-kernel(a)lists.infradead.org
Cc: alsa-devel(a)alsa-project.org
---
sound/arm/pxa2xx-pcm.c | 2 ++
sound/arm/pxa2xx-pcm.h | 3 +--
sound/soc/pxa/pxa-ssp.c | 2 --
sound/soc/pxa/pxa2xx-pcm.c | 2 ++
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index e6c727b..83be8e3 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -14,6 +14,8 @@
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
+#include <mach/dma.h>
+
#include <sound/core.h>
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 2a8fc08..0033098 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -9,12 +9,11 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <mach/dma.h>
struct pxa2xx_runtime_data {
int dma_ch;
struct snd_dmaengine_dai_dma_data *params;
- pxa_dma_desc *dma_desc_array;
+ struct pxa_dma_desc *dma_desc_array;
dma_addr_t dma_desc_array_phys;
};
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index a3119a0..9b19ee7 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -34,8 +34,6 @@
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>
-#include <mach/hardware.h>
-
#include "../../arm/pxa2xx-pcm.h"
#include "pxa-ssp.h"
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index d58b09f..42f2f01 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -15,6 +15,8 @@
#include <linux/dmaengine.h>
#include <linux/of.h>
+#include <mach/dma.h>
+
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/pxa2xx-lib.h>
--
1.7.9.5
From: Chander Kashyap <k.chander(a)samsung.com>
We don't have any protection against addition of duplicate OPPs currently and
in case some code tries to add them it will end up corrupting OPP tables.
There can be many combinations in which we may end up trying duplicate OPPs:
- both freq and volt are same, but earlier OPP may or may not be active.
- only freq is same and volt is different.
This patch tries to implement below logic for these cases:
Return 0 if new OPP was duplicate of existing one (i.e. same freq and volt) and
return -EEXIST if new OPP had same freq but different volt as of an existing OPP
OR if both freq/volt were same but earlier OPP was disabled.
Signed-off-by: Chander Kashyap <k.chander(a)samsung.com>
Signed-off-by: Inderpal Singh <inderpal.s(a)samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linrao.org>
---
V3->V4:
- handle duplicate OPPs more appropriately
- update comment over routine and enhance commit log
@Chander: I have kept your authorship as is, hope you don't mind me sending it
on your behalf :)
drivers/base/power/opp.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index 2553867..cd9af42 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -389,6 +389,11 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
* The opp is made available by default and it can be controlled using
* dev_pm_opp_enable/disable functions.
*
+ * Duplicate OPPs are discarded. Will return 0 if new OPP was duplicate of
+ * existing one (i.e. same freq and volt) and -EEXIST would be returned if new
+ * OPP had same freq but different volt as of an existing OPP OR if both were
+ * same but earlier OPP was disabled.
+ *
* 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
@@ -443,15 +448,31 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
new_opp->u_volt = u_volt;
new_opp->available = true;
- /* Insert new OPP in order of increasing frequency */
+ /*
+ * Insert new OPP in order of increasing frequency
+ * and discard if already present
+ */
head = &dev_opp->opp_list;
list_for_each_entry_rcu(opp, &dev_opp->opp_list, node) {
- if (new_opp->rate < opp->rate)
+ if (new_opp->rate <= opp->rate)
break;
else
head = &opp->node;
}
+ /* Duplicate OPPs ? */
+ if (new_opp->rate == opp->rate) {
+ int ret = (new_opp->u_volt == opp->u_volt) && opp->available ?
+ 0 : -EEXIST;
+
+ pr_warn("%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n",
+ __func__, opp->rate, opp->u_volt, opp->available,
+ new_opp->rate, new_opp->u_volt, new_opp->available);
+ mutex_unlock(&dev_opp_list_lock);
+ kfree(new_opp);
+ return ret;
+ }
+
list_add_rcu(&new_opp->node, head);
mutex_unlock(&dev_opp_list_lock);
--
2.0.0.rc2
Hi all,
I'm working with a custom OMAP4460 based platform running Android ICS.
Android for this platform is based on TI's 4AI.1.4 Release. Release Notes
available at
http://omappedia.org/wiki/4AI.1.4_OMAP4_Icecream_Sandwich_Release_Notes.
I need to upgrade to Android KitKat on this platform. I have chosen
Linaro's Release 14.04 for Pandaboard to be ported to the custom platform.
We use a Wireless module with TI's WL1271 core. The Wi-Fi driver provided
by the Module vendor was based on NL80211 framework.
WiFi with Linaro's KitKat port uses Wireless Extensions (WEXT) framework.
I understand that WEXT is an older implementation and NL80211 is more
recent. Is there a reason why WiFi on Linaro's KitKat port still uses WEXT
framework?
Is there any Android KitKat source base that uses NL80211 for WiFi
framework? This will help me validate the WiFi functionality on my custom
platform.
Thanks & Regards
Shajin
"Power" is a very bad term in the scheduler context. There are so many
meanings that can be attached to it. And with the upcoming "power
aware" scheduler work confusion is sure to happen.
The definition of "power" is typically the rate at which work is performed,
energy is converted or electric energy is transferred. The notion of
"compute capacity" is rather at odds with "power" to the point many
comments in the code have to make it explicit that "capacity" is the
actual intended meaning.
So let's make it clear what we man by using "capacity" in place of "power"
directly in the code. That will make the introduction of actual "power
consumption" concepts much clearer later on.
This is based on the latest tip tree where scheduler changes are already
queued.
Note: The diffstat is not completely symetric wrt added/removed lines as
some comments were reflowed.
arch/arm/kernel/topology.c | 54 +++----
include/linux/sched.h | 8 +-
kernel/sched/core.c | 89 ++++++-----
kernel/sched/fair.c | 322 ++++++++++++++++++++-------------------
kernel/sched/sched.h | 18 +--
5 files changed, 246 insertions(+), 245 deletions(-)
Nicolas
From: Liviu Dudau <Liviu.Dudau(a)arm.com>
Currently the tda998x driver only attempts to instantiate the CEC at I2C
address 0x34, meaning that if the CEC is instead at 0x35 (for example,
due to a conflict with another device) we will not be able to use it.
Attempt to handle some such situations by trying to instantiate the CEC
at 0x35 if we fail at 0x34.
[Wrote commit message -- broonie]
Signed-off-by: Liviu Dudau <Liviu.Dudau(a)arm.com>
Signed-off-by: Jon Medhurst <tixy(a)linaro.org>
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
I'm aware this isn't wonderful and is tied in with the general questions
about how to enumerate decomposed video devices, I'm partly looking for
feedback on the best way forwards here.
drivers/gpu/drm/i2c/tda998x_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 240c331405b9..a3368e7d12c4 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1246,6 +1246,8 @@ tda998x_encoder_init(struct i2c_client *client,
priv->current_page = 0xff;
priv->hdmi = client;
priv->cec = i2c_new_dummy(client->adapter, 0x34);
+ if (!priv->cec)
+ priv->cec = i2c_new_dummy(client->adapter, 0x35);
if (!priv->cec) {
kfree(priv);
return -ENODEV;
--
2.0.0.rc2
From: Mark Brown <broonie(a)linaro.org>
The OPP code is an in kernel library selected by its users, there is no
no architecture code required to implement it and enabling it without a
user just increases the kernel size. Since the users select rather than
depend on it just remove the ability to directly set the option from
Kconfig.
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
This leaves the ARCH_HAS_OPP symbol since removing that requires
updating the relevant architectures, if this is OK I can sumbit a
followup patch cleaning that up.
kernel/power/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc79b3d..9a83d780facd 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -257,8 +257,7 @@ config ARCH_HAS_OPP
bool
config PM_OPP
- bool "Operating Performance Point (OPP) Layer library"
- depends on ARCH_HAS_OPP
+ bool
---help---
SOCs have a standard set of tuples consisting of frequency and
voltage pairs that the device will support per voltage domain. This
--
2.0.0.rc2
Implement and enable context tracking for arm64 (which is
a prerequisite for FULL_NOHZ support). This patchset
builds upon earlier work by Kevin Hilman and is based on 3.15-rc2.
Changes v2 to v3:
* Save/restore necessary registers in ct_user_enter and ct_user_exit
* Annotate "error paths" out of el0_sync with ct_user_exit
Changes v1 to v2:
* Save far_el1 in x26 temporarily
Larry Bassel (2):
arm64: adjust el0_sync so that a function can be called
arm64: enable context tracking
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/thread_info.h | 1 +
arch/arm64/kernel/entry.S | 76 ++++++++++++++++++++++++++++++++----
3 files changed, 70 insertions(+), 8 deletions(-)
--
1.8.3.2
cpufreq-cpu0 uses thermal framework to register a cooling device, but doesn't
depend on it as there are dummy calls provided by thermal layer when
CONFIG_THERMAL=n. So, we don't really need to mention thermal as a dependency
for cpufreq-cpu0 in Kconfig.
Remove it.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
drivers/cpufreq/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 1fbe11f..4310997 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -185,7 +185,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
config GENERIC_CPUFREQ_CPU0
tristate "Generic CPU0 cpufreq driver"
- depends on HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL
+ depends on HAVE_CLK && REGULATOR && OF
select PM_OPP
help
This adds a generic cpufreq driver for CPU0 frequency management.
--
2.0.0.rc2
Douglas Anderson, recently pointed out an interesting problem due to which
udelay() was expiring earlier than it should.
While transitioning between frequencies few platforms may temporarily switch to
a stable frequency, waiting for the main PLL to stabilize.
For example: When we transition between very low frequencies on exynos, like
between 200MHz and 300MHz, we may temporarily switch to a PLL running at 800MHz.
No CPUFREQ notification is sent for that. That means there's a period of time
when we're running at 800MHz but loops_per_jiffy is calibrated at between 200MHz
and 300MHz. And so udelay behaves badly.
To get this fixed in a generic way, lets introduce another set of callbacks
get_intermediate() and target_intermediate(), only for drivers with
target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.
get_intermediate should return a stable intermediate frequency platform wants to
switch to, and target_intermediate() should set CPU to to that frequency, before
jumping to the frequency corresponding to 'index'. Core will take care of
sending notifications and driver doesn't have to handle them in
target_intermediate() or target_index().
This patchset also update Tegra to use this new infrastructure.
NOTE: Once set to intermediate frequency, driver isn't expected to fail for the
following ->target_index() call, if it fails core will issue a WARN().
@Stephen: Can you please test this? I haven't as I didn't had a board. :)
V1-V2: Almost changed completely, V1 was here: https://lkml.org/lkml/2014/5/15/40
Viresh Kumar (3):
cpufreq: handle calls to ->target_index() in separate routine
cpufreq: add support for intermediate (stable) frequencies
cpufreq: Tegra: implement intermediate frequency callbacks
Documentation/cpu-freq/cpu-drivers.txt | 19 +++++++-
drivers/cpufreq/cpufreq.c | 82 ++++++++++++++++++++++++----------
drivers/cpufreq/tegra-cpufreq.c | 81 ++++++++++++++++-----------------
include/linux/cpufreq.h | 15 +++++++
4 files changed, 128 insertions(+), 69 deletions(-)
--
2.0.0.rc2
Douglas Anderson, recently pointed out an interesting problem due to which his
udelay() was expiring earlier than it should:
https://lkml.org/lkml/2014/5/13/766
While transitioning between frequencies few platforms may temporarily switch to
a stable frequency, waiting for the main PLL to stabilize.
For example: When we transition between very low frequencies on exynos, like
between 200MHz and 300MHz, we may temporarily switch to a PLL running at 800MHz.
No CPUFREQ notification is sent for that. That means there's a period of time
when we're running at 800MHz but loops_per_jiffy is calibrated at between 200MHz
and 300MHz. And so udelay behaves badly.
To get this fixed in a generic way, lets introduce another callback safe_freq()
for the cpufreq drivers.
safe_freq() should return a stable intermediate frequency a platform might want
to switch to, before jumping to the frequency corresponding to 'index'. Core
will send the 'PRE' notification for this 'stable' frequency and 'POST' for the
'target' frequency. Though if ->target_index() fails, it will handle POST for
'stable' frequency only.
Drivers must send 'POST' notification for 'stable' freq and 'PRE' for 'target'
freq. If they can't switch to target frequency, they don't need to send any
notification.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
Doug/Stephen,
If this doesn't look too ugly, then I would need patches from you to fix your
platforms as I am not well aware of clk hierarchy of your platforms.
drivers/cpufreq/cpufreq.c | 13 +++++++++++--
include/linux/cpufreq.h | 18 ++++++++++++++++++
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a05c921..8d1cb4f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1874,11 +1874,17 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
if (notify) {
freqs.old = policy->cur;
- freqs.new = freq_table[index].frequency;
+ /* Switch to some safe intermediate freq */
+ if (cpufreq_driver->safe_freq)
+ freqs.new = cpufreq_driver->safe_freq(policy,
+ index);
+ else
+ freqs.new = freq_table[index].frequency;
freqs.flags = 0;
pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
- __func__, policy->cpu, freqs.old, freqs.new);
+ __func__, policy->cpu, freqs.old,
+ freq_table[index].frequency);
cpufreq_freq_transition_begin(policy, &freqs);
}
@@ -1887,6 +1893,9 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
if (retval)
pr_err("%s: Failed to change cpu frequency: %d\n",
__func__, retval);
+ else
+ /* Send POST notification for the target frequency */
+ freqs.new = freq_table[index].frequency;
if (notify)
cpufreq_freq_transition_end(policy, &freqs, retval);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3f45889..b5ba275 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -226,6 +226,24 @@ struct cpufreq_driver {
unsigned int relation);
int (*target_index) (struct cpufreq_policy *policy,
unsigned int index);
+ /*
+ * Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION
+ * unset.
+ *
+ * safe_freq() should return a stable intermediate frequency a platform
+ * might want to switch to, before jumping to the frequency
+ * corresponding to 'index'. Core will send the 'PRE' notification for
+ * this 'stable' frequency and 'POST' for the 'target' frequency. Though
+ * if ->target_index() fails, it will handle POST for 'stable' frequency
+ * only.
+ *
+ * Drivers must send 'POST' notification for 'stable' freq and 'PRE' for
+ * 'target' freq. If they can't switch to target frequency, they don't
+ * need to send any notification.
+ *
+ */
+ unsigned int (*safe_freq)(struct cpufreq_policy *policy,
+ unsigned int index);
/* should be defined, if possible */
unsigned int (*get) (unsigned int cpu);
--
2.0.0.rc2
Adding libdw DWARF post unwind support, which is part
of elfutils-devel/libdw-dev package from version 0.158.
Also includes the test suite for dwarf unwinding, by adding the
arch specific test code and the perf_regs_load function.
Jean Pihet (3):
perf tests: Introduce perf_regs_load function on ARM
perf tests: Add dwarf unwind test on ARM
perf tools: Add libdw DWARF post unwind support for ARM
tools/perf/Makefile.perf | 2 +-
tools/perf/arch/arm/Makefile | 7 ++++
tools/perf/arch/arm/include/perf_regs.h | 5 +++
tools/perf/arch/arm/tests/dwarf-unwind.c | 59 +++++++++++++++++++++++++++++++
tools/perf/arch/arm/tests/regs_load.S | 60 ++++++++++++++++++++++++++++++++
tools/perf/arch/arm/util/unwind-libdw.c | 36 +++++++++++++++++++
tools/perf/tests/builtin-test.c | 2 +-
tools/perf/tests/tests.h | 2 +-
8 files changed, 170 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/arch/arm/tests/dwarf-unwind.c
create mode 100644 tools/perf/arch/arm/tests/regs_load.S
create mode 100644 tools/perf/arch/arm/util/unwind-libdw.c
---
Rebased on the latest jolsa/perf/core
--
1.7.11.7
Hi Alex/Mark
Here's a pull request for the latest changes to big.LITTLE MP. These are
essentially the same changes as we had last month before they were
reverted pending more analysis.
The following changes since commit 1ade57e54ea2257ccf753dbd54144769439c3c70:
sched: hmp: Change small task packing defaults for all platforms (2014-05-07 11:34:00 +0100)
are available in the git repository at:
git://git.linaro.org/arm/big.LITTLE/mp.git for-lsk
for you to fetch changes up to d1df056f9e6dd9707037ed74621e170dfa8f4c52:
hmp: dont attempt to pull tasks if affinity doesn't allow it (2014-05-09 17:22:39 +0100)
----------------------------------------------------------------
Chris Redpath (4):
hmp: sched: Clean up hmp_up_threshold checks into a utility fn
sched: hmp: unify active migration code
hmp: Use idle pull to perform forced up-migrations
hmp: dont attempt to pull tasks if affinity doesn't allow it
kernel/sched/core.c | 11 +-
kernel/sched/fair.c | 395 ++++++++++++++++++++++++++++----------------------
kernel/sched/sched.h | 1 +
3 files changed, 230 insertions(+), 177 deletions(-)
There is a requirement to add another mode: CLOCK_EVT_MODE_ONESHOT_STOPPED
(lkml.org/lkml/2014/5/9/508) to clockevent devices and clockevent-drivers may or
maynot support it. And so can return failure codes on a call to ->set_mode(),
which has a return type of 'void' as of now.
To fix that, add another callback ->set_dev_mode(), with return type 'int'. All
clockevent drivers will be migrated to use this new interface later. Also mark
->set_mode() deprecated.
In order to propagate error codes to callers of clockevents_set_mode(), its
return type is also changed to 'int', but all the error handling is done inside
clockevents_set_mode() currently as none of the currently available modes are
allowed to fail.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
Hi Daniel/Preeti/Others..
I need to get some level of reviews done for some of my patches because of this:
https://lkml.org/lkml/2014/5/12/206
A reviewed-by: would be very helpful to get this upstreamed. Please review and
point out any improvement in the patch or the log..
V1->V2:
- Don't sprinkly WARN_ON() on call sites of clockevents_set_mode()
- Handle errors returned from ->set_dev_mode() in clockevents_set_mode() only.
include/linux/clockchips.h | 7 +++++--
kernel/time/clockevents.c | 29 ++++++++++++++++++++++++-----
kernel/time/timer_list.c | 9 +++++++--
3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 2e4cb67..bf902bf 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -81,7 +81,8 @@ enum clock_event_mode {
* @mode: operating mode assigned by the management code
* @features: features
* @retries: number of forced programming retries
- * @set_mode: set mode function
+ * @set_dev_mode: set dev mode function
+ * @set_mode: set mode function (deprecated, use set_dev_mode instead)
* @broadcast: function to broadcast events
* @min_delta_ticks: minimum delta value in ticks stored for reconfiguration
* @max_delta_ticks: maximum delta value in ticks stored for reconfiguration
@@ -109,6 +110,8 @@ struct clock_event_device {
unsigned long retries;
void (*broadcast)(const struct cpumask *mask);
+ int (*set_dev_mode)(enum clock_event_mode mode,
+ struct clock_event_device *);
void (*set_mode)(enum clock_event_mode mode,
struct clock_event_device *);
void (*suspend)(struct clock_event_device *);
@@ -160,7 +163,7 @@ extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq);
extern void clockevents_exchange_device(struct clock_event_device *old,
struct clock_event_device *new);
-extern void clockevents_set_mode(struct clock_event_device *dev,
+extern int clockevents_set_mode(struct clock_event_device *dev,
enum clock_event_mode mode);
extern int clockevents_program_event(struct clock_event_device *dev,
ktime_t expires, bool force);
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index ad362c2..087a5aa 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -101,11 +101,20 @@ EXPORT_SYMBOL_GPL(clockevent_delta2ns);
*
* Must be called with interrupts disabled !
*/
-void clockevents_set_mode(struct clock_event_device *dev,
+int clockevents_set_mode(struct clock_event_device *dev,
enum clock_event_mode mode)
{
if (dev->mode != mode) {
- dev->set_mode(mode, dev);
+ if (dev->set_dev_mode) {
+ int ret = dev->set_dev_mode(mode, dev);
+
+ /* Currently available modes are not allowed to fail */
+ if (WARN_ON(ret))
+ return ret;
+ } else {
+ dev->set_mode(mode, dev);
+ }
+
dev->mode = mode;
/*
@@ -119,6 +128,8 @@ void clockevents_set_mode(struct clock_event_device *dev,
}
}
}
+
+ return 0;
}
/**
@@ -441,15 +452,23 @@ EXPORT_SYMBOL_GPL(clockevents_config_and_register);
int __clockevents_update_freq(struct clock_event_device *dev, u32 freq)
{
+ int ret = 0;
+
clockevents_config(dev, freq);
if (dev->mode == CLOCK_EVT_MODE_ONESHOT)
return clockevents_program_event(dev, dev->next_event, false);
- if (dev->mode == CLOCK_EVT_MODE_PERIODIC)
- dev->set_mode(CLOCK_EVT_MODE_PERIODIC, dev);
+ if (dev->mode == CLOCK_EVT_MODE_PERIODIC) {
+ if (dev->set_dev_mode) {
+ ret = dev->set_dev_mode(CLOCK_EVT_MODE_PERIODIC, dev);
+ WARN_ON(ret);
+ } else {
+ dev->set_mode(CLOCK_EVT_MODE_PERIODIC, dev);
+ }
+ }
- return 0;
+ return ret;
}
/**
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 61ed862..3d854aa 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -228,8 +228,13 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
print_name_offset(m, dev->set_next_event);
SEQ_printf(m, "\n");
- SEQ_printf(m, " set_mode: ");
- print_name_offset(m, dev->set_mode);
+ if (dev->set_dev_mode) {
+ SEQ_printf(m, " set_dev_mode: ");
+ print_name_offset(m, dev->set_dev_mode);
+ } else {
+ SEQ_printf(m, " set_mode: ");
+ print_name_offset(m, dev->set_mode);
+ }
SEQ_printf(m, "\n");
SEQ_printf(m, " event_handler: ");
--
2.0.0.rc2
From: Liviu Dudau <Liviu.Dudau(a)arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau(a)arm.com>
Signed-off-by: Ryan Harkin <ryan.harkin(a)linaro.org>
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
drivers/usb/phy/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index bbe8f15ac014..2a7f6ea1ccfe 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -224,7 +224,7 @@ config USB_RCAR_GEN2_PHY
config USB_ULPI
bool "Generic ULPI Transceiver Driver"
- depends on ARM
+ depends on ARM || ARM64
help
Enable this to support ULPI connected USB OTG transceivers which
are likely found on embedded boards.
--
2.0.0.rc2
Hi Friends,
I recently went through a tool which can be very very useful while
doing similar modification across multiple files.. Examples:
Replace: bool foo = 0; b = 1; b == 1; b == 0, etc
with: bool foo = false; b = true; b == true; b == false, etc
Much more complex things are possible as well..
It wouldn't require any manual intervention even if you have to do
that for all the files present in your repository.
Many of us in Linaro have to regularly work on fixing things around
all available drivers for a particular framework. It would be very useful
there..
Useful Links:
http://coccinelle.lip6.fr/http://coccinelle.lip6.fr/papers.phphttps://www.youtube.com/watch?v=ohyn1DTuh18
I am still trying to learn it more and more, let me know if somebody
is already good in it, will ask some queries :)
(Thanks tglx to enlighten me :))
--
viresh
From: Liviu Dudau <Liviu.Dudau(a)arm.com>
Recent ARM boards have the KMI devices share one interrupt line rather
than having dedicated IRQs. Update the driver to take that into account.
Signed-off-by: Liviu Dudau <Liviu.Dudau(a)arm.com>
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
drivers/input/serio/ambakmi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 762b08432de0..8b748d99b934 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -79,7 +79,8 @@ static int amba_kmi_open(struct serio *io)
writeb(divisor, KMICLKDIV);
writeb(KMICR_EN, KMICR);
- ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi);
+ ret = request_irq(kmi->irq, amba_kmi_int, IRQF_SHARED, "kmi-pl050",
+ kmi);
if (ret) {
printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
writeb(0, KMICR);
--
2.0.0.rc2
On my test platform (B2020/STiH416) the serial port issues bad characters
during the initial message avalanche as the console comes up. The problem
also occurs when dense(ish) I/O is done using the polled I/O interface.
The problem is fixed for me by using the FIFO half-empty bit rather than
FIFO full bit. Note that using the half-empty bit causes the FIFO to be
managed in a similar way to interrupt based I/O (i.e. where the hardware
gets best test coverage).
Running the FIFO half full will have no impact (good or bad) on console
performance. The UART will still remain fully saturated and the busy-wait
until the FIFO is empty in asc_console_write() will complete at the same
time.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
---
drivers/tty/serial/st-asc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index dd3a96e..c7f61ac 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -194,9 +194,9 @@ static inline u32 asc_txfifo_is_empty(struct uart_port *port)
return asc_in(port, ASC_STA) & ASC_STA_TE;
}
-static inline int asc_txfifo_is_full(struct uart_port *port)
+static inline u32 asc_txfifo_is_half_empty(struct uart_port *port)
{
- return asc_in(port, ASC_STA) & ASC_STA_TF;
+ return asc_in(port, ASC_STA) & ASC_STA_THE;
}
static inline const char *asc_port_name(struct uart_port *port)
@@ -628,7 +628,7 @@ static int asc_get_poll_char(struct uart_port *port)
static void asc_put_poll_char(struct uart_port *port, unsigned char c)
{
- while (asc_txfifo_is_full(port))
+ while (!asc_txfifo_is_half_empty(port))
cpu_relax();
asc_out(port, ASC_TXBUF, c);
}
@@ -783,7 +783,7 @@ static void asc_console_putchar(struct uart_port *port, int ch)
unsigned int timeout = 1000000;
/* Wait for upto 1 second in case flow control is stopping us. */
- while (--timeout && asc_txfifo_is_full(port))
+ while (--timeout && !asc_txfifo_is_half_empty(port))
udelay(1);
asc_out(port, ASC_TXBUF, ch);
--
1.9.0
Dear Linaro term:
this is my system status:
kernel version: 3.10
kernel/user space split: 1G/3G
system memory: 2GB
lowmem/vmalloc: 760MB/240MB
CMA reverse: 512MB
If CMA is placed in the lowmem area, it is working fine; when i move it
to high zone, it working abnomaly:
<1>[ 647.755598] Unhandled fault: imprecise external abort (0x1c06) at
0x76429000
<0>[ 647.755621] Internal error: : 1c06 [#1] PREEMPT SMP ARM
<4>[ 647.755633] Modules linked in:
<4>[ 647.755648] CPU: 1 PID: 162 Comm: Binder_1 Not tainted 3.10.0 #48
<4>[ 647.755676] task: d6ac3700 ti: c576e000 task.ti: c576e000
<4>[ 647.755700] PC is at __memzero+0x28/0x80
<4>[ 647.755710] LR is at 0x0
<4>[ 647.755720] pc : [<c0250fa8>] lr : [<00000000>] psr: 20030013
<4>[ 0.000000] sp : c576fdd4 ip : 00000000 fp : 00b40000
<4>[ 647.755742] r10: 00000000 r9 : c0c18000 r8 : bff87000
<4>[ 647.755755] r7 : 00b38000 r6 : c1490100 r5 : c1490000 r4 : 00b40000
<4>[ 647.755768] r3 : 00000000 r2 : 00000000 r1 : 00000e80 r0 : bff87150
<4>[ 647.755783] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment
user
<4>[ 647.755799] Control: 10c5387d Table: 0560406a DAC: 00000015
Hi Thomas,
As suggested by you (https://lkml.org/lkml/2014/5/10/86), here is an attempt to
implement first two steps for fixing the bigger problem.
This patchset is about adding ->set_dev_mode() to struct clock_event_device with
return type 'int'. To achieve that return type of clockevents_set_mode() is also
changed to propagate failures.
Let me know if this is what you wanted to see or I screwed up again :(
I will then start updating drivers one by one (100 drivers AFAICT). I will try to
fix them in separate patches and will post them together in a single patchset.
And because the number is going to be over 100, let me know how do you want me
to send that..
Viresh Kumar (2):
clockevents: return 'int' from clockevents_set_mode()
clockevents: add ->set_dev_mode() to struct clock_event_device
arch/arm/common/bL_switcher.c | 5 +++--
include/linux/clockchips.h | 7 +++++--
kernel/time/clockevents.c | 34 +++++++++++++++++++++++++---------
kernel/time/tick-broadcast.c | 25 ++++++++++++++++---------
kernel/time/tick-common.c | 6 +++---
kernel/time/tick-oneshot.c | 6 +++---
kernel/time/timer_list.c | 9 +++++++--
7 files changed, 62 insertions(+), 30 deletions(-)
--
2.0.0.rc2
This happened for me during my NO_HZ_FULL testing on isolated CPU, but may
happen otherwise as well.
When the last htimer of a CPU is cancelled (For example: for NO_HZ_FULL when
expires == KTIME_MAX), we do not SHUTDOWN the event device. And because of that
we will get interrupted unnecessarily on the isolated core as event device will
interrupt as per the last value it is configured with.
The implementation of event device's driver may make it worse. For example:
drivers/clocksource/arm_arch_timer.c disables the event device only on
SHUTDOWN/UNUSED requests in set-mode. Otherwise, it will keep giving interrupts
at tick interval even if hrtimer_interrupt() didn't reprogram tick (When expires
== KTIME_MAX). And so we will keep getting interrupt every few milliseconds. To
confirm this I added a small hack in hrtimer.c [1] and got these results [2] as
soon as the CPU got isolated with NO_HZ_FULL and cpusets.
Probably the right solution to fix this is to disable the event device for such
cases, i.e. expires == KTIME_MAX and restart it later when required. This will
get rid of unnecessary interruption which can be avoided.
Tested over 3.15-rc4 on ARM Exynos5250 (Dual A15) board.
NOTE: Current implementation of NO_HZ_FULL has a limitation of 1 second and so
we might never end up cancelling sched_timer. I was using Kevin's debug patch:
https://lkml.org/lkml/2013/12/17/649, with which I am able to get expires to
KTIME_MAX and so ended up cancelling hrtimer.
[1] http://pastebin.com/MhDdawVd
[2] http://pastebin.com/5U5FBbTW
Viresh Kumar (2):
hrtimer: reprogram event for expires=KTIME_MAX in
hrtimer_force_reprogram()
tick: SHUTDOWN event-dev if no events are required for KTIME_MAX
include/linux/clockchips.h | 1 +
kernel/hrtimer.c | 3 +--
kernel/time/tick-oneshot.c | 14 +++++++++++++-
3 files changed, 15 insertions(+), 3 deletions(-)
--
2.0.0.rc2