aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-01-04 00:55:29 -0500
committerOlof Johansson <olof@lixom.net>2014-01-04 00:55:29 -0500
commit3d7e0207ced354d1647195f53bcc670f9756c649 (patch)
treebedff8fa54a8a086e7426d66a0069323b5864986
parent7bfc397fe76de447ca645edd7453d8ef6ab18279 (diff)
parent8e048b9997efbe75fe77b1f14d3af41700cc8724 (diff)
Merge tag 'integrator-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator into next/drivers
From Linus Walleij: Some Integrator patches that matured for v3.14: - Use PATCH_PHYS_TO_VIRT and AUTO_ZRELADDR. - Support cascaded interrupts on the SIC. - Complete clock implementation for the IM-PD1. * tag 'integrator-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator: clk: versatile: fixup IM-PD1 clock implementation clk: versatile: pass a name to ICST clock provider ARM: integrator: pass parent IRQ to the SIC irqchip: versatile FPGA: support cascaded interrupts from DT ARM: integrator: Default enable ARM_PATCH_PHYS_VIRT, AUTO_ZRELADDR Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt5
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/boot/dts/integratorcp.dts3
-rw-r--r--drivers/clk/versatile/clk-icst.c3
-rw-r--r--drivers/clk/versatile/clk-icst.h1
-rw-r--r--drivers/clk/versatile/clk-impd1.c88
-rw-r--r--drivers/clk/versatile/clk-integrator.c2
-rw-r--r--drivers/clk/versatile/clk-realview.c6
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c15
9 files changed, 103 insertions, 22 deletions
diff --git a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt
index 9989eda755d9..c9cf605bb995 100644
--- a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt
+++ b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt
@@ -29,3 +29,8 @@ pic: pic@14000000 {
29 clear-mask = <0xffffffff>; 29 clear-mask = <0xffffffff>;
30 valid-mask = <0x003fffff>; 30 valid-mask = <0x003fffff>;
31}; 31};
32
33Optional properties:
34- interrupts: if the FPGA IRQ controller is cascaded, i.e. if its IRQ
35 output is simply connected to the input of another IRQ controller,
36 then the parent IRQ shall be specified in this property.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8b768937c663..63ce70c988de 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -313,6 +313,8 @@ config ARCH_INTEGRATOR
313 bool "ARM Ltd. Integrator family" 313 bool "ARM Ltd. Integrator family"
314 select ARCH_HAS_CPUFREQ 314 select ARCH_HAS_CPUFREQ
315 select ARM_AMBA 315 select ARM_AMBA
316 select ARM_PATCH_PHYS_VIRT
317 select AUTO_ZRELADDR
316 select COMMON_CLK 318 select COMMON_CLK
317 select COMMON_CLK_VERSATILE 319 select COMMON_CLK_VERSATILE
318 select GENERIC_CLOCKEVENTS 320 select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
index 7deb3a3182b4..a21c17de9a5e 100644
--- a/arch/arm/boot/dts/integratorcp.dts
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -47,8 +47,11 @@
47 valid-mask = <0x00000007>; 47 valid-mask = <0x00000007>;
48 }; 48 };
49 49
50 /* The SIC is cascaded off IRQ 26 on the PIC */
50 sic: sic@ca000000 { 51 sic: sic@ca000000 {
51 compatible = "arm,versatile-fpga-irq"; 52 compatible = "arm,versatile-fpga-irq";
53 interrupt-parent = <&pic>;
54 interrupts = <26>;
52 #interrupt-cells = <1>; 55 #interrupt-cells = <1>;
53 interrupt-controller; 56 interrupt-controller;
54 reg = <0xca000000 0x100>; 57 reg = <0xca000000 0x100>;
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index f5e4c21b301f..8cbfcf88fae3 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -119,6 +119,7 @@ static const struct clk_ops icst_ops = {
119 119
120struct clk *icst_clk_register(struct device *dev, 120struct clk *icst_clk_register(struct device *dev,
121 const struct clk_icst_desc *desc, 121 const struct clk_icst_desc *desc,
122 const char *name,
122 void __iomem *base) 123 void __iomem *base)
123{ 124{
124 struct clk *clk; 125 struct clk *clk;
@@ -130,7 +131,7 @@ struct clk *icst_clk_register(struct device *dev,
130 pr_err("could not allocate ICST clock!\n"); 131 pr_err("could not allocate ICST clock!\n");
131 return ERR_PTR(-ENOMEM); 132 return ERR_PTR(-ENOMEM);
132 } 133 }
133 init.name = "icst"; 134 init.name = name;
134 init.ops = &icst_ops; 135 init.ops = &icst_ops;
135 init.flags = CLK_IS_ROOT; 136 init.flags = CLK_IS_ROOT;
136 init.parent_names = NULL; 137 init.parent_names = NULL;
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h
index dad51b6ffd00..be99dd0da785 100644
--- a/drivers/clk/versatile/clk-icst.h
+++ b/drivers/clk/versatile/clk-icst.h
@@ -15,4 +15,5 @@ struct clk_icst_desc {
15 15
16struct clk *icst_clk_register(struct device *dev, 16struct clk *icst_clk_register(struct device *dev,
17 const struct clk_icst_desc *desc, 17 const struct clk_icst_desc *desc,
18 const char *name,
18 void __iomem *base); 19 void __iomem *base);
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c
index 369139af2a3b..844f8d711a12 100644
--- a/drivers/clk/versatile/clk-impd1.c
+++ b/drivers/clk/versatile/clk-impd1.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Clock driver for the ARM Integrator/IM-PD1 board 2 * Clock driver for the ARM Integrator/IM-PD1 board
3 * Copyright (C) 2012 Linus Walleij 3 * Copyright (C) 2012-2013 Linus Walleij
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
@@ -18,20 +18,28 @@
18#include "clk-icst.h" 18#include "clk-icst.h"
19 19
20struct impd1_clk { 20struct impd1_clk {
21 struct clk *vcoclk; 21 char *vco1name;
22 struct clk *vco1clk;
23 char *vco2name;
24 struct clk *vco2clk;
25 struct clk *mmciclk;
26 char *uartname;
22 struct clk *uartclk; 27 struct clk *uartclk;
23 struct clk_lookup *clks[3]; 28 char *spiname;
29 struct clk *spiclk;
30 char *scname;
31 struct clk *scclk;
32 struct clk_lookup *clks[6];
24}; 33};
25 34
35/* One entry for each connected IM-PD1 LM */
26static struct impd1_clk impd1_clks[4]; 36static struct impd1_clk impd1_clks[4];
27 37
28/* 38/*
29 * There are two VCO's on the IM-PD1 but only one is used by the 39 * There are two VCO's on the IM-PD1
30 * kernel, that is why we are only implementing the control of
31 * IMPD1_OSC1 here.
32 */ 40 */
33 41
34static const struct icst_params impd1_vco_params = { 42static const struct icst_params impd1_vco1_params = {
35 .ref = 24000000, /* 24 MHz */ 43 .ref = 24000000, /* 24 MHz */
36 .vco_max = ICST525_VCO_MAX_3V, 44 .vco_max = ICST525_VCO_MAX_3V,
37 .vco_min = ICST525_VCO_MIN, 45 .vco_min = ICST525_VCO_MIN,
@@ -44,11 +52,29 @@ static const struct icst_params impd1_vco_params = {
44}; 52};
45 53
46static const struct clk_icst_desc impd1_icst1_desc = { 54static const struct clk_icst_desc impd1_icst1_desc = {
47 .params = &impd1_vco_params, 55 .params = &impd1_vco1_params,
48 .vco_offset = IMPD1_OSC1, 56 .vco_offset = IMPD1_OSC1,
49 .lock_offset = IMPD1_LOCK, 57 .lock_offset = IMPD1_LOCK,
50}; 58};
51 59
60static const struct icst_params impd1_vco2_params = {
61 .ref = 24000000, /* 24 MHz */
62 .vco_max = ICST525_VCO_MAX_3V,
63 .vco_min = ICST525_VCO_MIN,
64 .vd_min = 12,
65 .vd_max = 519,
66 .rd_min = 3,
67 .rd_max = 120,
68 .s2div = icst525_s2div,
69 .idx2s = icst525_idx2s,
70};
71
72static const struct clk_icst_desc impd1_icst2_desc = {
73 .params = &impd1_vco2_params,
74 .vco_offset = IMPD1_OSC2,
75 .lock_offset = IMPD1_LOCK,
76};
77
52/** 78/**
53 * integrator_impd1_clk_init() - set up the integrator clock tree 79 * integrator_impd1_clk_init() - set up the integrator clock tree
54 * @base: base address of the logic module (LM) 80 * @base: base address of the logic module (LM)
@@ -66,16 +92,39 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
66 } 92 }
67 imc = &impd1_clks[id]; 93 imc = &impd1_clks[id];
68 94
69 clk = icst_clk_register(NULL, &impd1_icst1_desc, base); 95 imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id);
70 imc->vcoclk = clk; 96 clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base);
97 imc->vco1clk = clk;
71 imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); 98 imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
72 99
73 /* UART reference clock */ 100 /* VCO2 is also called "CLK2" */
74 clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, 101 imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id);
75 14745600); 102 clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base);
103 imc->vco2clk = clk;
104
105 /* MMCI uses CLK2 right off */
106 imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00700", id);
107
108 /* UART reference clock divides CLK2 by a fixed factor 4 */
109 imc->uartname = kasprintf(GFP_KERNEL, "lm%x-uartclk", id);
110 clk = clk_register_fixed_factor(NULL, imc->uartname, imc->vco2name,
111 CLK_IGNORE_UNUSED, 1, 4);
76 imc->uartclk = clk; 112 imc->uartclk = clk;
77 imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id); 113 imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00100", id);
78 imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id); 114 imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00200", id);
115
116 /* SPI PL022 clock divides CLK2 by a fixed factor 64 */
117 imc->spiname = kasprintf(GFP_KERNEL, "lm%x-spiclk", id);
118 clk = clk_register_fixed_factor(NULL, imc->spiname, imc->vco2name,
119 CLK_IGNORE_UNUSED, 1, 64);
120 imc->clks[4] = clkdev_alloc(clk, NULL, "lm%x:00300", id);
121
122 /* Smart Card clock divides CLK2 by a fixed factor 4 */
123 imc->scname = kasprintf(GFP_KERNEL, "lm%x-scclk", id);
124 clk = clk_register_fixed_factor(NULL, imc->scname, imc->vco2name,
125 CLK_IGNORE_UNUSED, 1, 4);
126 imc->scclk = clk;
127 imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00600", id);
79 128
80 for (i = 0; i < ARRAY_SIZE(imc->clks); i++) 129 for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
81 clkdev_add(imc->clks[i]); 130 clkdev_add(imc->clks[i]);
@@ -92,6 +141,13 @@ void integrator_impd1_clk_exit(unsigned int id)
92 141
93 for (i = 0; i < ARRAY_SIZE(imc->clks); i++) 142 for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
94 clkdev_drop(imc->clks[i]); 143 clkdev_drop(imc->clks[i]);
144 clk_unregister(imc->spiclk);
95 clk_unregister(imc->uartclk); 145 clk_unregister(imc->uartclk);
96 clk_unregister(imc->vcoclk); 146 clk_unregister(imc->vco2clk);
147 clk_unregister(imc->vco1clk);
148 kfree(imc->scname);
149 kfree(imc->spiname);
150 kfree(imc->uartname);
151 kfree(imc->vco2name);
152 kfree(imc->vco1name);
97} 153}
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index 08593b4ee2c9..bda8967e09c2 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -78,7 +78,7 @@ void __init integrator_clk_init(bool is_cp)
78 clk_register_clkdev(clk, NULL, "sp804"); 78 clk_register_clkdev(clk, NULL, "sp804");
79 79
80 /* ICST VCO clock used on the Integrator/CP CLCD */ 80 /* ICST VCO clock used on the Integrator/CP CLCD */
81 clk = icst_clk_register(NULL, &cp_icst_desc, 81 clk = icst_clk_register(NULL, &cp_icst_desc, "icst",
82 __io_address(INTEGRATOR_HDR_BASE)); 82 __io_address(INTEGRATOR_HDR_BASE));
83 clk_register_clkdev(clk, NULL, "clcd"); 83 clk_register_clkdev(clk, NULL, "clcd");
84} 84}
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
index cda07e70a408..747e7b31117c 100644
--- a/drivers/clk/versatile/clk-realview.c
+++ b/drivers/clk/versatile/clk-realview.c
@@ -84,9 +84,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
84 84
85 /* ICST VCO clock */ 85 /* ICST VCO clock */
86 if (is_pb1176) 86 if (is_pb1176)
87 clk = icst_clk_register(NULL, &realview_osc0_desc, sysbase); 87 clk = icst_clk_register(NULL, &realview_osc0_desc,
88 "osc0", sysbase);
88 else 89 else
89 clk = icst_clk_register(NULL, &realview_osc4_desc, sysbase); 90 clk = icst_clk_register(NULL, &realview_osc4_desc,
91 "osc4", sysbase);
90 92
91 clk_register_clkdev(clk, NULL, "dev:clcd"); 93 clk_register_clkdev(clk, NULL, "dev:clcd");
92 clk_register_clkdev(clk, NULL, "issp:clcd"); 94 clk_register_clkdev(clk, NULL, "issp:clcd");
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 47a52ab580d8..3ae2bb8d9cf2 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -9,6 +9,7 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of.h> 10#include <linux/of.h>
11#include <linux/of_address.h> 11#include <linux/of_address.h>
12#include <linux/of_irq.h>
12 13
13#include <asm/exception.h> 14#include <asm/exception.h>
14#include <asm/mach/irq.h> 15#include <asm/mach/irq.h>
@@ -167,8 +168,12 @@ void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
167 f->used_irqs++; 168 f->used_irqs++;
168 } 169 }
169 170
170 pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", 171 pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs",
171 fpga_irq_id, name, base, f->used_irqs); 172 fpga_irq_id, name, base, f->used_irqs);
173 if (parent_irq != -1)
174 pr_cont(", parent IRQ: %d\n", parent_irq);
175 else
176 pr_cont("\n");
172 177
173 fpga_irq_id++; 178 fpga_irq_id++;
174} 179}
@@ -180,6 +185,7 @@ int __init fpga_irq_of_init(struct device_node *node,
180 void __iomem *base; 185 void __iomem *base;
181 u32 clear_mask; 186 u32 clear_mask;
182 u32 valid_mask; 187 u32 valid_mask;
188 int parent_irq;
183 189
184 if (WARN_ON(!node)) 190 if (WARN_ON(!node))
185 return -ENODEV; 191 return -ENODEV;
@@ -193,7 +199,12 @@ int __init fpga_irq_of_init(struct device_node *node,
193 if (of_property_read_u32(node, "valid-mask", &valid_mask)) 199 if (of_property_read_u32(node, "valid-mask", &valid_mask))
194 valid_mask = 0; 200 valid_mask = 0;
195 201
196 fpga_irq_init(base, node->name, 0, -1, valid_mask, node); 202 /* Some chips are cascaded from a parent IRQ */
203 parent_irq = irq_of_parse_and_map(node, 0);
204 if (!parent_irq)
205 parent_irq = -1;
206
207 fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
197 208
198 writel(clear_mask, base + IRQ_ENABLE_CLEAR); 209 writel(clear_mask, base + IRQ_ENABLE_CLEAR);
199 writel(clear_mask, base + FIQ_ENABLE_CLEAR); 210 writel(clear_mask, base + FIQ_ENABLE_CLEAR);