* [PATCH v2] clk: qoriq: added ls1012a clock configuration
From: Scott Wood @ 2016-11-23 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479802499-9083-1-git-send-email-yuantian.tang@nxp.com>
On 11/22/2016 02:28 AM, yuantian.tang at nxp.com wrote:
> From: Tang Yuantian <Yuantian.Tang@nxp.com>
>
> Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
> ---
> v2:
> - remove commit message as it is duplicated to title
>
> drivers/clk/clk-qoriq.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
> index 1bece0f..65c21d7 100644
> --- a/drivers/clk/clk-qoriq.c
> +++ b/drivers/clk/clk-qoriq.c
> @@ -202,6 +202,14 @@ static const struct clockgen_muxinfo ls1021a_cmux = {
> }
> };
>
> +static const struct clockgen_muxinfo ls1012a_cmux = {
> + {
> + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
> + {},
> + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
> + }
> +};
> +
> static const struct clockgen_muxinfo t1040_cmux = {
> {
> [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
> @@ -482,6 +490,16 @@ static const struct clockgen_chipinfo chipinfo[] = {
> .pll_mask = 0x03,
> },
> {
> + .compat = "fsl,ls1012a-clockgen",
> + .cmux_groups = {
> + &ls1012a_cmux
> + },
> + .cmux_to_group = {
> + 0, -1
> + },
> + .pll_mask = 0x03,
> + },
> + {
> .compat = "fsl,ls1043a-clockgen",
> .init_periph = t2080_init_periph,
> .cmux_groups = {
> @@ -1282,6 +1300,7 @@ static void __init clockgen_init(struct device_node *np)
> CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
> +CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
Again, can you please keep the chip lists sorted? ls1012a doesn't go
after ls1021a.
-Scott
^ permalink raw reply
* [PATCH] clk: qoriq: added ls1012a clock configuration
From: Scott Wood @ 2016-11-23 7:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <DB6PR0402MB28371BAAD862417B8AC8AED4F0B40@DB6PR0402MB2837.eurprd04.prod.outlook.com>
On 11/22/2016 02:20 AM, Y.T. Tang wrote:
> Hi Scott,
>
>> -----Original Message-----
>> From: Scott Wood [mailto:oss at buserror.net]
>> Sent: Wednesday, November 16, 2016 2:54 PM
>> To: Y.T. Tang <yuantian.tang@nxp.com>; mturquette at baylibre.com
>> Cc: sboyd at codeaurora.org; linux-kernel at vger.kernel.org; Scott Wood
>> <scott.wood@nxp.com>; linux-clk at vger.kernel.org; linux-arm-
>> kernel at lists.infradead.org
>> Subject: Re: [PATCH] clk: qoriq: added ls1012a clock configuration
>>
>> On Wed, 2016-11-16 at 13:58 +0800, yuantian.tang at nxp.com wrote:
>>> From: Tang Yuantian <Yuantian.Tang@nxp.com>
>>>
>>> Added ls1012a clock configuation information.
>>
>> Do we really need the same line in the changelog twice?
>>
>>>
>>> Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
>>> ---
>>> drivers/clk/clk-qoriq.c | 19 +++++++++++++++++++
>>> 1 file changed, 19 insertions(+)
>>>
>>> diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index
>>> 1bece0f..563d874 100644
>>> --- a/drivers/clk/clk-qoriq.c
>>> +++ b/drivers/clk/clk-qoriq.c
>>> @@ -202,6 +202,14 @@ static const struct clockgen_muxinfo ls1021a_cmux
>> = {
>>> }
>>> };
>>>
>>> +static const struct clockgen_muxinfo ls1012a_cmux = {
>>> + {
>>> + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
>>> + {},
>>> + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
>>> + }
>>> +};
>>> +
>>
>> Based on the "ls1021a_cmux" in the context it looks like this patch is
>> intended to apply on top
>> of https://patchwork.kernel.org/patch/8923541/ but I don't see any mention
>> of that.
>>
> I saw this patch had been merged already.
>
> Regards,
> Yuantian
I don't see it in linux-next.
-Scott
^ permalink raw reply
* [PATCH] arm/dts: ls1021a: Add dma-coherent property to usb3 node
From: Changming Huang @ 2016-11-23 7:15 UTC (permalink / raw)
To: linux-arm-kernel
This sets dma ops as coherent for usb 3.0 platform device
Signed-off-by: Changming Huang <jerry.huang@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
---
arch/arm/boot/dts/ls1021a.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 368e219..81fb4d9 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -627,6 +627,7 @@
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
+ dma-coherent;
};
pcie at 3400000 {
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 1/2] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Troy Jia @ 2016-11-23 7:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479884833.21746.44.camel@buserror.net>
> -----Original Message-----
> From: Scott Wood [mailto:oss at buserror.net]
> Sent: Wednesday, November 23, 2016 3:07 PM
> To: Troy Jia <hongtao.jia@nxp.com>; rui.zhang at intel.com; edubezval at gmail.com;
> robh+dt at kernel.org; Scott Wood <scott.wood@nxp.com>; shawnguo at kernel.org
> Cc: devicetree at vger.kernel.org; linuxppc-dev at lists.ozlabs.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH V3 1/2] powerpc/mpc85xx: Update TMU device tree node for
> T1040/T1042
>
> On Tue, 2016-10-25 at 10:15 +0800, Jia Hongtao wrote:
> > From: Hongtao Jia <hongtao.jia@nxp.com>
> >
> > Update #thermal-sensor-cells from 0 to 1 according to the new binding.
> > The sensor specifier added is the monitoring site ID, and represents
> > the "n" in TRITSRn and TRATSRn.
> >
> > Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
>
> Where can I find this new binding? ?As of the current linux-next I don't see anything
> in qoriq-thermal.txt about this.
Hi Rui Zhang,
As we discussed before. The time was inappropriate as merge window was about to close.
So do you have any plan for applying the binding file recently?
-Hongtao.
^ permalink raw reply
* [PATCH V3 1/2] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Scott Wood @ 2016-11-23 7:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477361742-589-1-git-send-email-hongtao.jia@nxp.com>
On Tue, 2016-10-25 at 10:15 +0800, Jia Hongtao wrote:
> From: Hongtao Jia <hongtao.jia@nxp.com>
>
> Update #thermal-sensor-cells from 0 to 1 according to the new binding. The
> sensor specifier added is the monitoring site ID, and represents the "n" in
> TRITSRn and TRATSRn.
>
> Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
Where can I find this new binding? ?As of the current linux-next I don't see
anything in qoriq-thermal.txt about this.
-Scott
^ permalink raw reply
* [PATCH v16 10/15] clocksource/drivers/arm_arch_timer: Refactor the timer init code to prepare for GTDT
From: Fu Wei @ 2016-11-23 6:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161118200335.GN1197@leverpostej>
Hi Mark,
On 19 November 2016 at 04:03, Mark Rutland <mark.rutland@arm.com> wrote:
> On Wed, Nov 16, 2016 at 09:49:03PM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> The patch refactor original memory-mapped timer init code:
>> (1) Extract a subfunction for detecting a bast time frame:
>> is_best_frame.
>
> Please leave this logic in arch_timer_mem_init(). Pulling it out gains
> us nothing, but makes the patch harder to review.
OK, I have put it back to arch_timer_mem_init() in next version: v17
>
>> (2) Refactor "arch_timer_mem_init", make it become a common code for
>> memory-mapped timer init.
>> (3) Add a new function "arch_timer_mem_of_init" for DT init.
>
> These generally look fine.
>
> Thanks,
> Mark.
>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>> drivers/clocksource/arm_arch_timer.c | 162 +++++++++++++++++++++++------------
>> 1 file changed, 107 insertions(+), 55 deletions(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 9ddc091..0836bb9 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -923,17 +923,35 @@ static int __init arch_timer_of_init(struct device_node *np)
>> CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
>> CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
>>
>> -static int __init arch_timer_mem_init(struct device_node *np)
>> +static bool __init is_best_frame(void __iomem *cntctlbase, u32 cnttidr, int n)
>> +{
>> + u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT | CNTACR_RWVT |
>> + CNTACR_RVOFF | CNTACR_RVCT;
>> +
>> + /* Try enabling everything, and see what sticks */
>> + writel_relaxed(cntacr, cntctlbase + CNTACR(n));
>> + cntacr = readl_relaxed(cntctlbase + CNTACR(n));
>> +
>> + if ((cnttidr & CNTTIDR_VIRT(n)) &&
>> + !(~cntacr & (CNTACR_RWVT | CNTACR_RVCT)))
>> + arch_timer_mem_use_virtual = true;
>> + else if (~cntacr & (CNTACR_RWPT | CNTACR_RPCT))
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +static int __init arch_timer_mem_init(struct arch_timer_mem *timer_mem)
>> {
>> - struct device_node *frame, *best_frame = NULL;
>> void __iomem *cntctlbase, *base;
>> - unsigned int irq, ret = -EINVAL;
>> + struct arch_timer_mem_frame *best_frame = NULL;
>> + unsigned int irq;
>> u32 cnttidr;
>> + int i, ret;
>>
>> - arch_timers_present |= ARCH_TIMER_TYPE_MEM;
>> - cntctlbase = of_iomap(np, 0);
>> + cntctlbase = ioremap(timer_mem->cntctlbase, timer_mem->size);
>> if (!cntctlbase) {
>> - pr_err("Can't find CNTCTLBase\n");
>> + pr_err("Can't map CNTCTLBase.\n");
>> return -ENXIO;
>> }
>>
>> @@ -943,76 +961,110 @@ static int __init arch_timer_mem_init(struct device_node *np)
>> * Try to find a virtual capable frame. Otherwise fall back to a
>> * physical capable frame.
>> */
>> - for_each_available_child_of_node(np, frame) {
>> - int n;
>> - u32 cntacr;
>> -
>> - if (of_property_read_u32(frame, "frame-number", &n)) {
>> - pr_err("Missing frame-number\n");
>> - of_node_put(frame);
>> - goto out;
>> - }
>> -
>> - /* Try enabling everything, and see what sticks */
>> - cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
>> - CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
>> - writel_relaxed(cntacr, cntctlbase + CNTACR(n));
>> - cntacr = readl_relaxed(cntctlbase + CNTACR(n));
>> -
>> - if ((cnttidr & CNTTIDR_VIRT(n)) &&
>> - !(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) {
>> - of_node_put(best_frame);
>> - best_frame = frame;
>> - arch_timer_mem_use_virtual = true;
>> - break;
>> + for (i = 0; i < timer_mem->num_frames; i++) {
>> + if (is_best_frame(cntctlbase, cnttidr,
>> + timer_mem->frame[i].frame_nr)) {
>> + best_frame = &timer_mem->frame[i];
>> + if (arch_timer_mem_use_virtual)
>> + break;
>> }
>> -
>> - if (~cntacr & (CNTACR_RWPT | CNTACR_RPCT))
>> - continue;
>> -
>> - of_node_put(best_frame);
>> - best_frame = of_node_get(frame);
>> }
>> + iounmap(cntctlbase);
>>
>> - ret= -ENXIO;
>> - base = arch_counter_base = of_iomap(best_frame, 0);
>> - if (!base) {
>> - pr_err("Can't map frame's registers\n");
>> - goto out;
>> + if (!best_frame) {
>> + pr_err("Can't find frame for register\n");
>> + return -EINVAL;
>> }
>>
>> if (arch_timer_mem_use_virtual)
>> - irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI);
>> + irq = best_frame->virt_irq;
>> else
>> - irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI);
>> + irq = best_frame->phys_irq;
>>
>> - ret = -EINVAL;
>> if (!irq) {
>> pr_err("Frame missing %s irq",
>> arch_timer_mem_use_virtual ? "virt" : "phys");
>> - goto out;
>> + return -EINVAL;
>> }
>>
>> - /*
>> - * Try to determine the frequency from the device tree,
>> - * if fail, get the frequency from CNTFRQ.
>> - */
>> - if (!arch_timer_rate &&
>> - of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
>> - arch_timer_detect_rate(base);
>> + base = ioremap(best_frame->cntbase, best_frame->size);
>> + if (!base) {
>> + pr_err("Can't map frame's registers\n");
>> + return -ENXIO;
>> + }
>> +
>> + arch_timer_detect_rate(base);
>>
>> ret = arch_timer_mem_register(base, irq);
>> - if (ret)
>> + if (ret) {
>> + iounmap(base);
>> + return ret;
>> + }
>> +
>> + arch_counter_base = base;
>> + arch_timers_present |= ARCH_TIMER_TYPE_MEM;
>> +
>> + return 0;
>> +}
>> +
>> +static int __init arch_timer_mem_of_init(struct device_node *np)
>> +{
>> + struct arch_timer_mem *timer_mem;
>> + struct device_node *frame_node;
>> + struct resource res;
>> + int i, ret = -EINVAL;
>> +
>> + timer_mem = kzalloc(sizeof(*timer_mem), GFP_KERNEL);
>> + if (!timer_mem)
>> + return -ENOMEM;
>> +
>> + if (of_address_to_resource(np, 0, &res))
>> goto out;
>> + timer_mem->cntctlbase = res.start;
>> + timer_mem->size = resource_size(&res);
>>
>> - return arch_timer_common_init();
>> + i = 0;
>> + for_each_available_child_of_node(np, frame_node) {
>> + int n;
>> + struct arch_timer_mem_frame *frame = &timer_mem->frame[i];
>> +
>> + if (of_property_read_u32(frame_node, "frame-number", &n)) {
>> + pr_err("Missing frame-number\n");
>> + of_node_put(frame_node);
>> + goto out;
>> + }
>> + frame->frame_nr = n;
>> +
>> + if (of_address_to_resource(frame_node, 0, &res)) {
>> + of_node_put(frame_node);
>> + goto out;
>> + }
>> + frame->cntbase = res.start;
>> + frame->size = resource_size(&res);
>> +
>> + frame->virt_irq = irq_of_parse_and_map(frame_node,
>> + ARCH_TIMER_VIRT_SPI);
>> + frame->phys_irq = irq_of_parse_and_map(frame_node,
>> + ARCH_TIMER_PHYS_SPI);
>> +
>> + if (++i >= ARCH_TIMER_MEM_MAX_FRAMES)
>> + break;
>> + }
>> + timer_mem->num_frames = i;
>> +
>> + /* Try to determine the frequency from the device tree */
>> + if (!arch_timer_rate)
>> + of_property_read_u32(np, "clock-frequency", &arch_timer_rate);
>> +
>> + ret = arch_timer_mem_init(timer_mem);
>> + if (!ret)
>> + ret = arch_timer_common_init();
>> out:
>> - iounmap(cntctlbase);
>> - of_node_put(best_frame);
>> + kfree(timer_mem);
>> return ret;
>> }
>> CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
>> - arch_timer_mem_init);
>> + arch_timer_mem_of_init);
>>
>> #ifdef CONFIG_ACPI
>> static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags)
>> --
>> 2.7.4
>>
--
Best regards,
Fu Wei
Software Engineer
Red Hat
^ permalink raw reply
* [PATCH v2 1/5] ARM: memory: da8xx-ddrctl: new driver
From: Sekhar Nori @ 2016-11-23 5:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <58348CB8.7050304@gmail.com>
On Tuesday 22 November 2016 11:51 PM, Frank Rowand wrote:
> Please note that the compatible property might contain several strings, not just
> a single string.
So I guess the best thing to do is to use
of_property_read_string_index() and print the sting at index 0.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH 2/4] ARM: dts: davinci: da850: add VPIF
From: Kevin Hilman @ 2016-11-23 5:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <51071aa1-50c5-1121-3e64-018edaf544bf@lechnology.com>
David Lechner <david@lechnology.com> writes:
> On 11/22/2016 01:45 PM, Kevin Hilman wrote:
>> Add VPIF and VPIF capture nodes to da850. VPIF capture has two input
>> channels describe using the standard DT ports and enpoints.
>>
>> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
>> ---
>> arch/arm/boot/dts/da850.dtsi | 28 ++++++++++++++++++++++++++++
>> 1 file changed, 28 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>> index 6205917b4f59..e05e2bb834e8 100644
>> --- a/arch/arm/boot/dts/da850.dtsi
>> +++ b/arch/arm/boot/dts/da850.dtsi
>> @@ -453,7 +453,35 @@
>> interrupts = <52>;
>> status = "disabled";
>> };
>> +
>> + vpif: video at 0x00217000 {
>
> Should be @217000
>
>> + compatible = "ti,da850-vpif";
>> + reg = <0x00217000 0x1000>;
>
> Could omit leading 0's to be consistent with existing entries.
>
> reg = <0x217000 0x1000>;
Ugh, yeah. I hate that convention, but better to be consistent, I guess.
>> + status = "disabled";
>> + };
>> +
>> + vpif_capture: video-capture at 0x00217000 {
>
> Again, @217000. But it seems odd to have two device nodes with the
> same address. Is enabling these mutually exclusive?
They're not mutually exclusive because the vpif is the one that actually
maps the register range (since it's shared between vpif_display and
vpif_capture) so I guess I should just drop the reg property from the
vpif_capture node.
>> + compatible = "ti,da850-vpif-capture";
>> + reg = <0x00217000 0x1000>;
>
> Ditto on the leading 0's.
>
Thanks for the review,
Kevin
^ permalink raw reply
* [PATCH 1/4] ARM: davinci: da8xx: VPIF: enable DT init
From: Kevin Hilman @ 2016-11-23 5:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <31948202-333f-b465-07b8-6260cce29b59@lechnology.com>
David Lechner <david@lechnology.com> writes:
> On 11/22/2016 01:45 PM, Kevin Hilman wrote:
>> Add basic support for DT initializaion of VPIF (capture) via DT. Clocks
>> and mux still need to happen in this file until there are real clock and
>> pinctrl drivers, but the video nodes and subdevs can all come from DT.
>>
>> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
>> ---
>> arch/arm/mach-davinci/da8xx-dt.c | 17 +++++++++++++++++
>> 1 file changed, 17 insertions(+)
>>
>> diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
>> index c9f7e9274aa8..7b41611f2665 100644
>> --- a/arch/arm/mach-davinci/da8xx-dt.c
>> +++ b/arch/arm/mach-davinci/da8xx-dt.c
>> @@ -17,6 +17,7 @@
>> #include <mach/common.h>
>> #include "cp_intc.h"
>> #include <mach/da8xx.h>
>> +#include <mach/mux.h>
>>
>> static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
>> OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
>> @@ -38,14 +39,30 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
>> NULL),
>> OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
>> OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", NULL),
>> + OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL),
>> {}
>> };
>>
>> #ifdef CONFIG_ARCH_DAVINCI_DA850
>>
>> +#if IS_ENABLED(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE)
>> +static __init void da850_vpif_capture_init(void)
>> +{
>> + int ret;
>> +
>> + ret = davinci_cfg_reg_list(da850_vpif_capture_pins);
>
> Why can't we use the existing pinctrl-single node in device tree for
> muxing the pins?
Oops, you're right. They can.
Kevin
^ permalink raw reply
* [RESEND PATCH 2/3] ARM: davinci: hawk: Remove vbus and over current gpios
From: Sekhar Nori @ 2016-11-23 5:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKXjFTMLt0j4yfHUww6k6FMu4=Z+mhZJCKi-tqmqdaOUs0fJ9Q@mail.gmail.com>
On Tuesday 22 November 2016 09:11 PM, Axel Haslam wrote:
> Hi Sekhar
>
> On Tue, Nov 22, 2016 at 11:37 AM, Sekhar Nori <nsekhar@ti.com> wrote:
>> On Monday 21 November 2016 10:23 PM, Axel Haslam wrote:
>>> The hawk board VBUS is fixed to a 5v source, and the over
>>> current pin is actually not connected to the SoC.
>>>
>>> Do not reseve these gpios for OHCI as they are not related
>>> to usb.
>>>
>>> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
>>
>> As discussed over the MMC/SD patches, this patch should be based off the
>> hawkboard schematic, not the LCDK schematic.
>>
>
> I looked at the hawkboard schematics and they are the same
> as the lcdk as far as usb i concerned:
>
> The ohci vbus is fixed to 5v, and the over current pins of the
> TPS are not connected. so this patch should be ok for
> both the hawk and the lcdk.
Alright! Thanks for checking.
Regards,
Sekhar
^ permalink raw reply
* [PATCH V9 1/6] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Chunyan Zhang @ 2016-11-23 5:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAG2=9p8AP4A09rnbqBLWr1UPiJ=7GzWB0Ncfzd0sb=yZ9kb56Q@mail.gmail.com>
Hi Steve,
Actually I had been keeping the idea that we would need to export most
kinds of traces rather than function trace only to somewhere else, say
STM, that's also why I made STM_SOURCE_FTRACE depending on TRACING
which was later changed to FUNCTION_TRACER according to you advice.
Thanks,
Chunyan
On 23 November 2016 at 10:27, Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
> On 23 November 2016 at 06:39, Steven Rostedt <rostedt@goodmis.org> wrote:
>> On Mon, 21 Nov 2016 15:57:18 +0800
>> Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
>>
>>> Currently Function traces can be only exported to ring buffer, this
>>> patch added trace_export concept which can process traces and export
>>> them to a registered destination as an addition to the current only
>>> one output of Ftrace - i.e. ring buffer.
>>>
>>> In this way, if we want Function traces to be sent to other destination
>>> rather than ring buffer only, we just need to register a new trace_export
>>> and implement its own .write() function for writing traces to storage.
>>>
>>> With this patch, only Function trace (trace type is TRACE_FN)
>>> is supported.
>>>
>>> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
>>> ---
>>> include/linux/trace.h | 28 +++++++++++
>>> kernel/trace/trace.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++-
>>> 2 files changed, 156 insertions(+), 1 deletion(-)
>>> create mode 100644 include/linux/trace.h
>>>
>>> diff --git a/include/linux/trace.h b/include/linux/trace.h
>>> new file mode 100644
>>> index 0000000..9330a58
>>> --- /dev/null
>>> +++ b/include/linux/trace.h
>>> @@ -0,0 +1,28 @@
>>> +#ifndef _LINUX_TRACE_H
>>> +#define _LINUX_TRACE_H
>>> +
>>> +#ifdef CONFIG_TRACING
>>> +/*
>>> + * The trace export - an export of Ftrace output. The trace_export
>>> + * can process traces and export them to a registered destination as
>>> + * an addition to the current only output of Ftrace - i.e. ring buffer.
>>> + *
>>> + * If you want traces to be sent to some other place rather than ring
>>> + * buffer only, just need to register a new trace_export and implement
>>> + * its own .write() function for writing traces to the storage.
>>> + *
>>> + * next - pointer to the next trace_export
>>> + * write - copy traces which have been delt with ->commit() to
>>> + * the destination
>>> + */
>>> +struct trace_export {
>>> + struct trace_export __rcu *next;
>>> + void (*write)(const void *, unsigned int);
>>> +};
>>> +
>>> +int register_ftrace_export(struct trace_export *export);
>>> +int unregister_ftrace_export(struct trace_export *export);
>>> +
>>> +#endif /* CONFIG_TRACING */
>>> +
>>> +#endif /* _LINUX_TRACE_H */
>>> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
>>> index 8696ce6..038291d 100644
>>> --- a/kernel/trace/trace.c
>>> +++ b/kernel/trace/trace.c
>>> @@ -40,6 +40,7 @@
>>> #include <linux/poll.h>
>>> #include <linux/nmi.h>
>>> #include <linux/fs.h>
>>> +#include <linux/trace.h>
>>> #include <linux/sched/rt.h>
>>>
>>> #include "trace.h"
>>> @@ -2128,6 +2129,129 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
>>> ftrace_trace_userstack(buffer, flags, pc);
>>> }
>>>
>>> +static void
>>> +trace_process_export(struct trace_export *export,
>>> + struct ring_buffer_event *event)
>>> +{
>>> + struct trace_entry *entry;
>>> + unsigned int size = 0;
>>> +
>>> + entry = ring_buffer_event_data(event);
>>> + size = ring_buffer_event_length(event);
>>> + export->write(entry, size);
>>> +}
>>> +
>>> +static DEFINE_MUTEX(ftrace_export_lock);
>>> +
>>> +static struct trace_export __rcu *ftrace_exports_list __read_mostly;
>>> +
>>> +static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
>>> +
>>> +static inline void ftrace_exports_enable(void)
>>> +{
>>> + static_branch_enable(&ftrace_exports_enabled);
>>> +}
>>> +
>>> +static inline void ftrace_exports_disable(void)
>>> +{
>>> + static_branch_disable(&ftrace_exports_enabled);
>>> +}
>>> +
>>> +void ftrace_exports(struct ring_buffer_event *event)
>>
>> I'm currently testing the patches, but is there a reason that
>> ftrace_exports() is not static?
>
> At present ftrace_exports() is only used by function trace though,
> but I hope it can be used by other traces when it needed.
> So I didn't mark it with static, but if you think it should better be
> static for the time being, I can revise that.
>
> Thanks,
> Chunyan
>
>
>>
>> -- Steve
>>
>>> +{
>>> + struct trace_export *export;
>>> +
>>> + preempt_disable_notrace();
>>> +
>>> + export = rcu_dereference_raw_notrace(ftrace_exports_list);
>>> + while (export) {
>>> + trace_process_export(export, event);
>>> + export = rcu_dereference_raw_notrace(export->next);
>>> + }
>>> +
>>> + preempt_enable_notrace();
>>> +}
>>> +
>>> +static inline void
>>> +add_trace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> + rcu_assign_pointer(export->next, *list);
>>> + /*
>>> + * We are entering export into the list but another
>>> + * CPU might be walking that list. We need to make sure
>>> + * the export->next pointer is valid before another CPU sees
>>> + * the export pointer included into the list.
>>> + */
>>> + rcu_assign_pointer(*list, export);
>>> +}
>>> +
>>> +static inline int
>>> +rm_trace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> + struct trace_export **p;
>>> +
>>> + for (p = list; *p != NULL; p = &(*p)->next)
>>> + if (*p == export)
>>> + break;
>>> +
>>> + if (*p != export)
>>> + return -1;
>>> +
>>> + rcu_assign_pointer(*p, (*p)->next);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static inline void
>>> +add_ftrace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> + if (*list == NULL)
>>> + ftrace_exports_enable();
>>> +
>>> + add_trace_export(list, export);
>>> +}
>>> +
>>> +static inline int
>>> +rm_ftrace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> + int ret;
>>> +
>>> + ret = rm_trace_export(list, export);
>>> + if (*list == NULL)
>>> + ftrace_exports_disable();
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +int register_ftrace_export(struct trace_export *export)
>>> +{
>>> + if (WARN_ON_ONCE(!export->write))
>>> + return -1;
>>> +
>>> + mutex_lock(&ftrace_export_lock);
>>> +
>>> + add_ftrace_export(&ftrace_exports_list, export);
>>> +
>>> + mutex_unlock(&ftrace_export_lock);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(register_ftrace_export);
>>> +
>>> +int unregister_ftrace_export(struct trace_export *export)
>>> +{
>>> + int ret;
>>> +
>>> + mutex_lock(&ftrace_export_lock);
>>> +
>>> + ret = rm_ftrace_export(&ftrace_exports_list, export);
>>> +
>>> + mutex_unlock(&ftrace_export_lock);
>>> +
>>> + return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(unregister_ftrace_export);
>>> +
>>> void
>>> trace_function(struct trace_array *tr,
>>> unsigned long ip, unsigned long parent_ip, unsigned long flags,
>>> @@ -2146,8 +2270,11 @@ trace_function(struct trace_array *tr,
>>> entry->ip = ip;
>>> entry->parent_ip = parent_ip;
>>>
>>> - if (!call_filter_check_discard(call, entry, buffer, event))
>>> + if (!call_filter_check_discard(call, entry, buffer, event)) {
>>> + if (static_branch_unlikely(&ftrace_exports_enabled))
>>> + ftrace_exports(event);
>>> __buffer_unlock_commit(buffer, event);
>>> + }
>>> }
>>>
>>> #ifdef CONFIG_STACKTRACE
>>
^ permalink raw reply
* [PATCH] dmaengine: qcom_hidma: autoload while probing ACPI
From: Vinod Koul @ 2016-11-23 4:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479583718-2716-1-git-send-email-okaya@codeaurora.org>
On Sat, Nov 19, 2016 at 02:28:37PM -0500, Sinan Kaya wrote:
> MODULE_DEVICE_TABLE is used by the kernel to determine which device driver
> should be loaded for which platform device. MODULE_DEVICE_TABLE has been
> only defined for the device-tree based platforms in the current code.
> Defining it also for ACPI based platforms.
Applied now
--
~Vinod
^ permalink raw reply
* [PATCH v4 3/3] dmaengine: sun6i: share the dma driver with sun50i
From: Vinod Koul @ 2016-11-23 4:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479638740-20520-4-git-send-email-hao5781286@gmail.com>
On Sun, Nov 20, 2016 at 06:45:40PM +0800, Hao Zhang wrote:
> Changes the limited buswith to 8 bytes,and add
> the test in sun6i_dma_config function
>
> Accroding to sun6i dma driver, i think ,if the client
^^^^^^^^
typo and other grammatical mistakes here..
> doesn't configure the address width with dmaengine_slave_config
> function, it would use the default width. So we can add the test
> in sun6i_dma_config function called by dmaengine_slave_config,
> and test the configuration whether is support for the device.
>
> Signed-off-by: Hao Zhang <hao5781286@gmail.com>
> ---
> drivers/dma/sun6i-dma.c | 33 ++++++++++++++++++++++++++++++++-
> 1 file changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index a235878..f7c90b6 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -250,7 +250,7 @@ static inline s8 convert_burst(u32 maxburst)
> static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width)
> {
> if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) ||
> - (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
> + (addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES))
> return -EINVAL;
>
> return addr_width >> 1;
> @@ -758,6 +758,18 @@ static int sun6i_dma_config(struct dma_chan *chan,
> {
> struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
>
> + if ((BIT(config->src_addr_width) | chan->device->src_addr_widths) !=
> + chan->device->src_addr_widths) {
First I dont like coding style here
Second, this is not driver specific, should be move to core..
--
~Vinod
^ permalink raw reply
* [PATCH 3/3] ARM: dts: da850: Add node for pullup/pulldown pinconf
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479871767-20160-1-git-send-email-david@lechnology.com>
This SoC has a separate pin controller for configuring pullup/pulldown
bias on groups of pins.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/boot/dts/da850.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 8945815..1c0224c 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -210,6 +210,11 @@
};
};
+ pinconf: pin-controller at 22c00c {
+ compatible = "ti,da850-pupd";
+ reg = <0x22c00c 0x8>;
+ status = "disabled";
+ };
prictrl: priority-controller at 14110 {
compatible = "ti,da850-mstpri";
reg = <0x14110 0x0c>;
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] pinctrl: New driver for TI DA8XX/OMAP-L138/AM18XX pinconf
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479871767-20160-1-git-send-email-david@lechnology.com>
This adds a new driver for pinconf on TI DA8XX/OMAP-L138/AM18XX. These
SoCs have a separate controller for controlling pullup/pulldown groups.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/pinctrl/Kconfig | 9 ++
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-da850-pupd.c | 210 +++++++++++++++++++++++++++++++++++
3 files changed, 220 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-da850-pupd.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 5f40ad6..54044a8 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -93,6 +93,15 @@ config PINCTRL_AMD
Requires ACPI/FDT device enumeration code to set up a platform
device.
+config PINCTRL_DA850_PUPD
+ tristate "TI DA850/OMAP-L138/AM18XX pullup/pulldown groups"
+ depends on OF && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
+ select PINCONF
+ select GENERIC_PINCONF
+ help
+ Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control
+ pullup/pulldown pin groups.
+
config PINCTRL_DIGICOLOR
bool
depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST)
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 3b8e6f7..25d50a8 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
+obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
diff --git a/drivers/pinctrl/pinctrl-da850-pupd.c b/drivers/pinctrl/pinctrl-da850-pupd.c
new file mode 100644
index 0000000..0446df7
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-da850-pupd.c
@@ -0,0 +1,210 @@
+/*
+ * Pinconf driver for TI DA850/OMAP-L138/AM18XX pullup/pulldown groups
+ *
+ * Copyright (C) 2016 David Lechner
+ *
+ * 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 <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+
+#define DA850_PUPD_ENA 0x00
+#define DA850_PUPD_SEL 0x04
+
+struct da850_pupd_data {
+ void __iomem *base;
+ struct pinctrl_desc desc;
+ struct pinctrl_dev *pinctrl;
+};
+
+static const char * const da850_pupd_group_names[] = {
+ "cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
+ "cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
+ "cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23",
+ "cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31",
+};
+
+static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(da850_pupd_group_names);
+}
+
+static const char *da850_pupd_get_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return da850_pupd_group_names[selector];
+}
+
+static int da850_pupd_get_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ *num_pins = 0;
+
+ return 0;
+}
+
+static const struct pinctrl_ops da850_pupd_pctlops = {
+ .get_groups_count = da850_pupd_get_groups_count,
+ .get_group_name = da850_pupd_get_get_group_name,
+ .get_group_pins = da850_pupd_get_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *config)
+{
+ struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 val;
+ u16 arg;
+
+ val = readl(data->base + DA850_PUPD_ENA);
+ arg = !!(~val & BIT(selector));
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg) {
+ /* bias is disabled */
+ arg = 0;
+ break;
+ }
+ val = readl(data->base + DA850_PUPD_SEL);
+ if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+ val = ~val;
+ arg = !!(val & BIT(selector));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
+ u32 ena, sel;
+ enum pin_config_param param;
+ u16 arg;
+ int i;
+
+ ena = readl(data->base + DA850_PUPD_ENA);
+ sel = readl(data->base + DA850_PUPD_SEL);
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ ena &= ~BIT(selector);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ ena |= BIT(selector);
+ sel |= BIT(selector);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ ena |= BIT(selector);
+ sel &= ~BIT(selector);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ writel(sel, data->base + DA850_PUPD_SEL);
+ writel(ena, data->base + DA850_PUPD_ENA);
+
+ return 0;
+}
+
+static const struct pinconf_ops da850_pupd_confops = {
+ .is_generic = true,
+ .pin_config_group_get = da850_pupd_pin_config_group_get,
+ .pin_config_group_set = da850_pupd_pin_config_group_set,
+};
+
+static int da850_pupd_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct da850_pupd_data *data;
+ struct resource *res;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(data->base)) {
+ dev_err(dev, "Could not map resource\n");
+ return PTR_ERR(data->base);
+ }
+
+ data->desc.name = dev_name(dev);
+ data->desc.pctlops = &da850_pupd_pctlops;
+ data->desc.confops = &da850_pupd_confops;
+ data->desc.owner = THIS_MODULE;
+
+ data->pinctrl = devm_pinctrl_register(dev, &data->desc, data);
+ if (IS_ERR(data->pinctrl)) {
+ dev_err(dev, "Failed to register pinctrl\n");
+ return PTR_ERR(data->pinctrl);
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int da850_pupd_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id da850_pupd_of_match[] = {
+ { .compatible = "ti,da850-pupd" },
+ { }
+};
+
+static struct platform_driver da850_pupd_driver = {
+ .driver = {
+ .name = "ti-da850-pupd",
+ .of_match_table = da850_pupd_of_match,
+ },
+ .probe = da850_pupd_probe,
+ .remove = da850_pupd_remove,
+};
+module_platform_driver(da850_pupd_driver);
+
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3] devicetree: bindings: pinctrl: Add binding for ti, da850-pupd
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479871767-20160-1-git-send-email-david@lechnology.com>
Device-tree bindings for TI DA8XX/OMAP-L138/AM18XX pullup/pulldown
pinconf controller.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../devicetree/bindings/pinctrl/ti,da850-pupd.txt | 55 ++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt b/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
new file mode 100644
index 0000000..7f29805
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
@@ -0,0 +1,55 @@
+* Pin configuration for TI DA850/OMAP-L138/AM18x
+
+These SoCs have a separate controller for setting bias (internal pullup/down).
+Bias can only be selected for groups rather than individual pins.
+
+Required Properties:
+
+ - compatible: Must be "ti,da850-pupd"
+ - reg: Base address and length of the memory resource used by the pullup/down
+ controller hardware module.
+
+The controller node also acts as a container for pin group configuration nodes.
+The names of these groups are ignored.
+
+Pin Group Node Properties:
+
+- groups: An array of strings, each string containing the name of a pin group.
+ Valid names are "cp0".."cp31".
+
+The pin configuration parameters use the generic pinconf bindings defined in
+pinctrl-bindings.txt in this directory. The supported parameters are
+bias-disable, bias-pull-up, bias-pull-down.
+
+
+Example
+-------
+
+In common dtsi file:
+
+ pinconf: pin-controller at 22c00c {
+ compatible = "ti,da850-pupd";
+ reg = <0x22c00c 0x8>;
+ };
+
+In board-specific file:
+
+ &pinconf {
+ pinctrl-0 = <&pinconf_bias_groups>;
+ pinctrl-names = "default";
+
+ pinconf_bias_groups: bias-groups {
+ pull-up {
+ groups = "cp30", "cp31";
+ bias-pull-up;
+ };
+ pull-down {
+ groups = "cp29", "cp28";
+ bias-pull-down;
+ };
+ disable {
+ groups = "cp27", "cp26";
+ bias-disable;
+ };
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH 0/3] TI DA850/OMAP-L138/AM18x pinconf
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: linux-arm-kernel
This series adds a new driver and DT bindings for TI DA850/OMAP-L138/AM18x
pinconf (bias pullup/pulldown).
The motivation for this series is LEGO MINDSTORMS EV3 support. It needs most,
if not all, internal pullup/down resistors disabled in order to work correctly.
David Lechner (3):
devicetree: bindings: pinctrl: Add binding for ti,da850-pupd
pinctrl: New driver for TI DA8XX/OMAP-L138/AM18XX pinconf
ARM: dts: da850: Add node for pullup/pulldown pinconf
.../devicetree/bindings/pinctrl/ti,da850-pupd.txt | 55 ++++++
arch/arm/boot/dts/da850.dtsi | 5 +
drivers/pinctrl/Kconfig | 9 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-da850-pupd.c | 210 +++++++++++++++++++++
5 files changed, 280 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
create mode 100644 drivers/pinctrl/pinctrl-da850-pupd.c
--
2.7.4
^ permalink raw reply
* [PATCH] PCI: Add information about describing PCI in ACPI
From: Zheng, Lv @ 2016-11-23 3:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117175938.17465.45820.stgit@bhelgaas-glaptop.roam.corp.google.com>
Hi, Bjorn
Thanks for the documentation.
It really helps!
However I have a question below.
> From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-owner at vger.kernel.org] On Behalf Of Bjorn
> Helgaas
> Subject: [PATCH] PCI: Add information about describing PCI in ACPI
>
> Add a writeup about how PCI host bridges should be described in ACPI
> using PNP0A03/PNP0A08 devices, PNP0C02 devices, and the MCFG table.
>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
> Documentation/PCI/00-INDEX | 2 +
> Documentation/PCI/acpi-info.txt | 136 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 138 insertions(+)
> create mode 100644 Documentation/PCI/acpi-info.txt
>
> diff --git a/Documentation/PCI/00-INDEX b/Documentation/PCI/00-INDEX
> index 147231f..0780280 100644
> --- a/Documentation/PCI/00-INDEX
> +++ b/Documentation/PCI/00-INDEX
> @@ -1,5 +1,7 @@
> 00-INDEX
> - this file
> +acpi-info.txt
> + - info on how PCI host bridges are represented in ACPI
> MSI-HOWTO.txt
> - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ.
> PCIEBUS-HOWTO.txt
> diff --git a/Documentation/PCI/acpi-info.txt b/Documentation/PCI/acpi-info.txt
> new file mode 100644
> index 0000000..ccbcfda
> --- /dev/null
> +++ b/Documentation/PCI/acpi-info.txt
> @@ -0,0 +1,136 @@
> + ACPI considerations for PCI host bridges
> +
> +The basic requirement is that the ACPI namespace should describe
> +*everything* that consumes address space unless there's another
> +standard way for the OS to find it [1, 2]. ?For example, windows that
> +are forwarded to PCI by a PCI host bridge should be described via ACPI
> +devices, since the OS can't locate the host bridge by itself. ?PCI
> +devices *below* the host bridge do not need to be described via ACPI,
> +because the resources they consume are inside the host bridge windows,
> +and the OS can discover them via the standard PCI enumeration
> +mechanism (using config accesses to read and size the BARs).
> +
> +This ACPI resource description is done via _CRS methods of devices in
> +the ACPI namespace [2]. ? _CRS methods are like generalized PCI BARs:
> +the OS can read _CRS and figure out what resource is being consumed
> +even if it doesn't have a driver for the device [3]. ?That's important
> +because it means an old OS can work correctly even on a system with
> +new devices unknown to the OS. ?The new devices won't do anything, but
> +the OS can at least make sure no resources conflict with them.
> +
> +Static tables like MCFG, HPET, ECDT, etc., are *not* mechanisms for
> +reserving address space! The static tables are for things the OS
> +needs to know early in boot, before it can parse the ACPI namespace.
> +If a new table is defined, an old OS needs to operate correctly even
> +though it ignores the table. _CRS allows that because it is generic
> +and understood by the old OS; a static table does not.
The entire document doesn't talk about the details of _CBA.
There is only one line below mentioned _CBA as an example.
> +
> +If the OS is expected to manage an ACPI device, that device will have
> +a specific _HID/_CID that tells the OS what driver to bind to it, and
> +the _CRS tells the OS and the driver where the device's registers are.
> +
> +PNP0C02 "motherboard" devices are basically a catch-all. ?There's no
> +programming model for them other than "don't use these resources for
> +anything else." ?So any address space that is (1) not claimed by some
> +other ACPI device and (2) should not be assigned by the OS to
> +something else, should be claimed by a PNP0C02 _CRS method.
> +
> +PCI host bridges are PNP0A03 or PNP0A08 devices. ?Their _CRS should
> +describe all the address space they consume. ?In principle, this would
> +be all the windows they forward down to the PCI bus, as well as the
> +bridge registers themselves. ?The bridge registers include things like
> +secondary/subordinate bus registers that determine the bus range below
> +the bridge, window registers that describe the apertures, etc. ?These
> +are all device-specific, non-architected things, so the only way a
> +PNP0A03/PNP0A08 driver can manage them is via _PRS/_CRS/_SRS, which
> +contain the device-specific details. ?These bridge registers also
> +include ECAM space, since it is consumed by the bridge.
> +
> +ACPI defined a Producer/Consumer bit that was intended to distinguish
> +the bridge apertures from the bridge registers [4, 5]. ?However,
> +BIOSes didn't use that bit correctly, and the result is that OSes have
> +to assume that everything in a PCI host bridge _CRS is a window. ?That
> +leaves no way to describe the bridge registers in the PNP0A03/PNP0A08
> +device itself.
> +
> +The workaround is to describe the bridge registers (including ECAM
> +space) in PNP0C02 catch-all devices [6]. ?With the exception of ECAM,
> +the bridge register space is device-specific anyway, so the generic
> +PNP0A03/PNP0A08 driver (pci_root.c) has no need to know about it. ?For
> +ECAM, pci_root.c learns about the space from either MCFG or the _CBA
> +method.
Should the relationship of MCFG and _CBA be covered in this document?
Thanks and best regards
Lv
> +
> +Note that the PCIe spec actually does require ECAM unless there's a
> +standard firmware interface for config access, e.g., the ia64 SAL
> +interface [7]. One reason is that we want a generic host bridge
> +driver (pci_root.c), and a generic driver requires a generic way to
> +access config space.
> +
> +
> +[1] ACPI 6.0, sec 6.1:
> + For any device that is on a non-enumerable type of bus (for
> + example, an ISA bus), OSPM enumerates the devices' identifier(s)
> + and the ACPI system firmware must supply an _HID object ... for
> + each device to enable OSPM to do that.
> +
> +[2] ACPI 6.0, sec 3.7:
> + The OS enumerates motherboard devices simply by reading through
> + the ACPI Namespace looking for devices with hardware IDs.
> +
> + Each device enumerated by ACPI includes ACPI-defined objects in
> + the ACPI Namespace that report the hardware resources the device
> + could occupy [_PRS], an object that reports the resources that are
> + currently used by the device [_CRS], and objects for configuring
> + those resources [_SRS]. The information is used by the Plug and
> + Play OS (OSPM) to configure the devices.
> +
> +[3] ACPI 6.0, sec 6.2:
> + OSPM uses device configuration objects to configure hardware
> + resources for devices enumerated via ACPI. Device configuration
> + objects provide information about current and possible resource
> + requirements, the relationship between shared resources, and
> + methods for configuring hardware resources.
> +
> + When OSPM enumerates a device, it calls _PRS to determine the
> + resource requirements of the device. It may also call _CRS to
> + find the current resource settings for the device. Using this
> + information, the Plug and Play system determines what resources
> + the device should consume and sets those resources by calling the
> + device?s _SRS control method.
> +
> + In ACPI, devices can consume resources (for example, legacy
> + keyboards), provide resources (for example, a proprietary PCI
> + bridge), or do both. Unless otherwise specified, resources for a
> + device are assumed to be taken from the nearest matching resource
> + above the device in the device hierarchy.
> +
> +[4] ACPI 6.0, sec 6.4.3.5.4:
> + Extended Address Space Descriptor
> + General Flags: Bit [0] Consumer/Producer:
> + 1?This device consumes this resource
> + 0?This device produces and consumes this resource
> +
> +[5] ACPI 6.0, sec 19.6.43:
> + ResourceUsage specifies whether the Memory range is consumed by
> + this device (ResourceConsumer) or passed on to child devices
> + (ResourceProducer). If nothing is specified, then
> + ResourceConsumer is assumed.
> +
> +[6] PCI Firmware 3.0, sec 4.1.2:
> + If the operating system does not natively comprehend reserving the
> + MMCFG region, the MMCFG region must be reserved by firmware. The
> + address range reported in the MCFG table or by _CBA method (see
> + Section 4.1.3) must be reserved by declaring a motherboard
> + resource. For most systems, the motherboard resource would appear
> + at the root of the ACPI namespace (under \_SB) in a node with a
> + _HID of EISAID (PNP0C02), and the resources in this case should
> + not be claimed in the root PCI bus?s _CRS. The resources can
> + optionally be returned in Int15 E820 or EFIGetMemoryMap as
> + reserved memory but must always be reported through ACPI as a
> + motherboard resource.
> +
> +[7] PCI Express 3.0, sec 7.2.2:
> + For systems that are PC-compatible, or that do not implement a
> + processor-architecture-specific firmware interface standard that
> + allows access to the Configuration Space, the ECAM is required as
> + defined in this section.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 2/2] mfd: axp20x: Fix AXP806 access errors on cold boot
From: Chen-Yu Tsai @ 2016-11-23 3:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123031616.10114-1-wens@csie.org>
The AXP806 supports either master/standalone or slave mode.
Slave mode allows sharing the serial bus, even with multiple
AXP806 which all have the same hardware address.
This is done with extra "serial interface address extension",
or AXP806_BUS_ADDR_EXT, and "register address extension", or
AXP806_REG_ADDR_EXT, registers. The former is read-only, with
1 bit customizable at the factory, and 1 bit depending on the
state of an external pin. The latter is writable. Only when
the these device addressing bits (in the upper 4 bits of the
registers) match, will the device respond to operations on
its other registers.
The AXP806_REG_ADDR_EXT was previously configured by Allwinner's
bootloader. Work on U-boot SPL support now allows us to switch
to mainline U-boot, which doesn't do this for us. There might
be other bare minimum bootloaders out there which don't to this
either. It's best to handle this in the kernel.
This patch sets AXP806_REG_ADDR_EXT to 0x10, which is what we
know to be the proper value for a standard AXP806 in slave mode.
Afterwards it will reinitialize the regmap cache, to purge any
invalid stale values.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/mfd/axp20x.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index cdaeb34a9a38..a0166c667656 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -31,6 +31,8 @@
#define AXP20X_OFF 0x80
+#define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4)
+
static const char * const axp20x_model_names[] = {
"AXP152",
"AXP202",
@@ -829,6 +831,42 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
{
int ret;
+ /*
+ * The AXP806 supports either master/standalone or slave mode.
+ * Slave mode allows sharing the serial bus, even with multiple
+ * AXP806 which all have the same hardware address.
+ *
+ * This is done with extra "serial interface address extension",
+ * or AXP806_BUS_ADDR_EXT, and "register address extension", or
+ * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
+ * 1 bit customizable at the factory, and 1 bit depending on the
+ * state of an external pin. The latter is writable. Only when
+ * the these device addressing bits (in the upper 4 bits of the
+ * registers) match, will the device respond to operations on its
+ * other registers.
+ *
+ * Since we only support an AXP806 chained to an AXP809 in slave
+ * mode, and there isn't any existing hardware which uses AXP806
+ * in master mode, or has 2 AXP806s in the same system, we can
+ * just program the register address extension to the slave mode
+ * address.
+ */
+ if (axp20x->variant == AXP806_ID) {
+ /* Write to the register address extension register */
+ regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
+ AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
+
+ /* Make sure the write hits the device */
+ regcache_sync_region(axp20x->regmap, AXP806_REG_ADDR_EXT,
+ AXP806_REG_ADDR_EXT);
+
+ /*
+ * Reinitialize the regmap cache in case the device didn't
+ * properly respond to our reads before.
+ */
+ regmap_reinit_cache(axp20x->regmap, axp20x->regmap_cfg);
+ }
+
ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
IRQF_ONESHOT | IRQF_SHARED, -1,
axp20x->regmap_irq_chip,
--
2.10.2
^ permalink raw reply related
* [PATCH v2 1/2] mfd: axp20x: Add address extension registers for AXP806 regmap
From: Chen-Yu Tsai @ 2016-11-23 3:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123031616.10114-1-wens@csie.org>
The AXP806 supports either master/standalone or slave mode.
Slave mode allows sharing the serial bus, even with multiple
AXP806 which all have the same hardware address.
This is done with extra "serial interface address extension",
or AXP806_BUS_ADDR_EXT, and "register address extension", or
AXP806_REG_ADDR_EXT, registers. The former is read-only, with
1 bit customizable at the factory, and 1 bit depending on the
state of an external pin. The latter is writable. Only when
the these device addressing bits (in the upper 4 bits of the
registers) match, will the device respond to operations on
its other registers.
Add these 2 registers to the regmap so we can access them.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/mfd/axp20x.c | 3 ++-
include/linux/mfd/axp20x.h | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index ba130be32e61..cdaeb34a9a38 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -135,6 +135,7 @@ static const struct regmap_range axp806_writeable_ranges[] = {
regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
+ regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
};
static const struct regmap_range axp806_volatile_ranges[] = {
@@ -305,7 +306,7 @@ static const struct regmap_config axp806_regmap_config = {
.val_bits = 8,
.wr_table = &axp806_writeable_table,
.volatile_table = &axp806_volatile_table,
- .max_register = AXP806_VREF_TEMP_WARN_L,
+ .max_register = AXP806_REG_ADDR_EXT,
.cache_type = REGCACHE_RBTREE,
};
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index fec597fb34cb..7e85ececcedf 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -115,6 +115,8 @@ enum {
#define AXP806_CLDO2_V_CTRL 0x25
#define AXP806_CLDO3_V_CTRL 0x26
#define AXP806_VREF_TEMP_WARN_L 0xf3
+#define AXP806_BUS_ADDR_EXT 0xfe
+#define AXP806_REG_ADDR_EXT 0xff
/* Interrupt */
#define AXP152_IRQ1_EN 0x40
--
2.10.2
^ permalink raw reply related
* [PATCH v2 0/2] mfd: axp20x: Fix AXP806 access errors on cold boot
From: Chen-Yu Tsai @ 2016-11-23 3:16 UTC (permalink / raw)
To: linux-arm-kernel
Hi Lee,
This is v2 of my AXP806 cold boot access fix series.
Changes since v1:
- Added define for value 0x10 written to AXP806_REG_ADDR_EXT
register.
Cover letter from v1:
Recently we've added full SPL support for A80 to mainline U-boot. This
means we no longer depend on Allwinner's bootloader. It also means that
some of system configuration the bootloader set up no longer applies.
The bootloader was correctly configuring the multi-device addressing
support in the AXP806 PMIC. If the PMIC is not correctly addressed, it
just ignores all reads and writes to the other registers. As mainline
U-boot does not support the AXP806, and since we can't always count on
a good bootloader, we should re-configure this in the kernel regardless.
Patch 1 adds the registers for the multi-device addressing scheme to
the AXP806 regmap.
Patch 2 configures the register at probe time, and reinitializes the
regmap cache.
Since support for this PMIC was just added in 4.9-rc1, I hope you can
merge these 2 patches as fixes for 4.9.
Thank you!
Regards
ChenYu
Chen-Yu Tsai (2):
mfd: axp20x: Add address extension registers for AXP806 regmap
mfd: axp20x: Fix AXP806 access errors on cold boot
drivers/mfd/axp20x.c | 41 ++++++++++++++++++++++++++++++++++++++++-
include/linux/mfd/axp20x.h | 2 ++
2 files changed, 42 insertions(+), 1 deletion(-)
--
2.10.2
^ permalink raw reply
* [PATCH 2/2] PCI: iproc: avoid maybe-uninitialized warning
From: Ray Jui @ 2016-11-23 3:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2504851.C6gOdhdaGF@wuerfel>
On 11/22/2016 1:15 PM, Arnd Bergmann wrote:
> On Tuesday, November 22, 2016 9:45:24 AM CET Ray Jui wrote:
>>> diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
>>> index 857ff5198317..0359569c8d78 100644
>>> --- a/drivers/pci/host/pcie-iproc.c
>>> +++ b/drivers/pci/host/pcie-iproc.c
>>> @@ -936,6 +936,7 @@ static int iproc_pcie_setup_ib(struct iproc_pcie *pcie,
>>>
>>> }
>>> }
>>> + ret = -EINVAL;
>>> err_ib:
>>> dev_err(dev, "unable to configure inbound mapping\n");
>>> dev_err(dev, "axi %pap, pci %pap, res size %pap\n",
>>>
>>
>> This change is good, but in my opinion, a further improvement for
>> clarity would be to initialize 'ret' to -EINVAL in the beginning of this
>> function when 'ret' is declared. What do you think?
>>
>
> I never do that, see https://rusty.ozlabs.org/?p=232 for a great
> explanation about why.
>
> Arnd
>
Okay got it. Thanks!
Ray
^ permalink raw reply
* [PATCH 1/2] PCI: iproc: fix 32-bit build
From: Ray Jui @ 2016-11-23 2:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4393833.rTFctaL9Kd@wuerfel>
On 11/22/2016 1:13 PM, Arnd Bergmann wrote:
> On Tuesday, November 22, 2016 9:42:05 AM CET Ray Jui wrote:
>>
>> Hmmm, somehow we've never seen this link error for the ARM32 based
>> platforms that we build for. Does it behave differently between
>> different versions of compilers?
>>
>> Nevertheless, this is a good change to take, thanks!
>
> I looked at it again, and see now that it only happens with
> a 64-bit RESOURCE_SIZE_T, which is only used on 32-bit
> platforms with more than 4GB of memory addresses. It would
> however show up in a multiplatform distro build for ARMv7VE,
> so the fix is still clearly needed.
>
> Arnd
>
Yes, got it for how it showed up in your environment, :)
This change stands good as it has been.
Thanks,
Ray
^ permalink raw reply
* [PATCH V9 1/6] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Chunyan Zhang @ 2016-11-23 2:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161122173950.56585f50@gandalf.local.home>
On 23 November 2016 at 06:39, Steven Rostedt <rostedt@goodmis.org> wrote:
> On Mon, 21 Nov 2016 15:57:18 +0800
> Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
>
>> Currently Function traces can be only exported to ring buffer, this
>> patch added trace_export concept which can process traces and export
>> them to a registered destination as an addition to the current only
>> one output of Ftrace - i.e. ring buffer.
>>
>> In this way, if we want Function traces to be sent to other destination
>> rather than ring buffer only, we just need to register a new trace_export
>> and implement its own .write() function for writing traces to storage.
>>
>> With this patch, only Function trace (trace type is TRACE_FN)
>> is supported.
>>
>> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
>> ---
>> include/linux/trace.h | 28 +++++++++++
>> kernel/trace/trace.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 156 insertions(+), 1 deletion(-)
>> create mode 100644 include/linux/trace.h
>>
>> diff --git a/include/linux/trace.h b/include/linux/trace.h
>> new file mode 100644
>> index 0000000..9330a58
>> --- /dev/null
>> +++ b/include/linux/trace.h
>> @@ -0,0 +1,28 @@
>> +#ifndef _LINUX_TRACE_H
>> +#define _LINUX_TRACE_H
>> +
>> +#ifdef CONFIG_TRACING
>> +/*
>> + * The trace export - an export of Ftrace output. The trace_export
>> + * can process traces and export them to a registered destination as
>> + * an addition to the current only output of Ftrace - i.e. ring buffer.
>> + *
>> + * If you want traces to be sent to some other place rather than ring
>> + * buffer only, just need to register a new trace_export and implement
>> + * its own .write() function for writing traces to the storage.
>> + *
>> + * next - pointer to the next trace_export
>> + * write - copy traces which have been delt with ->commit() to
>> + * the destination
>> + */
>> +struct trace_export {
>> + struct trace_export __rcu *next;
>> + void (*write)(const void *, unsigned int);
>> +};
>> +
>> +int register_ftrace_export(struct trace_export *export);
>> +int unregister_ftrace_export(struct trace_export *export);
>> +
>> +#endif /* CONFIG_TRACING */
>> +
>> +#endif /* _LINUX_TRACE_H */
>> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
>> index 8696ce6..038291d 100644
>> --- a/kernel/trace/trace.c
>> +++ b/kernel/trace/trace.c
>> @@ -40,6 +40,7 @@
>> #include <linux/poll.h>
>> #include <linux/nmi.h>
>> #include <linux/fs.h>
>> +#include <linux/trace.h>
>> #include <linux/sched/rt.h>
>>
>> #include "trace.h"
>> @@ -2128,6 +2129,129 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
>> ftrace_trace_userstack(buffer, flags, pc);
>> }
>>
>> +static void
>> +trace_process_export(struct trace_export *export,
>> + struct ring_buffer_event *event)
>> +{
>> + struct trace_entry *entry;
>> + unsigned int size = 0;
>> +
>> + entry = ring_buffer_event_data(event);
>> + size = ring_buffer_event_length(event);
>> + export->write(entry, size);
>> +}
>> +
>> +static DEFINE_MUTEX(ftrace_export_lock);
>> +
>> +static struct trace_export __rcu *ftrace_exports_list __read_mostly;
>> +
>> +static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
>> +
>> +static inline void ftrace_exports_enable(void)
>> +{
>> + static_branch_enable(&ftrace_exports_enabled);
>> +}
>> +
>> +static inline void ftrace_exports_disable(void)
>> +{
>> + static_branch_disable(&ftrace_exports_enabled);
>> +}
>> +
>> +void ftrace_exports(struct ring_buffer_event *event)
>
> I'm currently testing the patches, but is there a reason that
> ftrace_exports() is not static?
At present ftrace_exports() is only used by function trace though,
but I hope it can be used by other traces when it needed.
So I didn't mark it with static, but if you think it should better be
static for the time being, I can revise that.
Thanks,
Chunyan
>
> -- Steve
>
>> +{
>> + struct trace_export *export;
>> +
>> + preempt_disable_notrace();
>> +
>> + export = rcu_dereference_raw_notrace(ftrace_exports_list);
>> + while (export) {
>> + trace_process_export(export, event);
>> + export = rcu_dereference_raw_notrace(export->next);
>> + }
>> +
>> + preempt_enable_notrace();
>> +}
>> +
>> +static inline void
>> +add_trace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + rcu_assign_pointer(export->next, *list);
>> + /*
>> + * We are entering export into the list but another
>> + * CPU might be walking that list. We need to make sure
>> + * the export->next pointer is valid before another CPU sees
>> + * the export pointer included into the list.
>> + */
>> + rcu_assign_pointer(*list, export);
>> +}
>> +
>> +static inline int
>> +rm_trace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + struct trace_export **p;
>> +
>> + for (p = list; *p != NULL; p = &(*p)->next)
>> + if (*p == export)
>> + break;
>> +
>> + if (*p != export)
>> + return -1;
>> +
>> + rcu_assign_pointer(*p, (*p)->next);
>> +
>> + return 0;
>> +}
>> +
>> +static inline void
>> +add_ftrace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + if (*list == NULL)
>> + ftrace_exports_enable();
>> +
>> + add_trace_export(list, export);
>> +}
>> +
>> +static inline int
>> +rm_ftrace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + int ret;
>> +
>> + ret = rm_trace_export(list, export);
>> + if (*list == NULL)
>> + ftrace_exports_disable();
>> +
>> + return ret;
>> +}
>> +
>> +int register_ftrace_export(struct trace_export *export)
>> +{
>> + if (WARN_ON_ONCE(!export->write))
>> + return -1;
>> +
>> + mutex_lock(&ftrace_export_lock);
>> +
>> + add_ftrace_export(&ftrace_exports_list, export);
>> +
>> + mutex_unlock(&ftrace_export_lock);
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(register_ftrace_export);
>> +
>> +int unregister_ftrace_export(struct trace_export *export)
>> +{
>> + int ret;
>> +
>> + mutex_lock(&ftrace_export_lock);
>> +
>> + ret = rm_ftrace_export(&ftrace_exports_list, export);
>> +
>> + mutex_unlock(&ftrace_export_lock);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(unregister_ftrace_export);
>> +
>> void
>> trace_function(struct trace_array *tr,
>> unsigned long ip, unsigned long parent_ip, unsigned long flags,
>> @@ -2146,8 +2270,11 @@ trace_function(struct trace_array *tr,
>> entry->ip = ip;
>> entry->parent_ip = parent_ip;
>>
>> - if (!call_filter_check_discard(call, entry, buffer, event))
>> + if (!call_filter_check_discard(call, entry, buffer, event)) {
>> + if (static_branch_unlikely(&ftrace_exports_enabled))
>> + ftrace_exports(event);
>> __buffer_unlock_commit(buffer, event);
>> + }
>> }
>>
>> #ifdef CONFIG_STACKTRACE
>
^ permalink raw reply
* [PATCH 2/2] arm64: Pass RAM boundary and enable-dcache flag to purgatory
From: Pratyush Anand @ 2016-11-23 2:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123020300.GA3481@dhcp-128-65.nay.redhat.com>
On Wednesday 23 November 2016 07:33 AM, Dave Young wrote:
>> Although this is very unlikely that a hardware will support only 16K page
>> > sizes, however it is possible. Therefore, its better to keep it disabled by
>> > default.
> If it is *unlikely* it could be better to make it as default and add a
> --disable-dcache instead.
>
I think, I can do that.
~Pratyush
^ 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