aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 13:59:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 13:59:11 -0500
commit698d601224824bc1a5bf17f3d86be902e2aabff0 (patch)
tree10262bd1f83fd26f874cbd898818e5925844a2ef
parenta11da7df6543b5f71a150b47c0d08ecf0799a0f3 (diff)
parent4aa7cf79b1f760b5751d1686329351c2e060791b (diff)
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver specific changes from Olof Johansson: "A collection of mostly SoC-specific driver updates: - a handful of pincontrol and setup changes - new drivers for hwmon and reset controller for vexpress - timing support updates for OMAP (gpmc and other interfaces) - plus a collection of smaller cleanups" * tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (21 commits) ARM: ux500: fix pin warning ARM: OMAP2+: tusb6010: generic timing calculation ARM: OMAP2+: smc91x: generic timing calculation ARM: OMAP2+: onenand: generic timing calculation ARM: OMAP2+: gpmc: generic timing calculation ARM: OMAP2+: gpmc: handle additional timings ARM: OMAP2+: nand: remove redundant rounding gpio: samsung: use pr_* instead of printk ARM: ux500: fixup magnetometer pins ARM: ux500: add STM pin configuration ARM: ux500: 8500: add pinctrl support for uart1 and uart2 ARM: ux500: cosmetic fixups for uart0 gpio: samsung: Fix input mode setting function for GPIO int ARM: SAMSUNG: Insert bitmap_gpio_int member in samsung_gpio_chip ARM: ux500: 8500: define SDI sleep states ARM: vexpress: Reset driver ARM: ux500: 8500: update SKE keypad pinctrl table hwmon: Versatile Express hwmon driver ARM: ux500: delete duplicate macro ARM: ux500: 8500: add IDLE pin configuration for SPI ...
-rw-r--r--Documentation/bus-devices/ti-gpmc.txt122
-rw-r--r--Documentation/devicetree/bindings/hwmon/vexpress.txt23
-rw-r--r--Documentation/hwmon/vexpress34
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c26
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c143
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c43
-rw-r--r--arch/arm/mach-omap2/gpmc.c373
-rw-r--r--arch/arm/mach-omap2/gpmc.h113
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c181
-rw-r--r--arch/arm/mach-ux500/board-mop500-pins.c425
-rw-r--r--arch/arm/mach-vexpress/reset.c141
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h2
-rw-r--r--arch/arm/plat-samsung/s5p-irq-gpioint.c8
-rw-r--r--drivers/gpio/gpio-samsung.c25
-rw-r--r--drivers/hwmon/Kconfig8
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/vexpress.c229
17 files changed, 1525 insertions, 372 deletions
diff --git a/Documentation/bus-devices/ti-gpmc.txt b/Documentation/bus-devices/ti-gpmc.txt
new file mode 100644
index 00000000000..cc9ce57e0a2
--- /dev/null
+++ b/Documentation/bus-devices/ti-gpmc.txt
@@ -0,0 +1,122 @@
1GPMC (General Purpose Memory Controller):
2=========================================
3
4GPMC is an unified memory controller dedicated to interfacing external
5memory devices like
6 * Asynchronous SRAM like memories and application specific integrated
7 circuit devices.
8 * Asynchronous, synchronous, and page mode burst NOR flash devices
9 NAND flash
10 * Pseudo-SRAM devices
11
12GPMC is found on Texas Instruments SoC's (OMAP based)
13IP details: http://www.ti.com/lit/pdf/spruh73 section 7.1
14
15
16GPMC generic timing calculation:
17================================
18
19GPMC has certain timings that has to be programmed for proper
20functioning of the peripheral, while peripheral has another set of
21timings. To have peripheral work with gpmc, peripheral timings has to
22be translated to the form gpmc can understand. The way it has to be
23translated depends on the connected peripheral. Also there is a
24dependency for certain gpmc timings on gpmc clock frequency. Hence a
25generic timing routine was developed to achieve above requirements.
26
27Generic routine provides a generic method to calculate gpmc timings
28from gpmc peripheral timings. struct gpmc_device_timings fields has to
29be updated with timings from the datasheet of the peripheral that is
30connected to gpmc. A few of the peripheral timings can be fed either
31in time or in cycles, provision to handle this scenario has been
32provided (refer struct gpmc_device_timings definition). It may so
33happen that timing as specified by peripheral datasheet is not present
34in timing structure, in this scenario, try to correlate peripheral
35timing to the one available. If that doesn't work, try to add a new
36field as required by peripheral, educate generic timing routine to
37handle it, make sure that it does not break any of the existing.
38Then there may be cases where peripheral datasheet doesn't mention
39certain fields of struct gpmc_device_timings, zero those entries.
40
41Generic timing routine has been verified to work properly on
42multiple onenand's and tusb6010 peripherals.
43
44A word of caution: generic timing routine has been developed based
45on understanding of gpmc timings, peripheral timings, available
46custom timing routines, a kind of reverse engineering without
47most of the datasheets & hardware (to be exact none of those supported
48in mainline having custom timing routine) and by simulation.
49
50gpmc timing dependency on peripheral timings:
51[<gpmc_timing>: <peripheral timing1>, <peripheral timing2> ...]
52
531. common
54cs_on: t_ceasu
55adv_on: t_avdasu, t_ceavd
56
572. sync common
58sync_clk: clk
59page_burst_access: t_bacc
60clk_activation: t_ces, t_avds
61
623. read async muxed
63adv_rd_off: t_avdp_r
64oe_on: t_oeasu, t_aavdh
65access: t_iaa, t_oe, t_ce, t_aa
66rd_cycle: t_rd_cycle, t_cez_r, t_oez
67
684. read async non-muxed
69adv_rd_off: t_avdp_r
70oe_on: t_oeasu
71access: t_iaa, t_oe, t_ce, t_aa
72rd_cycle: t_rd_cycle, t_cez_r, t_oez
73
745. read sync muxed
75adv_rd_off: t_avdp_r, t_avdh
76oe_on: t_oeasu, t_ach, cyc_aavdh_oe
77access: t_iaa, cyc_iaa, cyc_oe
78rd_cycle: t_cez_r, t_oez, t_ce_rdyz
79
806. read sync non-muxed
81adv_rd_off: t_avdp_r
82oe_on: t_oeasu
83access: t_iaa, cyc_iaa, cyc_oe
84rd_cycle: t_cez_r, t_oez, t_ce_rdyz
85
867. write async muxed
87adv_wr_off: t_avdp_w
88we_on, wr_data_mux_bus: t_weasu, t_aavdh, cyc_aavhd_we
89we_off: t_wpl
90cs_wr_off: t_wph
91wr_cycle: t_cez_w, t_wr_cycle
92
938. write async non-muxed
94adv_wr_off: t_avdp_w
95we_on, wr_data_mux_bus: t_weasu
96we_off: t_wpl
97cs_wr_off: t_wph
98wr_cycle: t_cez_w, t_wr_cycle
99
1009. write sync muxed
101adv_wr_off: t_avdp_w, t_avdh
102we_on, wr_data_mux_bus: t_weasu, t_rdyo, t_aavdh, cyc_aavhd_we
103we_off: t_wpl, cyc_wpl
104cs_wr_off: t_wph
105wr_cycle: t_cez_w, t_ce_rdyz
106
10710. write sync non-muxed
108adv_wr_off: t_avdp_w
109we_on, wr_data_mux_bus: t_weasu, t_rdyo
110we_off: t_wpl, cyc_wpl
111cs_wr_off: t_wph
112wr_cycle: t_cez_w, t_ce_rdyz
113
114
115Note: Many of gpmc timings are dependent on other gpmc timings (a few
116gpmc timings purely dependent on other gpmc timings, a reason that
117some of the gpmc timings are missing above), and it will result in
118indirect dependency of peripheral timings to gpmc timings other than
119mentioned above, refer timing routine for more details. To know what
120these peripheral timings correspond to, please see explanations in
121struct gpmc_device_timings definition. And for gpmc timings refer
122IP details (link above).
diff --git a/Documentation/devicetree/bindings/hwmon/vexpress.txt b/Documentation/devicetree/bindings/hwmon/vexpress.txt
new file mode 100644
index 00000000000..9c27ed694bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/vexpress.txt
@@ -0,0 +1,23 @@
1Versatile Express hwmon sensors
2-------------------------------
3
4Requires node properties:
5- "compatible" value : one of
6 "arm,vexpress-volt"
7 "arm,vexpress-amp"
8 "arm,vexpress-temp"
9 "arm,vexpress-power"
10 "arm,vexpress-energy"
11- "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg
12 (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
13 for more details)
14
15Optional node properties:
16- label : string describing the monitored value
17
18Example:
19 energy@0 {
20 compatible = "arm,vexpress-energy";
21 arm,vexpress-sysreg,func = <13 0>;
22 label = "A15 Jcore";
23 };
diff --git a/Documentation/hwmon/vexpress b/Documentation/hwmon/vexpress
new file mode 100644
index 00000000000..557d6d5ad90
--- /dev/null
+++ b/Documentation/hwmon/vexpress
@@ -0,0 +1,34 @@
1Kernel driver vexpress
2======================
3
4Supported systems:
5 * ARM Ltd. Versatile Express platform
6 Prefix: 'vexpress'
7 Datasheets:
8 * "Hardware Description" sections of the Technical Reference Manuals
9 for the Versatile Express boards:
10 http://infocenter.arm.com/help/topic/com.arm.doc.subset.boards.express/index.html
11 * Section "4.4.14. System Configuration registers" of the V2M-P1 TRM:
12 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0447-/index.html
13
14Author: Pawel Moll
15
16Description
17-----------
18
19Versatile Express platform (http://www.arm.com/versatileexpress/) is a
20reference & prototyping system for ARM Ltd. processors. It can be set up
21from a wide range of boards, each of them containing (apart of the main
22chip/FPGA) a number of microcontrollers responsible for platform
23configuration and control. Theses microcontrollers can also monitor the
24board and its environment by a number of internal and external sensors,
25providing information about power lines voltages and currents, board
26temperature and power usage. Some of them also calculate consumed energy
27and provide a cumulative use counter.
28
29The configuration devices are _not_ memory mapped and must be accessed
30via a custom interface, abstracted by the "vexpress_config" API.
31
32As these devices are non-discoverable, they must be described in a Device
33Tree passed to the kernel. Details of the DT binding for them can be found
34in Documentation/devicetree/bindings/hwmon/vexpress.txt.
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 8607735b3ab..db969a5c499 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -52,27 +52,27 @@ static int omap2_nand_gpmc_retime(
52 52
53 memset(&t, 0, sizeof(t)); 53 memset(&t, 0, sizeof(t));
54 t.sync_clk = gpmc_t->sync_clk; 54 t.sync_clk = gpmc_t->sync_clk;
55 t.cs_on = gpmc_round_ns_to_ticks(gpmc_t->cs_on); 55 t.cs_on = gpmc_t->cs_on;
56 t.adv_on = gpmc_round_ns_to_ticks(gpmc_t->adv_on); 56 t.adv_on = gpmc_t->adv_on;
57 57
58 /* Read */ 58 /* Read */
59 t.adv_rd_off = gpmc_round_ns_to_ticks(gpmc_t->adv_rd_off); 59 t.adv_rd_off = gpmc_t->adv_rd_off;
60 t.oe_on = t.adv_on; 60 t.oe_on = t.adv_on;
61 t.access = gpmc_round_ns_to_ticks(gpmc_t->access); 61 t.access = gpmc_t->access;
62 t.oe_off = gpmc_round_ns_to_ticks(gpmc_t->oe_off); 62 t.oe_off = gpmc_t->oe_off;
63 t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_t->cs_rd_off); 63 t.cs_rd_off = gpmc_t->cs_rd_off;
64 t.rd_cycle = gpmc_round_ns_to_ticks(gpmc_t->rd_cycle); 64 t.rd_cycle = gpmc_t->rd_cycle;
65 65
66 /* Write */ 66 /* Write */
67 t.adv_wr_off = gpmc_round_ns_to_ticks(gpmc_t->adv_wr_off); 67 t.adv_wr_off = gpmc_t->adv_wr_off;
68 t.we_on = t.oe_on; 68 t.we_on = t.oe_on;
69 if (cpu_is_omap34xx()) { 69 if (cpu_is_omap34xx()) {
70 t.wr_data_mux_bus = gpmc_round_ns_to_ticks(gpmc_t->wr_data_mux_bus); 70 t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
71 t.wr_access = gpmc_round_ns_to_ticks(gpmc_t->wr_access); 71 t.wr_access = gpmc_t->wr_access;
72 } 72 }
73 t.we_off = gpmc_round_ns_to_ticks(gpmc_t->we_off); 73 t.we_off = gpmc_t->we_off;
74 t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_t->cs_wr_off); 74 t.cs_wr_off = gpmc_t->cs_wr_off;
75 t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_t->wr_cycle); 75 t.wr_cycle = gpmc_t->wr_cycle;
76 76
77 /* Configure GPMC */ 77 /* Configure GPMC */
78 if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) 78 if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index d102183ed9a..94a349e4dc9 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -33,7 +33,6 @@
33 33
34static unsigned onenand_flags; 34static unsigned onenand_flags;
35static unsigned latency; 35static unsigned latency;
36static int fclk_offset;
37 36
38static struct omap_onenand_platform_data *gpmc_onenand_data; 37static struct omap_onenand_platform_data *gpmc_onenand_data;
39 38
@@ -50,6 +49,7 @@ static struct platform_device gpmc_onenand_device = {
50 49
51static struct gpmc_timings omap2_onenand_calc_async_timings(void) 50static struct gpmc_timings omap2_onenand_calc_async_timings(void)
52{ 51{
52 struct gpmc_device_timings dev_t;
53 struct gpmc_timings t; 53 struct gpmc_timings t;
54 54
55 const int t_cer = 15; 55 const int t_cer = 15;
@@ -59,35 +59,24 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
59 const int t_aa = 76; 59 const int t_aa = 76;
60 const int t_oe = 20; 60 const int t_oe = 20;
61 const int t_cez = 20; /* max of t_cez, t_oez */ 61 const int t_cez = 20; /* max of t_cez, t_oez */
62 const int t_ds = 30;
63 const int t_wpl = 40; 62 const int t_wpl = 40;
64 const int t_wph = 30; 63 const int t_wph = 30;
65 64
66 memset(&t, 0, sizeof(t)); 65 memset(&dev_t, 0, sizeof(dev_t));
67 t.sync_clk = 0; 66
68 t.cs_on = 0; 67 dev_t.mux = true;
69 t.adv_on = 0; 68 dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
70 69 dev_t.t_avdp_w = dev_t.t_avdp_r;
71 /* Read */ 70 dev_t.t_aavdh = t_aavdh * 1000;
72 t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer)); 71 dev_t.t_aa = t_aa * 1000;
73 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh); 72 dev_t.t_ce = t_ce * 1000;
74 t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa); 73 dev_t.t_oe = t_oe * 1000;
75 t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce)); 74 dev_t.t_cez_r = t_cez * 1000;
76 t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe)); 75 dev_t.t_cez_w = dev_t.t_cez_r;
77 t.oe_off = t.access + gpmc_round_ns_to_ticks(1); 76 dev_t.t_wpl = t_wpl * 1000;
78 t.cs_rd_off = t.oe_off; 77 dev_t.t_wph = t_wph * 1000;
79 t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez); 78
80 79 gpmc_calc_timings(&t, &dev_t);
81 /* Write */
82 t.adv_wr_off = t.adv_rd_off;
83 t.we_on = t.oe_on;
84 if (cpu_is_omap34xx()) {
85 t.wr_data_mux_bus = t.we_on;
86 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
87 }
88 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
89 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
90 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
91 80
92 return t; 81 return t;
93} 82}
@@ -173,18 +162,15 @@ static struct gpmc_timings
173omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, 162omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
174 int freq) 163 int freq)
175{ 164{
165 struct gpmc_device_timings dev_t;
176 struct gpmc_timings t; 166 struct gpmc_timings t;
177 const int t_cer = 15; 167 const int t_cer = 15;
178 const int t_avdp = 12; 168 const int t_avdp = 12;
179 const int t_cez = 20; /* max of t_cez, t_oez */ 169 const int t_cez = 20; /* max of t_cez, t_oez */
180 const int t_ds = 30;
181 const int t_wpl = 40; 170 const int t_wpl = 40;
182 const int t_wph = 30; 171 const int t_wph = 30;
183 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; 172 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
184 u32 reg; 173 int div, gpmc_clk_ns;
185 int div, fclk_offset_ns, gpmc_clk_ns;
186 int ticks_cez;
187 int cs = cfg->cs;
188 174
189 if (cfg->flags & ONENAND_SYNC_READ) 175 if (cfg->flags & ONENAND_SYNC_READ)
190 onenand_flags = ONENAND_FLAG_SYNCREAD; 176 onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -251,77 +237,35 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
251 latency = 4; 237 latency = 4;
252 238
253 /* Set synchronous read timings */ 239 /* Set synchronous read timings */
254 memset(&t, 0, sizeof(t)); 240 memset(&dev_t, 0, sizeof(dev_t));
255
256 if (div == 1) {
257 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
258 reg |= (1 << 7);
259 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
260 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
261 reg |= (1 << 7);
262 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
263 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
264 reg |= (1 << 7);
265 reg |= (1 << 23);
266 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
267 } else {
268 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
269 reg &= ~(1 << 7);
270 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
271 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
272 reg &= ~(1 << 7);
273 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
274 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
275 reg &= ~(1 << 7);
276 reg &= ~(1 << 23);
277 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
278 }
279 241
280 t.sync_clk = min_gpmc_clk_period; 242 dev_t.mux = true;
281 t.cs_on = 0; 243 dev_t.sync_read = true;
282 t.adv_on = 0;
283 fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
284 fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
285 t.page_burst_access = gpmc_clk_ns;
286
287 /* Read */
288 t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
289 t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
290 /* Force at least 1 clk between AVD High to OE Low */
291 if (t.oe_on <= t.adv_rd_off)
292 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
293 t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
294 t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
295 t.cs_rd_off = t.oe_off;
296 ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
297 t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
298 ticks_cez);
299
300 /* Write */
301 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { 244 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
302 t.adv_wr_off = t.adv_rd_off; 245 dev_t.sync_write = true;
303 t.we_on = 0;
304 t.we_off = t.cs_rd_off;
305 t.cs_wr_off = t.cs_rd_off;
306 t.wr_cycle = t.rd_cycle;
307 if (cpu_is_omap34xx()) {
308 t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
309 gpmc_ps_to_ticks(min_gpmc_clk_period +
310 t_rdyo * 1000));
311 t.wr_access = t.access;
312 }
313 } else { 246 } else {
314 t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int, 247 dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
315 t_avdp, t_cer)); 248 dev_t.t_wpl = t_wpl * 1000;
316 t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh); 249 dev_t.t_wph = t_wph * 1000;
317 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl); 250 dev_t.t_aavdh = t_aavdh * 1000;
318 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
319 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
320 if (cpu_is_omap34xx()) {
321 t.wr_data_mux_bus = t.we_on;
322 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
323 }
324 } 251 }
252 dev_t.ce_xdelay = true;
253 dev_t.avd_xdelay = true;
254 dev_t.oe_xdelay = true;
255 dev_t.we_xdelay = true;
256 dev_t.clk = min_gpmc_clk_period;
257 dev_t.t_bacc = dev_t.clk;
258 dev_t.t_ces = t_ces * 1000;
259 dev_t.t_avds = t_avds * 1000;
260 dev_t.t_avdh = t_avdh * 1000;
261 dev_t.t_ach = t_ach * 1000;
262 dev_t.cyc_iaa = (latency + 1);
263 dev_t.t_cez_r = t_cez * 1000;
264 dev_t.t_cez_w = dev_t.t_cez_r;
265 dev_t.cyc_aavdh_oe = 1;
266 dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
267
268 gpmc_calc_timings(&t, &dev_t);
325 269
326 return t; 270 return t;
327} 271}
@@ -338,7 +282,6 @@ static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
338 (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) | 282 (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
339 (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) | 283 (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
340 (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) | 284 (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
341 GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
342 GPMC_CONFIG1_PAGE_LEN(2) | 285 GPMC_CONFIG1_PAGE_LEN(2) |
343 (cpu_is_omap34xx() ? 0 : 286 (cpu_is_omap34xx() ? 0 :
344 (GPMC_CONFIG1_WAIT_READ_MON | 287 (GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 6eed907d594..11d0b756f09 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -58,6 +58,7 @@ static struct platform_device gpmc_smc91x_device = {
58static int smc91c96_gpmc_retime(void) 58static int smc91c96_gpmc_retime(void)
59{ 59{
60 struct gpmc_timings t; 60 struct gpmc_timings t;
61 struct gpmc_device_timings dev_t;
61 const int t3 = 10; /* Figure 12.2 read and 12.4 write */ 62 const int t3 = 10; /* Figure 12.2 read and 12.4 write */
62 const int t4_r = 20; /* Figure 12.2 read */ 63 const int t4_r = 20; /* Figure 12.2 read */
63 const int t4_w = 5; /* Figure 12.4 write */ 64 const int t4_w = 5; /* Figure 12.4 write */
@@ -68,32 +69,6 @@ static int smc91c96_gpmc_retime(void)
68 const int t20 = 185; /* Figure 12.2 read and 12.4 write */ 69 const int t20 = 185; /* Figure 12.2 read and 12.4 write */
69 u32 l; 70 u32 l;
70 71
71 memset(&t, 0, sizeof(t));
72
73 /* Read timings */
74 t.cs_on = 0;
75 t.adv_on = t.cs_on;
76 t.oe_on = t.adv_on + t3;
77 t.access = t.oe_on + t5;
78 t.oe_off = t.access;
79 t.adv_rd_off = t.oe_off + max(t4_r, t6);
80 t.cs_rd_off = t.oe_off;
81 t.rd_cycle = t20 - t.oe_on;
82
83 /* Write timings */
84 t.we_on = t.adv_on + t3;
85
86 if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
87 t.wr_data_mux_bus = t.we_on;
88 t.we_off = t.wr_data_mux_bus + t7;
89 } else
90 t.we_off = t.we_on + t7;
91 if (cpu_is_omap34xx())
92 t.wr_access = t.we_off;
93 t.adv_wr_off = t.we_off + max(t4_w, t8);
94 t.cs_wr_off = t.we_off + t4_w;
95 t.wr_cycle = t20 - t.we_on;
96
97 l = GPMC_CONFIG1_DEVICESIZE_16; 72 l = GPMC_CONFIG1_DEVICESIZE_16;
98 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) 73 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
99 l |= GPMC_CONFIG1_MUXADDDATA; 74 l |= GPMC_CONFIG1_MUXADDDATA;
@@ -115,6 +90,22 @@ static int smc91c96_gpmc_retime(void)
115 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) 90 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
116 return 0; 91 return 0;
117 92
93 memset(&dev_t, 0, sizeof(dev_t));
94
95 dev_t.t_oeasu = t3 * 1000;
96 dev_t.t_oe = t5 * 1000;
97 dev_t.t_cez_r = t4_r * 1000;
98 dev_t.t_oez = t6 * 1000;
99 dev_t.t_rd_cycle = (t20 - t3) * 1000;
100
101 dev_t.t_weasu = t3 * 1000;
102 dev_t.t_wpl = t7 * 1000;
103 dev_t.t_wph = t8 * 1000;
104 dev_t.t_cez_w = t4_w * 1000;
105 dev_t.t_wr_cycle = (t20 - t3) * 1000;
106
107 gpmc_calc_timings(&t, &dev_t);
108
118 return gpmc_cs_set_timings(gpmc_cfg->cs, &t); 109 return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
119} 110}
120 111
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index bf6117c32f4..65468f6d7f0 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -74,6 +74,13 @@
74#define GPMC_ECC_CTRL_ECCREG8 0x008 74#define GPMC_ECC_CTRL_ECCREG8 0x008
75#define GPMC_ECC_CTRL_ECCREG9 0x009 75#define GPMC_ECC_CTRL_ECCREG9 0x009
76 76
77#define GPMC_CONFIG2_CSEXTRADELAY BIT(7)
78#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7)
79#define GPMC_CONFIG4_OEEXTRADELAY BIT(7)
80#define GPMC_CONFIG4_WEEXTRADELAY BIT(23)
81#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6)
82#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7)
83
77#define GPMC_CS0_OFFSET 0x60 84#define GPMC_CS0_OFFSET 0x60
78#define GPMC_CS_SIZE 0x30 85#define GPMC_CS_SIZE 0x30
79#define GPMC_BCH_SIZE 0x10 86#define GPMC_BCH_SIZE 0x10
@@ -223,6 +230,51 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
223 return ticks * gpmc_get_fclk_period() / 1000; 230 return ticks * gpmc_get_fclk_period() / 1000;
224} 231}
225 232
233static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
234{
235 return ticks * gpmc_get_fclk_period();
236}
237
238static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
239{
240 unsigned long ticks = gpmc_ps_to_ticks(time_ps);
241
242 return ticks * gpmc_get_fclk_period();
243}
244
245static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
246{
247 u32 l;
248
249 l = gpmc_cs_read_reg(cs, reg);
250 if (value)
251 l |= mask;
252 else
253 l &= ~mask;
254 gpmc_cs_write_reg(cs, reg, l);
255}
256
257static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
258{
259 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
260 GPMC_CONFIG1_TIME_PARA_GRAN,
261 p->time_para_granularity);
262 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
263 GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
264 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
265 GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
266 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
267 GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
268 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
269 GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
270 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
271 GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
272 p->cycle2cyclesamecsen);
273 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
274 GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN,
275 p->cycle2cyclediffcsen);
276}
277
226#ifdef DEBUG 278#ifdef DEBUG
227static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 279static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
228 int time, const char *name) 280 int time, const char *name)
@@ -316,6 +368,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
316 368
317 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); 369 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
318 370
371 GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
372 GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
373
374 GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
375 GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
376
319 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) 377 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
320 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); 378 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
321 if (gpmc_capability & GPMC_HAS_WR_ACCESS) 379 if (gpmc_capability & GPMC_HAS_WR_ACCESS)
@@ -335,6 +393,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
335 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); 393 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
336 } 394 }
337 395
396 gpmc_cs_bool_timings(cs, &t->bool_timings);
397
338 return 0; 398 return 0;
339} 399}
340 400
@@ -748,6 +808,319 @@ static int __devinit gpmc_mem_init(void)
748 return 0; 808 return 0;
749} 809}
750 810
811static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
812{
813 u32 temp;
814 int div;
815
816 div = gpmc_calc_divider(sync_clk);
817 temp = gpmc_ps_to_ticks(time_ps);
818 temp = (temp + div - 1) / div;
819 return gpmc_ticks_to_ps(temp * div);
820}
821
822/* XXX: can the cycles be avoided ? */
823static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
824 struct gpmc_device_timings *dev_t)
825{
826 bool mux = dev_t->mux;
827 u32 temp;
828
829 /* adv_rd_off */
830 temp = dev_t->t_avdp_r;
831 /* XXX: mux check required ? */
832 if (mux) {
833 /* XXX: t_avdp not to be required for sync, only added for tusb
834 * this indirectly necessitates requirement of t_avdp_r and
835 * t_avdp_w instead of having a single t_avdp
836 */
837 temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh);
838 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
839 }
840 gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
841
842 /* oe_on */
843 temp = dev_t->t_oeasu; /* XXX: remove this ? */
844 if (mux) {
845 temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach);
846 temp = max_t(u32, temp, gpmc_t->adv_rd_off +
847 gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
848 }
849 gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
850
851 /* access */
852 /* XXX: any scope for improvement ?, by combining oe_on
853 * and clk_activation, need to check whether
854 * access = clk_activation + round to sync clk ?
855 */
856 temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk);
857 temp += gpmc_t->clk_activation;
858 if (dev_t->cyc_oe)
859 temp = max_t(u32, temp, gpmc_t->oe_on +
860 gpmc_ticks_to_ps(dev_t->cyc_oe));
861 gpmc_t->access = gpmc_round_ps_to_ticks(temp);
862
863 gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
864 gpmc_t->cs_rd_off = gpmc_t->oe_off;
865
866 /* rd_cycle */
867 temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
868 temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
869 gpmc_t->access;
870 /* XXX: barter t_ce_rdyz with t_cez_r ? */
871 if (dev_t->t_ce_rdyz)
872 temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
873 gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
874
875 return 0;
876}
877
878static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
879 struct gpmc_device_timings *dev_t)
880{
881 bool mux = dev_t->mux;
882 u32 temp;
883
884 /* adv_wr_off */
885 temp = dev_t->t_avdp_w;
886 if (mux) {
887 temp = max_t(u32, temp,
888 gpmc_t->clk_activation + dev_t->t_avdh);
889 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
890 }
891 gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
892
893 /* wr_data_mux_bus */
894 temp = max_t(u32, dev_t->t_weasu,
895 gpmc_t->clk_activation + dev_t->t_rdyo);
896 /* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?,
897 * and in that case remember to handle we_on properly
898 */
899 if (mux) {
900 temp = max_t(u32, temp,
901 gpmc_t->adv_wr_off + dev_t->t_aavdh);
902 temp = max_t(u32, temp, gpmc_t->adv_wr_off +
903 gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
904 }
905 gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
906
907 /* we_on */
908 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
909 gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
910 else
911 gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
912
913 /* wr_access */
914 /* XXX: gpmc_capability check reqd ? , even if not, will not harm */
915 gpmc_t->wr_access = gpmc_t->access;
916
917 /* we_off */
918 temp = gpmc_t->we_on + dev_t->t_wpl;
919 temp = max_t(u32, temp,
920 gpmc_t->wr_access + gpmc_ticks_to_ps(1));
921 temp = max_t(u32, temp,
922 gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
923 gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
924
925 gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
926 dev_t->t_wph);
927
928 /* wr_cycle */
929 temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
930 temp += gpmc_t->wr_access;
931 /* XXX: barter t_ce_rdyz with t_cez_w ? */
932 if (dev_t->t_ce_rdyz)
933 temp = max_t(u32, temp,
934 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
935 gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
936
937 return 0;
938}
939
940static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
941 struct gpmc_device_timings *dev_t)
942{
943 bool mux = dev_t->mux;
944 u32 temp;
945
946 /* adv_rd_off */
947 temp = dev_t->t_avdp_r;
948 if (mux)
949 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
950 gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
951
952 /* oe_on */
953 temp = dev_t->t_oeasu;
954 if (mux)
955 temp = max_t(u32, temp,
956 gpmc_t->adv_rd_off + dev_t->t_aavdh);
957 gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
958
959 /* access */
960 temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */
961 gpmc_t->oe_on + dev_t->t_oe);
962 temp = max_t(u32, temp,
963 gpmc_t->cs_on + dev_t->t_ce);
964 temp = max_t(u32, temp,
965 gpmc_t->adv_on + dev_t->t_aa);
966 gpmc_t->access = gpmc_round_ps_to_ticks(temp);
967
968 gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
969 gpmc_t->cs_rd_off = gpmc_t->oe_off;
970
971 /* rd_cycle */
972 temp = max_t(u32, dev_t->t_rd_cycle,
973 gpmc_t->cs_rd_off + dev_t->t_cez_r);
974 temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
975 gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
976
977 return 0;
978}
979
980static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
981 struct gpmc_device_timings *dev_t)
982{
983 bool mux = dev_t->mux;
984 u32 temp;
985
986 /* adv_wr_off */
987 temp = dev_t->t_avdp_w;
988 if (mux)
989 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
990 gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
991
992 /* wr_data_mux_bus */
993 temp = dev_t->t_weasu;
994 if (mux) {
995 temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh);
996 temp = max_t(u32, temp, gpmc_t->adv_wr_off +
997 gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
998 }
999 gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
1000
1001 /* we_on */
1002 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
1003 gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
1004 else
1005 gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
1006
1007 /* we_off */
1008 temp = gpmc_t->we_on + dev_t->t_wpl;
1009 gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
1010
1011 gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
1012 dev_t->t_wph);
1013
1014 /* wr_cycle */
1015 temp = max_t(u32, dev_t->t_wr_cycle,
1016 gpmc_t->cs_wr_off + dev_t->t_cez_w);
1017 gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
1018
1019 return 0;
1020}
1021
1022static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
1023 struct gpmc_device_timings *dev_t)
1024{
1025 u32 temp;
1026
1027 gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
1028 gpmc_get_fclk_period();
1029
1030 gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
1031 dev_t->t_bacc,
1032 gpmc_t->sync_clk);
1033
1034 temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
1035 gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
1036
1037 if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
1038 return 0;
1039
1040 if (dev_t->ce_xdelay)
1041 gpmc_t->bool_timings.cs_extra_delay = true;
1042 if (dev_t->avd_xdelay)
1043 gpmc_t->bool_timings.adv_extra_delay = true;
1044 if (dev_t->oe_xdelay)
1045 gpmc_t->bool_timings.oe_extra_delay = true;
1046 if (dev_t->we_xdelay)
1047 gpmc_t->bool_timings.we_extra_delay = true;
1048
1049 return 0;
1050}
1051
1052static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
1053 struct gpmc_device_timings *dev_t)
1054{
1055 u32 temp;
1056
1057 /* cs_on */
1058 gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
1059
1060 /* adv_on */
1061 temp = dev_t->t_avdasu;
1062 if (dev_t->t_ce_avd)
1063 temp = max_t(u32, temp,
1064 gpmc_t->cs_on + dev_t->t_ce_avd);
1065 gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
1066
1067 if (dev_t->sync_write || dev_t->sync_read)
1068 gpmc_calc_sync_common_timings(gpmc_t, dev_t);
1069
1070 return 0;
1071}
1072
1073/* TODO: remove this function once all peripherals are confirmed to
1074 * work with generic timing. Simultaneously gpmc_cs_set_timings()
1075 * has to be modified to handle timings in ps instead of ns
1076*/
1077static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
1078{
1079 t->cs_on /= 1000;
1080 t->cs_rd_off /= 1000;
1081 t->cs_wr_off /= 1000;
1082 t->adv_on /= 1000;
1083 t->adv_rd_off /= 1000;
1084 t->adv_wr_off /= 1000;
1085 t->we_on /= 1000;
1086 t->we_off /= 1000;
1087 t->oe_on /= 1000;
1088 t->oe_off /= 1000;
1089 t->page_burst_access /= 1000;
1090 t->access /= 1000;
1091 t->rd_cycle /= 1000;
1092 t->wr_cycle /= 1000;
1093 t->bus_turnaround /= 1000;
1094 t->cycle2cycle_delay /= 1000;
1095 t->wait_monitoring /= 1000;
1096 t->clk_activation /= 1000;
1097 t->wr_access /= 1000;
1098 t->wr_data_mux_bus /= 1000;
1099}
1100
1101int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
1102 struct gpmc_device_timings *dev_t)
1103{
1104 memset(gpmc_t, 0, sizeof(*gpmc_t));
1105
1106 gpmc_calc_common_timings(gpmc_t, dev_t);
1107
1108 if (dev_t->sync_read)
1109 gpmc_calc_sync_read_timings(gpmc_t, dev_t);
1110 else
1111 gpmc_calc_async_read_timings(gpmc_t, dev_t);
1112
1113 if (dev_t->sync_write)
1114 gpmc_calc_sync_write_timings(gpmc_t, dev_t);
1115 else
1116 gpmc_calc_async_write_timings(gpmc_t, dev_t);
1117
1118 /* TODO: remove, see function definition */
1119 gpmc_convert_ps_to_ns(gpmc_t);
1120
1121 return 0;
1122}
1123
751static __devinit int gpmc_probe(struct platform_device *pdev) 1124static __devinit int gpmc_probe(struct platform_device *pdev)
752{ 1125{
753 int rc; 1126 int rc;
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 79f4dfc2adb..fe0a844d500 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -74,6 +74,17 @@
74#define GPMC_IRQ_COUNT_EVENT 0x02 74#define GPMC_IRQ_COUNT_EVENT 0x02
75 75
76 76
77/* bool type time settings */
78struct gpmc_bool_timings {
79 bool cycle2cyclediffcsen;
80 bool cycle2cyclesamecsen;
81 bool we_extra_delay;
82 bool oe_extra_delay;
83 bool adv_extra_delay;
84 bool cs_extra_delay;
85 bool time_para_granularity;
86};
87
77/* 88/*
78 * Note that all values in this struct are in nanoseconds except sync_clk 89 * Note that all values in this struct are in nanoseconds except sync_clk
79 * (which is in picoseconds), while the register values are in gpmc_fck cycles. 90 * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -83,34 +94,104 @@ struct gpmc_timings {
83 u32 sync_clk; 94 u32 sync_clk;
84 95
85 /* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */ 96 /* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
86 u16 cs_on; /* Assertion time */ 97 u32 cs_on; /* Assertion time */
87 u16 cs_rd_off; /* Read deassertion time */ 98 u32 cs_rd_off; /* Read deassertion time */
88 u16 cs_wr_off; /* Write deassertion time */ 99 u32 cs_wr_off; /* Write deassertion time */
89 100
90 /* ADV signal timings corresponding to GPMC_CONFIG3 */ 101 /* ADV signal timings corresponding to GPMC_CONFIG3 */
91 u16 adv_on; /* Assertion time */ 102 u32 adv_on; /* Assertion time */
92 u16 adv_rd_off; /* Read deassertion time */ 103 u32 adv_rd_off; /* Read deassertion time */
93 u16 adv_wr_off; /* Write deassertion time */ 104 u32 adv_wr_off; /* Write deassertion time */
94 105
95 /* WE signals timings corresponding to GPMC_CONFIG4 */ 106 /* WE signals timings corresponding to GPMC_CONFIG4 */
96 u16 we_on; /* WE assertion time */ 107 u32 we_on; /* WE assertion time */
97 u16 we_off; /* WE deassertion time */ 108 u32 we_off; /* WE deassertion time */
98 109
99 /* OE signals timings corresponding to GPMC_CONFIG4 */ 110 /* OE signals timings corresponding to GPMC_CONFIG4 */
100 u16 oe_on; /* OE assertion time */ 111 u32 oe_on; /* OE assertion time */
101 u16 oe_off; /* OE deassertion time */ 112 u32 oe_off; /* OE deassertion time */
102 113
103 /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */ 114 /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
104 u16 page_burst_access; /* Multiple access word delay */ 115 u32 page_burst_access; /* Multiple access word delay */
105 u16 access; /* Start-cycle to first data valid delay */ 116 u32 access; /* Start-cycle to first data valid delay */
106 u16 rd_cycle; /* Total read cycle time */ 117 u32 rd_cycle; /* Total read cycle time */
107 u16 wr_cycle; /* Total write cycle time */ 118 u32 wr_cycle; /* Total write cycle time */
119
120 u32 bus_turnaround;
121 u32 cycle2cycle_delay;
122
123 u32 wait_monitoring;
124 u32 clk_activation;
108 125
109 /* The following are only on OMAP3430 */ 126 /* The following are only on OMAP3430 */
110 u16 wr_access; /* WRACCESSTIME */ 127 u32 wr_access; /* WRACCESSTIME */
111 u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ 128 u32 wr_data_mux_bus; /* WRDATAONADMUXBUS */
129
130 struct gpmc_bool_timings bool_timings;
131};
132
133/* Device timings in picoseconds */
134struct gpmc_device_timings {
135 u32 t_ceasu; /* address setup to CS valid */
136 u32 t_avdasu; /* address setup to ADV valid */
137 /* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
138 * of tusb using these timings even for sync whilst
139 * ideally for adv_rd/(wr)_off it should have considered
140 * t_avdh instead. This indirectly necessitates r/w
141 * variations of t_avdp as it is possible to have one
142 * sync & other async
143 */
144 u32 t_avdp_r; /* ADV low time (what about t_cer ?) */
145 u32 t_avdp_w;
146 u32 t_aavdh; /* address hold time */
147 u32 t_oeasu; /* address setup to OE valid */
148 u32 t_aa; /* access time from ADV assertion */
149 u32 t_iaa; /* initial access time */
150 u32 t_oe; /* access time from OE assertion */
151 u32 t_ce; /* access time from CS asertion */
152 u32 t_rd_cycle; /* read cycle time */
153 u32 t_cez_r; /* read CS deassertion to high Z */
154 u32 t_cez_w; /* write CS deassertion to high Z */
155 u32 t_oez; /* OE deassertion to high Z */
156 u32 t_weasu; /* address setup to WE valid */
157 u32 t_wpl; /* write assertion time */
158 u32 t_wph; /* write deassertion time */
159 u32 t_wr_cycle; /* write cycle time */
160
161 u32 clk;
162 u32 t_bacc; /* burst access valid clock to output delay */
163 u32 t_ces; /* CS setup time to clk */
164 u32 t_avds; /* ADV setup time to clk */
165 u32 t_avdh; /* ADV hold time from clk */
166 u32 t_ach; /* address hold time from clk */
167 u32 t_rdyo; /* clk to ready valid */
168
169 u32 t_ce_rdyz; /* XXX: description ?, or use t_cez instead */
170 u32 t_ce_avd; /* CS on to ADV on delay */
171
172 /* XXX: check the possibility of combining
173 * cyc_aavhd_oe & cyc_aavdh_we
174 */
175 u8 cyc_aavdh_oe;/* read address hold time in cycles */
176 u8 cyc_aavdh_we;/* write address hold time in cycles */
177 u8 cyc_oe; /* access time from OE assertion in cycles */
178 u8 cyc_wpl; /* write deassertion time in cycles */
179 u32 cyc_iaa; /* initial access time in cycles */
180
181 bool mux; /* address & data muxed */
182 bool sync_write;/* synchronous write */
183 bool sync_read; /* synchronous read */
184
185 /* extra delays */
186 bool ce_xdelay;
187 bool avd_xdelay;
188 bool oe_xdelay;
189 bool we_xdelay;
112}; 190};
113 191
192extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
193 struct gpmc_device_timings *dev_t);
194
114extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); 195extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
115extern int gpmc_get_client_irq(unsigned irq_config); 196extern int gpmc_get_client_irq(unsigned irq_config);
116 197
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index a8795ff19e6..c5a3c6f9504 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -27,180 +27,88 @@ static u8 async_cs, sync_cs;
27static unsigned refclk_psec; 27static unsigned refclk_psec;
28 28
29 29
30/* t2_ps, when quantized to fclk units, must happen no earlier than
31 * the clock after after t1_NS.
32 *
33 * Return a possibly updated value of t2_ps, converted to nsec.
34 */
35static unsigned
36next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
37{
38 unsigned t1_ps = t1_NS * 1000;
39 unsigned t1_f, t2_f;
40
41 if ((t1_ps + fclk_ps) < t2_ps)
42 return t2_ps / 1000;
43
44 t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
45 t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
46
47 if (t1_f >= t2_f)
48 t2_f = t1_f + 1;
49
50 return (t2_f * fclk_ps) / 1000;
51}
52
53/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ 30/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
54 31
55static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps) 32static int tusb_set_async_mode(unsigned sysclk_ps)
56{ 33{
34 struct gpmc_device_timings dev_t;
57 struct gpmc_timings t; 35 struct gpmc_timings t;
58 unsigned t_acsnh_advnh = sysclk_ps + 3000; 36 unsigned t_acsnh_advnh = sysclk_ps + 3000;
59 unsigned tmp;
60
61 memset(&t, 0, sizeof(t));
62
63 /* CS_ON = t_acsnh_acsnl */
64 t.cs_on = 8;
65 /* ADV_ON = t_acsnh_advnh - t_advn */
66 t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
67
68 /*
69 * READ ... from omap2420 TRM fig 12-13
70 */
71
72 /* ADV_RD_OFF = t_acsnh_advnh */
73 t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
74
75 /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
76 t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
77
78 /* ACCESS = counters continue only after nRDY */
79 tmp = t.oe_on * 1000 + 300;
80 t.access = next_clk(t.oe_on, tmp, fclk_ps);
81
82 /* OE_OFF = after data gets sampled */
83 tmp = t.access * 1000;
84 t.oe_off = next_clk(t.access, tmp, fclk_ps);
85
86 t.cs_rd_off = t.oe_off;
87
88 tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
89 t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
90
91 /*
92 * WRITE ... from omap2420 TRM fig 12-15
93 */
94
95 /* ADV_WR_OFF = t_acsnh_advnh */
96 t.adv_wr_off = t.adv_rd_off;
97 37
98 /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */ 38 memset(&dev_t, 0, sizeof(dev_t));
99 t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
100 39
101 /* WE_OFF = after data gets sampled */ 40 dev_t.mux = true;
102 tmp = t.we_on * 1000 + 300;
103 t.we_off = next_clk(t.we_on, tmp, fclk_ps);
104 41
105 t.cs_wr_off = t.we_off; 42 dev_t.t_ceasu = 8 * 1000;
43 dev_t.t_avdasu = t_acsnh_advnh - 7000;
44 dev_t.t_ce_avd = 1000;
45 dev_t.t_avdp_r = t_acsnh_advnh;
46 dev_t.t_oeasu = t_acsnh_advnh + 1000;
47 dev_t.t_oe = 300;
48 dev_t.t_cez_r = 7000;
49 dev_t.t_cez_w = dev_t.t_cez_r;
50 dev_t.t_avdp_w = t_acsnh_advnh;
51 dev_t.t_weasu = t_acsnh_advnh + 1000;
52 dev_t.t_wpl = 300;
53 dev_t.cyc_aavdh_we = 1;
106 54
107 tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */; 55 gpmc_calc_timings(&t, &dev_t);
108 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
109 56
110 return gpmc_cs_set_timings(async_cs, &t); 57 return gpmc_cs_set_timings(async_cs, &t);
111} 58}
112 59
113static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps) 60static int tusb_set_sync_mode(unsigned sysclk_ps)
114{ 61{
62 struct gpmc_device_timings dev_t;
115 struct gpmc_timings t; 63 struct gpmc_timings t;
116 unsigned t_scsnh_advnh = sysclk_ps + 3000; 64 unsigned t_scsnh_advnh = sysclk_ps + 3000;
117 unsigned tmp;
118
119 memset(&t, 0, sizeof(t));
120 t.cs_on = 8;
121
122 /* ADV_ON = t_acsnh_advnh - t_advn */
123 t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
124
125 /* GPMC_CLK rate = fclk rate / div */
126 t.sync_clk = 11100 /* 11.1 nsec */;
127 tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
128 if (tmp > 4)
129 return -ERANGE;
130 if (tmp == 0)
131 tmp = 1;
132 t.page_burst_access = (fclk_ps * tmp) / 1000;
133
134 /*
135 * READ ... based on omap2420 TRM fig 12-19, 12-20
136 */
137
138 /* ADV_RD_OFF = t_scsnh_advnh */
139 t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
140
141 /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
142 tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
143 t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
144
145 /* ACCESS = number of clock cycles after t_adv_eon */
146 tmp = (t.oe_on * 1000) + (5 * fclk_ps);
147 t.access = next_clk(t.oe_on, tmp, fclk_ps);
148 65
149 /* OE_OFF = after data gets sampled */ 66 memset(&dev_t, 0, sizeof(dev_t));
150 tmp = (t.access * 1000) + (1 * fclk_ps); 67
151 t.oe_off = next_clk(t.access, tmp, fclk_ps); 68 dev_t.mux = true;
152 69 dev_t.sync_read = true;
153 t.cs_rd_off = t.oe_off; 70 dev_t.sync_write = true;
154 71
155 tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */; 72 dev_t.clk = 11100;
156 t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps); 73 dev_t.t_bacc = 1000;
157 74 dev_t.t_ces = 1000;
158 /* 75 dev_t.t_ceasu = 8 * 1000;
159 * WRITE ... based on omap2420 TRM fig 12-21 76 dev_t.t_avdasu = t_scsnh_advnh - 7000;
160 */ 77 dev_t.t_ce_avd = 1000;
161 78 dev_t.t_avdp_r = t_scsnh_advnh;
162 /* ADV_WR_OFF = t_scsnh_advnh */ 79 dev_t.cyc_aavdh_oe = 3;
163 t.adv_wr_off = t.adv_rd_off; 80 dev_t.cyc_oe = 5;
164 81 dev_t.t_ce_rdyz = 7000;
165 /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */ 82 dev_t.t_avdp_w = t_scsnh_advnh;
166 tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps); 83 dev_t.cyc_aavdh_we = 3;
167 t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps); 84 dev_t.cyc_wpl = 6;
168 85 dev_t.t_ce_rdyz = 7000;
169 /* WE_OFF = number of clock cycles after t_adv_wen */ 86
170 tmp = (t.we_on * 1000) + (6 * fclk_ps); 87 gpmc_calc_timings(&t, &dev_t);
171 t.we_off = next_clk(t.we_on, tmp, fclk_ps);
172
173 t.cs_wr_off = t.we_off;
174
175 tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
176 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
177 88
178 return gpmc_cs_set_timings(sync_cs, &t); 89 return gpmc_cs_set_timings(sync_cs, &t);
179} 90}
180 91
181extern unsigned long gpmc_get_fclk_period(void);
182
183/* tusb driver calls this when it changes the chip's clocking */ 92/* tusb driver calls this when it changes the chip's clocking */
184int tusb6010_platform_retime(unsigned is_refclk) 93int tusb6010_platform_retime(unsigned is_refclk)
185{ 94{
186 static const char error[] = 95 static const char error[] =
187 KERN_ERR "tusb6010 %s retime error %d\n"; 96 KERN_ERR "tusb6010 %s retime error %d\n";
188 97
189 unsigned fclk_ps = gpmc_get_fclk_period();
190 unsigned sysclk_ps; 98 unsigned sysclk_ps;
191 int status; 99 int status;
192 100
193 if (!refclk_psec || fclk_ps == 0) 101 if (!refclk_psec)
194 return -ENODEV; 102 return -ENODEV;
195 103
196 sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; 104 sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
197 105
198 status = tusb_set_async_mode(sysclk_ps, fclk_ps); 106 status = tusb_set_async_mode(sysclk_ps);
199 if (status < 0) { 107 if (status < 0) {
200 printk(error, "async", status); 108 printk(error, "async", status);
201 goto done; 109 goto done;
202 } 110 }
203 status = tusb_set_sync_mode(sysclk_ps, fclk_ps); 111 status = tusb_set_sync_mode(sysclk_ps);
204 if (status < 0) 112 if (status < 0)
205 printk(error, "sync", status); 113 printk(error, "sync", status);
206done: 114done:
@@ -284,7 +192,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
284 | GPMC_CONFIG1_READTYPE_SYNC 192 | GPMC_CONFIG1_READTYPE_SYNC
285 | GPMC_CONFIG1_WRITEMULTIPLE_SUPP 193 | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
286 | GPMC_CONFIG1_WRITETYPE_SYNC 194 | GPMC_CONFIG1_WRITETYPE_SYNC
287 | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
288 | GPMC_CONFIG1_PAGE_LEN(2) 195 | GPMC_CONFIG1_PAGE_LEN(2)
289 | GPMC_CONFIG1_WAIT_READ_MON 196 | GPMC_CONFIG1_WAIT_READ_MON
290 | GPMC_CONFIG1_WAIT_WRITE_MON 197 | GPMC_CONFIG1_WAIT_WRITE_MON
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index c34d4efd0d5..0a3f30df1eb 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -33,8 +33,6 @@ BIAS(in_nopull, PIN_INPUT_NOPULL);
33BIAS(in_nopull_slpm_nowkup, PIN_INPUT_NOPULL|PIN_SLPM_WAKEUP_DISABLE); 33BIAS(in_nopull_slpm_nowkup, PIN_INPUT_NOPULL|PIN_SLPM_WAKEUP_DISABLE);
34BIAS(in_pu, PIN_INPUT_PULLUP); 34BIAS(in_pu, PIN_INPUT_PULLUP);
35BIAS(in_pd, PIN_INPUT_PULLDOWN); 35BIAS(in_pd, PIN_INPUT_PULLDOWN);
36BIAS(in_pd_slpm_in_pu, PIN_INPUT_PULLDOWN|PIN_SLPM_INPUT_PULLUP);
37BIAS(in_pu_slpm_out_lo, PIN_INPUT_PULLUP|PIN_SLPM_OUTPUT_LOW);
38BIAS(out_hi, PIN_OUTPUT_HIGH); 36BIAS(out_hi, PIN_OUTPUT_HIGH);
39BIAS(out_lo, PIN_OUTPUT_LOW); 37BIAS(out_lo, PIN_OUTPUT_LOW);
40BIAS(out_lo_slpm_nowkup, PIN_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE); 38BIAS(out_lo_slpm_nowkup, PIN_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE);
@@ -46,14 +44,34 @@ BIAS(gpio_in_pd_slpm_gpio_nopull, PIN_INPUT_PULLDOWN|PIN_GPIOMODE_ENABLED|PIN_SL
46BIAS(gpio_out_hi, PIN_OUTPUT_HIGH|PIN_GPIOMODE_ENABLED); 44BIAS(gpio_out_hi, PIN_OUTPUT_HIGH|PIN_GPIOMODE_ENABLED);
47BIAS(gpio_out_lo, PIN_OUTPUT_LOW|PIN_GPIOMODE_ENABLED); 45BIAS(gpio_out_lo, PIN_OUTPUT_LOW|PIN_GPIOMODE_ENABLED);
48/* Sleep modes */ 46/* Sleep modes */
49BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED); 47BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|
50BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE); 48 PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE);
51BIAS(slpm_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED); 49BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|
52BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED); 50 PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
53BIAS(slpm_out_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED); 51BIAS(slpm_wkup_pdis, PIN_SLEEPMODE_ENABLED|
54BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE); 52 PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
55BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED); 53BIAS(slpm_out_lo_pdis, PIN_SLEEPMODE_ENABLED|
56BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_NOPULL|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED); 54 PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE|PIN_SLPM_PDIS_DISABLED);
55BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|
56 PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE);
57BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|
58 PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
59BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|
60 PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
61BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|
62 PIN_SLPM_INPUT_NOPULL|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
63BIAS(slpm_in_pu_wkup_pdis_en, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_PULLUP|
64 PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_ENABLED);
65BIAS(slpm_out_wkup_pdis, PIN_SLEEPMODE_ENABLED|
66 PIN_SLPM_DIR_OUTPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
67BIAS(out_lo_wkup_pdis, PIN_SLPM_OUTPUT_LOW|
68 PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
69BIAS(in_wkup_pdis_en, PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|
70 PIN_SLPM_PDIS_ENABLED);
71BIAS(in_wkup_pdis, PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|
72 PIN_SLPM_PDIS_DISABLED);
73BIAS(out_wkup_pdis, PIN_SLPM_DIR_OUTPUT|PIN_SLPM_WAKEUP_ENABLE|
74 PIN_SLPM_PDIS_DISABLED);
57 75
58/* We use these to define hog settings that are always done on boot */ 76/* We use these to define hog settings that are always done on boot */
59#define DB8500_MUX_HOG(group,func) \ 77#define DB8500_MUX_HOG(group,func) \
@@ -69,13 +87,16 @@ BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_NOPULL|PIN_S
69 PIN_MAP_MUX_GROUP_DEFAULT(dev, "pinctrl-db8500", group, func) 87 PIN_MAP_MUX_GROUP_DEFAULT(dev, "pinctrl-db8500", group, func)
70#define DB8500_PIN(pin,conf,dev) \ 88#define DB8500_PIN(pin,conf,dev) \
71 PIN_MAP_CONFIGS_PIN_DEFAULT(dev, "pinctrl-db8500", pin, conf) 89 PIN_MAP_CONFIGS_PIN_DEFAULT(dev, "pinctrl-db8500", pin, conf)
72#define DB8500_PIN_SLEEP(pin, conf, dev) \ 90#define DB8500_PIN_IDLE(pin, conf, dev) \
73 PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500", \ 91 PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_IDLE, "pinctrl-db8500", \
74 pin, conf) 92 pin, conf)
75 93#define DB8500_PIN_SLEEP(pin, conf, dev) \
76#define DB8500_PIN_SLEEP(pin,conf,dev) \
77 PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500", \ 94 PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500", \
78 pin, conf) 95 pin, conf)
96#define DB8500_MUX_STATE(group, func, dev, state) \
97 PIN_MAP_MUX_GROUP(dev, state, "pinctrl-db8500", group, func)
98#define DB8500_PIN_STATE(pin, conf, dev, state) \
99 PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-db8500", pin, conf)
79 100
80/* Pin control settings */ 101/* Pin control settings */
81static struct pinctrl_map __initdata mop500_family_pinmap[] = { 102static struct pinctrl_map __initdata mop500_family_pinmap[] = {
@@ -112,7 +133,7 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
112 * UART0, we do not mux in u0 here. 133 * UART0, we do not mux in u0 here.
113 * uart-0 pins gpio configuration should be kept intact to prevent 134 * uart-0 pins gpio configuration should be kept intact to prevent
114 * a glitch in tx line when the tty dev is opened. Later these pins 135 * a glitch in tx line when the tty dev is opened. Later these pins
115 * are configured to uart mop500_pins_uart0 136 * are configured by uart driver
116 */ 137 */
117 DB8500_PIN_HOG("GPIO0_AJ5", in_pu), /* CTS */ 138 DB8500_PIN_HOG("GPIO0_AJ5", in_pu), /* CTS */
118 DB8500_PIN_HOG("GPIO1_AJ3", out_hi), /* RTS */ 139 DB8500_PIN_HOG("GPIO1_AJ3", out_hi), /* RTS */
@@ -123,12 +144,13 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
123 * TODO: is this used on U8500 variants and Snowball really? 144 * TODO: is this used on U8500 variants and Snowball really?
124 * The setting on GPIO31 conflicts with magnetometer use on hrefv60 145 * The setting on GPIO31 conflicts with magnetometer use on hrefv60
125 */ 146 */
126 DB8500_MUX_HOG("u2rxtx_c_1", "u2"), 147 /* default state for UART2 */
127 DB8500_MUX_HOG("u2ctsrts_c_1", "u2"), 148 DB8500_MUX("u2rxtx_c_1", "u2", "uart2"),
128 DB8500_PIN_HOG("GPIO29_W2", in_pu), /* RXD */ 149 DB8500_PIN("GPIO29_W2", in_pu, "uart2"), /* RXD */
129 DB8500_PIN_HOG("GPIO30_W3", out_hi), /* TXD */ 150 DB8500_PIN("GPIO30_W3", out_hi, "uart2"), /* TXD */
130 DB8500_PIN_HOG("GPIO31_V3", in_pu), /* CTS */ 151 /* Sleep state for UART2 */
131 DB8500_PIN_HOG("GPIO32_V2", out_hi), /* RTS */ 152 DB8500_PIN_SLEEP("GPIO29_W2", in_wkup_pdis, "uart2"),
153 DB8500_PIN_SLEEP("GPIO30_W3", out_wkup_pdis, "uart2"),
132 /* 154 /*
133 * The following pin sets were known as "runtime pins" before being 155 * The following pin sets were known as "runtime pins" before being
134 * converted to the pinctrl model. Here we model them as "default" 156 * converted to the pinctrl model. Here we model them as "default"
@@ -140,11 +162,18 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
140 DB8500_PIN("GPIO1_AJ3", out_hi, "uart0"), /* RTS */ 162 DB8500_PIN("GPIO1_AJ3", out_hi, "uart0"), /* RTS */
141 DB8500_PIN("GPIO2_AH4", in_pu, "uart0"), /* RXD */ 163 DB8500_PIN("GPIO2_AH4", in_pu, "uart0"), /* RXD */
142 DB8500_PIN("GPIO3_AH3", out_hi, "uart0"), /* TXD */ 164 DB8500_PIN("GPIO3_AH3", out_hi, "uart0"), /* TXD */
143 /* UART0 sleep state */ 165 /* Sleep state for UART0 */
144 DB8500_PIN_SLEEP("GPIO0_AJ5", slpm_in_wkup_pdis, "uart0"), 166 DB8500_PIN_SLEEP("GPIO0_AJ5", slpm_in_wkup_pdis, "uart0"),
145 DB8500_PIN_SLEEP("GPIO1_AJ3", slpm_out_hi_wkup_pdis, "uart0"), 167 DB8500_PIN_SLEEP("GPIO1_AJ3", slpm_out_hi_wkup_pdis, "uart0"),
146 DB8500_PIN_SLEEP("GPIO2_AH4", slpm_in_wkup_pdis, "uart0"), 168 DB8500_PIN_SLEEP("GPIO2_AH4", slpm_in_wkup_pdis, "uart0"),
147 DB8500_PIN_SLEEP("GPIO3_AH3", slpm_out_wkup_pdis, "uart0"), 169 DB8500_PIN_SLEEP("GPIO3_AH3", slpm_out_wkup_pdis, "uart0"),
170 /* Mux in UART1 after initialization */
171 DB8500_MUX("u1rxtx_a_1", "u1", "uart1"),
172 DB8500_PIN("GPIO4_AH6", in_pu, "uart1"), /* RXD */
173 DB8500_PIN("GPIO5_AG6", out_hi, "uart1"), /* TXD */
174 /* Sleep state for UART1 */
175 DB8500_PIN_SLEEP("GPIO4_AH6", slpm_in_wkup_pdis, "uart1"),
176 DB8500_PIN_SLEEP("GPIO5_AG6", slpm_out_wkup_pdis, "uart1"),
148 /* MSP1 for ALSA codec */ 177 /* MSP1 for ALSA codec */
149 DB8500_MUX("msp1txrx_a_1", "msp1", "ux500-msp-i2s.1"), 178 DB8500_MUX("msp1txrx_a_1", "msp1", "ux500-msp-i2s.1"),
150 DB8500_MUX("msp1_a_1", "msp1", "ux500-msp-i2s.1"), 179 DB8500_MUX("msp1_a_1", "msp1", "ux500-msp-i2s.1"),
@@ -161,7 +190,10 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
161 DB8500_MUX("lcd_d8_d11_a_1", "lcd", "mcde-tvout"), 190 DB8500_MUX("lcd_d8_d11_a_1", "lcd", "mcde-tvout"),
162 DB8500_MUX("lcdaclk_b_1", "lcda", "mcde-tvout"), 191 DB8500_MUX("lcdaclk_b_1", "lcda", "mcde-tvout"),
163 /* Mux in LCD VSI1 and pull it up for MCDE HDMI output */ 192 /* Mux in LCD VSI1 and pull it up for MCDE HDMI output */
164 DB8500_MUX("lcdvsi1_a_1", "lcd", "av8100-hdmi"), 193 DB8500_MUX("lcdvsi1_a_1", "lcd", "0-0070"),
194 DB8500_PIN("GPIO69_E2", in_pu, "0-0070"),
195 /* LCD VSI1 sleep state */
196 DB8500_PIN_SLEEP("GPIO69_E2", slpm_in_wkup_pdis, "0-0070"),
165 /* Mux in i2c0 block, default state */ 197 /* Mux in i2c0 block, default state */
166 DB8500_MUX("i2c0_a_1", "i2c0", "nmk-i2c.0"), 198 DB8500_MUX("i2c0_a_1", "i2c0", "nmk-i2c.0"),
167 /* i2c0 sleep state */ 199 /* i2c0 sleep state */
@@ -194,6 +226,18 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
194 DB8500_PIN("GPIO26_Y2", in_pu, "sdi0"), /* DAT1 */ 226 DB8500_PIN("GPIO26_Y2", in_pu, "sdi0"), /* DAT1 */
195 DB8500_PIN("GPIO27_AA2", in_pu, "sdi0"), /* DAT2 */ 227 DB8500_PIN("GPIO27_AA2", in_pu, "sdi0"), /* DAT2 */
196 DB8500_PIN("GPIO28_AA1", in_pu, "sdi0"), /* DAT3 */ 228 DB8500_PIN("GPIO28_AA1", in_pu, "sdi0"), /* DAT3 */
229 /* SDI0 sleep state */
230 DB8500_PIN_SLEEP("GPIO18_AC2", slpm_out_hi_wkup_pdis, "sdi0"),
231 DB8500_PIN_SLEEP("GPIO19_AC1", slpm_out_hi_wkup_pdis, "sdi0"),
232 DB8500_PIN_SLEEP("GPIO20_AB4", slpm_out_hi_wkup_pdis, "sdi0"),
233 DB8500_PIN_SLEEP("GPIO22_AA3", slpm_in_wkup_pdis, "sdi0"),
234 DB8500_PIN_SLEEP("GPIO23_AA4", slpm_out_lo_wkup_pdis, "sdi0"),
235 DB8500_PIN_SLEEP("GPIO24_AB2", slpm_in_wkup_pdis, "sdi0"),
236 DB8500_PIN_SLEEP("GPIO25_Y4", slpm_in_wkup_pdis, "sdi0"),
237 DB8500_PIN_SLEEP("GPIO26_Y2", slpm_in_wkup_pdis, "sdi0"),
238 DB8500_PIN_SLEEP("GPIO27_AA2", slpm_in_wkup_pdis, "sdi0"),
239 DB8500_PIN_SLEEP("GPIO28_AA1", slpm_in_wkup_pdis, "sdi0"),
240
197 /* Mux in SDI1 (here called MC1) used for SDIO for CW1200 WLAN */ 241 /* Mux in SDI1 (here called MC1) used for SDIO for CW1200 WLAN */
198 DB8500_MUX("mc1_a_1", "mc1", "sdi1"), 242 DB8500_MUX("mc1_a_1", "mc1", "sdi1"),
199 DB8500_PIN("GPIO208_AH16", out_lo, "sdi1"), /* CLK */ 243 DB8500_PIN("GPIO208_AH16", out_lo, "sdi1"), /* CLK */
@@ -203,6 +247,15 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
203 DB8500_PIN("GPIO212_AF13", in_pu, "sdi1"), /* DAT1 */ 247 DB8500_PIN("GPIO212_AF13", in_pu, "sdi1"), /* DAT1 */
204 DB8500_PIN("GPIO213_AG13", in_pu, "sdi1"), /* DAT2 */ 248 DB8500_PIN("GPIO213_AG13", in_pu, "sdi1"), /* DAT2 */
205 DB8500_PIN("GPIO214_AH15", in_pu, "sdi1"), /* DAT3 */ 249 DB8500_PIN("GPIO214_AH15", in_pu, "sdi1"), /* DAT3 */
250 /* SDI1 sleep state */
251 DB8500_PIN_SLEEP("GPIO208_AH16", slpm_out_lo_wkup_pdis, "sdi1"), /* CLK */
252 DB8500_PIN_SLEEP("GPIO209_AG15", slpm_in_wkup_pdis, "sdi1"), /* FBCLK */
253 DB8500_PIN_SLEEP("GPIO210_AJ15", slpm_in_wkup_pdis, "sdi1"), /* CMD */
254 DB8500_PIN_SLEEP("GPIO211_AG14", slpm_in_wkup_pdis, "sdi1"), /* DAT0 */
255 DB8500_PIN_SLEEP("GPIO212_AF13", slpm_in_wkup_pdis, "sdi1"), /* DAT1 */
256 DB8500_PIN_SLEEP("GPIO213_AG13", slpm_in_wkup_pdis, "sdi1"), /* DAT2 */
257 DB8500_PIN_SLEEP("GPIO214_AH15", slpm_in_wkup_pdis, "sdi1"), /* DAT3 */
258
206 /* Mux in SDI2 (here called MC2) used for for PoP eMMC */ 259 /* Mux in SDI2 (here called MC2) used for for PoP eMMC */
207 DB8500_MUX("mc2_a_1", "mc2", "sdi2"), 260 DB8500_MUX("mc2_a_1", "mc2", "sdi2"),
208 DB8500_PIN("GPIO128_A5", out_lo, "sdi2"), /* CLK */ 261 DB8500_PIN("GPIO128_A5", out_lo, "sdi2"), /* CLK */
@@ -216,6 +269,19 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
216 DB8500_PIN("GPIO136_C7", in_pu, "sdi2"), /* DAT5 */ 269 DB8500_PIN("GPIO136_C7", in_pu, "sdi2"), /* DAT5 */
217 DB8500_PIN("GPIO137_A7", in_pu, "sdi2"), /* DAT6 */ 270 DB8500_PIN("GPIO137_A7", in_pu, "sdi2"), /* DAT6 */
218 DB8500_PIN("GPIO138_C5", in_pu, "sdi2"), /* DAT7 */ 271 DB8500_PIN("GPIO138_C5", in_pu, "sdi2"), /* DAT7 */
272 /* SDI2 sleep state */
273 DB8500_PIN_SLEEP("GPIO128_A5", out_lo_wkup_pdis, "sdi2"), /* CLK */
274 DB8500_PIN_SLEEP("GPIO129_B4", in_wkup_pdis_en, "sdi2"), /* CMD */
275 DB8500_PIN_SLEEP("GPIO130_C8", in_wkup_pdis_en, "sdi2"), /* FBCLK */
276 DB8500_PIN_SLEEP("GPIO131_A12", in_wkup_pdis, "sdi2"), /* DAT0 */
277 DB8500_PIN_SLEEP("GPIO132_C10", in_wkup_pdis, "sdi2"), /* DAT1 */
278 DB8500_PIN_SLEEP("GPIO133_B10", in_wkup_pdis, "sdi2"), /* DAT2 */
279 DB8500_PIN_SLEEP("GPIO134_B9", in_wkup_pdis, "sdi2"), /* DAT3 */
280 DB8500_PIN_SLEEP("GPIO135_A9", in_wkup_pdis, "sdi2"), /* DAT4 */
281 DB8500_PIN_SLEEP("GPIO136_C7", in_wkup_pdis, "sdi2"), /* DAT5 */
282 DB8500_PIN_SLEEP("GPIO137_A7", in_wkup_pdis, "sdi2"), /* DAT6 */
283 DB8500_PIN_SLEEP("GPIO138_C5", in_wkup_pdis, "sdi2"), /* DAT7 */
284
219 /* Mux in SDI4 (here called MC4) used for for PCB-mounted eMMC */ 285 /* Mux in SDI4 (here called MC4) used for for PCB-mounted eMMC */
220 DB8500_MUX("mc4_a_1", "mc4", "sdi4"), 286 DB8500_MUX("mc4_a_1", "mc4", "sdi4"),
221 DB8500_PIN("GPIO197_AH24", in_pu, "sdi4"), /* DAT3 */ 287 DB8500_PIN("GPIO197_AH24", in_pu, "sdi4"), /* DAT3 */
@@ -229,6 +295,19 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
229 DB8500_PIN("GPIO205_AG23", in_pu, "sdi4"), /* DAT6 */ 295 DB8500_PIN("GPIO205_AG23", in_pu, "sdi4"), /* DAT6 */
230 DB8500_PIN("GPIO206_AG24", in_pu, "sdi4"), /* DAT5 */ 296 DB8500_PIN("GPIO206_AG24", in_pu, "sdi4"), /* DAT5 */
231 DB8500_PIN("GPIO207_AJ23", in_pu, "sdi4"), /* DAT4 */ 297 DB8500_PIN("GPIO207_AJ23", in_pu, "sdi4"), /* DAT4 */
298 /*SDI4 sleep state */
299 DB8500_PIN_SLEEP("GPIO197_AH24", slpm_in_wkup_pdis, "sdi4"), /* DAT3 */
300 DB8500_PIN_SLEEP("GPIO198_AG25", slpm_in_wkup_pdis, "sdi4"), /* DAT2 */
301 DB8500_PIN_SLEEP("GPIO199_AH23", slpm_in_wkup_pdis, "sdi4"), /* DAT1 */
302 DB8500_PIN_SLEEP("GPIO200_AH26", slpm_in_wkup_pdis, "sdi4"), /* DAT0 */
303 DB8500_PIN_SLEEP("GPIO201_AF24", slpm_in_wkup_pdis, "sdi4"), /* CMD */
304 DB8500_PIN_SLEEP("GPIO202_AF25", slpm_in_wkup_pdis, "sdi4"), /* FBCLK */
305 DB8500_PIN_SLEEP("GPIO203_AE23", slpm_out_lo_wkup_pdis, "sdi4"), /* CLK */
306 DB8500_PIN_SLEEP("GPIO204_AF23", slpm_in_wkup_pdis, "sdi4"), /* DAT7 */
307 DB8500_PIN_SLEEP("GPIO205_AG23", slpm_in_wkup_pdis, "sdi4"), /* DAT6 */
308 DB8500_PIN_SLEEP("GPIO206_AG24", slpm_in_wkup_pdis, "sdi4"), /* DAT5 */
309 DB8500_PIN_SLEEP("GPIO207_AJ23", slpm_in_wkup_pdis, "sdi4"), /* DAT4 */
310
232 /* Mux in USB pins, drive STP high */ 311 /* Mux in USB pins, drive STP high */
233 DB8500_MUX("usb_a_1", "usb", "musb-ux500.0"), 312 DB8500_MUX("usb_a_1", "usb", "musb-ux500.0"),
234 DB8500_PIN("GPIO257_AE29", out_hi, "musb-ux500.0"), /* STP */ 313 DB8500_PIN("GPIO257_AE29", out_hi, "musb-ux500.0"), /* STP */
@@ -238,10 +317,232 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
238 DB8500_PIN("GPIO218_AH11", in_pd, "spi2"), /* RXD */ 317 DB8500_PIN("GPIO218_AH11", in_pd, "spi2"), /* RXD */
239 DB8500_PIN("GPIO215_AH13", out_lo, "spi2"), /* TXD */ 318 DB8500_PIN("GPIO215_AH13", out_lo, "spi2"), /* TXD */
240 DB8500_PIN("GPIO217_AH12", out_lo, "spi2"), /* CLK */ 319 DB8500_PIN("GPIO217_AH12", out_lo, "spi2"), /* CLK */
320 /* SPI2 idle state */
321 DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */
322 DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */
323 DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */
241 /* SPI2 sleep state */ 324 /* SPI2 sleep state */
325 DB8500_PIN_SLEEP("GPIO216_AG12", slpm_in_wkup_pdis, "spi2"), /* FRM */
242 DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */ 326 DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */
243 DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */ 327 DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */
244 DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */ 328 DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */
329
330 /* ske default state */
331 DB8500_MUX("kp_a_2", "kp", "nmk-ske-keypad"),
332 DB8500_PIN("GPIO153_B17", in_pd, "nmk-ske-keypad"), /* I7 */
333 DB8500_PIN("GPIO154_C16", in_pd, "nmk-ske-keypad"), /* I6 */
334 DB8500_PIN("GPIO155_C19", in_pd, "nmk-ske-keypad"), /* I5 */
335 DB8500_PIN("GPIO156_C17", in_pd, "nmk-ske-keypad"), /* I4 */
336 DB8500_PIN("GPIO161_D21", in_pd, "nmk-ske-keypad"), /* I3 */
337 DB8500_PIN("GPIO162_D20", in_pd, "nmk-ske-keypad"), /* I2 */
338 DB8500_PIN("GPIO163_C20", in_pd, "nmk-ske-keypad"), /* I1 */
339 DB8500_PIN("GPIO164_B21", in_pd, "nmk-ske-keypad"), /* I0 */
340 DB8500_PIN("GPIO157_A18", out_lo, "nmk-ske-keypad"), /* O7 */
341 DB8500_PIN("GPIO158_C18", out_lo, "nmk-ske-keypad"), /* O6 */
342 DB8500_PIN("GPIO159_B19", out_lo, "nmk-ske-keypad"), /* O5 */
343 DB8500_PIN("GPIO160_B20", out_lo, "nmk-ske-keypad"), /* O4 */
344 DB8500_PIN("GPIO165_C21", out_lo, "nmk-ske-keypad"), /* O3 */
345 DB8500_PIN("GPIO166_A22", out_lo, "nmk-ske-keypad"), /* O2 */
346 DB8500_PIN("GPIO167_B24", out_lo, "nmk-ske-keypad"), /* O1 */
347 DB8500_PIN("GPIO168_C22", out_lo, "nmk-ske-keypad"), /* O0 */
348 /* ske sleep state */
349 DB8500_PIN_SLEEP("GPIO153_B17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I7 */
350 DB8500_PIN_SLEEP("GPIO154_C16", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I6 */
351 DB8500_PIN_SLEEP("GPIO155_C19", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I5 */
352 DB8500_PIN_SLEEP("GPIO156_C17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I4 */
353 DB8500_PIN_SLEEP("GPIO161_D21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I3 */
354 DB8500_PIN_SLEEP("GPIO162_D20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I2 */
355 DB8500_PIN_SLEEP("GPIO163_C20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I1 */
356 DB8500_PIN_SLEEP("GPIO164_B21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I0 */
357 DB8500_PIN_SLEEP("GPIO157_A18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O7 */
358 DB8500_PIN_SLEEP("GPIO158_C18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O6 */
359 DB8500_PIN_SLEEP("GPIO159_B19", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O5 */
360 DB8500_PIN_SLEEP("GPIO160_B20", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O4 */
361 DB8500_PIN_SLEEP("GPIO165_C21", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O3 */
362 DB8500_PIN_SLEEP("GPIO166_A22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O2 */
363 DB8500_PIN_SLEEP("GPIO167_B24", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O1 */
364 DB8500_PIN_SLEEP("GPIO168_C22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O0 */
365
366 /* STM APE pins states */
367 DB8500_MUX_STATE("stmape_c_1", "stmape",
368 "stm", "ape_mipi34"),
369 DB8500_PIN_STATE("GPIO70_G5", in_nopull,
370 "stm", "ape_mipi34"), /* clk */
371 DB8500_PIN_STATE("GPIO71_G4", in_nopull,
372 "stm", "ape_mipi34"), /* dat3 */
373 DB8500_PIN_STATE("GPIO72_H4", in_nopull,
374 "stm", "ape_mipi34"), /* dat2 */
375 DB8500_PIN_STATE("GPIO73_H3", in_nopull,
376 "stm", "ape_mipi34"), /* dat1 */
377 DB8500_PIN_STATE("GPIO74_J3", in_nopull,
378 "stm", "ape_mipi34"), /* dat0 */
379
380 DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
381 "stm", "ape_mipi34_sleep"), /* clk */
382 DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
383 "stm", "ape_mipi34_sleep"), /* dat3 */
384 DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
385 "stm", "ape_mipi34_sleep"), /* dat2 */
386 DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
387 "stm", "ape_mipi34_sleep"), /* dat1 */
388 DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
389 "stm", "ape_mipi34_sleep"), /* dat0 */
390
391 DB8500_MUX_STATE("stmape_oc1_1", "stmape",
392 "stm", "ape_microsd"),
393 DB8500_PIN_STATE("GPIO23_AA4", in_nopull,
394 "stm", "ape_microsd"), /* clk */
395 DB8500_PIN_STATE("GPIO25_Y4", in_nopull,
396 "stm", "ape_microsd"), /* dat0 */
397 DB8500_PIN_STATE("GPIO26_Y2", in_nopull,
398 "stm", "ape_microsd"), /* dat1 */
399 DB8500_PIN_STATE("GPIO27_AA2", in_nopull,
400 "stm", "ape_microsd"), /* dat2 */
401 DB8500_PIN_STATE("GPIO28_AA1", in_nopull,
402 "stm", "ape_microsd"), /* dat3 */
403
404 DB8500_PIN_STATE("GPIO23_AA4", slpm_out_lo_wkup_pdis,
405 "stm", "ape_microsd_sleep"), /* clk */
406 DB8500_PIN_STATE("GPIO25_Y4", slpm_in_wkup_pdis,
407 "stm", "ape_microsd_sleep"), /* dat0 */
408 DB8500_PIN_STATE("GPIO26_Y2", slpm_in_wkup_pdis,
409 "stm", "ape_microsd_sleep"), /* dat1 */
410 DB8500_PIN_STATE("GPIO27_AA2", slpm_in_wkup_pdis,
411 "stm", "ape_microsd_sleep"), /* dat2 */
412 DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis,
413 "stm", "ape_microsd_sleep"), /* dat3 */
414
415 /* STM Modem pins states */
416 DB8500_MUX_STATE("stmmod_oc3_2", "stmmod",
417 "stm", "mod_mipi34"),
418 DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
419 "stm", "mod_mipi34"),
420 DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
421 "stm", "mod_mipi34"),
422 DB8500_PIN_STATE("GPIO70_G5", in_nopull,
423 "stm", "mod_mipi34"), /* clk */
424 DB8500_PIN_STATE("GPIO71_G4", in_nopull,
425 "stm", "mod_mipi34"), /* dat3 */
426 DB8500_PIN_STATE("GPIO72_H4", in_nopull,
427 "stm", "mod_mipi34"), /* dat2 */
428 DB8500_PIN_STATE("GPIO73_H3", in_nopull,
429 "stm", "mod_mipi34"), /* dat1 */
430 DB8500_PIN_STATE("GPIO74_J3", in_nopull,
431 "stm", "mod_mipi34"), /* dat0 */
432 DB8500_PIN_STATE("GPIO75_H2", in_pu,
433 "stm", "mod_mipi34"), /* uartmod rx */
434 DB8500_PIN_STATE("GPIO76_J2", out_lo,
435 "stm", "mod_mipi34"), /* uartmod tx */
436
437 DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
438 "stm", "mod_mipi34_sleep"), /* clk */
439 DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
440 "stm", "mod_mipi34_sleep"), /* dat3 */
441 DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
442 "stm", "mod_mipi34_sleep"), /* dat2 */
443 DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
444 "stm", "mod_mipi34_sleep"), /* dat1 */
445 DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
446 "stm", "mod_mipi34_sleep"), /* dat0 */
447 DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
448 "stm", "mod_mipi34_sleep"), /* uartmod rx */
449 DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
450 "stm", "mod_mipi34_sleep"), /* uartmod tx */
451
452 DB8500_MUX_STATE("stmmod_b_1", "stmmod",
453 "stm", "mod_microsd"),
454 DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
455 "stm", "mod_microsd"),
456 DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
457 "stm", "mod_microsd"),
458 DB8500_PIN_STATE("GPIO23_AA4", in_nopull,
459 "stm", "mod_microsd"), /* clk */
460 DB8500_PIN_STATE("GPIO25_Y4", in_nopull,
461 "stm", "mod_microsd"), /* dat0 */
462 DB8500_PIN_STATE("GPIO26_Y2", in_nopull,
463 "stm", "mod_microsd"), /* dat1 */
464 DB8500_PIN_STATE("GPIO27_AA2", in_nopull,
465 "stm", "mod_microsd"), /* dat2 */
466 DB8500_PIN_STATE("GPIO28_AA1", in_nopull,
467 "stm", "mod_microsd"), /* dat3 */
468 DB8500_PIN_STATE("GPIO75_H2", in_pu,
469 "stm", "mod_microsd"), /* uartmod rx */
470 DB8500_PIN_STATE("GPIO76_J2", out_lo,
471 "stm", "mod_microsd"), /* uartmod tx */
472
473 DB8500_PIN_STATE("GPIO23_AA4", slpm_out_lo_wkup_pdis,
474 "stm", "mod_microsd_sleep"), /* clk */
475 DB8500_PIN_STATE("GPIO25_Y4", slpm_in_wkup_pdis,
476 "stm", "mod_microsd_sleep"), /* dat0 */
477 DB8500_PIN_STATE("GPIO26_Y2", slpm_in_wkup_pdis,
478 "stm", "mod_microsd_sleep"), /* dat1 */
479 DB8500_PIN_STATE("GPIO27_AA2", slpm_in_wkup_pdis,
480 "stm", "mod_microsd_sleep"), /* dat2 */
481 DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis,
482 "stm", "mod_microsd_sleep"), /* dat3 */
483 DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
484 "stm", "mod_microsd_sleep"), /* uartmod rx */
485 DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
486 "stm", "mod_microsd_sleep"), /* uartmod tx */
487
488 /* STM dual Modem/APE pins state */
489 DB8500_MUX_STATE("stmmod_oc3_2", "stmmod",
490 "stm", "mod_mipi34_ape_mipi60"),
491 DB8500_MUX_STATE("stmape_c_2", "stmape",
492 "stm", "mod_mipi34_ape_mipi60"),
493 DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
494 "stm", "mod_mipi34_ape_mipi60"),
495 DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
496 "stm", "mod_mipi34_ape_mipi60"),
497 DB8500_PIN_STATE("GPIO70_G5", in_nopull,
498 "stm", "mod_mipi34_ape_mipi60"), /* clk */
499 DB8500_PIN_STATE("GPIO71_G4", in_nopull,
500 "stm", "mod_mipi34_ape_mipi60"), /* dat3 */
501 DB8500_PIN_STATE("GPIO72_H4", in_nopull,
502 "stm", "mod_mipi34_ape_mipi60"), /* dat2 */
503 DB8500_PIN_STATE("GPIO73_H3", in_nopull,
504 "stm", "mod_mipi34_ape_mipi60"), /* dat1 */
505 DB8500_PIN_STATE("GPIO74_J3", in_nopull,
506 "stm", "mod_mipi34_ape_mipi60"), /* dat0 */
507 DB8500_PIN_STATE("GPIO75_H2", in_pu,
508 "stm", "mod_mipi34_ape_mipi60"), /* uartmod rx */
509 DB8500_PIN_STATE("GPIO76_J2", out_lo,
510 "stm", "mod_mipi34_ape_mipi60"), /* uartmod tx */
511 DB8500_PIN_STATE("GPIO155_C19", in_nopull,
512 "stm", "mod_mipi34_ape_mipi60"), /* clk */
513 DB8500_PIN_STATE("GPIO156_C17", in_nopull,
514 "stm", "mod_mipi34_ape_mipi60"), /* dat3 */
515 DB8500_PIN_STATE("GPIO157_A18", in_nopull,
516 "stm", "mod_mipi34_ape_mipi60"), /* dat2 */
517 DB8500_PIN_STATE("GPIO158_C18", in_nopull,
518 "stm", "mod_mipi34_ape_mipi60"), /* dat1 */
519 DB8500_PIN_STATE("GPIO159_B19", in_nopull,
520 "stm", "mod_mipi34_ape_mipi60"), /* dat0 */
521
522 DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
523 "stm", "mod_mipi34_ape_mipi60_sleep"), /* clk */
524 DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
525 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat3 */
526 DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
527 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat2 */
528 DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
529 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */
530 DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
531 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */
532 DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
533 "stm", "mod_mipi34_ape_mipi60_sleep"), /* uartmod rx */
534 DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
535 "stm", "mod_mipi34_ape_mipi60_sleep"), /* uartmod tx */
536 DB8500_PIN_STATE("GPIO155_C19", slpm_in_wkup_pdis,
537 "stm", "mod_mipi34_ape_mipi60_sleep"), /* clk */
538 DB8500_PIN_STATE("GPIO156_C17", slpm_in_wkup_pdis,
539 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat3 */
540 DB8500_PIN_STATE("GPIO157_A18", slpm_in_wkup_pdis,
541 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat2 */
542 DB8500_PIN_STATE("GPIO158_C18", slpm_in_wkup_pdis,
543 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */
544 DB8500_PIN_STATE("GPIO159_B19", slpm_in_wkup_pdis,
545 "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */
245}; 546};
246 547
247/* 548/*
@@ -267,32 +568,48 @@ static struct pinctrl_map __initdata mop500_pinmap[] = {
267 DB8500_PIN_HOG("GPIO217_AH12", gpio_in_pu), 568 DB8500_PIN_HOG("GPIO217_AH12", gpio_in_pu),
268 /* Mux in UART1 and set the pull-ups */ 569 /* Mux in UART1 and set the pull-ups */
269 DB8500_MUX_HOG("u1rxtx_a_1", "u1"), 570 DB8500_MUX_HOG("u1rxtx_a_1", "u1"),
270 DB8500_MUX_HOG("u1ctsrts_a_1", "u1"),
271 DB8500_PIN_HOG("GPIO4_AH6", in_pu), /* RXD */ 571 DB8500_PIN_HOG("GPIO4_AH6", in_pu), /* RXD */
272 DB8500_PIN_HOG("GPIO5_AG6", out_hi), /* TXD */ 572 DB8500_PIN_HOG("GPIO5_AG6", out_hi), /* TXD */
273 DB8500_PIN_HOG("GPIO6_AF6", in_pu), /* CTS */
274 DB8500_PIN_HOG("GPIO7_AG5", out_hi), /* RTS */
275 /* 573 /*
276 * Runtime stuff: make it possible to mux in the SKE keypad 574 * Runtime stuff: make it possible to mux in the SKE keypad
277 * and bias the pins 575 * and bias the pins
278 */ 576 */
279 DB8500_MUX("kp_a_2", "kp", "ske"), 577 /* ske default state */
280 DB8500_PIN("GPIO153_B17", in_pd_slpm_in_pu, "ske"), /* I7 */ 578 DB8500_MUX("kp_a_2", "kp", "nmk-ske-keypad"),
281 DB8500_PIN("GPIO154_C16", in_pd_slpm_in_pu, "ske"), /* I6 */ 579 DB8500_PIN("GPIO153_B17", in_pu, "nmk-ske-keypad"), /* I7 */
282 DB8500_PIN("GPIO155_C19", in_pd_slpm_in_pu, "ske"), /* I5 */ 580 DB8500_PIN("GPIO154_C16", in_pu, "nmk-ske-keypad"), /* I6 */
283 DB8500_PIN("GPIO156_C17", in_pd_slpm_in_pu, "ske"), /* I4 */ 581 DB8500_PIN("GPIO155_C19", in_pu, "nmk-ske-keypad"), /* I5 */
284 DB8500_PIN("GPIO161_D21", in_pd_slpm_in_pu, "ske"), /* I3 */ 582 DB8500_PIN("GPIO156_C17", in_pu, "nmk-ske-keypad"), /* I4 */
285 DB8500_PIN("GPIO162_D20", in_pd_slpm_in_pu, "ske"), /* I2 */ 583 DB8500_PIN("GPIO161_D21", in_pu, "nmk-ske-keypad"), /* I3 */
286 DB8500_PIN("GPIO163_C20", in_pd_slpm_in_pu, "ske"), /* I1 */ 584 DB8500_PIN("GPIO162_D20", in_pu, "nmk-ske-keypad"), /* I2 */
287 DB8500_PIN("GPIO164_B21", in_pd_slpm_in_pu, "ske"), /* I0 */ 585 DB8500_PIN("GPIO163_C20", in_pu, "nmk-ske-keypad"), /* I1 */
288 DB8500_PIN("GPIO157_A18", in_pu_slpm_out_lo, "ske"), /* O7 */ 586 DB8500_PIN("GPIO164_B21", in_pu, "nmk-ske-keypad"), /* I0 */
289 DB8500_PIN("GPIO158_C18", in_pu_slpm_out_lo, "ske"), /* O6 */ 587 DB8500_PIN("GPIO157_A18", out_lo, "nmk-ske-keypad"), /* O7 */
290 DB8500_PIN("GPIO159_B19", in_pu_slpm_out_lo, "ske"), /* O5 */ 588 DB8500_PIN("GPIO158_C18", out_lo, "nmk-ske-keypad"), /* O6 */
291 DB8500_PIN("GPIO160_B20", in_pu_slpm_out_lo, "ske"), /* O4 */ 589 DB8500_PIN("GPIO159_B19", out_lo, "nmk-ske-keypad"), /* O5 */
292 DB8500_PIN("GPIO165_C21", in_pu_slpm_out_lo, "ske"), /* O3 */ 590 DB8500_PIN("GPIO160_B20", out_lo, "nmk-ske-keypad"), /* O4 */
293 DB8500_PIN("GPIO166_A22", in_pu_slpm_out_lo, "ske"), /* O2 */ 591 DB8500_PIN("GPIO165_C21", out_lo, "nmk-ske-keypad"), /* O3 */
294 DB8500_PIN("GPIO167_B24", in_pu_slpm_out_lo, "ske"), /* O1 */ 592 DB8500_PIN("GPIO166_A22", out_lo, "nmk-ske-keypad"), /* O2 */
295 DB8500_PIN("GPIO168_C22", in_pu_slpm_out_lo, "ske"), /* O0 */ 593 DB8500_PIN("GPIO167_B24", out_lo, "nmk-ske-keypad"), /* O1 */
594 DB8500_PIN("GPIO168_C22", out_lo, "nmk-ske-keypad"), /* O0 */
595 /* ske sleep state */
596 DB8500_PIN_SLEEP("GPIO153_B17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I7 */
597 DB8500_PIN_SLEEP("GPIO154_C16", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I6 */
598 DB8500_PIN_SLEEP("GPIO155_C19", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I5 */
599 DB8500_PIN_SLEEP("GPIO156_C17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I4 */
600 DB8500_PIN_SLEEP("GPIO161_D21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I3 */
601 DB8500_PIN_SLEEP("GPIO162_D20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I2 */
602 DB8500_PIN_SLEEP("GPIO163_C20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I1 */
603 DB8500_PIN_SLEEP("GPIO164_B21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I0 */
604 DB8500_PIN_SLEEP("GPIO157_A18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O7 */
605 DB8500_PIN_SLEEP("GPIO158_C18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O6 */
606 DB8500_PIN_SLEEP("GPIO159_B19", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O5 */
607 DB8500_PIN_SLEEP("GPIO160_B20", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O4 */
608 DB8500_PIN_SLEEP("GPIO165_C21", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O3 */
609 DB8500_PIN_SLEEP("GPIO166_A22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O2 */
610 DB8500_PIN_SLEEP("GPIO167_B24", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O1 */
611 DB8500_PIN_SLEEP("GPIO168_C22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O0 */
612
296 /* Mux in and drive the SDI0 DAT31DIR line high at runtime */ 613 /* Mux in and drive the SDI0 DAT31DIR line high at runtime */
297 DB8500_MUX("mc0dat31dir_a_1", "mc0", "sdi0"), 614 DB8500_MUX("mc0dat31dir_a_1", "mc0", "sdi0"),
298 DB8500_PIN("GPIO21_AB3", out_hi, "sdi0"), 615 DB8500_PIN("GPIO21_AB3", out_hi, "sdi0"),
@@ -395,28 +712,6 @@ static struct pinctrl_map __initdata hrefv60_pinmap[] = {
395 DB8500_PIN("GPIO217_AH12", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"), 712 DB8500_PIN("GPIO217_AH12", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"),
396 DB8500_PIN("GPIO145_C13", gpio_in_pd_slpm_gpio_nopull, "gpio-keys.0"), 713 DB8500_PIN("GPIO145_C13", gpio_in_pd_slpm_gpio_nopull, "gpio-keys.0"),
397 DB8500_PIN("GPIO139_C9", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"), 714 DB8500_PIN("GPIO139_C9", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"),
398 /*
399 * Make it possible to mux in the SKE keypad and bias the pins
400 * FIXME: what's the point with this on HREFv60? KP/SKE is already
401 * muxed in at another place! Enabling this will bork.
402 */
403 DB8500_MUX("kp_a_2", "kp", "ske"),
404 DB8500_PIN("GPIO153_B17", in_pd_slpm_in_pu, "ske"), /* I7 */
405 DB8500_PIN("GPIO154_C16", in_pd_slpm_in_pu, "ske"), /* I6 */
406 DB8500_PIN("GPIO155_C19", in_pd_slpm_in_pu, "ske"), /* I5 */
407 DB8500_PIN("GPIO156_C17", in_pd_slpm_in_pu, "ske"), /* I4 */
408 DB8500_PIN("GPIO161_D21", in_pd_slpm_in_pu, "ske"), /* I3 */
409 DB8500_PIN("GPIO162_D20", in_pd_slpm_in_pu, "ske"), /* I2 */
410 DB8500_PIN("GPIO163_C20", in_pd_slpm_in_pu, "ske"), /* I1 */
411 DB8500_PIN("GPIO164_B21", in_pd_slpm_in_pu, "ske"), /* I0 */
412 DB8500_PIN("GPIO157_A18", in_pu_slpm_out_lo, "ske"), /* O7 */
413 DB8500_PIN("GPIO158_C18", in_pu_slpm_out_lo, "ske"), /* O6 */
414 DB8500_PIN("GPIO159_B19", in_pu_slpm_out_lo, "ske"), /* O5 */
415 DB8500_PIN("GPIO160_B20", in_pu_slpm_out_lo, "ske"), /* O4 */
416 DB8500_PIN("GPIO165_C21", in_pu_slpm_out_lo, "ske"), /* O3 */
417 DB8500_PIN("GPIO166_A22", in_pu_slpm_out_lo, "ske"), /* O2 */
418 DB8500_PIN("GPIO167_B24", in_pu_slpm_out_lo, "ske"), /* O1 */
419 DB8500_PIN("GPIO168_C22", in_pu_slpm_out_lo, "ske"), /* O0 */
420}; 715};
421 716
422static struct pinctrl_map __initdata u9500_pinmap[] = { 717static struct pinctrl_map __initdata u9500_pinmap[] = {
diff --git a/arch/arm/mach-vexpress/reset.c b/arch/arm/mach-vexpress/reset.c
new file mode 100644
index 00000000000..465923aa381
--- /dev/null
+++ b/arch/arm/mach-vexpress/reset.c
@@ -0,0 +1,141 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14#include <linux/jiffies.h>
15#include <linux/of.h>
16#include <linux/of_device.h>
17#include <linux/platform_device.h>
18#include <linux/stat.h>
19#include <linux/vexpress.h>
20
21static void vexpress_reset_do(struct device *dev, const char *what)
22{
23 int err = -ENOENT;
24 struct vexpress_config_func *func =
25 vexpress_config_func_get_by_dev(dev);
26
27 if (func) {
28 unsigned long timeout;
29
30 err = vexpress_config_write(func, 0, 0);
31
32 timeout = jiffies + HZ;
33 while (time_before(jiffies, timeout))
34 cpu_relax();
35 }
36
37 dev_emerg(dev, "Unable to %s (%d)\n", what, err);
38}
39
40static struct device *vexpress_power_off_device;
41
42void vexpress_power_off(void)
43{
44 vexpress_reset_do(vexpress_power_off_device, "power off");
45}
46
47static struct device *vexpress_restart_device;
48
49void vexpress_restart(char str, const char *cmd)
50{
51 vexpress_reset_do(vexpress_restart_device, "restart");
52}
53
54static ssize_t vexpress_reset_active_show(struct device *dev,
55 struct device_attribute *attr, char *buf)
56{
57 return sprintf(buf, "%d\n", vexpress_restart_device == dev);
58}
59
60static ssize_t vexpress_reset_active_store(struct device *dev,
61 struct device_attribute *attr, const char *buf, size_t count)
62{
63 long value;
64 int err = kstrtol(buf, 0, &value);
65
66 if (!err && value)
67 vexpress_restart_device = dev;
68
69 return err ? err : count;
70}
71
72DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show,
73 vexpress_reset_active_store);
74
75
76enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };
77
78static struct of_device_id vexpress_reset_of_match[] = {
79 {
80 .compatible = "arm,vexpress-reset",
81 .data = (void *)FUNC_RESET,
82 }, {
83 .compatible = "arm,vexpress-shutdown",
84 .data = (void *)FUNC_SHUTDOWN
85 }, {
86 .compatible = "arm,vexpress-reboot",
87 .data = (void *)FUNC_REBOOT
88 },
89 {}
90};
91
92static int vexpress_reset_probe(struct platform_device *pdev)
93{
94 enum vexpress_reset_func func;
95 const struct of_device_id *match =
96 of_match_device(vexpress_reset_of_match, &pdev->dev);
97
98 if (match)
99 func = (enum vexpress_reset_func)match->data;
100 else
101 func = pdev->id_entry->driver_data;
102
103 switch (func) {
104 case FUNC_SHUTDOWN:
105 vexpress_power_off_device = &pdev->dev;
106 break;
107 case FUNC_RESET:
108 if (!vexpress_restart_device)
109 vexpress_restart_device = &pdev->dev;
110 device_create_file(&pdev->dev, &dev_attr_active);
111 break;
112 case FUNC_REBOOT:
113 vexpress_restart_device = &pdev->dev;
114 device_create_file(&pdev->dev, &dev_attr_active);
115 break;
116 };
117
118 return 0;
119}
120
121static const struct platform_device_id vexpress_reset_id_table[] = {
122 { .name = "vexpress-reset", .driver_data = FUNC_RESET, },
123 { .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
124 { .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
125 {}
126};
127
128static struct platform_driver vexpress_reset_driver = {
129 .probe = vexpress_reset_probe,
130 .driver = {
131 .name = "vexpress-reset",
132 .of_match_table = vexpress_reset_of_match,
133 },
134 .id_table = vexpress_reset_id_table,
135};
136
137static int __init vexpress_reset_init(void)
138{
139 return platform_driver_register(&vexpress_reset_driver);
140}
141device_initcall(vexpress_reset_init);
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 1fe6917f6a2..dfd8b7af8c7 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -48,6 +48,7 @@ struct samsung_gpio_cfg;
48 * @config: special function and pull-resistor control information. 48 * @config: special function and pull-resistor control information.
49 * @lock: Lock for exclusive access to this gpio bank. 49 * @lock: Lock for exclusive access to this gpio bank.
50 * @pm_save: Save information for suspend/resume support. 50 * @pm_save: Save information for suspend/resume support.
51 * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not.
51 * 52 *
52 * This wrapper provides the necessary information for the Samsung 53 * This wrapper provides the necessary information for the Samsung
53 * specific gpios being registered with gpiolib. 54 * specific gpios being registered with gpiolib.
@@ -71,6 +72,7 @@ struct samsung_gpio_chip {
71#ifdef CONFIG_PM 72#ifdef CONFIG_PM
72 u32 pm_save[4]; 73 u32 pm_save[4];
73#endif 74#endif
75 u32 bitmap_gpio_int;
74}; 76};
75 77
76static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc) 78static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c
index 23557d30e44..bae56131a50 100644
--- a/arch/arm/plat-samsung/s5p-irq-gpioint.c
+++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c
@@ -185,7 +185,7 @@ int __init s5p_register_gpio_interrupt(int pin)
185 185
186 /* check if the group has been already registered */ 186 /* check if the group has been already registered */
187 if (my_chip->irq_base) 187 if (my_chip->irq_base)
188 return my_chip->irq_base + offset; 188 goto success;
189 189
190 /* register gpio group */ 190 /* register gpio group */
191 ret = s5p_gpioint_add(my_chip); 191 ret = s5p_gpioint_add(my_chip);
@@ -193,9 +193,13 @@ int __init s5p_register_gpio_interrupt(int pin)
193 my_chip->chip.to_irq = samsung_gpiolib_to_irq; 193 my_chip->chip.to_irq = samsung_gpiolib_to_irq;
194 printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", 194 printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
195 group); 195 group);
196 return my_chip->irq_base + offset; 196 goto success;
197 } 197 }
198 return ret; 198 return ret;
199success:
200 my_chip->bitmap_gpio_int |= BIT(offset);
201
202 return my_chip->irq_base + offset;
199} 203}
200 204
201int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) 205int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index 88f41e51565..01f7fe95559 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -42,12 +42,6 @@
42#include <plat/gpio-fns.h> 42#include <plat/gpio-fns.h>
43#include <plat/pm.h> 43#include <plat/pm.h>
44 44
45#ifndef DEBUG_GPIO
46#define gpio_dbg(x...) do { } while (0)
47#else
48#define gpio_dbg(x...) printk(KERN_DEBUG x)
49#endif
50
51int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, 45int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
52 unsigned int off, samsung_gpio_pull_t pull) 46 unsigned int off, samsung_gpio_pull_t pull)
53{ 47{
@@ -596,10 +590,13 @@ static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
596 unsigned long con; 590 unsigned long con;
597 591
598 con = __raw_readl(base + GPIOCON_OFF); 592 con = __raw_readl(base + GPIOCON_OFF);
599 con &= ~(0xf << con_4bit_shift(offset)); 593 if (ourchip->bitmap_gpio_int & BIT(offset))
594 con |= 0xf << con_4bit_shift(offset);
595 else
596 con &= ~(0xf << con_4bit_shift(offset));
600 __raw_writel(con, base + GPIOCON_OFF); 597 __raw_writel(con, base + GPIOCON_OFF);
601 598
602 gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); 599 pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
603 600
604 return 0; 601 return 0;
605} 602}
@@ -627,7 +624,7 @@ static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
627 __raw_writel(con, base + GPIOCON_OFF); 624 __raw_writel(con, base + GPIOCON_OFF);
628 __raw_writel(dat, base + GPIODAT_OFF); 625 __raw_writel(dat, base + GPIODAT_OFF);
629 626
630 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); 627 pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
631 628
632 return 0; 629 return 0;
633} 630}
@@ -671,7 +668,7 @@ static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
671 con &= ~(0xf << con_4bit_shift(offset)); 668 con &= ~(0xf << con_4bit_shift(offset));
672 __raw_writel(con, regcon); 669 __raw_writel(con, regcon);
673 670
674 gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); 671 pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
675 672
676 return 0; 673 return 0;
677} 674}
@@ -706,7 +703,7 @@ static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
706 __raw_writel(con, regcon); 703 __raw_writel(con, regcon);
707 __raw_writel(dat, base + GPIODAT_OFF); 704 __raw_writel(dat, base + GPIODAT_OFF);
708 705
709 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); 706 pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
710 707
711 return 0; 708 return 0;
712} 709}
@@ -926,10 +923,10 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
926#ifdef CONFIG_PM 923#ifdef CONFIG_PM
927 if (chip->pm != NULL) { 924 if (chip->pm != NULL) {
928 if (!chip->pm->save || !chip->pm->resume) 925 if (!chip->pm->save || !chip->pm->resume)
929 printk(KERN_ERR "gpio: %s has missing PM functions\n", 926 pr_err("gpio: %s has missing PM functions\n",
930 gc->label); 927 gc->label);
931 } else 928 } else
932 printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); 929 pr_err("gpio: %s has no PM function\n", gc->label);
933#endif 930#endif
934 931
935 /* gpiochip_add() prints own failure message on error. */ 932 /* gpiochip_add() prints own failure message on error. */
@@ -1081,6 +1078,8 @@ static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip
1081 if ((base != NULL) && (chip->base == NULL)) 1078 if ((base != NULL) && (chip->base == NULL))
1082 chip->base = base + ((i) * 0x20); 1079 chip->base = base + ((i) * 0x20);
1083 1080
1081 chip->bitmap_gpio_int = 0;
1082
1084 samsung_gpiolib_add(chip); 1083 samsung_gpiolib_add(chip);
1085 } 1084 }
1086} 1085}
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4800d4c2a7b..32f238f3cae 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1208,6 +1208,14 @@ config SENSORS_TWL4030_MADC
1208 This driver can also be built as a module. If so it will be called 1208 This driver can also be built as a module. If so it will be called
1209 twl4030-madc-hwmon. 1209 twl4030-madc-hwmon.
1210 1210
1211config SENSORS_VEXPRESS
1212 tristate "Versatile Express"
1213 depends on VEXPRESS_CONFIG
1214 help
1215 This driver provides support for hardware sensors available on
1216 the ARM Ltd's Versatile Express platform. It can provide wide
1217 range of information like temperature, power, energy.
1218
1211config SENSORS_VIA_CPUTEMP 1219config SENSORS_VIA_CPUTEMP
1212 tristate "VIA CPU temperature sensor" 1220 tristate "VIA CPU temperature sensor"
1213 depends on X86 1221 depends on X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index a930f0997d2..5da287443f6 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -122,6 +122,7 @@ obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
122obj-$(CONFIG_SENSORS_TMP401) += tmp401.o 122obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
123obj-$(CONFIG_SENSORS_TMP421) += tmp421.o 123obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
124obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o 124obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
125obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o
125obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o 126obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
126obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 127obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
127obj-$(CONFIG_SENSORS_VT1211) += vt1211.o 128obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c
new file mode 100644
index 00000000000..59fd1268e58
--- /dev/null
+++ b/drivers/hwmon/vexpress.c
@@ -0,0 +1,229 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14#define DRVNAME "vexpress-hwmon"
15#define pr_fmt(fmt) DRVNAME ": " fmt
16
17#include <linux/device.h>
18#include <linux/err.h>
19#include <linux/hwmon.h>
20#include <linux/hwmon-sysfs.h>
21#include <linux/module.h>
22#include <linux/of_device.h>
23#include <linux/platform_device.h>
24#include <linux/vexpress.h>
25
26struct vexpress_hwmon_data {
27 struct device *hwmon_dev;
28 struct vexpress_config_func *func;
29};
30
31static ssize_t vexpress_hwmon_name_show(struct device *dev,
32 struct device_attribute *dev_attr, char *buffer)
33{
34 const char *compatible = of_get_property(dev->of_node, "compatible",
35 NULL);
36
37 return sprintf(buffer, "%s\n", compatible);
38}
39
40static ssize_t vexpress_hwmon_label_show(struct device *dev,
41 struct device_attribute *dev_attr, char *buffer)
42{
43 const char *label = of_get_property(dev->of_node, "label", NULL);
44
45 if (!label)
46 return -ENOENT;
47
48 return snprintf(buffer, PAGE_SIZE, "%s\n", label);
49}
50
51static ssize_t vexpress_hwmon_u32_show(struct device *dev,
52 struct device_attribute *dev_attr, char *buffer)
53{
54 struct vexpress_hwmon_data *data = dev_get_drvdata(dev);
55 int err;
56 u32 value;
57
58 err = vexpress_config_read(data->func, 0, &value);
59 if (err)
60 return err;
61
62 return snprintf(buffer, PAGE_SIZE, "%u\n", value /
63 to_sensor_dev_attr(dev_attr)->index);
64}
65
66static ssize_t vexpress_hwmon_u64_show(struct device *dev,
67 struct device_attribute *dev_attr, char *buffer)
68{
69 struct vexpress_hwmon_data *data = dev_get_drvdata(dev);
70 int err;
71 u32 value_hi, value_lo;
72
73 err = vexpress_config_read(data->func, 0, &value_lo);
74 if (err)
75 return err;
76
77 err = vexpress_config_read(data->func, 1, &value_hi);
78 if (err)
79 return err;
80
81 return snprintf(buffer, PAGE_SIZE, "%llu\n",
82 div_u64(((u64)value_hi << 32) | value_lo,
83 to_sensor_dev_attr(dev_attr)->index));
84}
85
86static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL);
87
88#define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \
89struct attribute *vexpress_hwmon_attrs_##_name[] = { \
90 &dev_attr_name.attr, \
91 &dev_attr_##_label_attr.attr, \
92 &sensor_dev_attr_##_input_attr.dev_attr.attr, \
93 NULL \
94}
95
96#if !defined(CONFIG_REGULATOR_VEXPRESS)
97static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
98static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show,
99 NULL, 1000);
100static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input);
101static struct attribute_group vexpress_hwmon_group_volt = {
102 .attrs = vexpress_hwmon_attrs_volt,
103};
104#endif
105
106static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
107static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, vexpress_hwmon_u32_show,
108 NULL, 1000);
109static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input);
110static struct attribute_group vexpress_hwmon_group_amp = {
111 .attrs = vexpress_hwmon_attrs_amp,
112};
113
114static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
115static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show,
116 NULL, 1000);
117static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input);
118static struct attribute_group vexpress_hwmon_group_temp = {
119 .attrs = vexpress_hwmon_attrs_temp,
120};
121
122static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
123static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show,
124 NULL, 1);
125static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input);
126static struct attribute_group vexpress_hwmon_group_power = {
127 .attrs = vexpress_hwmon_attrs_power,
128};
129
130static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
131static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show,
132 NULL, 1);
133static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input);
134static struct attribute_group vexpress_hwmon_group_energy = {
135 .attrs = vexpress_hwmon_attrs_energy,
136};
137
138static struct of_device_id vexpress_hwmon_of_match[] = {
139#if !defined(CONFIG_REGULATOR_VEXPRESS)
140 {
141 .compatible = "arm,vexpress-volt",
142 .data = &vexpress_hwmon_group_volt,
143 },
144#endif
145 {
146 .compatible = "arm,vexpress-amp",
147 .data = &vexpress_hwmon_group_amp,
148 }, {
149 .compatible = "arm,vexpress-temp",
150 .data = &vexpress_hwmon_group_temp,
151 }, {
152 .compatible = "arm,vexpress-power",
153 .data = &vexpress_hwmon_group_power,
154 }, {
155 .compatible = "arm,vexpress-energy",
156 .data = &vexpress_hwmon_group_energy,
157 },
158 {}
159};
160MODULE_DEVICE_TABLE(of, vexpress_hwmon_of_match);
161
162static int vexpress_hwmon_probe(struct platform_device *pdev)
163{
164 int err;
165 const struct of_device_id *match;
166 struct vexpress_hwmon_data *data;
167
168 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
169 if (!data)
170 return -ENOMEM;
171 platform_set_drvdata(pdev, data);
172
173 match = of_match_device(vexpress_hwmon_of_match, &pdev->dev);
174 if (!match)
175 return -ENODEV;
176
177 data->func = vexpress_config_func_get_by_dev(&pdev->dev);
178 if (!data->func)
179 return -ENODEV;
180
181 err = sysfs_create_group(&pdev->dev.kobj, match->data);
182 if (err)
183 goto error;
184
185 data->hwmon_dev = hwmon_device_register(&pdev->dev);
186 if (IS_ERR(data->hwmon_dev)) {
187 err = PTR_ERR(data->hwmon_dev);
188 goto error;
189 }
190
191 return 0;
192
193error:
194 sysfs_remove_group(&pdev->dev.kobj, match->data);
195 vexpress_config_func_put(data->func);
196 return err;
197}
198
199static int __devexit vexpress_hwmon_remove(struct platform_device *pdev)
200{
201 struct vexpress_hwmon_data *data = platform_get_drvdata(pdev);
202 const struct of_device_id *match;
203
204 hwmon_device_unregister(data->hwmon_dev);
205
206 match = of_match_device(vexpress_hwmon_of_match, &pdev->dev);
207 sysfs_remove_group(&pdev->dev.kobj, match->data);
208
209 vexpress_config_func_put(data->func);
210
211 return 0;
212}
213
214static struct platform_driver vexpress_hwmon_driver = {
215 .probe = vexpress_hwmon_probe,
216 .remove = __devexit_p(vexpress_hwmon_remove),
217 .driver = {
218 .name = DRVNAME,
219 .owner = THIS_MODULE,
220 .of_match_table = vexpress_hwmon_of_match,
221 },
222};
223
224module_platform_driver(vexpress_hwmon_driver);
225
226MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
227MODULE_DESCRIPTION("Versatile Express hwmon sensors driver");
228MODULE_LICENSE("GPL");
229MODULE_ALIAS("platform:vexpress-hwmon");