[PATCH/RFC 0/3] UHS-I SDR-104 support for sh_mobile_sdhi
Hi, this series is based on work by Ai Kyuse to add UHS-I SDR-104 support for sh_mobile_sdhi. It builds on work by Shinobu Uehara, Rob Taylor, William Towle and Ian Molton, Ben Hutchings, Wolfram Sang and others to add UHS-I SDR-50 support to the same driver. This series enables UHS-I SDR-104 on the r8a7790/Lager where UHS-I SDR-50 is already enabled. It is based on a merge of: * The next branch of the mmc tree * The renesas-next-20160427v2-v4.6-rc1 tag of the renesas tree * The sh-pfc-for-v4.7-tag1 tag of the renesas-drivers tree The first two mmc driver patches are targeted at the next branch of the mmc tree. The last DT patch is targeted at the devel branch of the renesas tree. To aid review this series is provided in the _temporary_ topic/sdr104 branch of the renesas tree. A description of testing performed follows: * Environment SoC/Board: r8a7790/Lager SanDisk Card: SanDisk Ultra 64Gb microSDXC UHS-1 Identifier on Packaging: SDSQUNC-064G-GN6MA Samsung Card: Samsung 32Gb microSDHC Card Class 10 UHS-1 U3 ModelCode: MB-MG32EA/FFP * Wit these patches (topic/sdr104 branch) # mount -t debugfs none /sys/kernel/debug # cat /sys/kernel/debug/mmc1/ios clock: 19500 Hz vdd:21 (3.3 ~ 3.4 V) bus mode: 2 (push-pull) chip select:0 (don't care) power mode: 2 (on) bus width: 2 (4 bits) timing spec:6 (sd uhs SDR104) signal voltage: 1 (1.80 V) driver type:0 (driver type B) SanDisk Card: # dd bs=1M count=512 iflag=direct if=/dev/mmcblk1 of=/dev/null 536870912 bytes (537 MB) copied, 13.6713 s, 39.3 MB/s Samsung Card: # dd bs=1M count=512 iflag=direct if=/dev/mmcblk1 of=/dev/null 536870912 bytes (537 MB) copied, 16.4952 s, 32.5 MB/s * Without these patches (base of topic/sdr104 branch) # mount -t debugfs none /sys/kernel/debug # cat /sys/kernel/debug/mmc1/ios clock: 1 Hz vdd:21 (3.3 ~ 3.4 V) bus mode: 2 (push-pull) chip select:0 (don't care) power mode: 2 (on) bus width: 2 (4 bits) timing spec:5 (sd uhs SDR50) signal voltage: 1 (1.80 V) driver type:0 (driver type B) SanDisk Card: # dd bs=1M count=512 iflag=direct if=/dev/mmcblk1 of=/dev/null 536870912 bytes (537 MB) copied, 17.7253 s, 30.3 MB/s Samsung Card: # dd bs=1M count=512 iflag=direct if=/dev/mmcblk1 of=/dev/null 536870912 bytes (537 MB) copied, 20.7866 s, 25.8 MB/s Ai Kyuse (2): mmc: tmio: Add tuning support mmc: sh_mobile_sdhi: Add tuning support Simon Horman (1): ARM: dts: r8a7790: lager: Enable UHS-I SDR-104 arch/arm/boot/dts/r8a7790-lager.dts | 1 + drivers/mmc/host/sh_mobile_sdhi.c | 264 +++- drivers/mmc/host/tmio_mmc.h | 10 ++ drivers/mmc/host/tmio_mmc_pio.c | 249 -- include/linux/mfd/tmio.h| 3 + 5 files changed, 518 insertions(+), 9 deletions(-) -- 2.1.4
[PATCH/RFC 1/3] mmc: tmio: Add tuning support
From: Ai KyuseAdd tuning support for use with SDR104 mode Signed-off-by: Ai Kyuse Signed-off-by: Simon Horman --- v1 [Simon Horman] * Omit start_signal_voltage_switch and tmio_mmc_card_busy changes which are already present in mainline in a different form * Return num from init_tuning rather than passing an extra parameter to hold the return value * Only call host->init_tuning if it is non-NULL * Place tmio_mmc_execute_tuning() such that no new forward declarations are required * Remove unused TMIO_MMC_HAS_UHS_SCC define v0 [Ai Kyuse] --- drivers/mmc/host/tmio_mmc.h | 10 ++ drivers/mmc/host/tmio_mmc_pio.c | 249 ++-- include/linux/mfd/tmio.h| 3 + 3 files changed, 254 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 1aac2ad8edf2..cacc64c87fa0 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -19,6 +19,7 @@ #define TMIO_MMC_H #include +#include #include #include #include @@ -150,6 +151,9 @@ struct tmio_mmc_host { struct mutexios_lock; /* protect set_ios() context */ boolnative_hotplug; boolsdio_irq_enabled; + u32 scc_tappos; + booldone_tuning; + struct completion completion; int (*write16_hook)(struct tmio_mmc_host *host, int addr); int (*clk_enable)(struct tmio_mmc_host *host); @@ -160,6 +164,12 @@ struct tmio_mmc_host { unsigned int direction, int blk_size); int (*start_signal_voltage_switch)(struct mmc_host *mmc, struct mmc_ios *ios); + bool (*inquiry_tuning)(struct tmio_mmc_host *host); + unsigned int (*init_tuning)(struct tmio_mmc_host *host); + int (*prepare_tuning)(struct tmio_mmc_host *host, unsigned long tap); + int (*select_tuning)(struct tmio_mmc_host *host, unsigned long *tap); + bool (*retuning)(struct tmio_mmc_host *host); + void (*hw_reset)(struct tmio_mmc_host *host); }; struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev); diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index f44e2ab7aea2..4e6d80ad7bac 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -277,6 +278,8 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) { struct mmc_request *mrq; unsigned long flags; + bool result; + struct mmc_command *cmd = host->cmd; spin_lock_irqsave(>lock, flags); @@ -290,7 +293,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) host->data = NULL; host->force_pio = false; - cancel_delayed_work(>delayed_reset_work); + if (!(host->inquiry_tuning && host->inquiry_tuning(host) && + !host->done_tuning) || cmd != mrq->sbc) + cancel_delayed_work(>delayed_reset_work); host->mrq = NULL; spin_unlock_irqrestore(>lock, flags); @@ -298,6 +303,29 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) if (mrq->cmd->error || (mrq->data && mrq->data->error)) tmio_mmc_abort_dma(host); + if (host->inquiry_tuning && host->inquiry_tuning(host) && +!host->done_tuning) { + /* call retuning() to clear SCC error bit */ + if (host->retuning) + host->retuning(host); + /* finish processing tuning request */ + complete(>completion); + return; + } + + /* Check retuning */ + if (host->retuning && host->done_tuning) { + result = host->retuning(host); + if (result || (mrq->cmd->error == -EILSEQ)) + host->done_tuning = false; + } + + if (cmd == mrq->sbc) { + /* finish SET_BLOCK_COUNT request */ + complete(>completion); + return; + } + mmc_request_done(host->mmc, mrq); } @@ -363,7 +391,8 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command * multiple block transfer */ if ((host->pdata->flags & TMIO_MMC_HAVE_CMD12_CTRL) && - (cmd->opcode == SD_IO_RW_EXTENDED)) + ((cmd->opcode == SD_IO_RW_EXTENDED) || +host->mrq->sbc)) c |= NO_CMD12_ISSUE; } if (data->flags & MMC_DATA_READ) @@ -520,7 +549,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
[PATCH/RFC 3/3] ARM: dts: r8a7790: lager: Enable UHS-I SDR-104
Add the sd-uhs-sdr104 property to SDHI0. Signed-off-by: Simon Horman--- arch/arm/boot/dts/r8a7790-lager.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 749ba02b6a53..05d1ff7acee2 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -559,6 +559,7 @@ vqmmc-supply = <_sdhi0>; cd-gpios = < 6 GPIO_ACTIVE_LOW>; sd-uhs-sdr50; + sd-uhs-sdr104; status = "okay"; }; -- 2.1.4
Re: [PATCH 1/2] cpufreq: rcar: Add support for R8A7795 SoC
On 10-05-16, 11:57, Khiem Nguyen wrote: > After the commit "a399dc9fc50 cpufreq: shmobile: Use generic platdev > driver", will use cpufreq-dt-platdev driver to enable cpufreq-dt support. > Hence, follow the implementation to support new R8A7795 SoC. > > Signed-off-by: Khiem Nguyen> --- > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > 1 file changed, 1 insertion(+) Acked-by: Viresh Kumar -- viresh
Re: [PATCH 2/2] cpufreq: rcar: Add support for R8A7796 SoC
On 10-05-16, 11:59, Khiem Nguyen wrote: > Signed-off-by: Khiem Nguyen> --- > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c > b/drivers/cpufreq/cpufreq-dt-platdev.c > index 32f6dda..7d038fd 100644 > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > @@ -54,6 +54,7 @@ static const struct of_device_id machines[] __initconst = > { > { .compatible = "renesas,r8a7793", }, > { .compatible = "renesas,r8a7794", }, > { .compatible = "renesas,r8a7795", }, > + { .compatible = "renesas,r8a7796", }, > { .compatible = "renesas,sh73a0", }, > > { .compatible = "rockchip,rk2928", }, Well, you could have done that in the same patch. But I don't mind two patches now. Acked-by: Viresh Kumar -- viresh
[PATCH 2/2] cpufreq: rcar: Add support for R8A7796 SoC
Signed-off-by: Khiem Nguyen--- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 32f6dda..7d038fd 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -54,6 +54,7 @@ static const struct of_device_id machines[] __initconst = { { .compatible = "renesas,r8a7793", }, { .compatible = "renesas,r8a7794", }, { .compatible = "renesas,r8a7795", }, + { .compatible = "renesas,r8a7796", }, { .compatible = "renesas,sh73a0", }, { .compatible = "rockchip,rk2928", }, -- 1.9.1
[PATCH 1/2] cpufreq: rcar: Add support for R8A7795 SoC
After the commit "a399dc9fc50 cpufreq: shmobile: Use generic platdev driver", will use cpufreq-dt-platdev driver to enable cpufreq-dt support. Hence, follow the implementation to support new R8A7795 SoC. Signed-off-by: Khiem Nguyen--- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index ac4a0ba..32f6dda 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -53,6 +53,7 @@ static const struct of_device_id machines[] __initconst = { { .compatible = "renesas,r8a7791", }, { .compatible = "renesas,r8a7793", }, { .compatible = "renesas,r8a7794", }, + { .compatible = "renesas,r8a7795", }, { .compatible = "renesas,sh73a0", }, { .compatible = "rockchip,rk2928", }, -- 1.9.1
[PATCH 0/2] cpufreq: rcar: Enable CPUFreq support
This series enables CPUFreq support in available R-Car Gen3 SoC. It depends on 2 series below: [PATCH 0/4] clk: renesas: cpg-mssr: Add support for R-Car M3-W [RFC 0/4] Add Z clock support All comments are appreciated. Khiem Nguyen (2): cpufreq: rcar: Add support for R8A7795 SoC cpufreq: rcar: Add support for R8A7796 SoC drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++ 1 file changed, 2 insertions(+) -- 1.9.1
[RFC 4/4] arm64: dts: r8a7795: Add Z clock scaling support
This patch adds Z clock scaling support for CA57 in R8A7795 SoC. An OPP table is created with the supported frequency scaling. Signed-off-by: Dien PhamSigned-off-by: Takeshi Kihara Signed-off-by: Khiem Nguyen --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 26 ++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 7181db0..041d0f2 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -43,6 +43,8 @@ power-domains = < R8A7795_PD_CA57_CPU0>; next-level-cache = <_CA57>; enable-method = "psci"; + clocks =< CPG_CORE R8A7795_CLK_Z>; + operating-points-v2 = <_opp_tb0>; }; a57_1: cpu@1 { @@ -52,6 +54,7 @@ power-domains = < R8A7795_PD_CA57_CPU1>; next-level-cache = <_CA57>; enable-method = "psci"; + operating-points-v2 = <_opp_tb0>; }; a57_2: cpu@2 { compatible = "arm,cortex-a57","arm,armv8"; @@ -60,6 +63,7 @@ power-domains = < R8A7795_PD_CA57_CPU2>; next-level-cache = <_CA57>; enable-method = "psci"; + operating-points-v2 = <_opp_tb0>; }; a57_3: cpu@3 { compatible = "arm,cortex-a57","arm,armv8"; @@ -68,6 +72,28 @@ power-domains = < R8A7795_PD_CA57_CPU3>; next-level-cache = <_CA57>; enable-method = "psci"; + operating-points-v2 = <_opp_tb0>; + }; + }; + + cluster0_opp_tb0: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5 { + opp-hz = /bits/ 64 <5>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; + opp@10 { + opp-hz = /bits/ 64 <10>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; + opp@15 { + opp-hz = /bits/ 64 <15>; + opp-microvolt = <82>; + clock-latency-ns = <30>; }; }; -- 1.9.1
[RFC 2/4] clk: renesas: r8a7795: Add Z clock
Signed-off-by: Khiem Nguyen--- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index e53aff5..4120506 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -104,6 +104,7 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_DIV6_RO("r_int",CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), + DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), }; static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { -- 1.9.1
[RFC 1/4] clk: renesas: rcar-gen3-cpg: Add Z clock
Base on Dien Pham work. Signed-off-by: Khiem Nguyen--- drivers/clk/renesas/rcar-gen3-cpg.c | 143 drivers/clk/renesas/rcar-gen3-cpg.h | 1 + 2 files changed, 144 insertions(+) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index bb4f2f9..45209ac 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -28,6 +28,146 @@ #define CPG_PLL2CR 0x002c #define CPG_PLL4CR 0x01f4 +/** Modify for Z-clock + * - + * Z Clock + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is adjustable. clk->rate = parent->rate * mult / 32 + * parent - fixed parent. No clk_set_parent support + */ +#define CPG_FRQCRB 0x0004 +#define CPG_FRQCRB_KICKBIT(31) +#define CPG_FRQCRC 0x00e0 +#define CPG_FRQCRC_ZFC_MASK(0x1f << 8) +#define CPG_FRQCRC_ZFC_SHIFT 8 + + +struct cpg_z_clk { + struct clk_hw hw; + void __iomem *reg; + void __iomem *kick_reg; +}; + +#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) + +static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + unsigned int val; + unsigned long rate; + + val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) + >> CPG_FRQCRC_ZFC_SHIFT; + mult = 32 - val; + + rate = div_u64((u64)parent_rate * mult + 16, 32); + /* Round to closest value at 100MHz unit */ + rate = 1*DIV_ROUND_CLOSEST(rate, 1); + return rate; +} + +static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, +unsigned long *parent_rate) +{ + unsigned long prate = *parent_rate; + unsigned int mult; + + if (!prate) + prate = 1; + + mult = div_u64((u64)rate * 32 + prate/2, prate); + mult = clamp(mult, 1U, 32U); + + return *parent_rate / 32 * mult; +} + +static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + u32 val, kick; + unsigned int i; + + mult = div_u64((u64)rate * 32 + parent_rate/2, parent_rate); + mult = clamp(mult, 1U, 32U); + + if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) + return -EBUSY; + + val = clk_readl(zclk->reg); + val &= ~CPG_FRQCRC_ZFC_MASK; + val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; + clk_writel(val, zclk->reg); + + /* +* Set KICK bit in FRQCRB to update hardware setting and wait for +* clock change completion. +*/ + kick = clk_readl(zclk->kick_reg); + kick |= CPG_FRQCRB_KICK; + clk_writel(kick, zclk->kick_reg); + + /* +* Note: There is no HW information about the worst case latency. +* +* Using experimental measurements, it seems that no more than +* ~10 iterations are needed, independently of the CPU rate. +* Since this value might be dependent of external xtal rate, pll1 +* rate or even the other emulation clocks rate, use 1000 as a +* "super" safe value. +*/ + for (i = 1000; i; i--) { + if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) + return 0; + + cpu_relax(); + } + + return -ETIMEDOUT; +} + +static const struct clk_ops cpg_z_clk_ops = { + .recalc_rate = cpg_z_clk_recalc_rate, + .round_rate = cpg_z_clk_round_rate, + .set_rate = cpg_z_clk_set_rate, +}; + +static struct clk * __init cpg_z_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + const char *parent_name) +{ + struct clk_init_data init; + struct cpg_z_clk *zclk; + struct clk *clk; + + zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + if (!zclk) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = _z_clk_ops; + init.flags = CLK_SET_RATE_GATE; + init.parent_names = _name; + init.num_parents = 1; + + zclk->reg = base + CPG_FRQCRC; + zclk->kick_reg = base + CPG_FRQCRB; + zclk->hw.init = + + clk = clk_register(NULL, >hw); + if (IS_ERR(clk)) + kfree(zclk); + + return clk; +} + +/** End of modifying for Z-clock */ /* * SDn Clock @@ -325,6 +465,9 @@ struct clk * __init
[PATCH] ASoC: rsnd: don't use prohibited number to PDMACHCRn.SRS
From: Kuninori MorimotoCurrent rsnd_dmapp_get_id() returns 0xFF as error code if system used strange connection. It will be used as PDMACHCRn.SRS, but 0xFF is prohibited number. In order not to use prohibited number, this patch indicates error message and returns 0x00 (same as SSI00) in error case. Special thanks to Dung-san. Reported-by: Nguyen Viet Dung Signed-off-by: Kuninori Morimoto --- sound/soc/sh/rcar/dma.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 7658e8f..6bc93cb 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -316,11 +316,15 @@ static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io, size = ARRAY_SIZE(gen2_id_table_cmd); } - if (!entry) - return 0xFF; + if ((!entry) || (size <= id)) { + struct device *dev = rsnd_priv_to_dev(rsnd_io_to_priv(io)); - if (size <= id) - return 0xFF; + dev_err(dev, "unknown connection (%s[%d])\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + + /* use non-prohibited SRS number as error */ + return 0x00; /* SSI00 */ + } return entry[id]; } -- 1.9.1
Re: [GIT PULL] Renesas ARM64 Based SoC DT PM Domain Updates for v4.7
On Mon, May 09, 2016 at 03:10:40PM +0200, Arnd Bergmann wrote: > On Friday 06 May 2016 09:21:25 Simon Horman wrote: > > Hi, > > > > On Wed, Apr 27, 2016 at 02:20:10PM +1000, Simon Horman wrote: > > > Hi Olof, Hi Kevin, Hi Arnd, > > > > > > Please consider these Renesas ARM64 based SoC DT PM Domain updates for > > > v4.7. > > > > > > This pull requests is based on a merge of: > > > > > > * "[GIT PULL] Second Round of Renesas ARM Based SoC R-Car SYSC Updates for > > > v4.7", tagged as renesas-rcar-sysc2-for-v4.7, which you have already > > > pulled > > > * "[GIT PULL] Second Round of Renesas ARM64 Based SoC DT Updates for > > > v4.7", > > > tagged as renesas-arm64-dt2-for-v4.7, which I have sent a pull request > > > for. > > > > > > The reason for the somewhat tedious base on > > > renesas-rcar-sysc2-for-v4.7, which provides driver changes, > > > is a hard run-time dependency. > > > > > > I also have a similar set of changes for ARM (32-bit) which I will send > > > separately. > > > > I am wondering if this pull-request might have slipped through the cracks. > > > > FWIW, all other pull requests I have submitted for v4.7 have been pulled > > (thanks!) including a similar pull-request for ARM (32-bit) which is > > present in the next/late branch of the arm-soc tree. > > > > I do not plan to send any more non-fix pull requests for v4.7. > > And at this stage I am not aware of any fixes for v4.7. > > > > Indeed it did, thanks for the reminder! I've put it on my stack now > and should start doing merges later today when I'm through my mail. Great, thanks! I see that it has now been pulled.
Re: [PATCH] MAINTAINERS: update entry for TMIO MMC driver
On Mon, May 09, 2016 at 10:26:58AM +0200, Wolfram Sang wrote: > From: Wolfram Sang> > I have some more additions planned for this driver, so I'd like to get > notified of other changes and coordinate them. Drop Ian as maintainer > because he hasn't been involved in development for a while. Thanks for > all the initial work, of course! Also, reflect the recent changes to > the include file layout. > > Signed-off-by: Wolfram Sang > Cc: Ian Molton Acked-by: Simon Horman > --- > > Ian: If you'd like to stay involved, please speak up and I'll change my patch > accordingly. > > MAINTAINERS | 9 - > 1 file changed, 4 insertions(+), 5 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 42e65d128d015e..d22540c44b534b 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -11245,14 +11245,13 @@ S: Maintained > F: drivers/media/i2c/tc358743* > F: include/media/i2c/tc358743.h > > -TMIO MMC DRIVER > -M: Ian Molton > +TMIO/SDHI MMC DRIVER > +M: Wolfram Sang > L: linux-...@vger.kernel.org > -S: Maintained > +S: Supported > F: drivers/mmc/host/tmio_mmc* > F: drivers/mmc/host/sh_mobile_sdhi.c > -F: include/linux/mmc/tmio.h > -F: include/linux/mmc/sh_mobile_sdhi.h > +F: include/linux/mfd/tmio.h > > TMP401 HARDWARE MONITOR DRIVER > M: Guenter Roeck > -- > 2.7.0 >
[PATCHv6 4/8] arm: dma-mapping: add {map,unmap}_resource for iommu ops
Add methods to map/unmap device resources addresses for dma_map_ops that are IOMMU aware. This is needed to map a device MMIO register from a physical address. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- arch/arm/mm/dma-mapping.c | 63 +++ 1 file changed, 63 insertions(+) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index deac58d..d5fe32b 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1962,6 +1962,63 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, __free_iova(mapping, iova, len); } +/** + * arm_iommu_map_resource - map a device resource for DMA + * @dev: valid struct device pointer + * @phys_addr: physical address of resource + * @size: size of resource to map + * @dir: DMA transfer direction + */ +static dma_addr_t arm_iommu_map_resource(struct device *dev, + phys_addr_t phys_addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) +{ + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + dma_addr_t dma_addr; + int ret, prot; + phys_addr_t addr = phys_addr & PAGE_MASK; + int offset = phys_addr & ~PAGE_MASK; + int len = PAGE_ALIGN(size + offset); + + dma_addr = __alloc_iova(mapping, size); + if (dma_addr == DMA_ERROR_CODE) + return dma_addr; + + prot = __dma_direction_to_prot(dir) | IOMMU_MMIO; + + ret = iommu_map(mapping->domain, dma_addr, addr, len, prot); + if (ret < 0) + goto fail; + + return dma_addr + offset; +fail: + __free_iova(mapping, dma_addr, size); + return DMA_ERROR_CODE; +} + +/** + * arm_iommu_unmap_resource - unmap a device DMA resource + * @dev: valid struct device pointer + * @dma_handle: DMA address to resource + * @size: size of resource to map + * @dir: DMA transfer direction + */ +static void arm_iommu_unmap_resource(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + dma_addr_t iova = dma_handle & PAGE_MASK; + int offset = dma_handle & ~PAGE_MASK; + int len = PAGE_ALIGN(size + offset); + + if (!iova) + return; + + iommu_unmap(mapping->domain, iova, len); + __free_iova(mapping, iova, len); +} + static void arm_iommu_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir) { @@ -2006,6 +2063,9 @@ struct dma_map_ops iommu_ops = { .sync_sg_for_cpu= arm_iommu_sync_sg_for_cpu, .sync_sg_for_device = arm_iommu_sync_sg_for_device, + .map_resource = arm_iommu_map_resource, + .unmap_resource = arm_iommu_unmap_resource, + .set_dma_mask = arm_dma_set_mask, }; @@ -2021,6 +2081,9 @@ struct dma_map_ops iommu_coherent_ops = { .map_sg = arm_coherent_iommu_map_sg, .unmap_sg = arm_coherent_iommu_unmap_sg, + .map_resource = arm_iommu_map_resource, + .unmap_resource = arm_iommu_unmap_resource, + .set_dma_mask = arm_dma_set_mask, }; -- 2.8.2
[PATCHv6 2/8] dma-debug: add support for resource mappings
A MMIO mapped resource can not be represented by a struct page so a new debug type is needed to handle this. This patch add such type and functionality to add/remove entries and how to translate them to a physical address. Signed-off-by: Niklas Söderlund--- include/linux/dma-debug.h | 19 + lib/dma-debug.c | 52 +-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h index fe8cb61..c7d844f 100644 --- a/include/linux/dma-debug.h +++ b/include/linux/dma-debug.h @@ -56,6 +56,13 @@ extern void debug_dma_alloc_coherent(struct device *dev, size_t size, extern void debug_dma_free_coherent(struct device *dev, size_t size, void *virt, dma_addr_t addr); +extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr, + size_t size, int direction, + dma_addr_t dma_addr); + +extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, +size_t size, int direction); + extern void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, int direction); @@ -141,6 +148,18 @@ static inline void debug_dma_free_coherent(struct device *dev, size_t size, { } +static inline void debug_dma_map_resource(struct device *dev, phys_addr_t addr, + size_t size, int direction, + dma_addr_t dma_addr) +{ +} + +static inline void debug_dma_unmap_resource(struct device *dev, + dma_addr_t dma_addr, size_t size, + int direction) +{ +} + static inline void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, int direction) diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 4a1515f..fb12d5c 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -43,6 +43,7 @@ enum { dma_debug_page, dma_debug_sg, dma_debug_coherent, + dma_debug_resource, }; enum map_err_types { @@ -150,8 +151,9 @@ static const char *const maperr2str[] = { [MAP_ERR_CHECKED] = "dma map error checked", }; -static const char *type2name[4] = { "single", "page", - "scather-gather", "coherent" }; +static const char *type2name[5] = { "single", "page", + "scather-gather", "coherent", + "resource" }; static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE", "DMA_FROM_DEVICE", "DMA_NONE" }; @@ -397,6 +399,9 @@ static void hash_bucket_del(struct dma_debug_entry *entry) static unsigned long long phys_addr(struct dma_debug_entry *entry) { + if (entry->type == dma_debug_resource) + return PHYS_PFN(entry->pfn) + entry->offset; + return page_to_phys(pfn_to_page(entry->pfn)) + entry->offset; } @@ -1493,6 +1498,49 @@ void debug_dma_free_coherent(struct device *dev, size_t size, } EXPORT_SYMBOL(debug_dma_free_coherent); +void debug_dma_map_resource(struct device *dev, phys_addr_t addr, size_t size, + int direction, dma_addr_t dma_addr) +{ + struct dma_debug_entry *entry; + + if (unlikely(dma_debug_disabled())) + return; + + entry = dma_entry_alloc(); + if (!entry) + return; + + entry->type = dma_debug_resource; + entry->dev = dev; + entry->pfn = __phys_to_pfn(addr); + entry->offset = addr - PHYS_PFN(entry->pfn); + entry->size = size; + entry->dev_addr = dma_addr; + entry->direction= direction; + entry->map_err_type = MAP_ERR_NOT_CHECKED; + + add_dma_entry(entry); +} +EXPORT_SYMBOL(debug_dma_map_resource); + +void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, + size_t size, int direction) +{ + struct dma_debug_entry ref = { + .type = dma_debug_resource, + .dev= dev, + .dev_addr = dma_addr, + .size = size, + .direction = direction, + }; + + if (unlikely(dma_debug_disabled())) + return; + + check_unmap(); +} +EXPORT_SYMBOL(debug_dma_unmap_resource); + void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, int direction) { -- 2.8.2
[PATCHv6 6/8] dmaengine: rcar-dmac: add iommu support for slave transfers
Enable slave transfers to a device behind a IPMMU by mapping the slave addresses using the dma-mapping API. Signed-off-by: Niklas Söderlund--- drivers/dma/sh/rcar-dmac.c | 82 +- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index b0c3bb2..8592598 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -128,6 +128,18 @@ struct rcar_dmac_chan_slave { }; /* + * struct rcar_dmac_chan_map - Map of slave device phys to dma address + * @addr: slave dma address + * @dir: direction of mapping + * @slave: slave configuration that is mapped + */ +struct rcar_dmac_chan_map { + dma_addr_t addr; + enum dma_data_direction dir; + struct rcar_dmac_chan_slave slave; +}; + +/* * struct rcar_dmac_chan - R-Car Gen2 DMA Controller Channel * @chan: base DMA channel object * @iomem: channel I/O memory base @@ -152,6 +164,7 @@ struct rcar_dmac_chan { struct rcar_dmac_chan_slave src; struct rcar_dmac_chan_slave dst; + struct rcar_dmac_chan_map map; int mid_rid; spinlock_t lock; @@ -1027,13 +1040,65 @@ rcar_dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, DMA_MEM_TO_MEM, flags, false); } +static int rcar_dmac_map_slave_addr(struct dma_chan *chan, + enum dma_transfer_direction dir) +{ + struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); + struct rcar_dmac_chan_map *map = >map; + phys_addr_t dev_addr; + size_t dev_size; + enum dma_data_direction dev_dir; + + if (dir == DMA_DEV_TO_MEM) { + dev_addr = rchan->src.slave_addr; + dev_size = rchan->src.xfer_size; + dev_dir = DMA_TO_DEVICE; + } else { + dev_addr = rchan->dst.slave_addr; + dev_size = rchan->dst.xfer_size; + dev_dir = DMA_FROM_DEVICE; + } + + /* Reuse current map if possible. */ + if (dev_addr == map->slave.slave_addr && + dev_size == map->slave.xfer_size && + dev_dir == map->dir) + return 0; + + /* Remove old mapping if present. */ + if (map->slave.xfer_size) + dma_unmap_resource(chan->device->dev, map->addr, + map->slave.xfer_size, map->dir, NULL); + map->slave.xfer_size = 0; + + /* Create new slave address map. */ + map->addr = dma_map_resource(chan->device->dev, dev_addr, dev_size, +dev_dir, NULL); + + if (dma_mapping_error(chan->device->dev, map->addr)) { + dev_err(chan->device->dev, + "chan%u: failed to map %zx@%pap", rchan->index, + dev_size, _addr); + return -EIO; + } + + dev_dbg(chan->device->dev, "chan%u: map %zx@%pap to %pad dir: %s\n", + rchan->index, dev_size, _addr, >addr, + dev_dir == DMA_TO_DEVICE ? "DMA_TO_DEVICE" : "DMA_FROM_DEVICE"); + + map->slave.slave_addr = dev_addr; + map->slave.xfer_size = dev_size; + map->dir = dev_dir; + + return 0; +} + static struct dma_async_tx_descriptor * rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction dir, unsigned long flags, void *context) { struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); - dma_addr_t dev_addr; /* Someone calling slave DMA on a generic channel? */ if (rchan->mid_rid < 0 || !sg_len) { @@ -1043,9 +1108,10 @@ rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - dev_addr = dir == DMA_DEV_TO_MEM -? rchan->src.slave_addr : rchan->dst.slave_addr; - return rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr, + if (rcar_dmac_map_slave_addr(chan, dir)) + return NULL; + + return rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, rchan->map.addr, dir, flags, false); } @@ -1059,7 +1125,6 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); struct dma_async_tx_descriptor *desc; struct scatterlist *sgl; - dma_addr_t dev_addr; unsigned int sg_len; unsigned int i; @@ -1071,6 +1136,9 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, return NULL; } + if (rcar_dmac_map_slave_addr(chan, dir)) + return NULL; + sg_len = buf_len / period_len; if (sg_len > RCAR_DMAC_MAX_SG_LEN) { dev_err(chan->device->dev, @@ -1098,9 +1166,7 @@
[PATCHv6 5/8] dmaengine: rcar-dmac: group slave configuration
Group slave address and transfer size in own structs for source and destination. This is in preparation for hooking up the dma-mapping API to the slave addresses. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/dma/sh/rcar-dmac.c | 38 ++ 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index dfb1792..b0c3bb2 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -118,14 +118,22 @@ struct rcar_dmac_desc_page { sizeof(struct rcar_dmac_xfer_chunk)) /* + * struct rcar_dmac_chan_slave - Slave configuration + * @slave_addr: slave memory address + * @xfer_size: size (in bytes) of hardware transfers + */ +struct rcar_dmac_chan_slave { + phys_addr_t slave_addr; + unsigned int xfer_size; +}; + +/* * struct rcar_dmac_chan - R-Car Gen2 DMA Controller Channel * @chan: base DMA channel object * @iomem: channel I/O memory base * @index: index of this channel in the controller - * @src_xfer_size: size (in bytes) of hardware transfers on the source side - * @dst_xfer_size: size (in bytes) of hardware transfers on the destination side - * @src_slave_addr: slave source memory address - * @dst_slave_addr: slave destination memory address + * @src: slave memory address and size on the source side + * @dst: slave memory address and size on the destination side * @mid_rid: hardware MID/RID for the DMA client using this channel * @lock: protects the channel CHCR register and the desc members * @desc.free: list of free descriptors @@ -142,10 +150,8 @@ struct rcar_dmac_chan { void __iomem *iomem; unsigned int index; - unsigned int src_xfer_size; - unsigned int dst_xfer_size; - dma_addr_t src_slave_addr; - dma_addr_t dst_slave_addr; + struct rcar_dmac_chan_slave src; + struct rcar_dmac_chan_slave dst; int mid_rid; spinlock_t lock; @@ -793,13 +799,13 @@ static void rcar_dmac_chan_configure_desc(struct rcar_dmac_chan *chan, case DMA_DEV_TO_MEM: chcr = RCAR_DMACHCR_DM_INC | RCAR_DMACHCR_SM_FIXED | RCAR_DMACHCR_RS_DMARS; - xfer_size = chan->src_xfer_size; + xfer_size = chan->src.xfer_size; break; case DMA_MEM_TO_DEV: chcr = RCAR_DMACHCR_DM_FIXED | RCAR_DMACHCR_SM_INC | RCAR_DMACHCR_RS_DMARS; - xfer_size = chan->dst_xfer_size; + xfer_size = chan->dst.xfer_size; break; case DMA_MEM_TO_MEM: @@ -1038,7 +1044,7 @@ rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } dev_addr = dir == DMA_DEV_TO_MEM -? rchan->src_slave_addr : rchan->dst_slave_addr; +? rchan->src.slave_addr : rchan->dst.slave_addr; return rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr, dir, flags, false); } @@ -1093,7 +1099,7 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, } dev_addr = dir == DMA_DEV_TO_MEM -? rchan->src_slave_addr : rchan->dst_slave_addr; +? rchan->src.slave_addr : rchan->dst.slave_addr; desc = rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr, dir, flags, true); @@ -1110,10 +1116,10 @@ static int rcar_dmac_device_config(struct dma_chan *chan, * We could lock this, but you shouldn't be configuring the * channel, while using it... */ - rchan->src_slave_addr = cfg->src_addr; - rchan->dst_slave_addr = cfg->dst_addr; - rchan->src_xfer_size = cfg->src_addr_width; - rchan->dst_xfer_size = cfg->dst_addr_width; + rchan->src.slave_addr = cfg->src_addr; + rchan->dst.slave_addr = cfg->dst_addr; + rchan->src.xfer_size = cfg->src_addr_width; + rchan->dst.xfer_size = cfg->dst_addr_width; return 0; } -- 2.8.2
[PATCHv6 3/8] dma-mapping: add dma_{map,unmap}_resource
Map/Unmap a device MMIO resource from a physical address. If no dma_map_ops method is available the operation is a no-op. Signed-off-by: Niklas Söderlund--- Documentation/DMA-API.txt | 22 +- include/linux/dma-mapping.h | 36 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 45ef3f2..c7e5f99 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -277,14 +277,26 @@ and parameters are provided to do partial page mapping, it is recommended that you never use these unless you really know what the cache width is. +dma_addr_t +dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size, +enum dma_data_direction dir, struct dma_attrs *attrs) + +void +dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) + +API for mapping and unmapping for MMIO resources. All the notes and +warnings for the other mapping APIs apply here. The API should only be +used to map device MMIO resources, mapping of RAM is not permitted. + int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -In some circumstances dma_map_single() and dma_map_page() will fail to create -a mapping. A driver can check for these errors by testing the returned -DMA address with dma_mapping_error(). A non-zero return value means the mapping -could not be created and the driver should take appropriate action (e.g. -reduce current DMA mapping usage or delay and try again later). +In some circumstances dma_map_single(), dma_map_page() and dma_map_resource() +will fail to create a mapping. A driver can check for these errors by testing +the returned DMA address with dma_mapping_error(). A non-zero return value +means the mapping could not be created and the driver should take appropriate +action (e.g. reduce current DMA mapping usage or delay and try again later). int dma_map_sg(struct device *dev, struct scatterlist *sg, diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 8617fa1..dd228ce 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -218,6 +218,42 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, debug_dma_unmap_page(dev, addr, size, dir, false); } +static inline dma_addr_t dma_map_resource(struct device *dev, + phys_addr_t phys_addr, + size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + unsigned long pfn = __phys_to_pfn(phys_addr); + dma_addr_t addr; + + BUG_ON(!valid_dma_direction(dir)); + + /* Don't allow RAM to be mapped */ + BUG_ON(pfn_valid(pfn)); + + addr = phys_addr; + if (ops->map_resource) + addr = ops->map_resource(dev, phys_addr, size, dir, attrs); + + debug_dma_map_resource(dev, phys_addr, size, dir, addr); + + return addr; +} + +static inline void dma_unmap_resource(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + + BUG_ON(!valid_dma_direction(dir)); + if (ops->unmap_resource) + ops->unmap_resource(dev, addr, size, dir, attrs); + debug_dma_unmap_resource(dev, addr, size, dir); +} + static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) -- 2.8.2
[PATCHv6 0/8] dmaengine: rcar-dmac: add iommu support for slave transfers
Hi, This series tries to solve the problem with DMA with device registers (MMIO registers) that are behind an IOMMU for the rcar-dmac driver. A recent patch '9575632 (dmaengine: make slave address physical)' clarifies that DMA slave address provided by clients is the physical address. This puts the task of mapping the DMA slave address from a phys_addr_t to a dma_addr_t on the DMA engine. Without an IOMMU this is easy since the phys_addr_t and dma_addr_t are the same and no special care is needed. However if you have a IOMMU you need to map the DMA slave phys_addr_t to a dma_addr_t using something like this. This series is based on top of and requires the patches from Robin Murphy in the tag 'arm/io-pgtable' from the iommu repository at: git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git It's tested on a Koelsch with CONFIG_IPMMU_VMSA and by enabling the ipmmu_ds node in r8a7791.dtsi. I verified operation by interacting with /dev/mmcblk1 and the serial console which both are devices behind the iommu. Furthermore I have audited to the best of my ability all call paths involved to make sure that the dma_addr_t obtained from dma_map_resource() to is not used in a way where it would be expected for the mapping to be RAM (have a struct page). Many thanks to Christoph Hellwig and Laurent Pinchart for there input in this effort. * drivers/dma/sh/rcar-dmac.c Once the phys_addr_t is mapped to a dma_addr_t using dma_map_resource() it is only used to check that the transferee do not cross 4GB boundaries and then only directly written to HW registers. * drivers/iommu/iommu.c - iommu_map() Check that it's align to min page size or return -EINVAL then calls domain->ops->map() * drivers/iommu/ipmmu-vmsa.c - ipmmu_map() No logic only calls domain->ops->map() * drivers/iommu/io-pgtable-arm.c - arm_lpae_map() No logic only calls __arm_lpae_map() - __arm_lpae_map() No logic only calls arm_lpae_init_pte() - arm_lpae_init_pte() Used to get a pte: pte |= pfn_to_iopte(paddr >> data->pg_shift, data); * drivers/iommu/io-pgtable-arm-v7s.c - arm_v7s_map() No logic only calls __arm_v7s_map() - __arm_v7s_map() No logic only calls arm_v7s_init_pte() - arm_v7s_init_pte Used to get a pte: pte |= paddr & ARM_V7S_LVL_MASK(lvl); * ARM dma-mapping - dma_unmap_* Only valid unmap is dma_unmap_resource() all others are an invalid use case. - dma_sync_single_* Invalid use case, memory that is mapped is device memory - dma_common_mmap() and dma_mmap_attrs() Invalid use case - dma_common_get_sgtable() and dma_get_sgtable_attrs() Invalid use case, only for dma_alloc_* allocated memory, - dma_mapping_error() OK While working on the dma-debug parts of this series I found an unrelated issue with drivers/iommu/io-pgtable-arm.c and CONFIG_DMA_API_DEBUG on the Koelsch. I tried to address this in the thread https://lkml.org/lkml/2016/5/8/33 , however it turned out my solution was not the correct one. I have not tried to address this further so running this series with CONFIG_DMA_API_DEBUG will trigger this warning but is unrelated to this work. * Changes since v5 - Add dma-debug work which adds a new mapping type for the resource mapping which correctly can be translated to a physical address. - Drop patches from Robin Murphy since they now are accepted in the iommu repository and base the series on that tree instead. - Add a review tag from Laurent. * Changes since v4 - Move the mapping from phys_addr_t to dma_addr_t from slave_config to the prepare calls. This way we know the direction of the mapping and don't have to use DMA_BIDIRECTIONAL. Thanks Vinod for suggesting this. - To be clear that the data type for slave addresses are changed add a patch that only changes the data type to phys_addr_t. - Fixed up commit messages. * Changes since v3 - Folded in a fix from Robin to his patch. - Added a check to make sure dma_map_resource can not be used to map RAM as pointed out by Robin. I use BUG_ON to enforce this. It might not be the best method but I saw no other good way since DMA_ERROR_CODE might not be defined on all platforms. - Added comment about that DTS changes will disable 2 DMA channels due to a HW (?) but in the DMAC. - Dropped the use of dma_attrs, no longer needed. - Collected Acked-by and Reviewed-by from Laurent. - Various indentation fix ups. * Changes since v2 - Drop patch to add dma_{map,unmap}_page_attrs. - Add dma_{map,unmap}_resource to handle the mapping without involving a 'struct page'. Thanks Laurent and Robin for pointing this out. - Use size instead of address to keep track of if a mapping exist or not since addr == 0 is valid. Thanks Laurent. - Pick up patch from Robin with Laurents ack (hope it's OK for me to attach the ack?) to add IOMMU_MMIO. - Fix bug in rcar_dmac_device_config where the error
Re: V4L2 SDR compliance test?
Em Mon, 9 May 2016 13:59:52 + Ramesh Shanmugasundaramescreveu: > Hi Mauro, > > Thanks for the clarifications. > > > Ramesh Shanmugasundaram escreveu: > > > > > Hi Maintainers, All, > > > > > > Renesas R-Car SoCs have Digital Radio Interface (DRIF) controllers. > > > They are receive only SPI slave modules that support I2S format. The > > > targeted application of these controllers is SDR. > [...] > > > Two possible cases: > > > --- > > > 1) Third party tuner driver > > > - The framework does provide support to register tuner as a subdev > > > and can be bound to the SDR device using notifier callbacks > > > > Tuner is usually an i2c subdev, visible by the main SDR driver. No > > problem > > here: the main driver should use the subdev callbacks to direct the > > tuner- specific ioctls to the tuner subdev. > > Yes. The main SDR driver can have code to direct tuner subdev. > > > > > > 2) User space Tuner app > > > - We also have cases where the tuner s/w logic can be a vendor > > > supplied user space application or library that talks to the chip > > > using generic system calls - like i2c read/writes. > > > > Well, an userspace tuner app is out of the Kernel tree, so I can't see > > how it would affect it: it can have whatever API it needs (or even no > > API at all). Of course, in this case, the performance will very likely > > be worse, as the SDR data should also be handled in userspace. > > > > If, for performance issues, it would require a faster I/O, then such > > tuner app should be converted to be a Kernel driver. Usually, it is > > not hard to convert those drivers to Kernelspace, as typically it is > > just a bunch of registers that should be set to make it to tune into > > an specific frequency and to adjust the tuner filters to the desired > > bandwidth and modulation type, in order to improve noise rejection. > > Yes, this is possible. However, this is Tuner chip vendor's decision (NDA, > license issues etc.) and it is not in our control. True, but an independent tuner driver very likely can be written with very little effort. All it requires is to monitor the traffic at the I2C bus and to write a driver that reproduces it, identifying what part of the I2C messages contain the frequency and enable/disable the filters. We have several such drivers in the Kernel, and that's the procedure used when the chipset vendor doesn't see the value of having his chipset used by a Linux-based device. > As mentioned above, we can have the main SDR (DRIF) driver code to direct > tuner subdev if present. However, when we want to upstream the DRIF driver we > may not have a real Tuner driver/device to get the compliance test results. > Should we run the compliance tests with a dummy stubbed tuner subdev? No, an upstream requirement is to have everything tested on real hardware. What I recommend you is to either convince the tuner provider to send upstream a driver (or allow you to do so) or to switch to some other vendor whose driver is already in the Kernel or sees the value of having his chipset used on Linux. > Please do suggest how to proceed in this case? > Regards, Mauro
[PATCH] mmc: sh_mobile_sdhi: enable SDIO IRQs for RCar Gen3
From: Wolfram SangTested on a Salvator-X board with a Spectec SDW-823 WLAN card. Signed-off-by: Wolfram Sang --- drivers/mmc/host/sh_mobile_sdhi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 5309c73be1f04f..f750f9494410b0 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -71,7 +71,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = { static const struct sh_mobile_sdhi_of_data of_rcar_gen3_compatible = { .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_CLK_ACTUAL | TMIO_MMC_MIN_RCAR2, - .capabilities = MMC_CAP_SD_HIGHSPEED, + .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, .bus_shift = 2, }; -- 2.7.0
RE: V4L2 SDR compliance test?
Hi Mauro, Thanks for the clarifications. > Ramesh Shanmugasundaramescreveu: > > > Hi Maintainers, All, > > > > Renesas R-Car SoCs have Digital Radio Interface (DRIF) controllers. > > They are receive only SPI slave modules that support I2S format. The > > targeted application of these controllers is SDR. [...] > > Two possible cases: > > --- > > 1) Third party tuner driver > > - The framework does provide support to register tuner as a subdev > > and can be bound to the SDR device using notifier callbacks > > Tuner is usually an i2c subdev, visible by the main SDR driver. No > problem > here: the main driver should use the subdev callbacks to direct the > tuner- specific ioctls to the tuner subdev. Yes. The main SDR driver can have code to direct tuner subdev. > > > 2) User space Tuner app > > - We also have cases where the tuner s/w logic can be a vendor > > supplied user space application or library that talks to the chip > > using generic system calls - like i2c read/writes. > > Well, an userspace tuner app is out of the Kernel tree, so I can't see > how it would affect it: it can have whatever API it needs (or even no > API at all). Of course, in this case, the performance will very likely > be worse, as the SDR data should also be handled in userspace. > > If, for performance issues, it would require a faster I/O, then such > tuner app should be converted to be a Kernel driver. Usually, it is > not hard to convert those drivers to Kernelspace, as typically it is > just a bunch of registers that should be set to make it to tune into > an specific frequency and to adjust the tuner filters to the desired > bandwidth and modulation type, in order to improve noise rejection. Yes, this is possible. However, this is Tuner chip vendor's decision (NDA, license issues etc.) and it is not in our control. As mentioned above, we can have the main SDR (DRIF) driver code to direct tuner subdev if present. However, when we want to upstream the DRIF driver we may not have a real Tuner driver/device to get the compliance test results. Should we run the compliance tests with a dummy stubbed tuner subdev? Please do suggest how to proceed in this case? Thanks, Ramesh
Re: [GIT PULL] Renesas ARM64 Based SoC DT PM Domain Updates for v4.7
On Wednesday 27 April 2016 14:20:10 Simon Horman wrote: > Hi Olof, Hi Kevin, Hi Arnd, > > Please consider these Renesas ARM64 based SoC DT PM Domain updates for v4.7. > > This pull requests is based on a merge of: > > * "[GIT PULL] Second Round of Renesas ARM Based SoC R-Car SYSC Updates for > v4.7", tagged as renesas-rcar-sysc2-for-v4.7, which you have already > pulled > * "[GIT PULL] Second Round of Renesas ARM64 Based SoC DT Updates for v4.7", > tagged as renesas-arm64-dt2-for-v4.7, which I have sent a pull request > for. > > The reason for the somewhat tedious base on > renesas-rcar-sysc2-for-v4.7, which provides driver changes, > is a hard run-time dependency. > > I also have a similar set of changes for ARM (32-bit) which I will send > separately. > Pulled into next/late now along with the 32-bit branch. Thanks, Arnd
Re: [GIT PULL] Renesas ARM64 Based SoC DT PM Domain Updates for v4.7
On Friday 06 May 2016 09:21:25 Simon Horman wrote: > Hi, > > On Wed, Apr 27, 2016 at 02:20:10PM +1000, Simon Horman wrote: > > Hi Olof, Hi Kevin, Hi Arnd, > > > > Please consider these Renesas ARM64 based SoC DT PM Domain updates for v4.7. > > > > This pull requests is based on a merge of: > > > > * "[GIT PULL] Second Round of Renesas ARM Based SoC R-Car SYSC Updates for > > v4.7", tagged as renesas-rcar-sysc2-for-v4.7, which you have already > > pulled > > * "[GIT PULL] Second Round of Renesas ARM64 Based SoC DT Updates for v4.7", > > tagged as renesas-arm64-dt2-for-v4.7, which I have sent a pull request > > for. > > > > The reason for the somewhat tedious base on > > renesas-rcar-sysc2-for-v4.7, which provides driver changes, > > is a hard run-time dependency. > > > > I also have a similar set of changes for ARM (32-bit) which I will send > > separately. > > I am wondering if this pull-request might have slipped through the cracks. > > FWIW, all other pull requests I have submitted for v4.7 have been pulled > (thanks!) including a similar pull-request for ARM (32-bit) which is > present in the next/late branch of the arm-soc tree. > > I do not plan to send any more non-fix pull requests for v4.7. > And at this stage I am not aware of any fixes for v4.7. > Indeed it did, thanks for the reminder! I've put it on my stack now and should start doing merges later today when I'm through my mail. Arnd
Re: [PATCH 0/3] soc: renesas: rcar-sysc: Add support for R-Car M3-W power areas
Hi Geert, Thank you for the patches. For the whole series, Acked-by: Laurent PinchartOn Wednesday 04 May 2016 16:36:07 Geert Uytterhoeven wrote: > Hi Simon, Magnus, > > This patch series adds support for the power areas exposed by the System > Controller on the Renesas R-Car M3-W SoC. > > /sys/kernel/debug/pm_genpd/pm_genpd_summary output: > > domain status slaves > /device runtime status > -- > clock-controlleron > a3iroff-0 > 3dg-b off-0 > 3dg-a off-0 3dg-b > a2vc1 off-0 > a2vc0 off-0 > a3vcoff-0 a2vc0, a2vc1 > cr7 off-0 > ca53-cpu3 on > ca53-cpu2 on > ca53-cpu1 on > ca53-cpu0 on > ca53-scuon ca53-cpu0, ca53-cpu1, > ca53-cpu2, ca53-cpu3 ca57-cpu1 on > ca57-cpu0 on > ca57-scuon ca57-cpu0, ca57-cpu1 > always-on on ca57-scu, ca53-scu, cr7, > a3vc, 3dg-a, a3ir /devices/platform/soc/e6e88000.serial > active > > For your convenience, I've pushed this series to the > topic/r8a7796-sysc-v1 branch of > https://git.kernel.org/cgit/linux/kernel/git/geert/renesas-drivers.git. > > Integration with renesas-drivers-2016-04-26-v4.6-rc5, and minimal board > integration for testing is available in the topic/gen3-latest branch. > > This has received minimal testing on r8a7796/salvator-x. > > Thanks for your comments! > > Geert Uytterhoeven (3): > soc: renesas: rcar-sysc: Document r8a7796 support > soc: renesas: Add r8a7796 SYSC PM Domain Binding Definitions > soc: renesas: rcar-sysc: Add support for R-Car M3-W power areas > > .../bindings/power/renesas,rcar-sysc.txt | 1 + > drivers/soc/renesas/Makefile | 1 + > drivers/soc/renesas/r8a7796-sysc.c | 48 +++ > drivers/soc/renesas/rcar-sysc.c| 3 ++ > drivers/soc/renesas/rcar-sysc.h| 1 + > include/dt-bindings/power/r8a7796-sysc.h | 36 > 6 files changed, 90 insertions(+) > create mode 100644 drivers/soc/renesas/r8a7796-sysc.c > create mode 100644 include/dt-bindings/power/r8a7796-sysc.h -- Regards, Laurent Pinchart
About lazy_max_pages()
Hi, I have a question about (1) in the following RFC: http://www.spinics.net/lists/linux-rt-users/msg15082.html Does Upstream accept such a patch? < Overview > My environment (v4.6-rc5 on arm64 / r8a7795) has similar situation when dma_free_coherent() is called. < For example (The buffer size is 1024 bytes.) > - Sometimes the function spends about 8 msecs (worst-case). - If I modified the value such the patch, sometimes the spend time is about 1 msecs (worst-case). So, I would like to know that upstream accepts such a patch. < Remarks > I also tried both the (1) and (2) patches on my environment. However, kernel stopped on the way. Best regards, Yoshihiro Shimoda
Re: [PATCH 05/10] clk: renesas: rcar-gen2: Obtain MD pin value using boot-mode-reg
Hello. On 5/9/2016 10:13 AM, Dirk Behme wrote: From: Simon HormanUse new boot mode reg infrastructure to obtain the mode pin value for initialising clocks for for R-Car Gen2 SoCs. My spell-checker trips over "initialising". Perhaps initializing? Signed-off-by: Simon Horman [...] @@ -421,9 +423,15 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks", rcar_gen2_cpg_clocks_init); -void __init rcar_gen2_clocks_init(u32 mode) +void __init rcar_gen2_clocks_init(void) { - cpg_mode = mode; + int err; + + err = boot_mode_reg_get(_mode); + if (err) { + pr_err("%s: failed obtain boot mode\n", __func__); Failed to obtain? [...] MBR, Sergei
Re: [PATCH 0/2] Fix incorrect warning from dma-debug
On 09/05/16 10:37, Robin Murphy wrote: Hi Niklas, On 08/05/16 11:59, Niklas Söderlund wrote: Hi, While using CONFIG_DMA_API_DEBUG i came across this warning which I think is a false positive. As shown dma_sync_single_for_device() are called from the dma_map_single() call path. This triggers the warning since the dma-debug code have not yet been made aware of the mapping. Almost right ;) The thing being mapped (the SPI device's buffer) and the thing being synced (the IOMMU's PTE) are entirely unrelated. Due to the current of_iommu_init() setup, the IOMMU is probed long before dma_debug_init() gets called, therefore DMA debug is missing entries for some of the initial page table mappings and gets confused when we update them later. I try to solve this by introducing __dma_sync_single_for_device() which do not call into the dma-debug code. I'm no expert and this might be a bad way of solving the problem but it allowed me to keep working. The simple fix should be to just call dma_debug_init() from a sufficiently earlier initcall level. The best would be to sort out a proper device dependency order to avoid the whole early-IOMMU-creation thing entirely. A tangential idea, as Will just suggested to me, would be to make this false-positive situation more explicit, something like (untested): ---8<--- diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 4a1515f4b452..e16684a4ce86 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -107,7 +107,8 @@ static bool dma_debug_initialized __read_mostly; static inline bool dma_debug_disabled(void) { - return global_disable || !dma_debug_initialized; + return global_disable || WARN_ONCE(!dma_debug_initialized, + "early DMA-API call not tracked"); } /* Global error count */ --->8--- but it seems like this a sufficiently rare case that it's probably not worth cluttering up the code for. Robin. [ cut here ] WARNING: CPU: 0 PID: 1 at lib/dma-debug.c:1209 check_sync+0x154/0x5e4 ipmmu-vmsa e674.mmu: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x6e89b008] [size=8 bytes] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc5-00012-g52e78c1-dirty #1 Hardware name: Generic R8A7791 (Flattened Device Tree) Backtrace: [] (dump_backtrace) from [] (show_stack+0x18/0x1c) r7:c03ebad0 r6:0009 r5:6093 r4: [] (show_stack) from [] (dump_stack+0x84/0xa4) [] (dump_stack) from [] (__warn+0xd0/0x100) r5: r4:ef05dac8 [] (__warn) from [] (warn_slowpath_fmt+0x40/0x48) r9:0001 r8: r7:c0c69c40 r6:c0c02754 r5:ef05db78 r4:ef222810 [] (warn_slowpath_fmt) from [] (check_sync+0x154/0x5e4) r3:c0945b6f r2:c0936e85 [] (check_sync) from [] (debug_dma_sync_single_for_device+0x64/0x70) r10:0009 r9:000c r8:ee89b008 r7: r6:6e89b008 r5: r4:6e89b008 [] (debug_dma_sync_single_for_device) from [] (__arm_lpae_set_pte.part.0+0x80/0x8c) r5:0001 r4:ef222810 [] (__arm_lpae_set_pte.part.0) from [] (__arm_lpae_map+0x298/0x2f0) r7:0008 r6:ef25e000 r4:ee898500 [] (__arm_lpae_map) from [] (arm_lpae_map+0xcc/0xe4) r10:c0465f40 r9:1000 r8:4000 r7: r6:6f25c000 r5: r4:08c0 [] (arm_lpae_map) from [] (ipmmu_map+0x38/0x40) r7:4000 r6: r5:1000 r4:c0465a4c [] (ipmmu_map) from [] (iommu_map+0xf8/0x15c) r4:ee895608 [] (iommu_map) from [] (arm_coherent_iommu_map_page+0x1d4/0x2d4) r10:ef386940 r9:1000 r8: r7: r6:4000 r5: r4: [] (arm_coherent_iommu_map_page) from [] (arm_iommu_map_page+0x6c/0x74) r10:c0c61f44 r9:ef19d210 r8:0001 r7:1000 r6: r5:ec5ddb80 r4: [] (arm_iommu_map_page) from [] (sh_msiof_spi_probe+0x430/0x7b0) r9: r8:c0213624 r7:ef19d210 r6:ef242800 r5:ef1b4010 r4:ef242af0 [] (sh_msiof_spi_probe) from [] (platform_drv_probe+0x58/0xa8) r10: r9: r8:c0c1f8d4 r7:c0c7e910 r6:c0c1f8d4 r5:ef1b4010 r4:c04f7934 [] (platform_drv_probe) from [] (driver_probe_device+0x13c/0x2a4) r7:c0c7e910 r6: r5:c0c7e900 r4:ef1b4010 [] (driver_probe_device) from [] (__driver_attach+0x88/0xac) r9:c0c34000 r8:c0a3c010 r7:c0c1cf08 r6:c0c1f8d4 r5:ef1b4044 r4:ef1b4010 [] (__driver_attach) from [] (bus_for_each_dev+0x74/0x98) r7:c0c1cf08 r6:c049e8f0 r5:c0c1f8d4 r4: [] (bus_for_each_dev) from [] (driver_attach+0x20/0x28) r6:ef1cc200 r5: r4:c0c1f8d4 [] (driver_attach) from [] (bus_add_driver+0xd4/0x1e4) [] (bus_add_driver) from [] (driver_register+0xa4/0xe8) r7:c0a3c010 r6: r5:c0a1e400 r4:c0c1f8d4 [] (driver_register) from [] (__platform_driver_register+0x38/0x4c) r5:c0a1e400 r4:ee958fc0 [] (__platform_driver_register) from [] (sh_msiof_spi_drv_init+0x18/0x20) [] (sh_msiof_spi_drv_init) from [] (do_one_initcall+0x10c/0x1c0) [] (do_one_initcall) from [] (kernel_init_freeable+0x128/0x1f4) r9:c0c34000 r8:c0c34000 r7:c0a47e60 r6:c0a3c83c
Re: [PATCH 0/2] Fix incorrect warning from dma-debug
Hi Niklas, On 08/05/16 11:59, Niklas Söderlund wrote: Hi, While using CONFIG_DMA_API_DEBUG i came across this warning which I think is a false positive. As shown dma_sync_single_for_device() are called from the dma_map_single() call path. This triggers the warning since the dma-debug code have not yet been made aware of the mapping. Almost right ;) The thing being mapped (the SPI device's buffer) and the thing being synced (the IOMMU's PTE) are entirely unrelated. Due to the current of_iommu_init() setup, the IOMMU is probed long before dma_debug_init() gets called, therefore DMA debug is missing entries for some of the initial page table mappings and gets confused when we update them later. I try to solve this by introducing __dma_sync_single_for_device() which do not call into the dma-debug code. I'm no expert and this might be a bad way of solving the problem but it allowed me to keep working. The simple fix should be to just call dma_debug_init() from a sufficiently earlier initcall level. The best would be to sort out a proper device dependency order to avoid the whole early-IOMMU-creation thing entirely. Robin. [ cut here ] WARNING: CPU: 0 PID: 1 at lib/dma-debug.c:1209 check_sync+0x154/0x5e4 ipmmu-vmsa e674.mmu: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x6e89b008] [size=8 bytes] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc5-00012-g52e78c1-dirty #1 Hardware name: Generic R8A7791 (Flattened Device Tree) Backtrace: [] (dump_backtrace) from [] (show_stack+0x18/0x1c) r7:c03ebad0 r6:0009 r5:6093 r4: [] (show_stack) from [] (dump_stack+0x84/0xa4) [] (dump_stack) from [] (__warn+0xd0/0x100) r5: r4:ef05dac8 [] (__warn) from [] (warn_slowpath_fmt+0x40/0x48) r9:0001 r8: r7:c0c69c40 r6:c0c02754 r5:ef05db78 r4:ef222810 [] (warn_slowpath_fmt) from [] (check_sync+0x154/0x5e4) r3:c0945b6f r2:c0936e85 [] (check_sync) from [] (debug_dma_sync_single_for_device+0x64/0x70) r10:0009 r9:000c r8:ee89b008 r7: r6:6e89b008 r5: r4:6e89b008 [] (debug_dma_sync_single_for_device) from [] (__arm_lpae_set_pte.part.0+0x80/0x8c) r5:0001 r4:ef222810 [] (__arm_lpae_set_pte.part.0) from [] (__arm_lpae_map+0x298/0x2f0) r7:0008 r6:ef25e000 r4:ee898500 [] (__arm_lpae_map) from [] (arm_lpae_map+0xcc/0xe4) r10:c0465f40 r9:1000 r8:4000 r7: r6:6f25c000 r5: r4:08c0 [] (arm_lpae_map) from [] (ipmmu_map+0x38/0x40) r7:4000 r6: r5:1000 r4:c0465a4c [] (ipmmu_map) from [] (iommu_map+0xf8/0x15c) r4:ee895608 [] (iommu_map) from [] (arm_coherent_iommu_map_page+0x1d4/0x2d4) r10:ef386940 r9:1000 r8: r7: r6:4000 r5: r4: [] (arm_coherent_iommu_map_page) from [] (arm_iommu_map_page+0x6c/0x74) r10:c0c61f44 r9:ef19d210 r8:0001 r7:1000 r6: r5:ec5ddb80 r4: [] (arm_iommu_map_page) from [] (sh_msiof_spi_probe+0x430/0x7b0) r9: r8:c0213624 r7:ef19d210 r6:ef242800 r5:ef1b4010 r4:ef242af0 [] (sh_msiof_spi_probe) from [] (platform_drv_probe+0x58/0xa8) r10: r9: r8:c0c1f8d4 r7:c0c7e910 r6:c0c1f8d4 r5:ef1b4010 r4:c04f7934 [] (platform_drv_probe) from [] (driver_probe_device+0x13c/0x2a4) r7:c0c7e910 r6: r5:c0c7e900 r4:ef1b4010 [] (driver_probe_device) from [] (__driver_attach+0x88/0xac) r9:c0c34000 r8:c0a3c010 r7:c0c1cf08 r6:c0c1f8d4 r5:ef1b4044 r4:ef1b4010 [] (__driver_attach) from [] (bus_for_each_dev+0x74/0x98) r7:c0c1cf08 r6:c049e8f0 r5:c0c1f8d4 r4: [] (bus_for_each_dev) from [] (driver_attach+0x20/0x28) r6:ef1cc200 r5: r4:c0c1f8d4 [] (driver_attach) from [] (bus_add_driver+0xd4/0x1e4) [] (bus_add_driver) from [] (driver_register+0xa4/0xe8) r7:c0a3c010 r6: r5:c0a1e400 r4:c0c1f8d4 [] (driver_register) from [] (__platform_driver_register+0x38/0x4c) r5:c0a1e400 r4:ee958fc0 [] (__platform_driver_register) from [] (sh_msiof_spi_drv_init+0x18/0x20) [] (sh_msiof_spi_drv_init) from [] (do_one_initcall+0x10c/0x1c0) [] (do_one_initcall) from [] (kernel_init_freeable+0x128/0x1f4) r9:c0c34000 r8:c0c34000 r7:c0a47e60 r6:c0a3c83c r5:00bd r4:0006 [] (kernel_init_freeable) from [] (kernel_init+0x10/0x118) r9:[1.879529] ata1: link resume succeeded after 1 retries r8: r7: r6: r5:c071066c r4: [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) r5:c071066c r4: ---[ end trace 6eb9a3df3009d491 ]--- Niklas Söderlund (2): dma-mapping: add __dma_sync_single_for_device() iommu/io-pgtable-arm: use __dma_sync_single_for_device() drivers/iommu/io-pgtable-arm.c | 2 +- include/linux/dma-mapping.h| 9 - 2 files changed, 9 insertions(+), 2 deletions(-) -- 2.8.2 ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org
Re: [PATCH 2/2] iommu/io-pgtable-arm: use __dma_sync_single_for_device()
On Sun, May 08, 2016 at 12:59:56PM +0200, Niklas Söderlund wrote: > The call to dma_sync_single_for_device() can be reached from > dma_map_single(). If CONFIG_DMA_API_DEBUG is enabled this would result > in a check that the mapping being synced is valid. Since the call to > dma_map_single is not yet completed the mapping is not recorded in > dma-debug and the check fails and a warning is printed. Avoid this > warning by calling __dma_sync_single_for_device() which don't preform > this check. Hmm, I don't understand why this would trigger that warning. The memory being sync'd here is the page table memory, not the buffer being mapped. The page table memory is "mapped" using dma_map_single in __arm_lpae_alloc_pages, so it sounds like the issue something else. Will
V4L2 SDR compliance test?
Hi Maintainers, All, Renesas R-Car SoCs have Digital Radio Interface (DRIF) controllers. They are receive only SPI slave modules that support I2S format. The targeted application of these controllers is SDR. While evaluating the V4L2 SDR framework for this controller, we noticed the compliance test demands TUNER ioctls for SDR device. As a SoC controller, DRIF is independent of tuner functionality as a third party provides this device. The DRIF driver will support V4L2_CID_xxx & V4L2_SDR_FMT_xxx ioctls but not the tuner ioctls. Two possible cases: --- 1) Third party tuner driver - The framework does provide support to register tuner as a subdev and can be bound to the SDR device using notifier callbacks 2) User space Tuner app - We also have cases where the tuner s/w logic can be a vendor supplied user space application or library that talks to the chip using generic system calls - like i2c read/writes. The DRIF driver code as such will have v4l2_async_notifier_register only to be informed if a tuner device attaches. But this may or may not happen depending on the target board. >From upstream V4L2 SDR driver perspective, these DRIF patches will FAIL V4L2 compliance tests (a criteria needed to submit fresh driver patches). Questions are 1) Is this approach acceptable to the maintainers? 2) Should the SDR compliance tests be updated for these evolving use cases? -- Thanks, Ramesh
[PATCH] MAINTAINERS: update entry for TMIO MMC driver
From: Wolfram SangI have some more additions planned for this driver, so I'd like to get notified of other changes and coordinate them. Drop Ian as maintainer because he hasn't been involved in development for a while. Thanks for all the initial work, of course! Also, reflect the recent changes to the include file layout. Signed-off-by: Wolfram Sang Cc: Ian Molton --- Ian: If you'd like to stay involved, please speak up and I'll change my patch accordingly. MAINTAINERS | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 42e65d128d015e..d22540c44b534b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11245,14 +11245,13 @@ S:Maintained F: drivers/media/i2c/tc358743* F: include/media/i2c/tc358743.h -TMIO MMC DRIVER -M: Ian Molton +TMIO/SDHI MMC DRIVER +M: Wolfram Sang L: linux-...@vger.kernel.org -S: Maintained +S: Supported F: drivers/mmc/host/tmio_mmc* F: drivers/mmc/host/sh_mobile_sdhi.c -F: include/linux/mmc/tmio.h -F: include/linux/mmc/sh_mobile_sdhi.h +F: include/linux/mfd/tmio.h TMP401 HARDWARE MONITOR DRIVER M: Guenter Roeck -- 2.7.0
[PATCH] mmc: sdio: fall back to SDIO 1.0 for broken 1.1 cards
From: Wolfram SangI have two SDIO WLAN cards which specify being SDIO Rev. 1.1 cards but their FUNCE tuple reports the smaller size of a Rev 1.0 card. So, enforce 1.0 on these cards to avoid reading the not present registers. They are not really used anyhow. My cards initialize properly after this patch. Signed-off-by: Wolfram Sang --- drivers/mmc/core/sdio_cis.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 6f6fc527a26338..dcb3dee59fa5f2 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -177,8 +177,13 @@ static int cistpl_funce_func(struct mmc_card *card, struct sdio_func *func, vsn = func->card->cccr.sdio_vsn; min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; - if (size < min_size) + if (size == 28 && vsn == SDIO_SDIO_REV_1_10) { + pr_warn("%s: card has broken SDIO 1.1 CIS, forcing SDIO 1.0\n", + mmc_hostname(card->host)); + vsn = SDIO_SDIO_REV_1_00; + } else if (size < min_size) { return -EINVAL; + } /* TPLFE_MAX_BLK_SIZE */ func->max_blksize = buf[12] | (buf[13] << 8); -- 2.7.0
Re: [PATCH 09/10] ARM: r8a779x: Add boot mode reg support
Hi Geert, On 09.05.2016 09:54, Geert Uytterhoeven wrote: Hi Dirk, On Mon, May 9, 2016 at 9:52 AM, Dirk Behmewrote: On 09.05.2016 09:44, Geert Uytterhoeven wrote: On Mon, May 9, 2016 at 9:14 AM, Dirk Behme wrote: --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -1102,6 +1102,11 @@ #power-domain-cells = <0>; }; + modemr: modemr@e6160060 { + compatible = "renesas,modemr"; + reg = <0 0xe6160060 0 0x4>; + }; + This should be a node for the complete RST module, not just for the RST module's MODEMR register. You mean reset: reset@e616 { compatible = "renesas,reset"; reg = <0 0xe616 0 0x200>; }; and then use anything like #define MODEMR 0x60 in the code? Yes, more or less: reset-controller@e616 { compatible = "renesas,r8a7795-rst"; Hmm, do we really want the r8a7795 here? Then we would need r8a7790-rst r8a7791-rst r8a7792-rst r8a7793-rst r8a7794-rst r8a7795-rst r8a7796-rst ... ? Best regards Dirk
Re: [PATCH 09/10] ARM: r8a779x: Add boot mode reg support
Hi Dirk, On Mon, May 9, 2016 at 9:52 AM, Dirk Behmewrote: > On 09.05.2016 09:44, Geert Uytterhoeven wrote: >> >> On Mon, May 9, 2016 at 9:14 AM, Dirk Behme >> wrote: >>> >>> --- a/arch/arm/boot/dts/r8a7790.dtsi >>> +++ b/arch/arm/boot/dts/r8a7790.dtsi >>> @@ -1102,6 +1102,11 @@ >>> #power-domain-cells = <0>; >>> }; >>> >>> + modemr: modemr@e6160060 { >>> + compatible = "renesas,modemr"; >>> + reg = <0 0xe6160060 0 0x4>; >>> + }; >>> + >> >> >> This should be a node for the complete RST module, not just for the RST >> module's >> MODEMR register. > > > > You mean > > reset: reset@e616 { > compatible = "renesas,reset"; > reg = <0 0xe616 0 0x200>; > }; > > and then use anything like > > #define MODEMR 0x60 > > in the code? Yes, more or less: reset-controller@e616 { compatible = "renesas,r8a7795-rst"; reg = <0 0xe616 0 0x0200>; }; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@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
Re: [PATCH 09/10] ARM: r8a779x: Add boot mode reg support
On 09.05.2016 09:44, Geert Uytterhoeven wrote: On Mon, May 9, 2016 at 9:14 AM, Dirk Behmewrote: --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -1102,6 +1102,11 @@ #power-domain-cells = <0>; }; + modemr: modemr@e6160060 { + compatible = "renesas,modemr"; + reg = <0 0xe6160060 0 0x4>; + }; + This should be a node for the complete RST module, not just for the RST module's MODEMR register. You mean reset: reset@e616 { compatible = "renesas,reset"; reg = <0 0xe616 0 0x200>; }; and then use anything like #define MODEMR 0x60 in the code? Best regards Dirk
Re: [PATCH] ARM: shmobile: pm-rmobile: Postpone call to pm_genpd_init()
On 4 May 2016 at 10:27, Geert Uytterhoevenwrote: > All local setup of the generic_pm_domain structure should have been > completed before calling pm_genpd_init(). > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Ulf Hansson Kind regards Uffe > --- > arch/arm/mach-shmobile/pm-rmobile.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm/mach-shmobile/pm-rmobile.c > b/arch/arm/mach-shmobile/pm-rmobile.c > index ecc92bad3500c1c1..175bd3d91ebcbcb4 100644 > --- a/arch/arm/mach-shmobile/pm-rmobile.c > +++ b/arch/arm/mach-shmobile/pm-rmobile.c > @@ -131,13 +131,13 @@ static void rmobile_init_pm_domain(struct > rmobile_pm_domain *rmobile_pd) > struct dev_power_governor *gov = rmobile_pd->gov; > > genpd->flags = GENPD_FLAG_PM_CLK; > - pm_genpd_init(genpd, gov ? : _qos_governor, false); > genpd->dev_ops.active_wakeup= rmobile_pd_active_wakeup; > genpd->power_off= rmobile_pd_power_down; > genpd->power_on = rmobile_pd_power_up; > genpd->attach_dev = cpg_mstp_attach_dev; > genpd->detach_dev = cpg_mstp_detach_dev; > __rmobile_pd_power_up(rmobile_pd, false); > + pm_genpd_init(genpd, gov ? : _qos_governor, false); > } > > static int rmobile_pd_suspend_busy(void) > -- > 1.9.1 >
Re: [PATCH 00/10] arm64: renesas: Obtain MD pin values using syscon/regmap
Hi Dirk, Thanks for your series! On Mon, May 9, 2016 at 9:13 AM, Dirk Behmewrote: > This is a resend of > > http://www.spinics.net/lists/linux-sh/msg44757.html I guess you meant http://www.spinics.net/lists/linux-sh/msg45969.html? You do want to keep (part of) the bindings from "[PATCH 1/6] reset: Add renesas,rst DT bindings." from the former series, though ;-) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@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
Re: [PATCH 10/10] boot-mode-reg: Convert to device tree
On Mon, May 9, 2016 at 9:14 AM, Dirk Behmewrote: > --- a/drivers/misc/boot-mode-reg/rcar.c > +++ b/drivers/misc/boot-mode-reg/rcar.c > @@ -16,24 +16,32 @@ > #include > #include > #include > +#include > > #include > > -#define MODEMR 0xe6160060 > - > static int __init rcar_read_mode_pins(void) > { > void __iomem *modemr; > + struct device_node *np; > int err = -ENOMEM; > static u32 mode; > > - modemr = ioremap_nocache(MODEMR, 4); > + np = of_find_compatible_node(NULL, NULL, "renesas,modemr"); > + if (!np) { > + pr_err("can't find renesas,modemr device node"); > + goto err; At least for R-Car Gen2, we need to preserve compatibility with old DTBs that don't have the node in DT. > + } > + > + modemr = of_iomap(np, 0); Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@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
Re: [PATCH 01/10] boot-mode-reg: Add core
On Mon, May 9, 2016 at 9:13 AM, Dirk Behmewrote: > --- /dev/null > +++ b/drivers/misc/boot-mode-reg/core.c > @@ -0,0 +1,78 @@ > +/** > + * boot_mode_reg_get() - retrieve boot mode register value > + * @mode: implementation-dependent boot mode register value > + * > + * Retrieves the boot mode register value previously registered > + * using boot_mode_reg_set(). > + * > + * return: 0 on success > + */ > +int boot_mode_reg_get(u32 *mode) > +{ > + int err = -ENOENT; > + > + mutex_lock(_mode_mutex); > + if (!boot_mode_is_set) > + goto err; > + *mode = boot_mode; > + err = 0; > +err: The goto and label can easily be avoided by inverting the if condition: if (boot_mode_is_set) { *mode = boot_mode; err = 0; } > + mutex_unlock(_mode_mutex); > + return err; > +} > +EXPORT_SYMBOL_GPL(boot_mode_reg_get); > + > +/** > + * boot_mode_reg_set() - record boot mode register value > + * @mode: implementation-dependent boot mode register value > + * > + * Records the boot mode register value which may subsequently > + * be retrieved using boot_mode_reg_get(). > + * > + * return: 0 on success > + */ > +int boot_mode_reg_set(u32 mode) > +{ > + int err = -EBUSY; > + > + mutex_lock(_mode_mutex); > + if (boot_mode_is_set && boot_mode != mode) > + goto err; > + boot_mode = mode; > + boot_mode_is_set = true; > + err = 0; > +err: Convert goto and label to inverted if. > + mutex_unlock(_mode_mutex); > + return err; > +} > +EXPORT_SYMBOL_GPL(boot_mode_reg_set); Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@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
[PATCH 00/10] arm64: renesas: Obtain MD pin values using syscon/regmap
This is a resend of http://www.spinics.net/lists/linux-sh/msg44757.html Besides some minor clean up and fixes, it's rebased against https://git.kernel.org/cgit/linux/kernel/git/geert/renesas-drivers.git/log/?h=topic/gen3-latest 0ea1cc9f0c9537d3fb42722c188 [WIP] arm64: r8a7796: Integration and adds support for RCar Gen3. Additionally, it moves the MODEMR register to device tree instead of hard coding its address. These patches are available in https://github.com/dirkbehme/linux-renesas-rcar-gen3/commits/geert/topic/gen3-latest-modereg too. It's boot tested on r8a7795 Salvator-X and checked that the same mode value is read without and with this patch series. Dirk
[PATCH 06/10] arm: renesas: rcar-gen2: Remove unused rcar_gen2_read_mode_pins()
From: Simon HormanThe new boot mode reg infrastructure is now used in place of rcar_gen2_read_mode_pins so the latter may now be removed. Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/rcar-gen2.h | 1 - arch/arm/mach-shmobile/setup-rcar-gen2.c | 18 -- 2 files changed, 19 deletions(-) diff --git a/arch/arm/mach-shmobile/rcar-gen2.h b/arch/arm/mach-shmobile/rcar-gen2.h index 8a66b4a..4c4ec37 100644 --- a/arch/arm/mach-shmobile/rcar-gen2.h +++ b/arch/arm/mach-shmobile/rcar-gen2.h @@ -3,7 +3,6 @@ void rcar_gen2_timer_init(void); #define MD(nr) BIT(nr) -u32 rcar_gen2_read_mode_pins(void); void rcar_gen2_reserve(void); void rcar_gen2_pm_init(void); diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 2af84d8..5942b93 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -29,24 +29,6 @@ #include "common.h" #include "rcar-gen2.h" -#define MODEMR 0xe6160060 - -u32 rcar_gen2_read_mode_pins(void) -{ - static u32 mode; - static bool mode_valid; - - if (!mode_valid) { - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - mode_valid = true; - } - - return mode; -} - #define CNTCR 0 #define CNTFID0 0x20 -- 2.8.0
[PATCH 07/10] arm: renesas: rcar-gen3: Make boot-mode-reg Gen3 compatible
From: Dirk BehmeThe boot mode register is available on Renesas Gen3, too. Use the same driver on Gen3 as on Gen2. Signed-off-by: Dirk Behme --- arch/arm64/Kconfig.platforms | 1 + drivers/misc/boot-mode-reg/rcar.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index fda93a2..591ab8f 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -106,6 +106,7 @@ config ARCH_SHMOBILE config ARCH_RENESAS bool "Renesas SoC Platforms" select ARCH_SHMOBILE + select BOOT_MODE_REG_RCAR select PINCTRL select PM select PM_GENERIC_DOMAINS diff --git a/drivers/misc/boot-mode-reg/rcar.c b/drivers/misc/boot-mode-reg/rcar.c index c3b778fe..e994980 100644 --- a/drivers/misc/boot-mode-reg/rcar.c +++ b/drivers/misc/boot-mode-reg/rcar.c @@ -48,7 +48,9 @@ int __init rcar_init_boot_mode(void) of_machine_is_compatible("renesas,r8a7791") || of_machine_is_compatible("renesas,r8a7792") || of_machine_is_compatible("renesas,r8a7793") || - of_machine_is_compatible("renesas,r8a7794")) + of_machine_is_compatible("renesas,r8a7794") || + of_machine_is_compatible("renesas,r8a7795") || + of_machine_is_compatible("renesas,r8a7796")) return rcar_read_mode_pins(); return 0; -- 2.8.0
[PATCH 04/10] arm: renesas: r8a7791: Obtain MD pin value using boot-mode-reg
From: Simon HormanUse new boot mode reg infrastructure to obtain the mode pin value when initialising SMP for r8a7791 SoC. Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/smp-r8a7791.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c index 2d6417a..df784d6 100644 --- a/arch/arm/mach-shmobile/smp-r8a7791.c +++ b/arch/arm/mach-shmobile/smp-r8a7791.c @@ -20,6 +20,8 @@ #include +#include + #include "common.h" #include "platsmp-apmu.h" #include "r8a7791.h" @@ -45,8 +47,17 @@ static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) static int r8a7791_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) { + int err; + u32 mode; + + err = boot_mode_reg_get(); + if (err) { + pr_warn("Unable retrieve boot mode register\n"); + return err; + } + /* Error out when hardware debug mode is enabled */ - if (rcar_gen2_read_mode_pins() & BIT(21)) { + if (mode & BIT(21)) { pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu); return -ENOTSUPP; } -- 2.8.0
[PATCH 01/10] boot-mode-reg: Add core
From: Simon HormanThe motivation for this new module is to add a small frame work to allow kernel subsystems to obtain boot mode information from a centralised source using a new, and hopefully soon well-known, API. The new API consists of two function calls and nothing more: boot_mode_reg_set: Should be called by platform-specific drivers to register the boot mode register value which they obtain from hardware or otherwise. boot_mode_reg_get: Should be called by consumers; subsystems that wish to know he boot mode register. The boot mode register is a 32bit unsigned entity, the meaning of its values are implementation dependent. Signed-off-by: Simon Horman --- MAINTAINERS | 1 + drivers/misc/Kconfig| 1 + drivers/misc/Makefile | 1 + drivers/misc/boot-mode-reg/Kconfig | 11 ++ drivers/misc/boot-mode-reg/Makefile | 6 +++ drivers/misc/boot-mode-reg/core.c | 78 + include/misc/boot-mode-reg.h| 24 7 files changed, 122 insertions(+) create mode 100644 drivers/misc/boot-mode-reg/Kconfig create mode 100644 drivers/misc/boot-mode-reg/Makefile create mode 100644 drivers/misc/boot-mode-reg/core.c create mode 100644 include/misc/boot-mode-reg.h diff --git a/MAINTAINERS b/MAINTAINERS index 23e68db..e2bf6ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10734,6 +10734,7 @@ S: Maintained F: Documentation/sh/ F: arch/sh/ F: drivers/sh/ +F: drivers/misc/boot-mode-reg/ SUSPEND TO RAM M: "Rafael J. Wysocki" diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a216b46..deba6b6 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -816,4 +816,5 @@ source "drivers/misc/mic/Kconfig" source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" source "drivers/misc/cxl/Kconfig" +source "drivers/misc/boot-mode-reg/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b2fb6dbf..d2a8ae4 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -57,3 +57,4 @@ obj-$(CONFIG_ECHO)+= echo/ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o obj-$(CONFIG_CXL_BASE) += cxl/ obj-$(CONFIG_PANEL) += panel.o +obj-$(CONFIG_BOOT_MODE_REG_CORE) += boot-mode-reg/ diff --git a/drivers/misc/boot-mode-reg/Kconfig b/drivers/misc/boot-mode-reg/Kconfig new file mode 100644 index 000..3c4ddde --- /dev/null +++ b/drivers/misc/boot-mode-reg/Kconfig @@ -0,0 +1,11 @@ +# +# Boot Mode Register Drivers +# + +config BOOT_MODE_REG_CORE + tristate "Boot Mode Register Core Driver" + default n + depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST + help + Say Y here to allow support for drivers to read boot mode + registers and make the value available to other subsystems. diff --git a/drivers/misc/boot-mode-reg/Makefile b/drivers/misc/boot-mode-reg/Makefile new file mode 100644 index 000..19134b2 --- /dev/null +++ b/drivers/misc/boot-mode-reg/Makefile @@ -0,0 +1,6 @@ + +# +# Makefile for misc devices that really don't fit anywhere else. +# + +obj-$(CONFIG_BOOT_MODE_REG_CORE) += core.o diff --git a/drivers/misc/boot-mode-reg/core.c b/drivers/misc/boot-mode-reg/core.c new file mode 100644 index 000..210cd85 --- /dev/null +++ b/drivers/misc/boot-mode-reg/core.c @@ -0,0 +1,78 @@ +/* + * Boot Mode Register + * + * Copyright (C) 2015 Simon Horman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include +#include + +#include + +static DEFINE_MUTEX(boot_mode_mutex); +static bool boot_mode_is_set; +static u32 boot_mode; + +/** + * boot_mode_reg_get() - retrieve boot mode register value + * @mode: implementation-dependent boot mode register value + * + * Retrieves the boot mode register value previously registered + * using boot_mode_reg_set(). + * + * return: 0 on success + */ +int boot_mode_reg_get(u32 *mode) +{ + int err = -ENOENT; + + mutex_lock(_mode_mutex); + if (!boot_mode_is_set) + goto err; + *mode = boot_mode; + err = 0; +err: + mutex_unlock(_mode_mutex); + return err; +} +EXPORT_SYMBOL_GPL(boot_mode_reg_get); + +/** + * boot_mode_reg_set() - record boot mode register value + * @mode: implementation-dependent boot mode register value + * + * Records the boot mode register value which may subsequently + *
[PATCH 02/10] boot-mode-reg: Add R-Car driver
From: Simon HormanBoot mode register driver for R-Car. If running on a supported platform it reads the boot mode register and records it using the boot mode register infrastructure established by an earlier patch. rcar_init_boot_mode() is exported allow it to be explicitly called in cases where the boot mode register is needed before init calls are made. Signed-off-by: Simon Horman --- drivers/misc/boot-mode-reg/Kconfig | 8 + drivers/misc/boot-mode-reg/Makefile | 1 + drivers/misc/boot-mode-reg/rcar.c | 60 + include/misc/boot-mode-reg.h| 3 ++ 4 files changed, 72 insertions(+) create mode 100644 drivers/misc/boot-mode-reg/rcar.c diff --git a/drivers/misc/boot-mode-reg/Kconfig b/drivers/misc/boot-mode-reg/Kconfig index 3c4ddde..3868c36 100644 --- a/drivers/misc/boot-mode-reg/Kconfig +++ b/drivers/misc/boot-mode-reg/Kconfig @@ -9,3 +9,11 @@ config BOOT_MODE_REG_CORE help Say Y here to allow support for drivers to read boot mode registers and make the value available to other subsystems. + +config BOOT_MODE_REG_RCAR + tristate "Boot Mode Register Driver for Renesas R-Car SoCs" + default n + select BOOT_MODE_REG_CORE + help + Say Y here to allow support for reading the boot mode register + on Renesas R-Car SoCs. diff --git a/drivers/misc/boot-mode-reg/Makefile b/drivers/misc/boot-mode-reg/Makefile index 19134b2..5469a1d 100644 --- a/drivers/misc/boot-mode-reg/Makefile +++ b/drivers/misc/boot-mode-reg/Makefile @@ -4,3 +4,4 @@ # obj-$(CONFIG_BOOT_MODE_REG_CORE) += core.o +obj-$(CONFIG_BOOT_MODE_REG_RCAR) += rcar.o diff --git a/drivers/misc/boot-mode-reg/rcar.c b/drivers/misc/boot-mode-reg/rcar.c new file mode 100644 index 000..c3b778fe --- /dev/null +++ b/drivers/misc/boot-mode-reg/rcar.c @@ -0,0 +1,60 @@ +/* + * R-Car Boot Mode Register Driver + * + * Copyright (C) 2015 Simon Horman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include + +#define MODEMR 0xe6160060 + +static int __init rcar_read_mode_pins(void) +{ + void __iomem *modemr; + int err = -ENOMEM; + static u32 mode; + + modemr = ioremap_nocache(MODEMR, 4); + if (!modemr) { + pr_err("failed to map boot mode register"); + goto err; + } + mode = ioread32(modemr); + iounmap(modemr); + + err = boot_mode_reg_set(mode); +err: + if (err) + pr_err("failed to initialise boot mode"); + return err; +} + +int __init rcar_init_boot_mode(void) +{ + if (of_machine_is_compatible("renesas,r8a7790") || + of_machine_is_compatible("renesas,r8a7791") || + of_machine_is_compatible("renesas,r8a7792") || + of_machine_is_compatible("renesas,r8a7793") || + of_machine_is_compatible("renesas,r8a7794")) + return rcar_read_mode_pins(); + + return 0; +} +early_initcall(rcar_init_boot_mode); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Simon Horman "); +MODULE_DESCRIPTION("R-Car Boot Mode Register Driver"); diff --git a/include/misc/boot-mode-reg.h b/include/misc/boot-mode-reg.h index 34ee653..35d7f57 100644 --- a/include/misc/boot-mode-reg.h +++ b/include/misc/boot-mode-reg.h @@ -21,4 +21,7 @@ int boot_mode_reg_get(u32 *mode); int boot_mode_reg_set(u32 mode); +/* Allow explicit initialisation before initcalls */ +int rcar_init_boot_mode(void); + #endif -- 2.8.0