* Re: [PATCH 2/3] powerpc/mpic: add global timer support
From: Scott Wood @ 2013-03-28 19:47 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Wood Scott-B07421, Gala Kumar-B11780,
linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBBE13@039-SN2MPN1-022.039d.mgd.msft.net>
On 03/27/2013 09:29:26 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Thursday, March 28, 2013 1:12 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Li Yang-R58472
> > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> >
> > On 03/26/2013 10:23:38 PM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Wednesday, March 27, 2013 1:32 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Li Yang-R58472
> > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > >
> > > > On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Wood Scott-B07421
> > > > > > Sent: Saturday, March 23, 2013 6:30 AM
> > > > > > To: Wang Dongsheng-B40534
> > > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > > linuxppc-dev@lists.ozlabs.org;
> > > > > > Li Yang-R58472
> > > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer =20
> support
> > > > > >
> > > > > > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > > > > > >
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Wood Scott-B07421
> > > > > > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > > > > > To: Wang Dongsheng-B40534
> > > > > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > > > > linuxppc-dev@lists.ozlabs.org;
> > > > > > > > Li Yang-R58472
> > > > > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer
> > > support
> > > > > > > >
> > > > > > > > BTW, the input clock frequency has been similarly =20
> scaled,
> > > yet
> > > > > you
> > > > > > > don't
> > > > > > > > try to scrounge up that information to get further
> > > precision...
> > > > > > > >
> > > > > > > Let's go back patch, do you think the code is repeated?
> > > > > > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" =20
> branch,
> > > > > there
> > > > > > > will be no redundant code.
> > > > > >
> > > > > > I'd rather that branch be kept and the more complicated =20
> branch
> > > > > deleted,
> > > > > > and priv->timerfreq frequency be adjusted on initialization =20
> to
> > > > > account
> > > > > > for the scaler.
> > > > >
> > > > > static void convert_ticks_to_time(struct timer_group_priv =20
> *priv,
> > > > > const u64 ticks, struct timeval *time) {
> > > > > u64 tmp_sec;
> > > > >
> > > > > time->tv_sec =3D (__kernel_time_t)div_u64(ticks,
> > > > > priv->timerfreq);
> > > > > tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
> > > > >
> > > > > time->tv_usec =3D (__kernel_suseconds_t)
> > > > > div_u64((ticks - tmp_sec) * 1000000,
> > > priv->timerfreq);
> > > > >
> > > > > return;
> > > > > }
> > > > >
> > > > > timer_group_get_freq() {
> > > > > ...
> > > > > if (priv->flags & FSL_GLOBAL_TIMER) {
> > > > > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * =20
> 8;
> > > > > priv->timerfreq /=3D div;
> > > > > }
> > > > > ...
> > > > > }
> > > > > Do you want to do that?
> > > >
> > > > if (priv->flags & FSL_GLOBAL_TIMER)
> > > > priv->timerfreq /=3D 64;
> > > >
> > > > ...but otherwise yes.
> > > Ok, I would like do this.
> > >
> > > if (priv->flags & FSL_GLOBAL_TIMER) {
> > > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > > priv->timerfreq /=3D div;
> >
> > Why? What do you get out of that obfuscation?
> >
> Change MPIC_TIMER_TCR_CLKDIV_64 to MPIC_TIMER_TCR_CLKDIV
OK, that would at least provide the ability to adjust the clock divider =20
in one place rather than two -- though I don't know why we'd ever need =20
to change the divider.
> Because macro is friendly, and other functions also used the macro.
Using the macro rather than hardcoding register bit encodings is =20
friendly. The calculation to turn the bit encoding into an actual =20
divider value is not particularly friendly.
-Scott=
^ permalink raw reply
* weird elf header issues, is it binutils or my linker script?
From: Chris Friesen @ 2013-03-28 15:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev
Hi all,
We're running into an problem with a (somewhat complicated) 32-bit powerpc binary.
When we try to run it, it hits the null-terminated interpreter test in the kernel and
bails out with ENOEXEC.
Looking at the binary with readelf, the program headers contain the following:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0xf2000034 0xf2000034 0x00120 0x00120 R 0x4
INTERP 0x000154 0xf2000154 0xf2000154 0x00030 0x0002d R 0x4
[Requesting program interpreter: /lib/ld.so.1]
Notice the unusually large size of the INTERP header--instead of 0xd it's 0x30.
This causes problems when we try to run, because while the string "/lib/ld.so.1"
is null-terminated it just so happens that the byte at 0x000154+0x00030-1
(which corresponds to elf_interpreter[elf_ppnt->p_filesz - 1] in the kernel code)
is not, and so it fails the kernel test.
We do use a custom linker script when building this binary. I can only find
two entries related to the interpreter:
PHDRS
{
headers PT_PHDR PHDRS ;
interp PT_INTERP ;
<snip>
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0xf2000000); . = 0xf2000000 + SIZEOF_HEADERS;
.interp : { *(.interp) } :text :interp
<snip>
}
So I'm wondering...is this something wrong with our linker script, or is there a bug
in our binutils? I'm no linker expert, but the interpreter sections in the script
seem to match the binutils documentation that I found and I don't see anything that
would be messing with the length.
Any suggestions on where to look?
Thanks,
Chris
--
Chris Friesen
Software Designer
500 Palladium Drive, Suite 2100
Ottawa, Ontario K2N 1C2, Canada
www.genband.com
office:+1.343.883.2717
chris.friesen@genband.com
^ permalink raw reply
* Re: [PATCH 2/2 v2] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
From: Viresh Kumar @ 2013-03-28 14:54 UTC (permalink / raw)
To: Yuantian.Tang; +Cc: rjw, linuxppc-dev, cpufreq, linux-pm
In-Reply-To: <1364464508-25393-1-git-send-email-Yuantian.Tang@freescale.com>
On 28 March 2013 15:25, <Yuantian.Tang@freescale.com> wrote:
> From: Tang Yuantian <yuantian.tang@freescale.com>
>
> Add cpufreq driver for Freescale e500mc, e5500 and e6500 SoCs
> which are capable of changing the frequency of CPU dynamically
>
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> v2:
> - change the per_cpu variable to point type
> - fixed other issues
This changelog is pretty important and useful. People forget what comments
they gave on earlier version.
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
> +/**
> + * struct cpufreq_data - cpufreq driver data
> + * @cpus_per_cluster: CPU numbers per cluster
> + * @cpufreq_lock: the mutex lock
rather add what's its purpose and what it protects.
> + */
> +struct cpufreq_data {
> + int cpus_per_cluster;
> + struct mutex cpufreq_lock;
> +};
You actually need a struct for this? Simply create globals ?
> +/**
> + * struct cpu_data - per CPU data struct
> + * @clk: the clk data of CPU
remove "data"
> + * @parent: the parent node of clock of cpu
s/clock of cpu/cpu clock
> + * @table: frequency table point
point? you mean pointer? Just remove it.
> +struct cpu_data {
> + struct clk *clk;
> + struct device_node *parent;
> + struct cpufreq_frequency_table *table;
> +};
> +
> +static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> +static struct cpufreq_data freq_data;
> +
> +static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
> +{
> + struct cpu_data *data = per_cpu(cpu_data, cpu);
> +
> + return clk_get_rate(data->clk) / 1000;
> +}
> +
> +/* reduce the duplicated frequency in frequency table */
> +static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
> + int count)
> +{
> + int i, j;
> +
> + for (i = 1; i < count; i++) {
> + for (j = 0; j < i; j++) {
> + if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID ||
> + freq_table[j].frequency !=
> + freq_table[i].frequency)
> + continue;
> +
> + freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
> + break;
> + }
> + }
> +}
Looks better now :)
> +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> + unsigned int cpu = policy->cpu;
> + struct device_node *np;
> + int i, count;
> + struct clk *clk;
> + struct cpufreq_frequency_table *table;
> + struct cpu_data *data;
> +
> + np = of_get_cpu_node(cpu, NULL);
> + if (!np)
> + return -ENODEV;
> +
> + data = kzalloc(sizeof(struct cpu_data), GFP_KERNEL);
I told you, you missed my comment earlier.
You need to write: sizeof(*data) :(
> + if (!data)
> + return -ENOMEM;
> +
> + data->clk = of_clk_get(np, 0);
> + data->parent = of_parse_phandle(np, "clocks", 0);
> + if (!data->parent) {
> + pr_err("%s: could not get clock information\n", __func__);
> + goto err_nomem2;
> + }
> +
> + count = of_property_count_strings(data->parent, "clock-names");
> +
> + table = kcalloc(count + 1,
> + sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
sizeof(*table)
> + if (!table) {
> + pr_err("%s: no memory\n", __func__);
> + goto err_nomem2;
> + }
> +
> + for (i = cpu; i < freq_data.cpus_per_cluster + cpu; i++)
> + cpumask_set_cpu(i, policy->cpus);
I can see some regression here. Suppose you have two clusters of 4
cpus each: (0123) and (4567).. Now at boot time above code will work
perfectly fine. Now you hot unplug 0,1,2,3 and then hotplug 3 in.
Here, init would be called for cpu 3 and so you will end up saving 3456
in your policy->cpus
:)
> + for (i = 0; i < count; i++) {
> + table[i].index = i;
> + clk = of_clk_get(data->parent, i);
> + table[i].frequency = clk_get_rate(clk) / 1000;
> + }
> + freq_table_redup(table, count);
> + table[i].frequency = CPUFREQ_TABLE_END;
> +
> + data->table = table;
> + per_cpu(cpu_data, cpu) = data;
> +
> + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
> + policy->cur = corenet_cpufreq_get_speed(policy->cpu);
> +
> + /* set the min and max frequency properly */
> + i = cpufreq_frequency_table_cpuinfo(policy, table);
i doesn't suit here, use variable like ret or err..
And move this just after the line where you set freq as TABLE_END.
So that you don't execute unnecessary code for error case.
> +static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
> +{
> + struct cpufreq_frequency_table *table;
> +
> + table = per_cpu(cpu_data, policy->cpu)->table;
merge above two lines.
> + return cpufreq_frequency_table_verify(policy, table);
> +}
> +
> +static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> + unsigned int target_freq, unsigned int relation)
> +{
> + struct cpufreq_freqs freqs;
> + unsigned int new;
> + struct clk *parent;
> + int ret;
> + struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> +
> + cpufreq_frequency_table_target(policy, data->table,
> + target_freq, relation, &new);
> +
> + if (policy->cur == data->table[new].frequency)
> + return 0;
> +
> + freqs.old = policy->cur;
> + freqs.new = data->table[new].frequency;
> + freqs.cpu = policy->cpu;
> +
> + mutex_lock(&freq_data.cpufreq_lock);
> + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
You need to notify freq change for all cpus in this group :)
BUT you don't need to worry about it due to this:
http://patches.linaro.org/15569/
> + parent = of_clk_get(data->parent, new);
> + ret = clk_set_parent(data->clk, parent);
> + if (ret) {
> + mutex_unlock(&freq_data.cpufreq_lock);
Probably for error case too you need to notify others about completion
of freq change, but with old freq.
> + return ret;
> + }
> +
> + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> + mutex_unlock(&freq_data.cpufreq_lock);
> +
> + return 0;
> +}
> +
> +static struct freq_attr *corenet_cpu_clks_attr[] = {
name it better, maybe corenet_cpufreq_attr ?
> + &cpufreq_freq_attr_scaling_available_freqs,
> + NULL,
> +};
> +
> +static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> + .name = "ppc_cpufreq",
> + .owner = THIS_MODULE,
> + .flags = CPUFREQ_CONST_LOOPS,
> + .init = corenet_cpufreq_cpu_init,
> + .exit = __exit_p(corenet_cpufreq_cpu_exit),
> + .verify = corenet_cpufreq_verify,
> + .target = corenet_cpufreq_target,
> + .get = corenet_cpufreq_get_speed,
> + .attr = corenet_cpu_clks_attr,
> +};
> +
> +static const struct of_device_id node_matches[] __initconst = {
> + { .compatible = "fsl,qoriq-clockgen-1.0", .data = (void *)1, },
> + { .compatible = "fsl,qoriq-clockgen-2", .data = (void *)8, },
> + {}
> +};
> +
> +static int __init ppc_corenet_cpufreq_init(void)
> +{
> + int ret = 0;
> + struct device_node *np;
> + const struct of_device_id *match;
> +
> + np = of_find_matching_node(NULL, node_matches);
> + if (!np)
> + return -ENODEV;
> +
> + match = of_match_node(node_matches, np);
> + freq_data.cpus_per_cluster = (unsigned long)match->data;
> + mutex_init(&freq_data.cpufreq_lock);
> + of_node_put(np);
> +
> + ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> + if (ret)
> + return ret;
> +
> + pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
Or write it as:
ret = cpufreq_register_driver();
if (!ret)
pr_info();
return ret;
> +
> + return ret;
> +}
> +module_init(ppc_corenet_cpufreq_init);
> +
> +static void __exit ppc_corenet_cpufreq_exit(void)
> +{
> + cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +}
> +module_exit(ppc_corenet_cpufreq_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> +MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
^ permalink raw reply
* [PATCH 1/2 V2] clk: add PowerPC corenet clock driver support
From: Yuantian.Tang @ 2013-03-28 9:57 UTC (permalink / raw)
To: galak; +Cc: Tang Yuantian, linuxppc-dev
From: Tang Yuantian <yuantian.tang@freescale.com>
This adds the clock driver for Freescale PowerPC corenet
series SoCs using common clock infrastructure.
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
v2: add the document for device tree clock bindings
.../bindings/clock/freescale-corenet-clock.txt | 67 +++++
arch/powerpc/platforms/Kconfig.cputype | 1 +
drivers/clk/Kconfig | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-ppc-corenet.c | 285 +++++++++++++++++++++
5 files changed, 361 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/freescale-corenet-clock.txt
create mode 100644 drivers/clk/clk-ppc-corenet.c
diff --git a/Documentation/devicetree/bindings/clock/freescale-corenet-clock.txt b/Documentation/devicetree/bindings/clock/freescale-corenet-clock.txt
new file mode 100644
index 0000000..696c85f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/freescale-corenet-clock.txt
@@ -0,0 +1,67 @@
+Device Tree Clock bindings for Freescale PowerPC corenet platform
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+ "fsl,core-pll-clock" - for a core PLL clock
+ "fsl,core-mux-clock" - for a core multiplexer clock. Divided from the
+ core PLL clock
+ "fixed-clock" - from common clock binding; should be output clock
+ of oscillator
+- reg : shall be the control register offset from clock block base address.
+- clocks : shall be the input parent clock phandle for the clock.
+- #clock-cells : from common clock binding; shall be set to 0 or 1.
+- clock-names : from common clock binding
+- clock-output-names : from common clock binding
+
+Example SoC include file:
+
+/ {
+ clockgen: global-utilities@e1000 {
+ compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0",
+ "fixed-clock";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ clock-output-names = "sysclk";
+ #clock-cells = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pll0: pll0@800 {
+ #clock-cells = <1>;
+ reg = <0x800>;
+ compatible = "fsl,core-pll-clock";
+ clocks = <&clockgen>;
+ clock-output-names = "pll0", "pll0-div2", "pll0-div4";
+ };
+ pll1: pll1@820 {
+ #clock-cells = <1>;
+ reg = <0x820>;
+ compatible = "fsl,core-pll-clock";
+ clocks = <&clockgen>;
+ clock-output-names = "pll1", "pll1-div2", "pll1-div4";
+ };
+ mux0: mux0@0 {
+ #clock-cells = <0>;
+ reg = <0x0>;
+ compatible = "fsl,core-mux-clock";
+ clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
+ <&pll1 0>, <&pll1 1>, <&pll1 2>;
+ clock-names = "pll0_0", "pll0_1", "pll0_2",
+ "pll1_0", "pll1_1", "pll1_2";
+ clock-output-names = "cmux0";
+ };
+ mux1: mux1@20 {
+ #clock-cells = <0>;
+ reg = <0x20>;
+ compatible = "fsl,core-mux-clock";
+ clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
+ <&pll1 0>, <&pll1 1>, <&pll1 2>;
+ clock-names = "pll0_0", "pll0_1", "pll0_2",
+ "pll1_0", "pll1_1", "pll1_2";
+ clock-output-names = "cmux1";
+ };
+ };
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 18e3b76..cf065b8 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -158,6 +158,7 @@ config E500
config PPC_E500MC
bool "e500mc Support"
select PPC_FPU
+ select COMMON_CLK
depends on E500
help
This must be enabled for running on e500mc (and derivatives
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a47e6ee..6e2fd9c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -63,6 +63,13 @@ config CLK_TWL6040
McPDM. McPDM module is using the external bit clock on the McPDM bus
as functional clock.
+config CLK_PPC_CORENET
+ bool "Clock driver for PowerPC corenet platforms"
+ depends on PPC_E500MC && OF
+ ---help---
+ This adds the clock driver support for Freescale PowerPC corenet
+ platforms using common clock framework.
+
endmenu
source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 300d477..6720319 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_X86) += x86/
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
+obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c
new file mode 100644
index 0000000..6811e03
--- /dev/null
+++ b/drivers/clk/clk-ppc-corenet.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * clock driver for Freescale PowerPC corenet SoCs.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+struct cmux_clk {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u32 flags;
+};
+
+#define PLL_KILL BIT(31)
+#define CLKSEL_SHIFT 27
+#define CLKSEL_ADJUST BIT(0)
+
+#define to_cmux_clk(p) container_of(p, struct cmux_clk, hw)
+
+static void __iomem *base;
+static unsigned int clocks_per_pll;
+
+static int cmux_set_parent(struct clk_hw *hw, u8 idx)
+{
+ struct cmux_clk *clk = to_cmux_clk(hw);
+ u32 clksel;
+
+ clksel = ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll;
+ if (clk->flags & CLKSEL_ADJUST)
+ clksel += 8;
+ clksel = (clksel & 0xf) << CLKSEL_SHIFT;
+ iowrite32be(clksel, clk->reg);
+
+ return 0;
+}
+
+static u8 cmux_get_parent(struct clk_hw *hw)
+{
+ struct cmux_clk *clk = to_cmux_clk(hw);
+ u32 clksel;
+
+ clksel = ioread32be(clk->reg);
+ clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
+ if (clk->flags & CLKSEL_ADJUST)
+ clksel -= 8;
+ clksel = (clksel >> 2) * clocks_per_pll + clksel % 4;
+
+ return clksel;
+}
+
+const struct clk_ops cmux_ops = {
+ .get_parent = cmux_get_parent,
+ .set_parent = cmux_set_parent,
+};
+
+static void __init core_mux_init(struct device_node *np)
+{
+ struct clk *clk;
+ struct clk_init_data init;
+ struct cmux_clk *cmux_clk;
+ struct device_node *node;
+ int rc, count, i;
+ u32 offset;
+ const char *clk_name;
+ const char **parent_names;
+
+ rc = of_property_read_u32(np, "reg", &offset);
+ if (rc) {
+ pr_err("%s: could not get reg property\n", np->name);
+ return;
+ }
+
+ /* get the input clock source count */
+ count = of_property_count_strings(np, "clock-names");
+ if (count < 0) {
+ pr_err("%s: get clock count error\n", np->name);
+ return;
+ }
+ parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL);
+ if (!parent_names) {
+ pr_err("%s: could not allocate parent_names\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < count; i++)
+ parent_names[i] = of_clk_get_parent_name(np, i);
+
+ cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL);
+ if (!cmux_clk) {
+ pr_err("%s: could not allocate cmux_clk\n", __func__);
+ goto err_name;
+ }
+ cmux_clk->reg = base + offset;
+
+ node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
+ if (node && (offset >= 0x80))
+ cmux_clk->flags = CLKSEL_ADJUST;
+
+ rc = of_property_read_string_index(np, "clock-output-names",
+ 0, &clk_name);
+ if (rc) {
+ pr_err("%s: read clock names error\n", np->name);
+ goto err_clk;
+ }
+
+ init.name = clk_name;
+ init.ops = &cmux_ops;
+ init.parent_names = parent_names;
+ init.num_parents = count;
+ init.flags = 0;
+ cmux_clk->hw.init = &init;
+
+ clk = clk_register(NULL, &cmux_clk->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: could not register clock\n", clk_name);
+ goto err_clk;
+ }
+
+ rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ if (rc) {
+ pr_err("Could not register clock provider for node:%s\n",
+ np->name);
+ goto err_clk;
+ }
+ goto err_name;
+
+err_clk:
+ kfree(cmux_clk);
+err_name:
+ /* free *_names because they are reallocated when registered */
+ kfree(parent_names);
+}
+
+static void __init core_pll_init(struct device_node *np)
+{
+ u32 offset, mult;
+ int i, rc, count;
+ const char *clk_name, *parent_name;
+ struct clk_onecell_data *onecell_data;
+ struct clk **subclks;
+
+ rc = of_property_read_u32(np, "reg", &offset);
+ if (rc) {
+ pr_err("%s: could not get reg property\n", np->name);
+ return;
+ }
+
+ /* get the multiple of PLL */
+ mult = ioread32be(base + offset);
+
+ /* check if this PLL is disabled */
+ if (mult & PLL_KILL) {
+ pr_debug("PLL:%s is disabled\n", np->name);
+ return;
+ }
+ mult = (mult >> 1) & 0x3f;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name) {
+ pr_err("PLL: %s must have a parent\n", np->name);
+ return;
+ }
+
+ count = of_property_count_strings(np, "clock-output-names");
+ if (count < 0 || count > 4) {
+ pr_err("%s: clock is not supported\n", np->name);
+ return;
+ }
+
+ /* output clock number per PLL */
+ clocks_per_pll = count;
+
+ subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
+ if (!subclks) {
+ pr_err("%s: could not allocate subclks\n", __func__);
+ return;
+ }
+
+ onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!onecell_data) {
+ pr_err("%s: could not allocate onecell_data\n", __func__);
+ goto err_clks;
+ }
+
+ for (i = 0; i < count; i++) {
+ rc = of_property_read_string_index(np, "clock-output-names",
+ i, &clk_name);
+ if (rc) {
+ pr_err("%s: could not get clock names\n", np->name);
+ goto err_cell;
+ }
+
+ /*
+ * when count == 4, there are 4 output clocks:
+ * /1, /2, /3, /4 respectively
+ * when count < 4, there are at least 2 output clocks:
+ * /1, /2, (/4, if count == 3) respectively.
+ */
+ if (count == 4)
+ subclks[i] = clk_register_fixed_factor(NULL, clk_name,
+ parent_name, 0, mult, 1 + i);
+ else
+
+ subclks[i] = clk_register_fixed_factor(NULL, clk_name,
+ parent_name, 0, mult, 1 << i);
+
+ if (IS_ERR(subclks[i])) {
+ pr_err("%s: could not register clock\n", clk_name);
+ goto err_cell;
+ }
+ }
+
+ onecell_data->clks = subclks;
+ onecell_data->clk_num = count;
+
+ rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
+ if (rc) {
+ pr_err("Could not register clk provider for node:%s\n",
+ np->name);
+ goto err_cell;
+ }
+
+ return;
+err_cell:
+ kfree(onecell_data);
+err_clks:
+ kfree(subclks);
+}
+
+static const struct of_device_id clk_match[] __initconst = {
+ { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+ { .compatible = "fsl,core-pll-clock", .data = core_pll_init, },
+ { .compatible = "fsl,core-mux-clock", .data = core_mux_init, },
+ {}
+};
+
+static int __init ppc_corenet_clk_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+
+ np = pdev->dev.of_node;
+ base = of_iomap(np, 0);
+ if (!base) {
+ dev_err(&pdev->dev, "iomap error\n");
+ return -ENOMEM;
+ }
+ of_clk_init(clk_match);
+
+ return 0;
+}
+
+static const struct of_device_id ppc_clk_ids[] __initconst = {
+ { .compatible = "fsl,qoriq-clockgen-1.0", },
+ { .compatible = "fsl,qoriq-clockgen-2", },
+ {}
+};
+
+static struct platform_driver ppc_corenet_clk_driver = {
+ .driver = {
+ .name = "ppc_corenet_clock",
+ .owner = THIS_MODULE,
+ .of_match_table = ppc_clk_ids,
+ },
+ .probe = ppc_corenet_clk_probe,
+};
+
+static int __init ppc_corenet_clk_init(void)
+{
+ return platform_driver_register(&ppc_corenet_clk_driver);
+}
+subsys_initcall(ppc_corenet_clk_init);
+
+MODULE_AUTHOR("Tang Yuantian: <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("Clock Driver for Freescale PowerPC Corenet Platform");
+MODULE_LICENSE("GPL V2");
--
1.8.0
^ permalink raw reply related
* [PATCH 2/2 v2] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
From: Yuantian.Tang @ 2013-03-28 9:55 UTC (permalink / raw)
To: rjw; +Cc: linux-pm, viresh.kumar, cpufreq, Tang Yuantian, linuxppc-dev
From: Tang Yuantian <yuantian.tang@freescale.com>
Add cpufreq driver for Freescale e500mc, e5500 and e6500 SoCs
which are capable of changing the frequency of CPU dynamically
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
v2:
- change the per_cpu variable to point type
- fixed other issues
drivers/cpufreq/Kconfig.powerpc | 10 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/ppc-corenet-cpufreq.c | 255 ++++++++++++++++++++++++++++++++++
3 files changed, 266 insertions(+)
create mode 100644 drivers/cpufreq/ppc-corenet-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index e76992f..3a0d8d0 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE
help
This adds support for frequency switching on Maple 970FX
Evaluation Board and compatible boards (IBM JS2x blades).
+
+config PPC_CORENET_CPUFREQ
+ tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
+ depends on PPC_E500MC && OF && COMMON_CLK
+ select CPU_FREQ_TABLE
+ select CLK_PPC_CORENET
+ help
+ This adds the CPUFreq driver support for Freescale e500mc,
+ e5500 and e6500 series SoCs which are capable of changing
+ the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 863fd18..2416559 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
##################################################################################
# PowerPC platform drivers
obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o
+obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
new file mode 100644
index 0000000..a50ab5a
--- /dev/null
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/**
+ * struct cpufreq_data - cpufreq driver data
+ * @cpus_per_cluster: CPU numbers per cluster
+ * @cpufreq_lock: the mutex lock
+ */
+struct cpufreq_data {
+ int cpus_per_cluster;
+ struct mutex cpufreq_lock;
+};
+
+/**
+ * struct cpu_data - per CPU data struct
+ * @clk: the clk data of CPU
+ * @parent: the parent node of clock of cpu
+ * @table: frequency table point
+ */
+struct cpu_data {
+ struct clk *clk;
+ struct device_node *parent;
+ struct cpufreq_frequency_table *table;
+};
+
+static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
+static struct cpufreq_data freq_data;
+
+static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
+{
+ struct cpu_data *data = per_cpu(cpu_data, cpu);
+
+ return clk_get_rate(data->clk) / 1000;
+}
+
+/* reduce the duplicated frequency in frequency table */
+static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
+ int count)
+{
+ int i, j;
+
+ for (i = 1; i < count; i++) {
+ for (j = 0; j < i; j++) {
+ if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID ||
+ freq_table[j].frequency !=
+ freq_table[i].frequency)
+ continue;
+
+ freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ break;
+ }
+ }
+}
+
+static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ unsigned int cpu = policy->cpu;
+ struct device_node *np;
+ int i, count;
+ struct clk *clk;
+ struct cpufreq_frequency_table *table;
+ struct cpu_data *data;
+
+ np = of_get_cpu_node(cpu, NULL);
+ if (!np)
+ return -ENODEV;
+
+ data = kzalloc(sizeof(struct cpu_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->clk = of_clk_get(np, 0);
+ data->parent = of_parse_phandle(np, "clocks", 0);
+ if (!data->parent) {
+ pr_err("%s: could not get clock information\n", __func__);
+ goto err_nomem2;
+ }
+
+ count = of_property_count_strings(data->parent, "clock-names");
+
+ table = kcalloc(count + 1,
+ sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
+ if (!table) {
+ pr_err("%s: no memory\n", __func__);
+ goto err_nomem2;
+ }
+
+ for (i = cpu; i < freq_data.cpus_per_cluster + cpu; i++)
+ cpumask_set_cpu(i, policy->cpus);
+
+ for (i = 0; i < count; i++) {
+ table[i].index = i;
+ clk = of_clk_get(data->parent, i);
+ table[i].frequency = clk_get_rate(clk) / 1000;
+ }
+ freq_table_redup(table, count);
+ table[i].frequency = CPUFREQ_TABLE_END;
+
+ data->table = table;
+ per_cpu(cpu_data, cpu) = data;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = corenet_cpufreq_get_speed(policy->cpu);
+
+ /* set the min and max frequency properly */
+ i = cpufreq_frequency_table_cpuinfo(policy, table);
+ if (i) {
+ pr_err("invalid frequency table: %d\n", i);
+ goto err_nomem1;
+ }
+ cpufreq_frequency_table_get_attr(table, cpu);
+
+ return 0;
+
+err_nomem1:
+ kfree(table);
+err_nomem2:
+ per_cpu(cpu_data, cpu) = NULL;
+ kfree(data);
+
+ return -ENODEV;
+}
+
+static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ kfree(data->table);
+ kfree(data);
+
+ return 0;
+}
+
+static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ struct cpufreq_frequency_table *table;
+
+ table = per_cpu(cpu_data, policy->cpu)->table;
+
+ return cpufreq_frequency_table_verify(policy, table);
+}
+
+static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned int new;
+ struct clk *parent;
+ int ret;
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_target(policy, data->table,
+ target_freq, relation, &new);
+
+ if (policy->cur == data->table[new].frequency)
+ return 0;
+
+ freqs.old = policy->cur;
+ freqs.new = data->table[new].frequency;
+ freqs.cpu = policy->cpu;
+
+ mutex_lock(&freq_data.cpufreq_lock);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ parent = of_clk_get(data->parent, new);
+ ret = clk_set_parent(data->clk, parent);
+ if (ret) {
+ mutex_unlock(&freq_data.cpufreq_lock);
+ return ret;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&freq_data.cpufreq_lock);
+
+ return 0;
+}
+
+static struct freq_attr *corenet_cpu_clks_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
+ .name = "ppc_cpufreq",
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_CONST_LOOPS,
+ .init = corenet_cpufreq_cpu_init,
+ .exit = __exit_p(corenet_cpufreq_cpu_exit),
+ .verify = corenet_cpufreq_verify,
+ .target = corenet_cpufreq_target,
+ .get = corenet_cpufreq_get_speed,
+ .attr = corenet_cpu_clks_attr,
+};
+
+static const struct of_device_id node_matches[] __initconst = {
+ { .compatible = "fsl,qoriq-clockgen-1.0", .data = (void *)1, },
+ { .compatible = "fsl,qoriq-clockgen-2", .data = (void *)8, },
+ {}
+};
+
+static int __init ppc_corenet_cpufreq_init(void)
+{
+ int ret = 0;
+ struct device_node *np;
+ const struct of_device_id *match;
+
+ np = of_find_matching_node(NULL, node_matches);
+ if (!np)
+ return -ENODEV;
+
+ match = of_match_node(node_matches, np);
+ freq_data.cpus_per_cluster = (unsigned long)match->data;
+ mutex_init(&freq_data.cpufreq_lock);
+ of_node_put(np);
+
+ ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+ if (ret)
+ return ret;
+
+ pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+
+ return ret;
+}
+module_init(ppc_corenet_cpufreq_init);
+
+static void __exit ppc_corenet_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+}
+module_exit(ppc_corenet_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
--
1.8.0
^ permalink raw reply related
* RE: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
From: Wang Dongsheng-B40534 @ 2013-03-28 3:09 UTC (permalink / raw)
To: Wood Scott-B07421
Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
Zhao Chenhui-B35336
In-Reply-To: <1364415959.31930.16@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 28, 2013 4:26 AM
> To: Wang Dongsheng-B40534
> Cc: Wood Scott-B07421; Gala Kumar-B11780; linuxppc-dev@lists.ozlabs.org;
> Zhao Chenhui-B35336; Li Yang-R58472
> Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
>=20
> On 03/26/2013 10:21:04 PM, Wang Dongsheng-B40534 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Wednesday, March 27, 2013 1:36 AM
> > > To: Wang Dongsheng-B40534
> > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > linuxppc-dev@lists.ozlabs.org;
> > > Zhao Chenhui-B35336; Li Yang-R58472
> > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
> > >
> > > On 03/25/2013 10:27:24 PM, Wang Dongsheng-B40534 wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wood Scott-B07421
> > > > > Sent: Saturday, March 23, 2013 6:11 AM
> > > > > To: Wang Dongsheng-B40534
> > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > linuxppc-dev@lists.ozlabs.org;
> > > > > Zhao Chenhui-B35336; Li Yang-R58472
> > > > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup
> > support
> > > > >
> > > > > On 03/22/2013 12:46:24 AM, Wang Dongsheng-B40534 wrote:
> > > > > > Under what case is unsafe, please make sense.
> > > > >
> > > > > char buffer[1] =3D { '5' };
> > > > > write(fd, &buffer, 1);
> > > > >
> > > > > What comes after that '5' byte in the pointer you pass to
> > kstrtol?
> > > > >
> > > > The buffer is userspace. It will fall in the kernel space.
> > > > Kernel will get a free page, and copy the buffer to page.
> > > > This page has been cleared before copy to page.
> > > > The page has already have null-terminated.
> > >
> > > It doesn't allocate a whole page, it uses kmalloc (not kzalloc!).
> > Even
> > > if kzalloc were used, a larger user buffer could be the exact size
> > of the
> > > region that was allocated.
> > >
> > > See memdup_user() in mm/util.c
> > >
> > Did you miss something?
> > See fill_write_buffer() in fs/sysfs/file.c. It's used
> > get_zeroed_page()...
>=20
> OK, I was looking at fs/sysfs/bin.c which is something slightly different=
.
>=20
> fill_write_buffer() forces the size to be no more than "PAGE_SIZE - 1"
> so we know there's a terminator.
>=20
> Perhaps kernel/rtmutex-tester.c and kernel/time/clocksource.c are
> similarly confused?
>=20
Yes. But its depends on file->f_op.
See vfs_write in fs/read_write.c.
^ permalink raw reply
* RE: [PATCH 3/3] cpufreq: Add cpufreq driver for Freescale e500mc SOCs
From: Tang Yuantian-B29983 @ 2013-03-28 3:02 UTC (permalink / raw)
To: Phillips Kim-R1AAHA
Cc: rjw@sisk.pl, linuxppc-dev@lists.ozlabs.org,
cpufreq@vger.kernel.org, linux-pm@vger.kernel.org
In-Reply-To: <20130327143236.7cb4613b78ad18d79bfbcc57@freescale.com>
> > + return ret;
> > +
> > + pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> > +
> > + return ret;
> > +}
> > +
> > +static void __exit ppc_corenet_cpufreq_exit(void) {
> > + cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +}
> > +
> > +module_init(ppc_corenet_cpufreq_init);
> > +module_exit(ppc_corenet_cpufreq_exit);
>=20
> this needs to be a module_platform_driver.
>=20
The compatible string is used for clock driver.
This driver can not be a platform_driver.
-Yuantian
^ permalink raw reply
* RE: [PATCH 2/3] powerpc/mpic: add global timer support
From: Wang Dongsheng-B40534 @ 2013-03-28 2:29 UTC (permalink / raw)
To: Wood Scott-B07421
Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <1364404295.31930.1@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 28, 2013 1:12 AM
> To: Wang Dongsheng-B40534
> Cc: Wood Scott-B07421; Gala Kumar-B11780; linuxppc-dev@lists.ozlabs.org;
> Li Yang-R58472
> Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
>=20
> On 03/26/2013 10:23:38 PM, Wang Dongsheng-B40534 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Wednesday, March 27, 2013 1:32 AM
> > > To: Wang Dongsheng-B40534
> > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > linuxppc-dev@lists.ozlabs.org;
> > > Li Yang-R58472
> > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > >
> > > On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wood Scott-B07421
> > > > > Sent: Saturday, March 23, 2013 6:30 AM
> > > > > To: Wang Dongsheng-B40534
> > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > linuxppc-dev@lists.ozlabs.org;
> > > > > Li Yang-R58472
> > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > > >
> > > > > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Wood Scott-B07421
> > > > > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > > > > To: Wang Dongsheng-B40534
> > > > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > > > linuxppc-dev@lists.ozlabs.org;
> > > > > > > Li Yang-R58472
> > > > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer
> > support
> > > > > > >
> > > > > > > BTW, the input clock frequency has been similarly scaled,
> > yet
> > > > you
> > > > > > don't
> > > > > > > try to scrounge up that information to get further
> > precision...
> > > > > > >
> > > > > > Let's go back patch, do you think the code is repeated?
> > > > > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch,
> > > > there
> > > > > > will be no redundant code.
> > > > >
> > > > > I'd rather that branch be kept and the more complicated branch
> > > > deleted,
> > > > > and priv->timerfreq frequency be adjusted on initialization to
> > > > account
> > > > > for the scaler.
> > > >
> > > > static void convert_ticks_to_time(struct timer_group_priv *priv,
> > > > const u64 ticks, struct timeval *time) {
> > > > u64 tmp_sec;
> > > >
> > > > time->tv_sec =3D (__kernel_time_t)div_u64(ticks,
> > > > priv->timerfreq);
> > > > tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
> > > >
> > > > time->tv_usec =3D (__kernel_suseconds_t)
> > > > div_u64((ticks - tmp_sec) * 1000000,
> > priv->timerfreq);
> > > >
> > > > return;
> > > > }
> > > >
> > > > timer_group_get_freq() {
> > > > ...
> > > > if (priv->flags & FSL_GLOBAL_TIMER) {
> > > > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > > > priv->timerfreq /=3D div;
> > > > }
> > > > ...
> > > > }
> > > > Do you want to do that?
> > >
> > > if (priv->flags & FSL_GLOBAL_TIMER)
> > > priv->timerfreq /=3D 64;
> > >
> > > ...but otherwise yes.
> > Ok, I would like do this.
> >
> > if (priv->flags & FSL_GLOBAL_TIMER) {
> > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > priv->timerfreq /=3D div;
>=20
> Why? What do you get out of that obfuscation?
>=20
Change MPIC_TIMER_TCR_CLKDIV_64 to MPIC_TIMER_TCR_CLKDIV
/* Clock Ratio
* Divide by 64 0x00000300
* Divide by 32 0x00000200
* Divide by 16 0x00000100
* Divide by 8 0x00000000 (Hardware default div)
*/
#define MPIC_TIMER_TCR_CLKDIV 0x00000300
timer_group_init() {
...
/* Init FSL timer hardware */
if (priv->flags & FSL_GLOBAL_TIMER)
setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
...
}
mpic_timer_resume() {
...
/* Init FSL timer hardware */
if (priv->flags & FSL_GLOBAL_TIMER)
setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
...
}
Because macro is friendly, and other functions also used the macro.
^ permalink raw reply
* Re: [PATCH] powerpc: drop even more unused Kconfig symbols
From: Michael Ellerman @ 2013-03-28 0:31 UTC (permalink / raw)
To: Paul Bolle; +Cc: linuxppc-dev, linux-kernel, Paul Mackerras
In-Reply-To: <1364381495.1345.21.camel@x61.thuisdomein>
On Wed, Mar 27, 2013 at 11:51:35AM +0100, Paul Bolle wrote:
> On Thu, 2013-03-21 at 12:10 +0100, Paul Bolle wrote:
> > diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
> > index 79d2225..9eea710 100644
> > --- a/arch/powerpc/platforms/wsp/Kconfig
> > +++ b/arch/powerpc/platforms/wsp/Kconfig
> > @@ -29,7 +29,3 @@ config PPC_CHROMA
> > default y
> >
> > endmenu
> > -
> > -config PPC_A2_DD2
> > - bool "Support for DD2 based A2/WSP systems"
> > - depends on PPC_A2
>
> This part was not included in the "powerpc: remove PReP" follow up
> patch. Should I resend separately?
Yes thanks.
It was added in commit a1d0d98 "Add WSP platform" but should not have
been, it was to support bringup hacks that were never merged upstream.
cheers
^ permalink raw reply
* Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
From: Scott Wood @ 2013-03-27 20:25 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Wood Scott-B07421, Gala Kumar-B11780,
linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
Zhao Chenhui-B35336
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBB71C@039-SN2MPN1-022.039d.mgd.msft.net>
On 03/26/2013 10:21:04 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Wednesday, March 27, 2013 1:36 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Zhao Chenhui-B35336; Li Yang-R58472
> > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
> >
> > On 03/25/2013 10:27:24 PM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Saturday, March 23, 2013 6:11 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Zhao Chenhui-B35336; Li Yang-R58472
> > > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup =20
> support
> > > >
> > > > On 03/22/2013 12:46:24 AM, Wang Dongsheng-B40534 wrote:
> > > > > Under what case is unsafe, please make sense.
> > > >
> > > > char buffer[1] =3D { '5' };
> > > > write(fd, &buffer, 1);
> > > >
> > > > What comes after that '5' byte in the pointer you pass to =20
> kstrtol?
> > > >
> > > The buffer is userspace. It will fall in the kernel space.
> > > Kernel will get a free page, and copy the buffer to page.
> > > This page has been cleared before copy to page.
> > > The page has already have null-terminated.
> >
> > It doesn't allocate a whole page, it uses kmalloc (not kzalloc!). =20
> Even
> > if kzalloc were used, a larger user buffer could be the exact size =20
> of the
> > region that was allocated.
> >
> > See memdup_user() in mm/util.c
> >
> Did you miss something?
> See fill_write_buffer() in fs/sysfs/file.c. It's used =20
> get_zeroed_page()...
OK, I was looking at fs/sysfs/bin.c which is something slightly =20
different.
fill_write_buffer() forces the size to be no more than "PAGE_SIZE - 1" =20
so we know there's a terminator.
Perhaps kernel/rtmutex-tester.c and kernel/time/clocksource.c are =20
similarly confused?
-Scott=
^ permalink raw reply
* Re: [PATCH 2/3] x86/mm/numa: use setup_nr_node_ids() instead of opencoding.
From: H. Peter Anvin @ 2013-03-27 19:32 UTC (permalink / raw)
To: Yinghai Lu
Cc: Cody P Schafer, linux-kernel, linux-mm, Ingo Molnar,
Paul Mackerras, Andrew Morton, linuxppc-dev, Thomas Gleixner
In-Reply-To: <CAE9FiQVSPdCqaLKapG4DJ1CXtPKb8F29=s_-e9OLpXP7yG1XTA@mail.gmail.com>
On 03/26/2013 10:56 AM, Yinghai Lu wrote:
>
> For 1 and 2,
>
> Acked-by: Yinghai Lu <yinghai@kernel.org>
>
Similarly:
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
-hpa
^ permalink raw reply
* Re: [PATCH 3/3] cpufreq: Add cpufreq driver for Freescale e500mc SOCs
From: Kim Phillips @ 2013-03-27 19:32 UTC (permalink / raw)
To: Yuantian.Tang; +Cc: rjw, linuxppc-dev, cpufreq, linux-pm
In-Reply-To: <1364265391-26077-3-git-send-email-Yuantian.Tang@freescale.com>
On Tue, 26 Mar 2013 10:36:31 +0800
<Yuantian.Tang@freescale.com> wrote:
> +static int __init ppc_corenet_cpufreq_init(void)
> +{
> + int ret = 0;
> + struct device_node *np;
> + const struct of_device_id *match;
> +
> + np = of_find_matching_node(NULL, node_matches);
> + if (!np)
> + return -ENODEV;
> +
> + match = of_match_node(node_matches, np);
> + freq_data.cpus_per_cluster = (long)match->data;
> + mutex_init(&freq_data.cpufreq_lock);
> + of_node_put(np);
> +
> + ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> + if (ret)
> + return ret;
> +
> + pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> +
> + return ret;
> +}
> +
> +static void __exit ppc_corenet_cpufreq_exit(void)
> +{
> + cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +}
> +
> +module_init(ppc_corenet_cpufreq_init);
> +module_exit(ppc_corenet_cpufreq_exit);
this needs to be a module_platform_driver.
Kim
^ permalink raw reply
* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
From: Scott Wood @ 2013-03-27 17:50 UTC (permalink / raw)
To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-6-git-send-email-mihai.caraman@freescale.com>
On 03/26/2013 05:05:10 PM, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb =20
> entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
>=20
> arch/powerpc/kvm/e500_mmu.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> + vcpu->arch.mmucfg &=3D ~MMUCFG_LRAT;
> +
> if (has_feature(vcpu, VCPU_FTR_E_PT))
> vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
> else
> vcpu->arch.eptcfg =3D 0;
>=20
> + /* Guest mmu emulation currently doesn't handle E.PT */
> + vcpu->arch.tlbcfg[0] &=3D ~TLBnCFG_PT;
> + vcpu->arch.tlbcfg[1] &=3D ~TLBnCFG_IND;
You're clearing these bits *after* calling has_feature() -- doesn't =20
has_feature() depend on those bits being cleared to not advertise E_PT =20
support?
-Scott=
^ permalink raw reply
* [PATCH 04/22] block: Convert bio_for_each_segment() to bvec_iter
From: Kent Overstreet @ 2013-03-27 17:39 UTC (permalink / raw)
To: axboe, linux-kernel, linux-fsdevel, dm-devel
Cc: Jeremy Fitzhardinge, Herton Ronaldo Krzesinski, Jan Kara,
Ed L. Cashin, neilb, Kent Overstreet, support, Paul Clements,
virtualization, Keith Busch, linux-mm, Quoc-Son Anh,
Paul Mackerras, James E.J. Bottomley, Stephen Hemminger,
Joshua Morris, Nick Piggin, devel, linux-s390, xen-devel,
Jerome Marchand, Mike Snitzer, linux-scsi, Minchan Kim,
Sebastian Ott, Philip Kelleher, Steven Whitehouse, cluster-devel,
Geert Uytterhoeven, Asai Thambi S P, Lars Ellenberg, Sam Bradshaw,
Nitin Gupta, cbe-oss-dev, nbd-general, Sage Weil,
Konrad Rzeszutek Wilk, Heiko Carstens, DL-MPTFusionLinux,
Chris Metcalf, linux-raid, Martin Schwidefsky, linux-m68k,
Alexander Viro, Selvan Mani, ceph-devel, drbd-user,
Nagalakshmi Nandigama, Yehuda Sadeh, Alex Elder, Seth Jennings,
Martin K. Petersen, Geoff Levand, Jiri Kosina, Darrick J. Wong,
Jim Paris, Sreekanth Reddy, Vivek Goyal, Greg Kroah-Hartman, tj,
linux390, Andrew Morton, linuxppc-dev, Guo Chao, Matthew Wilcox
In-Reply-To: <1364405992-28424-1-git-send-email-koverstreet@google.com>
More prep work for immutable biovecs - with immutable bvecs drivers
won't be able to use the biovec directly, they'll need to use helpers
that take into account bio->bi_iter.bi_bvec_done.
This updates callers for the new usage without changing the
implementation yet.
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: "Ed L. Cashin" <ecashin@coraid.com>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Lars Ellenberg <drbd-dev@lists.linbit.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Paul Clements <Paul.Clements@steeleye.com>
Cc: Jim Paris <jim@jtan.com>
Cc: Geoff Levand <geoff@infradead.org>
Cc: Yehuda Sadeh <yehuda@inktank.com>
Cc: Sage Weil <sage@inktank.com>
Cc: Alex Elder <elder@inktank.com>
Cc: ceph-devel@vger.kernel.org
Cc: Joshua Morris <josh.h.morris@us.ibm.com>
Cc: Philip Kelleher <pjk1939@linux.vnet.ibm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Neil Brown <neilb@suse.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
Cc: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
Cc: support@lsi.com
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Kent Overstreet <koverstreet@google.com>
Cc: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Guo Chao <yan@linux.vnet.ibm.com>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Quoc-Son Anh <quoc-sonx.anh@intel.com>
Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Jerome Marchand <jmarchan@redhat.com>
Cc: Seth Jennings <sjenning@linux.vnet.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Mike Snitzer <snitzer@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-m68k@lists.linux-m68k.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: drbd-user@lists.linbit.com
Cc: nbd-general@lists.sourceforge.net
Cc: cbe-oss-dev@lists.ozlabs.org
Cc: xen-devel@lists.xensource.com
Cc: virtualization@lists.linux-foundation.org
Cc: linux-raid@vger.kernel.org
Cc: linux-s390@vger.kernel.org
Cc: DL-MPTFusionLinux@lsi.com
Cc: linux-scsi@vger.kernel.org
Cc: devel@driverdev.osuosl.org
Cc: linux-fsdevel@vger.kernel.org
Cc: cluster-devel@redhat.com
Cc: linux-mm@kvack.org
---
arch/m68k/emu/nfblock.c | 11 ++++---
arch/powerpc/sysdev/axonram.c | 18 +++++------
block/blk-merge.c | 45 ++++++++++++++-------------
drivers/block/aoe/aoecmd.c | 16 +++++-----
drivers/block/brd.c | 12 ++++----
drivers/block/drbd/drbd_main.c | 27 +++++++++--------
drivers/block/drbd/drbd_receiver.c | 13 ++++----
drivers/block/drbd/drbd_worker.c | 8 ++---
drivers/block/floppy.c | 12 ++++----
drivers/block/loop.c | 23 +++++++-------
drivers/block/mtip32xx/mtip32xx.c | 13 ++++----
drivers/block/nbd.c | 12 ++++----
drivers/block/nvme.c | 27 +++++++++--------
drivers/block/ps3vram.c | 10 +++---
drivers/block/rbd.c | 36 +++++++++++-----------
drivers/block/rsxx/dma.c | 11 ++++---
drivers/block/xen-blkfront.c | 14 ++++-----
drivers/md/md.c | 16 +++++-----
drivers/md/raid5.c | 12 ++++----
drivers/s390/block/dcssblk.c | 14 ++++-----
drivers/s390/block/xpram.c | 10 +++---
drivers/scsi/mpt2sas/mpt2sas_transport.c | 31 ++++++++++---------
drivers/scsi/mpt3sas/mpt3sas_transport.c | 31 ++++++++++---------
drivers/staging/zram/zram_drv.c | 19 ++++++------
fs/bio-integrity.c | 30 +++++++++---------
fs/bio.c | 16 +++++-----
fs/gfs2/lops.c | 10 +++---
include/linux/bio.h | 25 ++++++++-------
include/linux/blkdev.h | 7 +++--
mm/bounce.c | 52 +++++++++++++++-----------------
30 files changed, 296 insertions(+), 285 deletions(-)
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 9070d6c..d2b260c 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -62,17 +62,18 @@ struct nfhd_device {
static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
{
struct nfhd_device *dev = queue->queuedata;
- struct bio_vec *bvec;
- int i, dir, len, shift;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+ int dir, len, shift;
sector_t sec = bio->bi_iter.bi_sector;
dir = bio_data_dir(bio);
shift = dev->bshift;
- bio_for_each_segment(bvec, bio, i) {
- len = bvec->bv_len;
+ bio_for_each_segment(bvec, bio, iter) {
+ len = bvec.bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
- bvec_to_phys(bvec));
+ bvec_to_phys(&bvec));
sec += len;
}
bio_endio(bio, 0);
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index f33bcba..47b6b9f 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -109,28 +109,28 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
unsigned long phys_mem, phys_end;
void *user_mem;
- struct bio_vec *vec;
+ struct bio_vec vec;
unsigned int transfered;
- unsigned short idx;
+ struct bvec_iter iter;
phys_mem = bank->io_addr + (bio->bi_iter.bi_sector <<
AXON_RAM_SECTOR_SHIFT);
phys_end = bank->io_addr + bank->size;
transfered = 0;
- bio_for_each_segment(vec, bio, idx) {
- if (unlikely(phys_mem + vec->bv_len > phys_end)) {
+ bio_for_each_segment(vec, bio, iter) {
+ if (unlikely(phys_mem + vec.bv_len > phys_end)) {
bio_io_error(bio);
return;
}
- user_mem = page_address(vec->bv_page) + vec->bv_offset;
+ user_mem = page_address(vec.bv_page) + vec.bv_offset;
if (bio_data_dir(bio) == READ)
- memcpy(user_mem, (void *) phys_mem, vec->bv_len);
+ memcpy(user_mem, (void *) phys_mem, vec.bv_len);
else
- memcpy((void *) phys_mem, user_mem, vec->bv_len);
+ memcpy((void *) phys_mem, user_mem, vec.bv_len);
- phys_mem += vec->bv_len;
- transfered += vec->bv_len;
+ phys_mem += vec.bv_len;
+ transfered += vec.bv_len;
}
bio_endio(bio, 0);
}
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 5b04c25..cd15b38 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -12,10 +12,11 @@
static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
struct bio *bio)
{
- struct bio_vec *bv, *bvprv = NULL;
- int cluster, i, high, highprv = 1;
+ struct bio_vec bv, bvprv;
+ int cluster, high, highprv = 1;
unsigned int seg_size, nr_phys_segs;
struct bio *fbio, *bbio;
+ struct bvec_iter iter;
if (!bio)
return 0;
@@ -25,25 +26,25 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
seg_size = 0;
nr_phys_segs = 0;
for_each_bio(bio) {
- bio_for_each_segment(bv, bio, i) {
+ bio_for_each_segment(bv, bio, iter) {
/*
* the trick here is making sure that a high page is
* never considered part of another segment, since that
* might change with the bounce page.
*/
- high = page_to_pfn(bv->bv_page) > queue_bounce_pfn(q);
+ high = page_to_pfn(bv.bv_page) > queue_bounce_pfn(q);
if (high || highprv)
goto new_segment;
if (cluster) {
- if (seg_size + bv->bv_len
+ if (seg_size + bv.bv_len
> queue_max_segment_size(q))
goto new_segment;
- if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
+ if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bv))
goto new_segment;
- if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
+ if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bv))
goto new_segment;
- seg_size += bv->bv_len;
+ seg_size += bv.bv_len;
bvprv = bv;
continue;
}
@@ -54,7 +55,7 @@ new_segment:
nr_phys_segs++;
bvprv = bv;
- seg_size = bv->bv_len;
+ seg_size = bv.bv_len;
highprv = high;
}
bbio = bio;
@@ -110,21 +111,21 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
return 0;
}
-static void
+static inline void
__blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
- struct scatterlist *sglist, struct bio_vec **bvprv,
+ struct scatterlist *sglist, struct bio_vec *bvprv,
struct scatterlist **sg, int *nsegs, int *cluster)
{
int nbytes = bvec->bv_len;
- if (*bvprv && *cluster) {
+ if (*sg && *cluster) {
if ((*sg)->length + nbytes > queue_max_segment_size(q))
goto new_segment;
- if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec))
+ if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
goto new_segment;
- if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec))
+ if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
goto new_segment;
(*sg)->length += nbytes;
@@ -150,7 +151,7 @@ new_segment:
sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
(*nsegs)++;
}
- *bvprv = bvec;
+ *bvprv = *bvec;
}
/*
@@ -160,7 +161,7 @@ new_segment:
int blk_rq_map_sg(struct request_queue *q, struct request *rq,
struct scatterlist *sglist)
{
- struct bio_vec *bvec, *bvprv;
+ struct bio_vec bvec, bvprv;
struct req_iterator iter;
struct scatterlist *sg;
int nsegs, cluster;
@@ -171,10 +172,9 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
/*
* for each bio in rq
*/
- bvprv = NULL;
sg = NULL;
rq_for_each_segment(bvec, rq, iter) {
- __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+ __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
&nsegs, &cluster);
} /* segments in rq */
@@ -223,18 +223,17 @@ EXPORT_SYMBOL(blk_rq_map_sg);
int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
struct scatterlist *sglist)
{
- struct bio_vec *bvec, *bvprv;
+ struct bio_vec bvec, bvprv;
struct scatterlist *sg;
int nsegs, cluster;
- unsigned long i;
+ struct bvec_iter iter;
nsegs = 0;
cluster = blk_queue_cluster(q);
- bvprv = NULL;
sg = NULL;
- bio_for_each_segment(bvec, bio, i) {
- __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+ bio_for_each_segment(bvec, bio, iter) {
+ __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
&nsegs, &cluster);
} /* segments in bio */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 80e5d65..63acfa1 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -887,12 +887,12 @@ rqbiocnt(struct request *r)
static void
bio_pageinc(struct bio *bio)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
struct page *page;
- int i;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i) {
- page = bv->bv_page;
+ bio_for_each_segment(bv, bio, iter) {
+ page = bv.bv_page;
/* Non-zero page count for non-head members of
* compound pages is no longer allowed by the kernel,
* but this has never been seen here.
@@ -909,11 +909,11 @@ bio_pageinc(struct bio *bio)
static void
bio_pagedec(struct bio *bio)
{
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i)
- atomic_dec(&bv->bv_page->_count);
+ bio_for_each_segment(bv, bio, iter)
+ atomic_dec(&bv.bv_page->_count);
}
static void
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index ddf2b79..0f3a3bb 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -328,9 +328,9 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
struct block_device *bdev = bio->bi_bdev;
struct brd_device *brd = bdev->bd_disk->private_data;
int rw;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
sector_t sector;
- int i;
+ struct bvec_iter iter;
int err = -EIO;
sector = bio->bi_iter.bi_sector;
@@ -347,10 +347,10 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
if (rw == READA)
rw = READ;
- bio_for_each_segment(bvec, bio, i) {
- unsigned int len = bvec->bv_len;
- err = brd_do_bvec(brd, bvec->bv_page, len,
- bvec->bv_offset, rw, sector);
+ bio_for_each_segment(bvec, bio, iter) {
+ unsigned int len = bvec.bv_len;
+ err = brd_do_bvec(brd, bvec.bv_page, len,
+ bvec.bv_offset, rw, sector);
if (err)
break;
sector += len >> SECTOR_SHIFT;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e98da67..e90074c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1537,15 +1537,17 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
{
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+
/* hint all but last page with MSG_MORE */
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_no_send_page(mdev, bvec->bv_page,
- bvec->bv_offset, bvec->bv_len,
- i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+ err = _drbd_no_send_page(mdev, bvec.bv_page,
+ bvec.bv_offset, bvec.bv_len,
+ bio_iter_last(bio, iter)
+ ? 0 : MSG_MORE);
if (err)
return err;
}
@@ -1554,15 +1556,16 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
{
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+
/* hint all but last page with MSG_MORE */
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_send_page(mdev, bvec->bv_page,
- bvec->bv_offset, bvec->bv_len,
- i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+ err = _drbd_send_page(mdev, bvec.bv_page,
+ bvec.bv_offset, bvec.bv_len,
+ bio_iter_last(bio, iter) ? 0 : MSG_MORE);
if (err)
return err;
}
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bd27a65..7735ce0 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1593,9 +1593,10 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size)
static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
sector_t sector, int data_size)
{
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct bio *bio;
- int dgs, err, i, expect;
+ int dgs, err, expect;
void *dig_in = mdev->tconn->int_dig_in;
void *dig_vv = mdev->tconn->int_dig_vv;
@@ -1615,11 +1616,11 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
bio = req->master_bio;
D_ASSERT(sector == bio->bi_iter.bi_sector);
- bio_for_each_segment(bvec, bio, i) {
- void *mapped = kmap(bvec->bv_page) + bvec->bv_offset;
- expect = min_t(int, data_size, bvec->bv_len);
+ bio_for_each_segment(bvec, bio, iter) {
+ void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
+ expect = min_t(int, data_size, bvec.bv_len);
err = drbd_recv_all_warn(mdev->tconn, mapped, expect);
- kunmap(bvec->bv_page);
+ kunmap(bvec.bv_page);
if (err)
return err;
data_size -= expect;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 424dc7b..f961a3b 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -312,8 +312,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
{
struct hash_desc desc;
struct scatterlist sg;
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
desc.tfm = tfm;
desc.flags = 0;
@@ -321,8 +321,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
sg_init_table(&sg, 1);
crypto_hash_init(&desc);
- bio_for_each_segment(bvec, bio, i) {
- sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset);
+ bio_for_each_segment(bvec, bio, iter) {
+ sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
crypto_hash_update(&desc, &sg, sg.length);
}
crypto_hash_final(&desc, digest);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index f09fb23..ffea352 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2351,7 +2351,7 @@ static void rw_interrupt(void)
/* Compute maximal contiguous buffer size. */
static int buffer_chain_size(void)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
int size;
struct req_iterator iter;
char *base;
@@ -2360,10 +2360,10 @@ static int buffer_chain_size(void)
size = 0;
rq_for_each_segment(bv, current_req, iter) {
- if (page_address(bv->bv_page) + bv->bv_offset != base + size)
+ if (page_address(bv.bv_page) + bv.bv_offset != base + size)
break;
- size += bv->bv_len;
+ size += bv.bv_len;
}
return size >> 9;
@@ -2389,7 +2389,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
static void copy_buffer(int ssize, int max_sector, int max_sector_2)
{
int remaining; /* number of transferred 512-byte sectors */
- struct bio_vec *bv;
+ struct bio_vec bv;
char *buffer;
char *dma_buffer;
int size;
@@ -2427,10 +2427,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
if (!remaining)
break;
- size = bv->bv_len;
+ size = bv.bv_len;
SUPBOUND(size, remaining);
- buffer = page_address(bv->bv_page) + bv->bv_offset;
+ buffer = page_address(bv.bv_page) + bv.bv_offset;
if (dma_buffer + size >
floppy_track_buffer + (max_buffer_sectors << 10) ||
dma_buffer < floppy_track_buffer) {
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2e4e0be..cd4a90e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -286,9 +286,10 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
{
int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
struct page *page);
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct page *page = NULL;
- int i, ret = 0;
+ int ret = 0;
if (lo->transfer != transfer_none) {
page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
@@ -300,11 +301,11 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
do_lo_send = do_lo_send_direct_write;
}
- bio_for_each_segment(bvec, bio, i) {
- ret = do_lo_send(lo, bvec, pos, page);
+ bio_for_each_segment(bvec, bio, iter) {
+ ret = do_lo_send(lo, &bvec, pos, page);
if (ret < 0)
break;
- pos += bvec->bv_len;
+ pos += bvec.bv_len;
}
if (page) {
kunmap(page);
@@ -390,20 +391,20 @@ do_lo_receive(struct loop_device *lo,
static int
lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
{
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
ssize_t s;
- int i;
- bio_for_each_segment(bvec, bio, i) {
- s = do_lo_receive(lo, bvec, bsize, pos);
+ bio_for_each_segment(bvec, bio, iter) {
+ s = do_lo_receive(lo, &bvec, bsize, pos);
if (s < 0)
return s;
- if (s != bvec->bv_len) {
+ if (s != bvec.bv_len) {
zero_fill_bio(bio);
break;
}
- pos += bvec->bv_len;
+ pos += bvec.bv_len;
}
return 0;
}
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 85b9f12..daf84a3 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3731,7 +3731,8 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
{
struct driver_data *dd = queue->queuedata;
struct scatterlist *sg;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
int nents = 0;
int tag = 0;
@@ -3782,11 +3783,11 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
}
/* Create the scatter list for this bio. */
- bio_for_each_segment(bvec, bio, nents) {
- sg_set_page(&sg[nents],
- bvec->bv_page,
- bvec->bv_len,
- bvec->bv_offset);
+ bio_for_each_segment(bvec, bio, iter) {
+ sg_set_page(&sg[nents++],
+ bvec.bv_page,
+ bvec.bv_len,
+ bvec.bv_offset);
}
/* Issue the read/write. */
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 7fecc78..c426d18 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -271,7 +271,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
if (nbd_cmd(req) == NBD_CMD_WRITE) {
struct req_iterator iter;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
/*
* we are really probing at internals to determine
* whether to set MSG_MORE or not...
@@ -281,8 +281,8 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
if (!rq_iter_last(req, iter))
flags = MSG_MORE;
dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
- nbd->disk->disk_name, req, bvec->bv_len);
- result = sock_send_bvec(nbd, bvec, flags);
+ nbd->disk->disk_name, req, bvec.bv_len);
+ result = sock_send_bvec(nbd, &bvec, flags);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk),
"Send data failed (result %d)\n",
@@ -378,10 +378,10 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
nbd->disk->disk_name, req);
if (nbd_cmd(req) == NBD_CMD_READ) {
struct req_iterator iter;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
rq_for_each_segment(bvec, req, iter) {
- result = sock_recv_bvec(nbd, bvec);
+ result = sock_recv_bvec(nbd, &bvec);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
result);
@@ -389,7 +389,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
return req;
}
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
- nbd->disk->disk_name, req, bvec->bv_len);
+ nbd->disk->disk_name, req, bvec.bv_len);
}
}
return req;
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index bc97493..faddcf3 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -380,7 +380,7 @@ static void bio_completion(struct nvme_dev *dev, void *ctx,
nvme_free_iod(dev, iod);
if (status) {
bio_endio(bio, -EIO);
- } else if (bio->bi_vcnt > bio->bi_iter.bi_idx) {
+ } else if (bio->bi_iter.bi_size) {
requeue_bio(dev, bio);
} else {
bio_endio(bio, 0);
@@ -476,33 +476,34 @@ static int nvme_setup_prps(struct nvme_dev *dev,
static int nvme_map_bio(struct device *dev, struct nvme_iod *iod,
struct bio *bio, enum dma_data_direction dma_dir, int psegs)
{
- struct bio_vec *bvec, *bvprv = NULL;
+ struct bio_vec bvec, bvprv;
+ struct bvec_iter iter;
struct scatterlist *sg = NULL;
- int i, old_idx, length = 0, nsegs = 0;
+ int length = 0, nsegs = 0, first = 1;
sg_init_table(iod->sg, psegs);
- old_idx = bio->bi_iter.bi_idx;
- bio_for_each_segment(bvec, bio, i) {
- if (bvprv && BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) {
- sg->length += bvec->bv_len;
+ bio_for_each_segment(bvec, bio, iter) {
+ if (!first && BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) {
+ sg->length += bvec.bv_len;
} else {
- if (bvprv && BIOVEC_NOT_VIRT_MERGEABLE(bvprv, bvec))
+ if (!first && BIOVEC_NOT_VIRT_MERGEABLE(&bvprv, &bvec))
break;
sg = sg ? sg + 1 : iod->sg;
- sg_set_page(sg, bvec->bv_page, bvec->bv_len,
- bvec->bv_offset);
+ sg_set_page(sg, bvec.bv_page,
+ bvec.bv_len, bvec.bv_offset);
nsegs++;
}
- length += bvec->bv_len;
+ length += bvec.bv_len;
bvprv = bvec;
+ first = 0;
}
- bio->bi_iter.bi_idx = i;
iod->nents = nsegs;
sg_mark_end(sg);
if (dma_map_sg(dev, iod->sg, iod->nents, dma_dir) == 0) {
- bio->bi_iter.bi_idx = old_idx;
return -ENOMEM;
}
+
+ bio->bi_iter = iter;
return length;
}
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 75e112d..c30864d 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -555,14 +555,14 @@ static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
const char *op = write ? "write" : "read";
loff_t offset = bio->bi_sector << 9;
int error = 0;
- struct bio_vec *bvec;
- unsigned int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct bio *next;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
/* PS3 is ppc64, so we don't handle highmem */
- char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
- size_t len = bvec->bv_len, retlen;
+ char *ptr = page_address(bvec.bv_page) + bvec.bv_offset;
+ size_t len = bvec.bv_len, retlen;
dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op,
len, offset);
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 8115eb2..d1e4fd8 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -898,22 +898,22 @@ static void bio_chain_put(struct bio *chain)
*/
static void zero_bio_chain(struct bio *chain, int start_ofs)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
unsigned long flags;
void *buf;
- int i;
int pos = 0;
while (chain) {
- bio_for_each_segment(bv, chain, i) {
- if (pos + bv->bv_len > start_ofs) {
+ bio_for_each_segment(bv, chain, iter) {
+ if (pos + bv.bv_len > start_ofs) {
int remainder = max(start_ofs - pos, 0);
- buf = bvec_kmap_irq(bv, &flags);
+ buf = bvec_kmap_irq(&bv, &flags);
memset(buf + remainder, 0,
- bv->bv_len - remainder);
+ bv.bv_len - remainder);
bvec_kunmap_irq(buf, &flags);
}
- pos += bv->bv_len;
+ pos += bv.bv_len;
}
chain = chain->bi_next;
@@ -929,11 +929,11 @@ static struct bio *bio_clone_range(struct bio *bio_src,
unsigned int len,
gfp_t gfpmask)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
+ struct bvec_iter end_iter;
unsigned int resid;
- unsigned short idx;
unsigned int voff;
- unsigned short end_idx;
unsigned short vcnt;
struct bio *bio;
@@ -952,22 +952,22 @@ static struct bio *bio_clone_range(struct bio *bio_src,
/* Find first affected segment... */
resid = offset;
- bio_for_each_segment(bv, bio_src, idx) {
- if (resid < bv->bv_len)
+ bio_for_each_segment(bv, bio_src, iter) {
+ if (resid < bv.bv_len)
break;
- resid -= bv->bv_len;
+ resid -= bv.bv_len;
}
voff = resid;
/* ...and the last affected segment */
resid += len;
- __bio_for_each_segment(bv, bio_src, end_idx, idx) {
- if (resid <= bv->bv_len)
+ __bio_for_each_segment(bv, bio_src, end_iter, iter) {
+ if (resid <= bv.bv_len)
break;
- resid -= bv->bv_len;
+ resid -= bv.bv_len;
}
- vcnt = end_idx - idx + 1;
+ vcnt = end_iter.bi_idx = iter.bi_idx + 1;
/* Build the clone */
@@ -985,7 +985,7 @@ static struct bio *bio_clone_range(struct bio *bio_src,
* Copy over our part of the bio_vec, then update the first
* and last (or only) entries.
*/
- memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[idx],
+ memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[iter.bi_idx],
vcnt * sizeof (struct bio_vec));
bio->bi_io_vec[0].bv_offset += voff;
if (vcnt > 1) {
diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c
index 81d92cb..3b35bb6 100644
--- a/drivers/block/rsxx/dma.c
+++ b/drivers/block/rsxx/dma.c
@@ -638,7 +638,8 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
void *cb_data)
{
struct list_head dma_list[RSXX_MAX_TARGETS];
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned long long addr8;
unsigned int laddr;
unsigned int bv_len;
@@ -676,9 +677,9 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
bv_len -= RSXX_HW_BLK_SIZE;
}
} else {
- bio_for_each_segment(bvec, bio, i) {
- bv_len = bvec->bv_len;
- bv_off = bvec->bv_offset;
+ bio_for_each_segment(bvec, bio, iter) {
+ bv_len = bvec.bv_len;
+ bv_off = bvec.bv_offset;
while (bv_len > 0) {
tgt = rsxx_get_dma_tgt(card, addr8);
@@ -690,7 +691,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
st = rsxx_queue_dma(card, &dma_list[tgt],
bio_data_dir(bio),
dma_off, dma_len,
- laddr, bvec->bv_page,
+ laddr, bvec.bv_page,
bv_off, cb, cb_data);
if (st)
goto bvec_err;
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index c3dae2e..ce5d5ad 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -844,7 +844,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
struct blkif_response *bret)
{
int i = 0;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
struct req_iterator iter;
unsigned long flags;
char *bvec_data;
@@ -859,18 +859,18 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
* to be sure we are copying the data from the right shared page.
*/
rq_for_each_segment(bvec, s->request, iter) {
- BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE);
- if (bvec->bv_offset < offset)
+ BUG_ON((bvec.bv_offset + bvec.bv_len) > PAGE_SIZE);
+ if (bvec.bv_offset < offset)
i++;
BUG_ON(i >= s->req.u.rw.nr_segments);
shared_data = kmap_atomic(
pfn_to_page(s->grants_used[i]->pfn));
- bvec_data = bvec_kmap_irq(bvec, &flags);
- memcpy(bvec_data, shared_data + bvec->bv_offset,
- bvec->bv_len);
+ bvec_data = bvec_kmap_irq(&bvec, &flags);
+ memcpy(bvec_data, shared_data + bvec.bv_offset,
+ bvec.bv_len);
bvec_kunmap_irq(bvec_data, &flags);
kunmap_atomic(shared_data);
- offset = bvec->bv_offset + bvec->bv_len;
+ offset = bvec.bv_offset + bvec.bv_len;
}
}
/* Add the persistent grant into the list of free grants */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4fae0aa..2421ccf 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -186,8 +186,8 @@ void md_trim_bio(struct bio *bio, int offset, int size)
* the given offset and size.
* This requires adjusting bi_sector, bi_size, and bi_io_vec
*/
- int i;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
int sofar = 0;
size <<= 9;
@@ -209,14 +209,14 @@ void md_trim_bio(struct bio *bio, int offset, int size)
bio->bi_iter.bi_idx = 0;
}
/* Make sure vcnt and last bv are not too big */
- bio_for_each_segment(bvec, bio, i) {
- if (sofar + bvec->bv_len > size)
- bvec->bv_len = size - sofar;
- if (bvec->bv_len == 0) {
- bio->bi_vcnt = i;
+ bio_for_each_segment(bvec, bio, iter) {
+ if (sofar + bvec.bv_len > size)
+ bvec.bv_len = size - sofar;
+ if (bvec.bv_len == 0) {
+ bio->bi_vcnt = iter.bi_idx;
break;
}
- sofar += bvec->bv_len;
+ sofar += bvec.bv_len;
}
}
EXPORT_SYMBOL_GPL(md_trim_bio);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a98cbbe..53e3a9e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -720,9 +720,9 @@ static struct dma_async_tx_descriptor *
async_copy_data(int frombio, struct bio *bio, struct page *page,
sector_t sector, struct dma_async_tx_descriptor *tx)
{
- struct bio_vec *bvl;
+ struct bio_vec bvl;
+ struct bvec_iter iter;
struct page *bio_page;
- int i;
int page_offset;
struct async_submit_ctl submit;
enum async_tx_flags flags = 0;
@@ -736,8 +736,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
flags |= ASYNC_TX_FENCE;
init_async_submit(&submit, flags, tx, NULL, NULL, NULL);
- bio_for_each_segment(bvl, bio, i) {
- int len = bvl->bv_len;
+ bio_for_each_segment(bvl, bio, iter) {
+ int len = bvl.bv_len;
int clen;
int b_offset = 0;
@@ -753,8 +753,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
clen = len;
if (clen > 0) {
- b_offset += bvl->bv_offset;
- bio_page = bvl->bv_page;
+ b_offset += bvl.bv_offset;
+ bio_page = bvl.bv_page;
if (frombio)
tx = async_memcpy(page, bio_page, page_offset,
b_offset, clen, &submit);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index bcebfba..3621e5a 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -812,12 +812,12 @@ static void
dcssblk_make_request(struct request_queue *q, struct bio *bio)
{
struct dcssblk_dev_info *dev_info;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned long index;
unsigned long page_addr;
unsigned long source_addr;
unsigned long bytes_done;
- int i;
bytes_done = 0;
dev_info = bio->bi_bdev->bd_disk->private_data;
@@ -848,21 +848,21 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
}
index = (bio->bi_iter.bi_sector >> 3);
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
page_addr = (unsigned long)
- page_address(bvec->bv_page) + bvec->bv_offset;
+ page_address(bvec.bv_page) + bvec.bv_offset;
source_addr = dev_info->start + (index<<12) + bytes_done;
if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0)
// More paranoia.
goto fail;
if (bio_data_dir(bio) == READ) {
memcpy((void*)page_addr, (void*)source_addr,
- bvec->bv_len);
+ bvec.bv_len);
} else {
memcpy((void*)source_addr, (void*)page_addr,
- bvec->bv_len);
+ bvec.bv_len);
}
- bytes_done += bvec->bv_len;
+ bytes_done += bvec.bv_len;
}
bio_endio(bio, 0);
return;
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 0330859..c478839 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -184,11 +184,11 @@ static unsigned long xpram_highest_page_index(void)
static void xpram_make_request(struct request_queue *q, struct bio *bio)
{
xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned int index;
unsigned long page_addr;
unsigned long bytes;
- int i;
if ((bio->bi_iter.bi_sector & 7) != 0 ||
(bio->bi_iter.bi_size & 4095) != 0)
@@ -200,10 +200,10 @@ static void xpram_make_request(struct request_queue *q, struct bio *bio)
if ((bio->bi_iter.bi_sector >> 3) > 0xffffffffU - xdev->offset)
goto fail;
index = (bio->bi_iter.bi_sector >> 3) + xdev->offset;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
page_addr = (unsigned long)
- kmap(bvec->bv_page) + bvec->bv_offset;
- bytes = bvec->bv_len;
+ kmap(bvec.bv_page) + bvec.bv_offset;
+ bytes = bvec.bv_len;
if ((page_addr & 4095) != 0 || (bytes & 4095) != 0)
/* More paranoia. */
goto fail;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 193e7ae..2c2e01e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -1898,7 +1898,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
Mpi2SmpPassthroughRequest_t *mpi_request;
Mpi2SmpPassthroughReply_t *mpi_reply;
- int rc, i;
+ int rc;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@@ -1913,7 +1913,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
void *pci_addr_out = NULL;
u16 wait_state_count;
struct request *rsp = req->next_rq;
- struct bio_vec *bvec = NULL;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
if (!rsp) {
printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
@@ -1952,11 +1953,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
goto out;
}
- bio_for_each_segment(bvec, req->bio, i) {
+ bio_for_each_segment(bvec, req->bio, iter) {
memcpy(pci_addr_out + offset,
- page_address(bvec->bv_page) + bvec->bv_offset,
- bvec->bv_len);
- offset += bvec->bv_len;
+ page_address(bvec.bv_page) + bvec.bv_offset,
+ bvec.bv_len);
+ offset += bvec.bv_len;
}
} else {
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -2103,19 +2104,19 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u32 offset = 0;
u32 bytes_to_copy =
le16_to_cpu(mpi_reply->ResponseDataLength);
- bio_for_each_segment(bvec, rsp->bio, i) {
- if (bytes_to_copy <= bvec->bv_len) {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
+ bio_for_each_segment(bvec, rsp->bio, iter) {
+ if (bytes_to_copy <= bvec.bv_len) {
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
offset, bytes_to_copy);
break;
} else {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
- offset, bvec->bv_len);
- bytes_to_copy -= bvec->bv_len;
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
+ offset, bvec.bv_len);
+ bytes_to_copy -= bvec.bv_len;
}
- offset += bvec->bv_len;
+ offset += bvec.bv_len;
}
}
} else {
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index 87ca2b7..dd15b2d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -1881,7 +1881,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
Mpi2SmpPassthroughRequest_t *mpi_request;
Mpi2SmpPassthroughReply_t *mpi_reply;
- int rc, i;
+ int rc;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@@ -1895,7 +1895,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
void *pci_addr_out = NULL;
u16 wait_state_count;
struct request *rsp = req->next_rq;
- struct bio_vec *bvec = NULL;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
if (!rsp) {
pr_err(MPT3SAS_FMT "%s: the smp response space is missing\n",
@@ -1935,11 +1936,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
goto out;
}
- bio_for_each_segment(bvec, req->bio, i) {
+ bio_for_each_segment(bvec, req->bio, iter) {
memcpy(pci_addr_out + offset,
- page_address(bvec->bv_page) + bvec->bv_offset,
- bvec->bv_len);
- offset += bvec->bv_len;
+ page_address(bvec.bv_page) + bvec.bv_offset,
+ bvec.bv_len);
+ offset += bvec.bv_len;
}
} else {
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -2064,19 +2065,19 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u32 offset = 0;
u32 bytes_to_copy =
le16_to_cpu(mpi_reply->ResponseDataLength);
- bio_for_each_segment(bvec, rsp->bio, i) {
- if (bytes_to_copy <= bvec->bv_len) {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
+ bio_for_each_segment(bvec, rsp->bio, iter) {
+ if (bytes_to_copy <= bvec.bv_len) {
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
offset, bytes_to_copy);
break;
} else {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
- offset, bvec->bv_len);
- bytes_to_copy -= bvec->bv_len;
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
+ offset, bvec.bv_len);
+ bytes_to_copy -= bvec.bv_len;
}
- offset += bvec->bv_len;
+ offset += bvec.bv_len;
}
}
} else {
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 4d395a5..cd0ed36 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -367,9 +367,10 @@ static void update_position(u32 *index, int *offset, struct bio_vec *bvec)
static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
{
- int i, offset;
+ int offset;
u32 index;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
switch (rw) {
case READ:
@@ -384,33 +385,33 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
offset = (bio->bi_iter.bi_sector &
(SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int max_transfer_size = PAGE_SIZE - offset;
- if (bvec->bv_len > max_transfer_size) {
+ if (bvec.bv_len > max_transfer_size) {
/*
* zram_bvec_rw() can only make operation on a single
* zram page. Split the bio vector.
*/
struct bio_vec bv;
- bv.bv_page = bvec->bv_page;
+ bv.bv_page = bvec.bv_page;
bv.bv_len = max_transfer_size;
- bv.bv_offset = bvec->bv_offset;
+ bv.bv_offset = bvec.bv_offset;
if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
goto out;
- bv.bv_len = bvec->bv_len - max_transfer_size;
+ bv.bv_len = bvec.bv_len - max_transfer_size;
bv.bv_offset += max_transfer_size;
if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
goto out;
} else
- if (zram_bvec_rw(zram, bvec, index, offset, bio, rw)
+ if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
< 0)
goto out;
- update_position(&index, &offset, bvec);
+ update_position(&index, &offset, &bvec);
}
set_bit(BIO_UPTODATE, &bio->bi_flags);
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index f824c30..4220b96 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -299,25 +299,26 @@ static void bio_integrity_generate(struct bio *bio)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_exchg bix;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
sector_t sector = bio->bi_iter.bi_sector;
- unsigned int i, sectors, total;
+ unsigned int sectors, total;
void *prot_buf = bio->bi_integrity->bip_buf;
total = 0;
bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
bix.sector_size = bi->sector_size;
- bio_for_each_segment(bv, bio, i) {
- void *kaddr = kmap_atomic(bv->bv_page);
- bix.data_buf = kaddr + bv->bv_offset;
- bix.data_size = bv->bv_len;
+ bio_for_each_segment(bv, bio, iter) {
+ void *kaddr = kmap_atomic(bv.bv_page);
+ bix.data_buf = kaddr + bv.bv_offset;
+ bix.data_size = bv.bv_len;
bix.prot_buf = prot_buf;
bix.sector = sector;
bi->generate_fn(&bix);
- sectors = bv->bv_len / bi->sector_size;
+ sectors = bv.bv_len / bi->sector_size;
sector += sectors;
prot_buf += sectors * bi->tuple_size;
total += sectors * bi->tuple_size;
@@ -441,19 +442,20 @@ static int bio_integrity_verify(struct bio *bio)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_exchg bix;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
sector_t sector = bio->bi_integrity->bip_sector;
- unsigned int i, sectors, total, ret;
+ unsigned int sectors, total, ret;
void *prot_buf = bio->bi_integrity->bip_buf;
ret = total = 0;
bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
bix.sector_size = bi->sector_size;
- bio_for_each_segment(bv, bio, i) {
- void *kaddr = kmap_atomic(bv->bv_page);
- bix.data_buf = kaddr + bv->bv_offset;
- bix.data_size = bv->bv_len;
+ bio_for_each_segment(bv, bio, iter) {
+ void *kaddr = kmap_atomic(bv.bv_page);
+ bix.data_buf = kaddr + bv.bv_offset;
+ bix.data_size = bv.bv_len;
bix.prot_buf = prot_buf;
bix.sector = sector;
@@ -464,7 +466,7 @@ static int bio_integrity_verify(struct bio *bio)
return ret;
}
- sectors = bv->bv_len / bi->sector_size;
+ sectors = bv.bv_len / bi->sector_size;
sector += sectors;
prot_buf += sectors * bi->tuple_size;
total += sectors * bi->tuple_size;
diff --git a/fs/bio.c b/fs/bio.c
index 8543f85..400f90c 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -472,13 +472,13 @@ EXPORT_SYMBOL(bio_alloc_bioset);
void zero_fill_bio(struct bio *bio)
{
unsigned long flags;
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i) {
- char *data = bvec_kmap_irq(bv, &flags);
- memset(data, 0, bv->bv_len);
- flush_dcache_page(bv->bv_page);
+ bio_for_each_segment(bv, bio, iter) {
+ char *data = bvec_kmap_irq(&bv, &flags);
+ memset(data, 0, bv.bv_len);
+ flush_dcache_page(bv.bv_page);
bvec_kunmap_irq(data, &flags);
}
}
@@ -1676,10 +1676,10 @@ void bio_check_pages_dirty(struct bio *bio)
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
void bio_flush_dcache_pages(struct bio *bi)
{
- int i;
struct bio_vec *bvec;
+ struct bvec_iter iter;
- bio_for_each_segment(bvec, bi, i)
+ bio_for_each_segment(bvec, bi, iter)
flush_dcache_page(bvec->bv_page);
}
EXPORT_SYMBOL(bio_flush_dcache_pages);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 7b2399b..fa9fceb 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -203,19 +203,19 @@ static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec,
static void gfs2_end_log_write(struct bio *bio, int error)
{
struct gfs2_sbd *sdp = bio->bi_private;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct page *page;
- int i;
if (error) {
sdp->sd_log_error = error;
fs_err(sdp, "Error %d writing to log\n", error);
}
- bio_for_each_segment(bvec, bio, i) {
- page = bvec->bv_page;
+ bio_for_each_segment(bvec, bio, iter) {
+ page = bvec.bv_page;
if (page_has_buffers(page))
- gfs2_end_log_write_bh(sdp, bvec, error);
+ gfs2_end_log_write_bh(sdp, &bvec, error);
else
mempool_free(page, gfs2_page_pool);
}
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 580c9ae..a31bcd2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -61,6 +61,8 @@
* various member access, note that bio_data should of course not be used
* on highmem page vectors
*/
+#define bio_iovec_iter(bio, iter) ((bio)->bi_io_vec[(iter).bi_idx])
+
#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)]))
#define __bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_iter.bi_idx)
#define bio_iovec(bio) (*__bio_iovec(bio))
@@ -134,15 +136,6 @@ static inline void *bio_data(struct bio *bio)
#define bio_io_error(bio) bio_endio((bio), -EIO)
/*
- * drivers should not use the __ version unless they _really_ know what
- * they're doing
- */
-#define __bio_for_each_segment(bvl, bio, i, start_idx) \
- for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx); \
- i < (bio)->bi_vcnt; \
- bvl++, i++)
-
-/*
* drivers should _never_ use the all version - the bio may have been split
* before it got to the driver and the driver won't own all of it
*/
@@ -151,10 +144,16 @@ static inline void *bio_data(struct bio *bio)
bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \
i++)
-#define bio_for_each_segment(bvl, bio, i) \
- for (i = (bio)->bi_iter.bi_idx; \
- bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \
- i++)
+#define __bio_for_each_segment(bvl, bio, iter, start) \
+ for (iter = (start); \
+ bvl = bio_iovec_iter((bio), (iter)), \
+ (iter).bi_idx < (bio)->bi_vcnt; \
+ (iter).bi_idx++)
+
+#define bio_for_each_segment(bvl, bio, iter) \
+ __bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
+
+#define bio_iter_last(bio, iter) ((iter).bi_idx == (bio)->bi_vcnt - 1)
/*
* get a reference to a bio, so it won't disappear. the intended use is
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 89d89c7..f589ed3 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -699,7 +699,7 @@ struct rq_map_data {
};
struct req_iterator {
- int i;
+ struct bvec_iter iter;
struct bio *bio;
};
@@ -712,10 +712,11 @@ struct req_iterator {
#define rq_for_each_segment(bvl, _rq, _iter) \
__rq_for_each_bio(_iter.bio, _rq) \
- bio_for_each_segment(bvl, _iter.bio, _iter.i)
+ bio_for_each_segment(bvl, _iter.bio, _iter.iter)
#define rq_iter_last(rq, _iter) \
- (_iter.bio->bi_next == NULL && _iter.i == _iter.bio->bi_vcnt-1)
+ (_iter.bio->bi_next == NULL && \
+ bio_iter_last(_iter.bio, _iter.iter))
#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
# error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform"
diff --git a/mm/bounce.c b/mm/bounce.c
index f5326b2..deaf1b0 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -98,27 +98,24 @@ int init_emergency_isa_pool(void)
static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
{
unsigned char *vfrom;
- struct bio_vec *tovec, *fromvec;
- int i;
-
- bio_for_each_segment(tovec, to, i) {
- fromvec = from->bi_io_vec + i;
-
- /*
- * not bounced
- */
- if (tovec->bv_page == fromvec->bv_page)
- continue;
-
- /*
- * fromvec->bv_offset and fromvec->bv_len might have been
- * modified by the block layer, so use the original copy,
- * bounce_copy_vec already uses tovec->bv_len
- */
- vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;
+ struct bio_vec tovec, *fromvec = from->bi_io_vec;
+ struct bvec_iter iter;
+
+ bio_for_each_segment(tovec, to, iter) {
+ if (tovec.bv_page != fromvec->bv_page) {
+ /*
+ * fromvec->bv_offset and fromvec->bv_len might have
+ * been modified by the block layer, so use the original
+ * copy, bounce_copy_vec already uses tovec->bv_len
+ */
+ vfrom = page_address(fromvec->bv_page) +
+ tovec.bv_offset;
+
+ bounce_copy_vec(&tovec, vfrom);
+ flush_dcache_page(tovec.bv_page);
+ }
- bounce_copy_vec(tovec, vfrom);
- flush_dcache_page(tovec->bv_page);
+ fromvec++;
}
}
@@ -184,8 +181,8 @@ static int must_snapshot_stable_pages(struct request_queue *q, struct bio *bio)
struct page *page;
struct backing_dev_info *bdi;
struct address_space *mapping;
- struct bio_vec *from;
- int i;
+ struct bio_vec from;
+ struct bvec_iter iter;
if (bio_data_dir(bio) != WRITE)
return 0;
@@ -197,8 +194,8 @@ static int must_snapshot_stable_pages(struct request_queue *q, struct bio *bio)
* Based on the first page that has a valid mapping, decide whether or
* not we have to employ bounce buffering to guarantee stable pages.
*/
- bio_for_each_segment(from, bio, i) {
- page = from->bv_page;
+ bio_for_each_segment(from, bio, iter) {
+ page = from.bv_page;
mapping = page_mapping(page);
if (!mapping)
continue;
@@ -220,11 +217,12 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
{
struct bio *bio;
int rw = bio_data_dir(*bio_orig);
- struct bio_vec *to, *from;
+ struct bio_vec *to, from;
+ struct bvec_iter iter;
unsigned i;
- bio_for_each_segment(from, *bio_orig, i)
- if (page_to_pfn(from->bv_page) > queue_bounce_pfn(q))
+ bio_for_each_segment(from, *bio_orig, iter)
+ if (page_to_pfn(from.bv_page) > queue_bounce_pfn(q))
goto bounce;
return;
--
1.8.1.3
^ permalink raw reply related
* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
From: Alexander Graf @ 2013-03-27 17:23 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-6-git-send-email-mihai.caraman@freescale.com>
On 26.03.2013, at 23:05, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb =
entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
>=20
> arch/powerpc/kvm/e500_mmu.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> + vcpu->arch.mmucfg &=3D ~MMUCFG_LRAT;
> +
> if (has_feature(vcpu, VCPU_FTR_E_PT))
> vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
> else
> vcpu->arch.eptcfg =3D 0;
>=20
> + /* Guest mmu emulation currently doesn't handle E.PT */
> + vcpu->arch.tlbcfg[0] &=3D ~TLBnCFG_PT;
> + vcpu->arch.tlbcfg[1] &=3D ~TLBnCFG_IND;
Can we make this conditional on bits in EPTCFG? Then by initializing it =
to 0 today, we always mask PT/IND out, but later when we support EPT, we =
only have to set the bit in EPTCFG and everyone's happy?
Alex
> +
> vcpu->arch.tlbps[0] =3D mfspr(SPRN_TLB0PS);
> vcpu->arch.tlbps[1] =3D mfspr(SPRN_TLB1PS);
> }
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
From: Alexander Graf @ 2013-03-27 17:21 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-5-git-send-email-mihai.caraman@freescale.com>
On 26.03.2013, at 23:05, Mihai Caraman wrote:
> EPTCFG register defined by E.PT is accessed unconditionally by Linux =
guests
> in the presence of MAV 2.0. Support it now.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Use has_feature() function
>=20
> Documentation/virtual/kvm/api.txt | 1 +
> arch/powerpc/include/asm/kvm_host.h | 1 +
> arch/powerpc/include/uapi/asm/kvm.h | 1 +
> arch/powerpc/kvm/e500.h | 5 +++++
> arch/powerpc/kvm/e500_emulate.c | 9 +++++++++
> arch/powerpc/kvm/e500_mmu.c | 11 +++++++++++
> 6 files changed, 28 insertions(+), 0 deletions(-)
>=20
> diff --git a/Documentation/virtual/kvm/api.txt =
b/Documentation/virtual/kvm/api.txt
> index f045377..a1f2200 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1807,6 +1807,7 @@ registers, find a list below:
> PPC | KVM_REG_PPC_TLB1PS | 32
> PPC | KVM_REG_PPC_TLB2PS | 32
> PPC | KVM_REG_PPC_TLB3PS | 32
> + PPC | KVM_REG_PPC_EPTCFG | 32
>=20
> ARM registers are mapped using the lower 32 bits. The upper 16 of =
that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/asm/kvm_host.h =
b/arch/powerpc/include/asm/kvm_host.h
> index 3b6cee3..8a48e68 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
> u32 tlbcfg[4];
> u32 tlbps[4];
> u32 mmucfg;
> + u32 eptcfg;
> u32 epr;
> u32 crit_save;
> struct kvmppc_booke_debug_reg dbg_reg;
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h =
b/arch/powerpc/include/uapi/asm/kvm.h
> index 7cfd13f..9d7fbf0 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -443,4 +443,5 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
> #define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
> #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
> +#define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 795934d..6cfc669 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -24,6 +24,7 @@
> #include <asm/tlb.h>
>=20
> #define VCPU_FTR_MMU_V2 0
> +#define VCPU_FTR_E_PT 1
>=20
> #define E500_PID_NUM 3
> #define E500_TLB_NUM 2
> @@ -309,6 +310,10 @@ static inline bool has_feature(const struct =
kvm_vcpu *vcpu,
> case VCPU_FTR_MMU_V2:
> has_ftr =3D ((vcpu->arch.mmucfg & MMUCFG_MAVN) =3D=3D =
MMUCFG_MAVN_V2);
> break;
> + case VCPU_FTR_E_PT:
> + has_ftr =3D ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
> + (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
> + break;
> default:
> has_ftr =3D false;
> }
> diff --git a/arch/powerpc/kvm/e500_emulate.c =
b/arch/powerpc/kvm/e500_emulate.c
> index 12b8de2..b10a012 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu =
*vcpu, int sprn, ulong *spr_val)
> case SPRN_MMUCFG:
> *spr_val =3D vcpu->arch.mmucfg;
> break;
> + case SPRN_EPTCFG:
> + if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
> + return EMULATE_FAIL;
> + /*
> + * Legacy Linux guests access EPTCFG register even if =
the E.PT
> + * category is disabled in the VM. Give them a chance to =
live.
> + */
> + *spr_val =3D vcpu->arch.eptcfg;
> + break;
>=20
> /* extra exceptions */
> case SPRN_IVOR32:
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index e354fa1..cf60db1 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu =
*vcpu, u64 id,
> *val =3D get_reg_val(id, vcpu->arch.shared->mas6);
> case KVM_REG_PPC_MMUCFG:
> *val =3D get_reg_val(id, vcpu->arch.mmucfg);
> + case KVM_REG_PPC_EPTCFG:
> + *val =3D get_reg_val(id, vcpu->arch.eptcfg);
> case KVM_REG_PPC_TLB0CFG:
> case KVM_REG_PPC_TLB1CFG:
> case KVM_REG_PPC_TLB2CFG:
> @@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu =
*vcpu, u64 id,
> r =3D -EINVAL;
> break;
> }
> + case KVM_REG_PPC_EPTCFG:
> + if (set_reg_val(id, *val) !=3D vcpu->arch.eptcfg)
> + r =3D -EINVAL;
> + break;
> case KVM_REG_PPC_TLB0CFG:
> case KVM_REG_PPC_TLB1CFG:
> case KVM_REG_PPC_TLB2CFG:
> @@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> + if (has_feature(vcpu, VCPU_FTR_E_PT))
> + vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
Can't we just always set it to 0?
Alex
> + else
> + vcpu->arch.eptcfg =3D 0;
> +
> vcpu->arch.tlbps[0] =3D mfspr(SPRN_TLB0PS);
> vcpu->arch.tlbps[1] =3D mfspr(SPRN_TLB1PS);
> }
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/3] powerpc/mpic: add global timer support
From: Scott Wood @ 2013-03-27 17:11 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Wood Scott-B07421, Gala Kumar-B11780,
linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBB72D@039-SN2MPN1-022.039d.mgd.msft.net>
On 03/26/2013 10:23:38 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Wednesday, March 27, 2013 1:32 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Li Yang-R58472
> > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> >
> > On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Saturday, March 23, 2013 6:30 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Li Yang-R58472
> > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > >
> > > > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Wood Scott-B07421
> > > > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > > > To: Wang Dongsheng-B40534
> > > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > > linuxppc-dev@lists.ozlabs.org;
> > > > > > Li Yang-R58472
> > > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer =20
> support
> > > > > >
> > > > > > BTW, the input clock frequency has been similarly scaled, =20
> yet
> > > you
> > > > > don't
> > > > > > try to scrounge up that information to get further =20
> precision...
> > > > > >
> > > > > Let's go back patch, do you think the code is repeated?
> > > > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch,
> > > there
> > > > > will be no redundant code.
> > > >
> > > > I'd rather that branch be kept and the more complicated branch
> > > deleted,
> > > > and priv->timerfreq frequency be adjusted on initialization to
> > > account
> > > > for the scaler.
> > >
> > > static void convert_ticks_to_time(struct timer_group_priv *priv,
> > > const u64 ticks, struct timeval *time) {
> > > u64 tmp_sec;
> > >
> > > time->tv_sec =3D (__kernel_time_t)div_u64(ticks,
> > > priv->timerfreq);
> > > tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
> > >
> > > time->tv_usec =3D (__kernel_suseconds_t)
> > > div_u64((ticks - tmp_sec) * 1000000, =20
> priv->timerfreq);
> > >
> > > return;
> > > }
> > >
> > > timer_group_get_freq() {
> > > ...
> > > if (priv->flags & FSL_GLOBAL_TIMER) {
> > > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > > priv->timerfreq /=3D div;
> > > }
> > > ...
> > > }
> > > Do you want to do that?
> >
> > if (priv->flags & FSL_GLOBAL_TIMER)
> > priv->timerfreq /=3D 64;
> >
> > ...but otherwise yes.
> Ok, I would like do this.
>=20
> if (priv->flags & FSL_GLOBAL_TIMER) {
> div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> priv->timerfreq /=3D div;
Why? What do you get out of that obfuscation?
-Scott=
^ permalink raw reply
* Re: [PATCHv2 1/3] pci: added pcie_get_speed_cap_mask function
From: Bjorn Helgaas @ 2013-03-27 16:58 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: David Airlie, linux-pci@vger.kernel.org, DRI mailing list,
Alex Deucher, Thadeu Cascardo, Lucas Kannebley Tavares,
Brian King, linuxppc-dev
In-Reply-To: <1364397928.11644.41.camel@pasglop>
On Wed, Mar 27, 2013 at 9:25 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Tue, 2013-03-26 at 12:39 -0600, Bjorn Helgaas wrote:
>> But we also know pdev is a PCIe device, and I think a PCIe device on a
>> root bus must be a "Root Complex Integrated Endpoint" (PCIe spec sec
>> 1.3.2.3). Such a device does not have a link at all, so there's no
>> point in fiddling with its link speed.
>
> This is where our IBM hypervisor makes things murky. It doesn't expose
> the PCIe parents (basically somewhat makes PCIe look like PCI except we
> still have the PCIe caps on the child devices, just no access to the
> parent device).
Interesting. I wonder if we'll trip over this anywhere else, e.g.,
ASPM or other link-related things. I guess we'll just have to see if
anything else breaks.
> It's garbage but can't be fixed (would break AIX :-)
>
> However we might be able to populate the bus->max_bus_speed from some
> architecture specific quirk and have radeon use that.
That sounds like a good solution to me. It seems like it's really an
arch-specific deviation from the spec, so it'd be nice to have an
arch-specific solution for it.
Bjorn
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Benjamin Herrenschmidt @ 2013-03-27 15:27 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Paul Bolle, Florian Tobias Schandinat, linux-doc, linux-fbdev,
linux-kernel, Paul Mackerras, Rob Landley, Bjorn Helgaas,
linuxppc-dev, Adam Belay
In-Reply-To: <CAMuHMdVs-Xxu9e=8WZbTBXE1_+iYOBKODgj9_EKmVbZA3z=8JA@mail.gmail.com>
On Wed, 2013-03-27 at 13:05 +0100, Geert Uytterhoeven wrote:
> On Wed, Mar 27, 2013 at 11:47 AM, Paul Bolle <pebolle@tiscali.nl> wrote:
> > 3) I removed two files in documentation that are almost entirely PReP
> > specific. The remaining lines looked uninteresting.
>
> > --- a/Documentation/powerpc/sound.txt
> > +++ /dev/null
>
> > -2. IBM CHRP
> > -
> > - I have only tested this on the 43P-150. Build the kernel with the cs4232
> > - set as a module and load the module with irq=9 dma=1 dma2=2 io=0x550
>
> This section is CHRP-specific. The cs4232 driver also worked on the
> CHRP LongTrail.
> But I don't remember if the parameter values above also applied to LongTrail.
> I do remember it didn't work without specifing the right parameters, so you
> probably want to keep this section.
Isn't LongTrail support LongDead ? Can we still boot these things at
all ? Anybody still has a functional one ?
Cheers,
Ben.
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
From: Alexander Graf @ 2013-03-27 15:58 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-2-git-send-email-mihai.caraman@freescale.com>
On 26.03.2013, at 23:05, Mihai Caraman wrote:
> MMU registers were exposed to user-space using sregs interface. Add =
them
> to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg =
delegation
> interface introduced by book3s.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Restrict set_one_reg operation for MMU registers to HW values
>=20
> Documentation/virtual/kvm/api.txt | 11 +++++
> arch/powerpc/include/uapi/asm/kvm.h | 17 +++++++
> arch/powerpc/kvm/44x.c | 12 +++++
> arch/powerpc/kvm/booke.c | 83 =
++++++++++++++++++++--------------
> arch/powerpc/kvm/e500.c | 14 ++++++
> arch/powerpc/kvm/e500.h | 4 ++
> arch/powerpc/kvm/e500_mmu.c | 84 =
+++++++++++++++++++++++++++++++++++
> arch/powerpc/kvm/e500mc.c | 14 ++++++
> 8 files changed, 205 insertions(+), 34 deletions(-)
>=20
> diff --git a/Documentation/virtual/kvm/api.txt =
b/Documentation/virtual/kvm/api.txt
> index 976eb65..1a76663 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1792,6 +1792,17 @@ registers, find a list below:
> PPC | KVM_REG_PPC_TSR | 32
> PPC | KVM_REG_PPC_OR_TSR | 32
> PPC | KVM_REG_PPC_CLEAR_TSR | 32
> + PPC | KVM_REG_PPC_MAS0 | 32
> + PPC | KVM_REG_PPC_MAS1 | 32
> + PPC | KVM_REG_PPC_MAS2 | 64
> + PPC | KVM_REG_PPC_MAS7_3 | 64
> + PPC | KVM_REG_PPC_MAS4 | 32
> + PPC | KVM_REG_PPC_MAS6 | 32
> + PPC | KVM_REG_PPC_MMUCFG | 32
> + PPC | KVM_REG_PPC_TLB0CFG | 32
> + PPC | KVM_REG_PPC_TLB1CFG | 32
> + PPC | KVM_REG_PPC_TLB2CFG | 32
> + PPC | KVM_REG_PPC_TLB3CFG | 32
>=20
> ARM registers are mapped using the lower 32 bits. The upper 16 of =
that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h =
b/arch/powerpc/include/uapi/asm/kvm.h
> index ef072b1..777dc81 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -422,4 +422,21 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_CLEAR_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
> #define KVM_REG_PPC_TCR (KVM_REG_PPC | KVM_REG_SIZE_U32 =
| 0x89)
> #define KVM_REG_PPC_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 =
| 0x8a)
> +
> +/* MMU registers */
> +#define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
> +#define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
> +#define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
> +#define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
> +#define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
> +#define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
> +#define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
> +/*
> + * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed =
only using
> + * KVM_CAP_SW_TLB ioctl
> + */
> +#define KVM_REG_PPC_TLB0CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
> +#define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
> +#define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
> +#define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
> index 3d7fd21..2f5c6b6 100644
> --- a/arch/powerpc/kvm/44x.c
> +++ b/arch/powerpc/kvm/44x.c
> @@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + return -EINVAL;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + return -EINVAL;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> struct kvmppc_vcpu_44x *vcpu_44x;
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 58057d6..c67e99f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct =
kvm_vcpu *vcpu,
>=20
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct =
kvm_one_reg *reg)
> {
> - int r =3D -EINVAL;
> + int r =3D 0;
> + union kvmppc_one_reg val;
> + int size;
> + long int i;
> +
> + size =3D one_reg_size(reg->id);
> + if (size > sizeof(val))
> + return -EINVAL;
>=20
> switch (reg->id) {
> case KVM_REG_PPC_IAC1:
> case KVM_REG_PPC_IAC2:
> case KVM_REG_PPC_IAC3:
> case KVM_REG_PPC_IAC4: {
> - int iac =3D reg->id - KVM_REG_PPC_IAC1;
> - r =3D copy_to_user((u64 __user *)(long)reg->addr,
> - &vcpu->arch.dbg_reg.iac[iac], =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_IAC1;
> + val =3D get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);
Please split this into a separate patch. You're merely cleaning up =
existing code here, not adding new functionality as the patch =
description says.
> break;
> }
> case KVM_REG_PPC_DAC1:
> case KVM_REG_PPC_DAC2: {
> - int dac =3D reg->id - KVM_REG_PPC_DAC1;
> - r =3D copy_to_user((u64 __user *)(long)reg->addr,
> - &vcpu->arch.dbg_reg.dac[dac], =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_DAC1;
> + val =3D get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
> break;
> }
> case KVM_REG_PPC_EPR: {
> u32 epr =3D get_guest_epr(vcpu);
> - r =3D put_user(epr, (u32 __user *)(long)reg->addr);
> + val =3D get_reg_val(reg->id, epr);
> break;
> }
> #if defined(CONFIG_64BIT)
> case KVM_REG_PPC_EPCR:
> - r =3D put_user(vcpu->arch.epcr, (u32 __user =
*)(long)reg->addr);
> + val =3D get_reg_val(reg->id, vcpu->arch.epcr);
> break;
> #endif
> case KVM_REG_PPC_TCR:
> - r =3D put_user(vcpu->arch.tcr, (u32 __user =
*)(long)reg->addr);
> + val =3D get_reg_val(reg->id, vcpu->arch.tcr);
> break;
> case KVM_REG_PPC_TSR:
> - r =3D put_user(vcpu->arch.tsr, (u32 __user =
*)(long)reg->addr);
> + val =3D get_reg_val(reg->id, vcpu->arch.tsr);
> break;
> default:
> + r =3D kvmppc_get_one_reg(vcpu, reg->id, &val);
> break;
> }
> +
> + if (r)
> + return r;
> +
> + if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, =
size))
> + r =3D -EFAULT;
> +
> return r;
> }
>=20
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct =
kvm_one_reg *reg)
> {
> - int r =3D -EINVAL;
> + int r =3D 0;
> + union kvmppc_one_reg val;
> + int size;
> + long int i;
> +
> + size =3D one_reg_size(reg->id);
> + if (size > sizeof(val))
> + return -EINVAL;
> +
> + if (copy_from_user(&val, (char __user *)(unsigned =
long)reg->addr, size))
> + return -EFAULT;
>=20
> switch (reg->id) {
> case KVM_REG_PPC_IAC1:
> case KVM_REG_PPC_IAC2:
> case KVM_REG_PPC_IAC3:
> case KVM_REG_PPC_IAC4: {
> - int iac =3D reg->id - KVM_REG_PPC_IAC1;
> - r =3D copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
> - (u64 __user *)(long)reg->addr, =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_IAC1;
> + vcpu->arch.dbg_reg.iac[i] =3D set_reg_val(reg->id, val);
> break;
> }
> case KVM_REG_PPC_DAC1:
> case KVM_REG_PPC_DAC2: {
> - int dac =3D reg->id - KVM_REG_PPC_DAC1;
> - r =3D copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
> - (u64 __user *)(long)reg->addr, =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_DAC1;
> + vcpu->arch.dbg_reg.dac[i] =3D set_reg_val(reg->id, val);
> break;
> }
> case KVM_REG_PPC_EPR: {
> - u32 new_epr;
> - r =3D get_user(new_epr, (u32 __user *)(long)reg->addr);
> - if (!r)
> - kvmppc_set_epr(vcpu, new_epr);
> + u32 new_epr =3D set_reg_val(reg->id, val);
> + kvmppc_set_epr(vcpu, new_epr);
> break;
> }
> #if defined(CONFIG_64BIT)
> case KVM_REG_PPC_EPCR: {
> - u32 new_epcr;
> - r =3D get_user(new_epcr, (u32 __user *)(long)reg->addr);
> - if (r =3D=3D 0)
> - kvmppc_set_epcr(vcpu, new_epcr);
> + u32 new_epcr =3D set_reg_val(reg->id, val);
> + kvmppc_set_epcr(vcpu, new_epcr);
What about the sanity check?
> break;
> }
> #endif
> case KVM_REG_PPC_OR_TSR: {
> - u32 tsr_bits;
> - r =3D get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> + u32 tsr_bits =3D set_reg_val(reg->id, val);
> kvmppc_set_tsr_bits(vcpu, tsr_bits);
> break;
> }
> case KVM_REG_PPC_CLEAR_TSR: {
> - u32 tsr_bits;
> - r =3D get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> + u32 tsr_bits =3D set_reg_val(reg->id, val);
> kvmppc_clr_tsr_bits(vcpu, tsr_bits);
> break;
> }
> case KVM_REG_PPC_TSR: {
> - u32 tsr;
> - r =3D get_user(tsr, (u32 __user *)(long)reg->addr);
> + u32 tsr =3D set_reg_val(reg->id, val);
> kvmppc_set_tsr(vcpu, tsr);
> break;
> }
> case KVM_REG_PPC_TCR: {
> - u32 tcr;
> - r =3D get_user(tcr, (u32 __user *)(long)reg->addr);
> + u32 tcr =3D set_reg_val(reg->id, val);
> kvmppc_set_tcr(vcpu, tcr);
> break;
> }
> default:
> + r =3D kvmppc_set_one_reg(vcpu, reg->id, &val);
> break;
> }
> +
> return r;
> }
>=20
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index 6dd4de7..ce6b73c 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> struct kvmppc_vcpu_e500 *vcpu_e500;
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 33db48a..b73ca7a 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct =
kvmppc_vcpu_e500 *vcpu_e500);
> void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs =
*sregs);
> int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs =
*sregs);
>=20
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val);
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val);
>=20
> #ifdef CONFIG_KVM_E500V2
> unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index 5c44759..68c2b00 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu =
*vcpu, struct kvm_sregs *sregs)
> return 0;
> }
>=20
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D 0;
> + long int i;
> +
> + switch (id) {
> + case KVM_REG_PPC_MAS0:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas0);
Missing breaks?
Alex
> + case KVM_REG_PPC_MAS1:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas1);
> + case KVM_REG_PPC_MAS2:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas2);
> + case KVM_REG_PPC_MAS7_3:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas7_3);
> + case KVM_REG_PPC_MAS4:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas4);
> + case KVM_REG_PPC_MAS6:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas6);
> + case KVM_REG_PPC_MMUCFG:
> + *val =3D get_reg_val(id, vcpu->arch.mmucfg);
> + case KVM_REG_PPC_TLB0CFG:
> + case KVM_REG_PPC_TLB1CFG:
> + case KVM_REG_PPC_TLB2CFG:
> + case KVM_REG_PPC_TLB3CFG:
> + i =3D id - KVM_REG_PPC_TLB0CFG;
> + *val =3D get_reg_val(id, vcpu->arch.tlbcfg[i]);
> + default:
> + r =3D -EINVAL;
> + break;
> + }
> +
> + return r;
> +}
> +
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D 0;
> + long int i;
> +
> + switch (id) {
> + case KVM_REG_PPC_MAS0:
> + vcpu->arch.shared->mas0 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS1:
> + vcpu->arch.shared->mas1 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS2:
> + vcpu->arch.shared->mas2 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS7_3:
> + vcpu->arch.shared->mas7_3 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS4:
> + vcpu->arch.shared->mas4 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS6:
> + vcpu->arch.shared->mas6 =3D set_reg_val(id, *val);
> + break;
> + /* Only allow MMU registers to be set to the config supported by =
KVM */
> + case KVM_REG_PPC_MMUCFG: {
> + if (set_reg_val(id, *val) !=3D vcpu->arch.mmucfg)
> + r =3D -EINVAL;
> + break;
> + }
> + case KVM_REG_PPC_TLB0CFG:
> + case KVM_REG_PPC_TLB1CFG:
> + case KVM_REG_PPC_TLB2CFG:
> + case KVM_REG_PPC_TLB3CFG: {
> + /* MMU geometry (N_ENTRY/ASSOC) can be set only using =
SW_TLB */
> + i =3D id - KVM_REG_PPC_TLB0CFG;
> + if (set_reg_val(id, *val) !=3D vcpu->arch.tlbcfg[i])
> + r =3D -EINVAL;
> + break;
> + }
> + default:
> + r =3D -EINVAL;
> + break;
> + }
> +
> + return r;
> +}
> +
> int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
> struct kvm_config_tlb *cfg)
> {
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..ab073a8 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> struct kvmppc_vcpu_e500 *vcpu_e500;
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Gary Thomas @ 2013-03-27 15:24 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1364388152.1345.29.camel@x61.thuisdomein>
On 2013-03-27 06:42, Paul Bolle wrote:
> On Wed, 2013-03-27 at 13:05 +0100, Geert Uytterhoeven wrote:
>> This section is CHRP-specific. The cs4232 driver also worked on the
>> CHRP LongTrail.
>> But I don't remember if the parameter values above also applied to LongTrail.
>> I do remember it didn't work without specifing the right parameters, so you
>> probably want to keep this section.
>
> My reasoning was quite simply that this file was 14 years old so that
> probably nobody is using that stuff anymore. Are people actually using
> CHRP (whatever that is)? Anyhow, cs4232 is mentioned in some other files
Common Hardware Reference Platform - see
http://en.wikipedia.org/wiki/Common_Hardware_Reference_Platform
> too:
> $ git grep -l -n cs4232 Documentation/
> Documentation/powerpc/sound.txt
> Documentation/sound/alsa/ALSA-Configuration.txt
> Documentation/sound/alsa/alsa-parameters.txt
> Documentation/sound/oss/Introduction
> Documentation/sound/oss/Tropez+
>
> Could these few lines be dumped in one of these (except
> powerpc/sound.txt, of course)?
>
Seeing this stuff go marks the end of an era (the PreP and CHRP
platforms were some of the very first devices to run Linux back
in 1995...) I just sent my last one to the recycler a few months
back :-(
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Re: [PATCHv2 1/3] pci: added pcie_get_speed_cap_mask function
From: Benjamin Herrenschmidt @ 2013-03-27 15:25 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: David Airlie, linux-pci@vger.kernel.org, DRI mailing list,
Alex Deucher, Thadeu Cascardo, Lucas Kannebley Tavares,
Brian King, linuxppc-dev
In-Reply-To: <CAErSpo4rc=8mYgwuTO6693QCQJ9nsPsxmh7YAwxMygiVrPQR0A@mail.gmail.com>
On Tue, 2013-03-26 at 12:39 -0600, Bjorn Helgaas wrote:
> But we also know pdev is a PCIe device, and I think a PCIe device on a
> root bus must be a "Root Complex Integrated Endpoint" (PCIe spec sec
> 1.3.2.3). Such a device does not have a link at all, so there's no
> point in fiddling with its link speed.
This is where our IBM hypervisor makes things murky. It doesn't expose
the PCIe parents (basically somewhat makes PCIe look like PCI except we
still have the PCIe caps on the child devices, just no access to the
parent device).
It's garbage but can't be fixed (would break AIX :-)
However we might be able to populate the bus->max_bus_speed from some
architecture specific quirk and have radeon use that.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Paul Bolle @ 2013-03-27 12:55 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-fbdev, Florian Tobias Schandinat, linux-doc, linux-kernel,
Paul Mackerras, Rob Landley, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1364388152.1345.29.camel@x61.thuisdomein>
By the way, I get bounces from Adam's address:
> I'm sorry to have to inform you that your message could not
> be delivered to one or more recipients. It's attached below.
>
> For further assistance, please send mail to <postmaster>
>
> If you do so, please include this problem report. You can
> delete your own text from the attached returned message.
>
> <abelay@mit.edu>: 550 5.1.1 <abelay@mit.edu>... User unknown
(It's now removed from the CC line.) Does anyone know what's going on
here?
Paul Bolle
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Paul Bolle @ 2013-03-27 12:42 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-fbdev, Florian Tobias Schandinat, linux-doc, linux-kernel,
Paul Mackerras, Rob Landley, Bjorn Helgaas, linuxppc-dev,
Adam Belay
In-Reply-To: <CAMuHMdVs-Xxu9e=8WZbTBXE1_+iYOBKODgj9_EKmVbZA3z=8JA@mail.gmail.com>
On Wed, 2013-03-27 at 13:05 +0100, Geert Uytterhoeven wrote:
> This section is CHRP-specific. The cs4232 driver also worked on the
> CHRP LongTrail.
> But I don't remember if the parameter values above also applied to LongTrail.
> I do remember it didn't work without specifing the right parameters, so you
> probably want to keep this section.
My reasoning was quite simply that this file was 14 years old so that
probably nobody is using that stuff anymore. Are people actually using
CHRP (whatever that is)? Anyhow, cs4232 is mentioned in some other files
too:
$ git grep -l -n cs4232 Documentation/
Documentation/powerpc/sound.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/alsa-parameters.txt
Documentation/sound/oss/Introduction
Documentation/sound/oss/Tropez+
Could these few lines be dumped in one of these (except
powerpc/sound.txt, of course)?
Paul Bolle
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Geert Uytterhoeven @ 2013-03-27 12:05 UTC (permalink / raw)
To: Paul Bolle
Cc: linux-fbdev, Florian Tobias Schandinat, linux-doc, linux-kernel,
Paul Mackerras, Rob Landley, Bjorn Helgaas, linuxppc-dev,
Adam Belay
In-Reply-To: <1364381223.1345.18.camel@x61.thuisdomein>
On Wed, Mar 27, 2013 at 11:47 AM, Paul Bolle <pebolle@tiscali.nl> wrote:
> 3) I removed two files in documentation that are almost entirely PReP
> specific. The remaining lines looked uninteresting.
> --- a/Documentation/powerpc/sound.txt
> +++ /dev/null
> -2. IBM CHRP
> -
> - I have only tested this on the 43P-150. Build the kernel with the cs4232
> - set as a module and load the module with irq=9 dma=1 dma2=2 io=0x550
This section is CHRP-specific. The cs4232 driver also worked on the
CHRP LongTrail.
But I don't remember if the parameter values above also applied to LongTrail.
I do remember it didn't work without specifing the right parameters, so you
probably want to keep this section.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
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