This patchset implements COMMON_CLK support for the zynq. At this
point, only the basic fundamental clocks are modelled, and only
passively; for rate calculation. of_clk bindings are implemented to
allow specifying clock/peripheral relationships in the device tree.
Patch 1 and 2 are a followup to my early patch: "ARM: zynq: move ttc
timer code to drivers/clocksource". Patch 1 moves the definition
sys_timer definition out of the ttc code, and into the zynq common code.
Patch 2 is the actual rename, and makefile cleanup.
Patch 3 adds a description of the second uart to zynq-ep107.dts. I did
this pre-split (patch 4), because I felt it might make reviewing easier.
Patch 4 uses zynq-ep107.dts as a reference to create zynq-7000.dtsi,
which is intended to be a common dtsi snippet for inclusion in
describing zynq-7000 based boards. zynq-zc702.dts is created as an
example consumer. The zynq-ep107.dts file is removed entirely (it
describes, presumably, a board not available to consumers).
Patch 5 is the real meat; it adds an implementation of the clk models
for the PLLs, the CPU clock network, and basic (simplified) clk models
for the essential peripherals (UART and the TTC).
Patch 6 removes CONFIG_OF conditional code from the xilinx uart driver.
The zynq kernel requires CONFIG_OF, and this hardware is not currently
used on any other non CONFIG_OF platform.
Patch 7 adds support to the xilinx_uartps driver to allow getting clock
rate information form the device tree.
Patch 8 implements DT support for the ttc, including pulling clock tree
info.
---
There are some specific concerns that I had that I would like some
guidance on:
Two identical timers on the board have historically been statically
allocated to act as the system clocksource, and the clockevent_device.
With patch 8, this distinction is done in the device tree by tweaking
with the compatible properties of which of the timers you want used for
what purpose.
I feel, however, that this is an abuse of the device tree, which should
only be used to describe hardware, not to layout a policy on how the
hardware is used.
So, if it's not in the device tree, then where? Do I go back to the
static allocation routine, such that the first matching ttc node in the
tree becomes the clockevent_device, and the second one a clocksource?
That seems like a hack.
Is it somehow possible to have all of the timers registered as both a
clocksource and a clockevent_device, and have some higher level logic
make the policy decision as to which timer is used for what?
An additional question regarding of_clk bindings:
my_clock {
#clock-cells = <0>;
clock-output-names = "my_out_clock";
};
node_a {
clocks = <&clk>;
clock-names = "my_clock";
clock-ranges;
node_b {
/* ... */
};
};
In this scenario, should I be expecting of_clk_get(node_b, 0) to
retrieve a handle to parent's consumed clock (due to clock-ranges)? I
could make this work using of_clk_get_by_name(node_b, "my_clock"), but I
was somewhat surprised the former didn't work.
Thanks (and sorry for the novel),
Josh
---
Josh Cartwright (8):
ARM: zynq: move arm-specific sys_timer out of ttc
ARM: zynq: move ttc timer code to drivers/clocksource
ARM: zynq: dts: add description of the second uart
ARM: zynq: dts: split up device tree
ARM: zynq: add COMMON_CLK support
serial: xilinx_uartps: kill CONFIG_OF conditional
serial: xilinx_uartps: get clock rate info from dts
clocksource: xilinx_ttc: add OF_CLK support
.../devicetree/bindings/clock/zynq-7000.txt | 55 ++++
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/zynq-7000.dtsi | 166 ++++++++++
arch/arm/boot/dts/zynq-ep107.dts | 63 ----
arch/arm/boot/dts/zynq-zc702.dts | 44 +++
arch/arm/mach-zynq/Makefile | 2 +-
arch/arm/mach-zynq/common.c | 29 +-
arch/arm/mach-zynq/timer.c | 298 -----------------
drivers/clk/Makefile | 1 +
drivers/clk/clk-zynq.c | 355 +++++++++++++++++++++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/xilinx_ttc.c | 326 +++++++++++++++++++
drivers/tty/serial/xilinx_uartps.c | 39 +--
include/linux/clk/zynq.h | 24 ++
.../common.h => include/linux/xilinx_ttc.h | 8 +-
16 files changed, 1022 insertions(+), 391 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/zynq-7000.txt
create mode 100644 arch/arm/boot/dts/zynq-7000.dtsi
delete mode 100644 arch/arm/boot/dts/zynq-ep107.dts
create mode 100644 arch/arm/boot/dts/zynq-zc702.dts
delete mode 100644 arch/arm/mach-zynq/timer.c
create mode 100644 drivers/clk/clk-zynq.c
create mode 100644 drivers/clocksource/xilinx_ttc.c
create mode 100644 include/linux/clk/zynq.h
rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (81%)
--
1.8.0
The zynq-7000 has an additional UART at 0xE0001000. Describe it in the
device tree.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-ep107.dts | 7 +++++++
1 file changed, 7 insertions(+)
The Zynq platform requires the use of CONFIG_OF. Remove the #ifdef
conditionals in the uartps driver.
Signed-off-by: Josh Cartwright <redacted>
---
drivers/tty/serial/xilinx_uartps.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/arch/arm/mach-zynq/timer.c b/drivers/clocksource/xilinx_ttc.csimilarity index 99%rename from arch/arm/mach-zynq/timer.crename to drivers/clocksource/xilinx_ttc.cindex c93cbe5..ff38b3e 100644--- a/arch/arm/mach-zynq/timer.c+++ b/drivers/clocksource/xilinx_ttc.c
diff --git a/arch/arm/mach-zynq/common.h b/include/linux/xilinx_ttc.hsimilarity index 91%rename from arch/arm/mach-zynq/common.hrename to include/linux/xilinx_ttc.hindex 954b91c..303a3fd 100644--- a/arch/arm/mach-zynq/common.h+++ b/include/linux/xilinx_ttc.h
Add support for retrieving TTC configuration from device tree. This
includes the ability to pull information about the driving clocks from
the of_clk bindings.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-7000.dtsi | 53 ++++++++
arch/arm/boot/dts/zynq-zc702.dts | 10 ++
drivers/clocksource/xilinx_ttc.c | 273 ++++++++++++++++++++++-----------------
3 files changed, 218 insertions(+), 118 deletions(-)
@@ -23,30 +23,14 @@#include<linux/clocksource.h>#include<linux/clockchips.h>#include<linux/io.h>+#include<linux/of.h>+#include<linux/of_address.h>+#include<linux/of_irq.h>+#include<linux/slab.h>+#include<linux/clk-provider.h>#include<mach/zynq_soc.h>-#define IRQ_TIMERCOUNTER0 42--/*-*Thisdriverconfiguresthe216-bitcount-uptimersasfollows:-*-*T1:Timer1,clocksourceforgenerictimekeeping-*T2:Timer2,clockeventsourceforhrtimers-*T3:Timer3,<unused>-*-*Theinputfrequencytothetimermoduleforemulationis2.5MHzwhichis-*commontoallthetimerchannels(T1,T2,andT3).Withapre-scalerof32,-*thetimersareclockedat78.125KHz(12.8usresolution).-*-*Theinputfrequencytothetimermoduleinsiliconwillbe200MHz.Withthe-*pre-scalerof32,thetimersareclockedat6.25MHz(160nsresolution).-*/-#define XTTCPSS_CLOCKSOURCE 0 /* Timer 1 as a generic timekeeping */-#define XTTCPSS_CLOCKEVENT 1 /* Timer 2 as a clock event */--#define XTTCPSS_TIMER_BASE TTC0_BASE-#define XTTCPCC_EVENT_TIMER_IRQ (IRQ_TIMERCOUNTER0 + 1)/**TimerRegisterOffsetDefinitionsofTimer1,Incrementbaseaddressby4*andusesameoffsetsforTimer2
@@ -63,9 +47,14 @@#define XTTCPSS_CNT_CNTRL_DISABLE_MASK 0x1-/* Setup the timers to use pre-scaling */--#define TIMER_RATE (PERIPHERAL_CLOCK_RATE / 32)+/* Setup the timers to use pre-scaling, using a fixed value for now that will+*workacrossmostinputfrequency,butitmayneedtobemoredynamic+*/+#define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */+#define PRESCALE 2048 /* The exponent must match this */+#define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1)+#define CLK_CNTRL_PRESCALE_EN 1+#define CNT_CNTRL_RESET (1<<4)/***structxttcpss_timer-Thisdefinitiondefineslocaltimerstructure
@@ -99,7 +102,7 @@ static void xttcpss_set_interval(struct xttcpss_timer *timer,/* Reset the counter (0x10) so that it starts from 0, one-shotmodemakesthisneededfortimingtoberight.*/-ctrl_reg|=0x10;+ctrl_reg|=CNT_CNTRL_RESET;ctrl_reg&=~XTTCPSS_CNT_CNTRL_DISABLE_MASK;__raw_writel(ctrl_reg,timer->base_addr+XTTCPSS_CNT_CNTRL_OFFSET);}
@@ -114,90 +117,31 @@ static void xttcpss_set_interval(struct xttcpss_timer *timer,**/staticirqreturn_txttcpss_clock_event_interrupt(intirq,void*dev_id){-structclock_event_device*evt=&xttcpss_clockevent;-structxttcpss_timer*timer=dev_id;+structxttcpss_timer_clockevent*xttce=dev_id;+structxttcpss_timer*timer=&xttce->xttc;/* Acknowledge the interrupt and call event handler */__raw_writel(__raw_readl(timer->base_addr+XTTCPSS_ISR_OFFSET),timer->base_addr+XTTCPSS_ISR_OFFSET);-evt->event_handler(evt);+xttce->ce.event_handler(&xttce->ce);returnIRQ_HANDLED;}-staticstructirqactionevent_timer_irq={-.name="xttcpss clockevent",-.flags=IRQF_DISABLED|IRQF_TIMER,-.handler=xttcpss_clock_event_interrupt,-};--/**-*xttcpss_timer_hardware_init-Initializethetimerhardware-*-*Initializethehardwaretostarttheclocksource,gettheclock-*eventtimerreadytouse,andhookuptheinterrupt.-**/-staticvoid__initxttcpss_timer_hardware_init(void)-{-/* Setup the clock source counter to be an incrementing counter-*withnointerruptanditrollsoverat0xFFFF.Pre-scale-itby32also.Letitstartrunningnow.-*/-timers[XTTCPSS_CLOCKSOURCE].base_addr=XTTCPSS_TIMER_BASE;--__raw_writel(0x0,timers[XTTCPSS_CLOCKSOURCE].base_addr+-XTTCPSS_IER_OFFSET);-__raw_writel(0x9,timers[XTTCPSS_CLOCKSOURCE].base_addr+-XTTCPSS_CLK_CNTRL_OFFSET);-__raw_writel(0x10,timers[XTTCPSS_CLOCKSOURCE].base_addr+-XTTCPSS_CNT_CNTRL_OFFSET);--/* Setup the clock event timer to be an interval timer which-*isprescaledby32usingtheintervalinterrupt.Leaveit-*disabledfornow.-*/--timers[XTTCPSS_CLOCKEVENT].base_addr=XTTCPSS_TIMER_BASE+4;--__raw_writel(0x23,timers[XTTCPSS_CLOCKEVENT].base_addr+-XTTCPSS_CNT_CNTRL_OFFSET);-__raw_writel(0x9,timers[XTTCPSS_CLOCKEVENT].base_addr+-XTTCPSS_CLK_CNTRL_OFFSET);-__raw_writel(0x1,timers[XTTCPSS_CLOCKEVENT].base_addr+-XTTCPSS_IER_OFFSET);--/* Setup IRQ the clock event timer */-event_timer_irq.dev_id=&timers[XTTCPSS_CLOCKEVENT];-setup_irq(XTTCPCC_EVENT_TIMER_IRQ,&event_timer_irq);-}-/**-*__raw_readl_cycles-Readsthetimercounterregister+*__xttc_clocksource_read-Readsthetimercounterregister**returns:Currenttimercounterregistervalue**/-staticcycle_t__raw_readl_cycles(structclocksource*cs)+staticcycle_t__xttc_clocksource_read(structclocksource*cs){-structxttcpss_timer*timer=&timers[XTTCPSS_CLOCKSOURCE];+structxttcpss_timer*timer=&to_xttcpss_timer_clksrc(cs)->xttc;return(cycle_t)__raw_readl(timer->base_addr+XTTCPSS_COUNT_VAL_OFFSET);}--/*-*Instantiateandinitializetheclocksourcestructure-*/-staticstructclocksourceclocksource_xttcpss={-.name="xttcpss_timer1",-.rating=200,/* Reasonable clock source */-.read=__raw_readl_cycles,-.mask=CLOCKSOURCE_MASK(16),-.flags=CLOCK_SOURCE_IS_CONTINUOUS,-};--/***xttcpss_set_next_event-Setsthetimeintervalfornextevent*
@@ -224,12 +169,14 @@ static int xttcpss_set_next_event(unsigned long cycles,staticvoidxttcpss_set_mode(enumclock_event_modemode,structclock_event_device*evt){-structxttcpss_timer*timer=&timers[XTTCPSS_CLOCKEVENT];+structxttcpss_timer_clockevent*xttce=to_xttcpss_timer_clkevent(evt);+structxttcpss_timer*timer=&xttce->xttc;u32ctrl_reg;switch(mode){caseCLOCK_EVT_MODE_PERIODIC:-xttcpss_set_interval(timer,TIMER_RATE/HZ);+xttcpss_set_interval(timer,+clk_get_rate(xttce->clk)/PRESCALE);break;caseCLOCK_EVT_MODE_ONESHOT:caseCLOCK_EVT_MODE_UNUSED:
@@ -269,21 +300,27 @@ static struct clock_event_device xttcpss_clockevent = {**/void__initxttcpss_timer_init(void){-xttcpss_timer_hardware_init();-clocksource_register_hz(&clocksource_xttcpss,TIMER_RATE);+structdevice_node*np;++for_each_compatible_node(np,NULL,"xlnx,ttc"){+structdevice_node*np_chld;+void__iomem*base;-/* Calculate the parameters to allow the clockevent to operate using-integermath-*/-clockevents_calc_mult_shift(&xttcpss_clockevent,TIMER_RATE,4);+base=of_iomap(np,0);+WARN_ON(!base);-xttcpss_clockevent.max_delta_ns=-clockevent_delta2ns(0xfffe,&xttcpss_clockevent);-xttcpss_clockevent.min_delta_ns=-clockevent_delta2ns(1,&xttcpss_clockevent);+for_each_available_child_of_node(np,np_chld){+int(*cb)(structdevice_node*np,void__iomem*base);+conststructof_device_id*match;-/* Indicate that clock event is on 1st CPU as SMP boot needs it */+match=of_match_node(zynq_ttc_match,np_chld);+if(match){+interr;-xttcpss_clockevent.cpumask=cpumask_of(0);-clockevents_register_device(&xttcpss_clockevent);+cb=match->data;+err=cb(np_chld,base);+WARN_ON(err);+}+}+}}
@@ -0,0 +1,55 @@+Device Tree Clock bindings for the Zynq 7000 EPP++The Zynq EPP has several different clk providers, each with there own bindings.+The purpose of this document is to document their usage.++See clock_bindings.txt for more information on the generic clock bindings.+See Chapter 25 of Zynq TRM for more information about Zynq clocks.++== PLLs ==++Used to describe the ARM_PLL, DDR_PLL, and IO_PLL.++Required properties:+- #clock-cells : shall be 0 (only one clock is output from this node)+- compatible : "xlnx,zynq-pll"+- reg : pair of u32 values, which are the address offsets within the SLCR+ of the relevant PLL_CTRL register and PLL_CFG register respectively+- clocks : phandle for parent clock. should be the phandle for ps_clk++Optional properties:+- clock-output-names : name of the output clock++Example:+ armpll: armpll {+ #clock-cells = <0>;+ compatible = "xlnx,zynq-pll";+ clocks = <&ps_clk>;+ reg = <0x100 0x110>;+ clock-output-names = "armpll";+ };++== Peripheral clocks ==++Describes clock node for the SDIO, SMC, SPI, QSPI, and UART clocks.++Required properties:+- #clock-cells : shall be 1+- compatible : "xlnx,zynq-periph-clock"+- reg : a single u32 value, describing the offset within the SLCR where+ the CLK_CTRL register is found for this peripheral+- clocks : phandle for parent clocks. should hold phandles for+ the IO_PLL, ARM_PLL, and DDR_PLL in order++Optional properties:+- clock-output-names : name of the output clock++Example:+ uart_clk: uart_clk {+ #clock-cells = <1>;+ compatible = "xlnx,zynq-periph-clock";+ clocks = <&iopll &armpll &ddrpll>;+ reg = <0x154>;+ clock-output-names = "uart0_ref_clk",+ "uart1_ref_clk";+ };
@@ -53,5 +53,61 @@interrupts=<0504>;clock=<50000000>;};++slcr:slcr@f8000000{+compatible="xlnx,zynq-slcr";+reg=<0xF80000000x1000>;++clocks{+#address-cells=<1>;+#size-cells=<0>;++ps_clk:ps_clk{+#clock-cells=<0>;+compatible="fixed-clock";+/* clock-frequency set in board-specific file */+clock-output-names="ps_clk";+};+armpll:armpll{+#clock-cells=<0>;+compatible="xlnx,zynq-pll";+clocks=<&ps_clk>;+reg=<0x1000x110>;+clock-output-names="armpll";+};+ddrpll:ddrpll{+#clock-cells=<0>;+compatible="xlnx,zynq-pll";+clocks=<&ps_clk>;+reg=<0x1040x114>;+clock-output-names="ddrpll";+};+iopll:iopll{+#clock-cells=<0>;+compatible="xlnx,zynq-pll";+clocks=<&ps_clk>;+reg=<0x1080x118>;+clock-output-names="iopll";+};+uart_clk:uart_clk{+#clock-cells=<1>;+compatible="xlnx,zynq-periph-clock";+clocks=<&iopll&armpll&ddrpll>;+reg=<0x154>;+clock-output-names="uart0_ref_clk",+"uart1_ref_clk";+};+cpu_clk:cpu_clk{+#clock-cells=<1>;+compatible="xlnx,zynq-cpu-clock";+clocks=<&iopll&armpll&ddrpll>;+reg=<0x1200x1C4>;+clock-output-names="cpu_6x4x",+"cpu_3x2x",+"cpu_2x",+"cpu_1x";+};+};+};};};
Add support for specifying clock information for the uart clk via the
device tree. This eliminates the need to hardcode rates in the device
tree.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-7000.dtsi | 4 ++--
drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++-------------
2 files changed, 19 insertions(+), 15 deletions(-)
@@ -944,18 +945,20 @@ static int __devinit xuartps_probe(struct platform_device *pdev)intrc;structuart_port*port;structresource*res,*res2;-intclk=0;+structclk*clk;-constunsignedint*prop;--prop=of_get_property(pdev->dev.of_node,"clock",NULL);-if(prop)-clk=be32_to_cpup(prop);+clk=of_clk_get(pdev->dev.of_node,0);if(!clk){dev_err(&pdev->dev,"no clock specified\n");return-ENODEV;}+rc=clk_prepare_enable(clk);+if(rc){+dev_err(&pdev->dev,"could not enable clock\n");+return-EBUSY;+}+res=platform_get_resource(pdev,IORESOURCE_MEM,0);if(!res)return-ENODEV;
@@ -978,7 +981,8 @@ static int __devinit xuartps_probe(struct platform_device *pdev)port->mapbase=res->start;port->irq=res2->start;port->dev=&pdev->dev;-port->uartclk=clk;+port->uartclk=clk_get_rate(clk);+port->private_data=clk;dev_set_drvdata(&pdev->dev,port);rc=uart_add_one_port(&xuartps_uart_driver,port);if(rc){
@@ -1000,14 +1004,14 @@ static int __devinit xuartps_probe(struct platform_device *pdev)staticint__devexitxuartps_remove(structplatform_device*pdev){structuart_port*port=dev_get_drvdata(&pdev->dev);-intrc=0;+structclk*clk=port->private_data;+intrc;/* Remove the xuartps port from the serial core */-if(port){-rc=uart_remove_one_port(&xuartps_uart_driver,port);-dev_set_drvdata(&pdev->dev,NULL);-port->mapbase=0;-}+rc=uart_remove_one_port(&xuartps_uart_driver,port);+dev_set_drvdata(&pdev->dev,NULL);+port->mapbase=0;+clk_disable_unprepare(clk);returnrc;}
Move the sys_timer definition out of ttc driver and make it part of the
common zynq code. This is preparation for renaming and COMMON_CLK
support.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/mach-zynq/common.c | 13 +++++++++++++
arch/arm/mach-zynq/common.h | 4 +---
arch/arm/mach-zynq/timer.c | 10 +---------
3 files changed, 15 insertions(+), 12 deletions(-)
The purpose of the created zynq-7000.dtsi file is to describe the
hardware common to all Zynq 7000-based boards. Also, get rid of the
zynq-ep107 device tree, since it is not hardware anyone can purchase.
Add a zc702 dts file based on the zynq-7000.dtsi. Add it to the
dts/Makefile so it is built with the 'dtbs' target.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/Makefile | 1 +
.../boot/dts/{zynq-ep107.dts => zynq-7000.dtsi} | 19 +++-----------
arch/arm/boot/dts/zynq-zc702.dts | 30 ++++++++++++++++++++++
arch/arm/mach-zynq/common.c | 3 ++-
4 files changed, 36 insertions(+), 17 deletions(-)
rename arch/arm/boot/dts/{zynq-ep107.dts => zynq-7000.dtsi} (79%)
create mode 100644 arch/arm/boot/dts/zynq-zc702.dts
diff --git a/arch/arm/boot/dts/zynq-ep107.dts b/arch/arm/boot/dts/zynq-7000.dtsisimilarity index 79%rename from arch/arm/boot/dts/zynq-ep107.dtsrename to arch/arm/boot/dts/zynq-7000.dtsiindex 5caf100..8b30e59 100644--- a/arch/arm/boot/dts/zynq-ep107.dts+++ b/arch/arm/boot/dts/zynq-7000.dtsi
On Wed, Oct 31, 2012 at 01:56:14PM -0600, Josh Cartwright wrote:
quoted hunk
Add support for retrieving TTC configuration from device tree. This
includes the ability to pull information about the driving clocks from
the of_clk bindings.
Signed-off-by: Josh Cartwright <redacted>
---
@@ -224,12 +169,14 @@ static int xttcpss_set_next_event(unsigned long cycles,staticvoidxttcpss_set_mode(enumclock_event_modemode,structclock_event_device*evt){-structxttcpss_timer*timer=&timers[XTTCPSS_CLOCKEVENT];+structxttcpss_timer_clockevent*xttce=to_xttcpss_timer_clkevent(evt);+structxttcpss_timer*timer=&xttce->xttc;u32ctrl_reg;switch(mode){caseCLOCK_EVT_MODE_PERIODIC:-xttcpss_set_interval(timer,TIMER_RATE/HZ);+xttcpss_set_interval(timer,+clk_get_rate(xttce->clk)/PRESCALE);
I discovered with further testing that the above calculation is broken;
calculated interval also needs to be divided by HZ.
(I'll post a v2; just wanted to get this out there in the slim chance
anyone's testing this ;)
Josh
Add support for specifying clock information for the uart clk via the
device tree. This eliminates the need to hardcode rates in the device
tree.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-7000.dtsi | 4 ++--
drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++-------------
2 files changed, 19 insertions(+), 15 deletions(-)
Shouldn't the function abort if a error happens somewhere? Continuing here
will lead to undefined behavior. Same is probably true for the other WARN_ONs.
Shouldn't the function abort if a error happens somewhere? Continuing here
will lead to undefined behavior. Same is probably true for the other WARN_ONs.
The way I see it is: the kernel is will be left in a bad state in the
case of any failure, regardless of if we bail out or continue. AFAICT,
there is no clean way to recover from a failure this early.
Given that, it seems simpler (albeit marginally so) just to continue; so
that's what I chose to do. I'm not opposed to bailing out, just not
convinced it does anything for us.
On Fri, Nov 02, 2012 at 10:20:33AM +0100, Lars-Peter Clausen wrote:
On 10/31/2012 08:28 PM, Josh Cartwright wrote:
quoted
Add support for specifying clock information for the uart clk via the
device tree. This eliminates the need to hardcode rates in the device
tree.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-7000.dtsi | 4 ++--
drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++-------------
2 files changed, 19 insertions(+), 15 deletions(-)
Shouldn't the function abort if a error happens somewhere? Continuing here
will lead to undefined behavior. Same is probably true for the other WARN_ONs.
The way I see it is: the kernel is will be left in a bad state in the
case of any failure, regardless of if we bail out or continue. AFAICT,
there is no clean way to recover from a failure this early.
Given that, it seems simpler (albeit marginally so) just to continue; so
that's what I chose to do. I'm not opposed to bailing out, just not
convinced it does anything for us.
The issue with this approach is that, while you get a warning, unexpected
seemingly unrelated side-effects may happen later on. E.g. if no reg
property for the clock is specified the reg variable will be uninitialized
and contain whatever was on the stack before. The clock will be registered
nonetheless and the boot process continues. Now if the clock is enabled a
bit in a random register will be modified, which could result in strange and
abnormal behavior, which can be very hard to track down.
Also if for example just one clock has its reg property missing the system
will continue to boot if we bail out here. It is just that the peripherals
using that clock won't work. Which will certainly be easier to diagnose than
random abnormal behavior.
Shouldn't the function abort if a error happens somewhere? Continuing here
will lead to undefined behavior. Same is probably true for the other WARN_ONs.
The way I see it is: the kernel is will be left in a bad state in the
case of any failure, regardless of if we bail out or continue. AFAICT,
there is no clean way to recover from a failure this early.
Given that, it seems simpler (albeit marginally so) just to continue; so
that's what I chose to do. I'm not opposed to bailing out, just not
convinced it does anything for us.
The issue with this approach is that, while you get a warning, unexpected
seemingly unrelated side-effects may happen later on. E.g. if no reg
property for the clock is specified the reg variable will be uninitialized
and contain whatever was on the stack before. The clock will be registered
nonetheless and the boot process continues. Now if the clock is enabled a
bit in a random register will be modified, which could result in strange and
abnormal behavior, which can be very hard to track down.
Okay.....but any reasonable person would start their debugging quest at
the source of the WARN_ON. If someone sees the WARN_ON message but
stupidly chooses to ignore it, they deserves to spend the time trying to
track down abnormal behavior, so I'm still not convinced.
Josh
From: Michal Simek <hidden> Date: 2012-11-05 11:20:26
2012/10/31 Josh Cartwright [off-list ref]:
Move the sys_timer definition out of ttc driver and make it part of the
common zynq code. This is preparation for renaming and COMMON_CLK
support.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/mach-zynq/common.c | 13 +++++++++++++
arch/arm/mach-zynq/common.h | 4 +---
arch/arm/mach-zynq/timer.c | 10 +---------
3 files changed, 15 insertions(+), 12 deletions(-)
Tested-by: Michal Simek <redacted>
Looks good to me. I have added it to my testing branch
and will provide path to mainline through xilinx arm-next branch
Thanks,
Michal
From: Michal Simek <hidden> Date: 2012-11-05 11:22:58
2012/10/29 Josh Cartwright [off-list ref]:
Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to
drivers/clocksource, and out of the mach-zynq directory.
The common.h (which only held the timer declaration) was renamed to
xilinx_ttc.h and moved into include/linux.
Signed-off-by: Josh Cartwright <redacted>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-zynq/Makefile | 2 +-
arch/arm/mach-zynq/common.c | 2 +-
drivers/clocksource/Makefile | 1 +
arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h | 4 ++--
5 files changed, 5 insertions(+), 5 deletions(-)
rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Not going to apply this patch till there is clean way how to move all
drivers there.
Especially I don't like to add xilinx_ttc.h to include/linux folder.
Thanks,
Michal
From: Michal Simek <hidden> Date: 2012-11-05 11:32:22
2012/10/31 Josh Cartwright [off-list ref]:
The purpose of the created zynq-7000.dtsi file is to describe the
hardware common to all Zynq 7000-based boards. Also, get rid of the
zynq-ep107 device tree, since it is not hardware anyone can purchase.
Add a zc702 dts file based on the zynq-7000.dtsi. Add it to the
dts/Makefile so it is built with the 'dtbs' target.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/Makefile | 1 +
.../boot/dts/{zynq-ep107.dts => zynq-7000.dtsi} | 19 +++-----------
arch/arm/boot/dts/zynq-zc702.dts | 30 ++++++++++++++++++++++
arch/arm/mach-zynq/common.c | 3 ++-
4 files changed, 36 insertions(+), 17 deletions(-)
rename arch/arm/boot/dts/{zynq-ep107.dts => zynq-7000.dtsi} (79%)
create mode 100644 arch/arm/boot/dts/zynq-zc702.dts
Not going to apply this. We need to finish our discussion in
"[PATCH v4 1/5] zynq: use GIC device tree bindings" before.
Definitely I like idea to use "xlnx,zynq-7000" generic model name.
Thanks,
Michal
From: Michal Simek <hidden> Date: 2012-11-05 11:35:35
2012/10/31 Josh Cartwright [off-list ref]:
The zynq-7000 has an additional UART at 0xE0001000. Describe it in the
device tree.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-ep107.dts | 7 +++++++
1 file changed, 7 insertions(+)
From: Michal Simek <hidden> Date: 2012-11-05 12:16:10
2012/10/30 Josh Cartwright [off-list ref]:
The Zynq platform requires the use of CONFIG_OF. Remove the #ifdef
conditionals in the uartps driver.
Signed-off-by: Josh Cartwright <redacted>
---
drivers/tty/serial/xilinx_uartps.c | 9 ---------
1 file changed, 9 deletions(-)
Please send this separately out of this patchset.
Also if you do this change which is understandable, you should also
add
depends on OF
Thanks,
Michal
Shouldn't the function abort if a error happens somewhere? Continuing here
will lead to undefined behavior. Same is probably true for the other WARN_ONs.
The way I see it is: the kernel is will be left in a bad state in the
case of any failure, regardless of if we bail out or continue. AFAICT,
there is no clean way to recover from a failure this early.
Given that, it seems simpler (albeit marginally so) just to continue; so
that's what I chose to do. I'm not opposed to bailing out, just not
convinced it does anything for us.
The issue with this approach is that, while you get a warning, unexpected
seemingly unrelated side-effects may happen later on. E.g. if no reg
property for the clock is specified the reg variable will be uninitialized
and contain whatever was on the stack before. The clock will be registered
nonetheless and the boot process continues. Now if the clock is enabled a
bit in a random register will be modified, which could result in strange and
abnormal behavior, which can be very hard to track down.
Okay.....but any reasonable person would start their debugging quest at
the source of the WARN_ON. If someone sees the WARN_ON message but
stupidly chooses to ignore it, they deserves to spend the time trying to
track down abnormal behavior, so I'm still not convinced.
I am with Lars. You would be surprised how many people do no read bootlog.
It should be handled better.
Thanks,
Michal
From: Michal Simek <monstr@monstr.eu> Date: 2012-11-05 13:02:36
2012/10/31 Josh Cartwright [off-list ref]:
quoted hunk
Add support for retrieving TTC configuration from device tree. This
includes the ability to pull information about the driving clocks from
the of_clk bindings.
Signed-off-by: Josh Cartwright <redacted>
---
arch/arm/boot/dts/zynq-7000.dtsi | 53 ++++++++
arch/arm/boot/dts/zynq-zc702.dts | 10 ++
drivers/clocksource/xilinx_ttc.c | 273 ++++++++++++++++++++++-----------------
3 files changed, 218 insertions(+), 118 deletions(-)
Also this is ttc1: ttc1.
These type of faults can be simple removed by proper dts node generation.
Thanks,
Michal
--
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
From: Rob Herring <hidden> Date: 2012-11-05 14:49:22
On 11/05/2012 05:22 AM, Michal Simek wrote:
2012/10/29 Josh Cartwright [off-list ref]:
quoted
Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to
drivers/clocksource, and out of the mach-zynq directory.
The common.h (which only held the timer declaration) was renamed to
xilinx_ttc.h and moved into include/linux.
Signed-off-by: Josh Cartwright <redacted>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-zynq/Makefile | 2 +-
arch/arm/mach-zynq/common.c | 2 +-
drivers/clocksource/Makefile | 1 +
arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h | 4 ++--
5 files changed, 5 insertions(+), 5 deletions(-)
rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Not going to apply this patch till there is clean way how to move all
drivers there.
Especially I don't like to add xilinx_ttc.h to include/linux folder.
A cleaner way is how we are doing irqchips [1]. This needs a single
function (or one each for clksrc and clkevt) that has a DT match list of
all known timers and calls their init function. It should be a bit
simpler than irqchips init function because you don't need to worry
about hierarchy init ordering. That doesn't solve non-DT though and if
there are any extra functions like we have with irqchips, you still need
the header in include/linux.
Rob
[1] http://www.spinics.net/lists/arm-kernel/msg203687.html
On Mon, Nov 05, 2012 at 12:22:55PM +0100, Michal Simek wrote:
2012/10/29 Josh Cartwright [off-list ref]:
quoted
Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to
drivers/clocksource, and out of the mach-zynq directory.
The common.h (which only held the timer declaration) was renamed to
xilinx_ttc.h and moved into include/linux.
Signed-off-by: Josh Cartwright <redacted>
Cc: Arnd Bergmann <redacted>
---
arch/arm/mach-zynq/Makefile | 2 +-
arch/arm/mach-zynq/common.c | 2 +-
drivers/clocksource/Makefile | 1 +
arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h | 4 ++--
5 files changed, 5 insertions(+), 5 deletions(-)
rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Not going to apply this patch till there is clean way how to move all
drivers there. Especially I don't like to add xilinx_ttc.h to
include/linux folder.
Okay; I think it's best to defer the moving of the ttc driver from this
patchset. It is not a dependency of the clk driver support stuff.
If you agree, I can spin up a v2 of the patchset w/o this change, and
without the serial CONFIG_OF stuff. Should v2 contain the patches
you've already pulled into testing?
I'll give Rob's irqchip-like suggestion a spin and see how that works
out in parallel.
Thanks,
Josh
From: Michal Simek <hidden> Date: 2012-11-12 11:53:52
2012/11/5 Josh Cartwright [off-list ref]:
On Mon, Nov 05, 2012 at 12:22:55PM +0100, Michal Simek wrote:
quoted
2012/10/29 Josh Cartwright [off-list ref]:
quoted
Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to
drivers/clocksource, and out of the mach-zynq directory.
The common.h (which only held the timer declaration) was renamed to
xilinx_ttc.h and moved into include/linux.
Signed-off-by: Josh Cartwright <redacted>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-zynq/Makefile | 2 +-
arch/arm/mach-zynq/common.c | 2 +-
drivers/clocksource/Makefile | 1 +
arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h | 4 ++--
5 files changed, 5 insertions(+), 5 deletions(-)
rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Not going to apply this patch till there is clean way how to move all
drivers there. Especially I don't like to add xilinx_ttc.h to
include/linux folder.
Okay; I think it's best to defer the moving of the ttc driver from this
patchset. It is not a dependency of the clk driver support stuff.
If you agree, I can spin up a v2 of the patchset w/o this change, and
without the serial CONFIG_OF stuff. Should v2 contain the patches
you've already pulled into testing?
Sure and I see you have done which is good.
Thanks,
Michal