aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-05-13 01:33:24 -0400
committerOlof Johansson <olof@lixom.net>2012-05-13 01:33:24 -0400
commite29402edf848359d619ce06af86d61e62c292c87 (patch)
tree94451c1d400d478654e0d0e78564e882081b806c /drivers
parentbf98a6eaa9964fef49f186834713bfc57d16ede1 (diff)
parent530f1d416091212243b341e0022b2967886b30e4 (diff)
Merge branch 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt2
* 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6: (51 commits) ARM: dts: enable audio support for imx28-evk ARM: dts: enable i2c device for imx28-evk i2c: mxs: add device tree probe support ARM: dts: enable mmc for imx28-evk ARM: dts: enable mmc for imx23-evk mmc: mxs-mmc: add device tree support mmc: mxs-mmc: copy wp_gpio in struct mxs_mmc_host mmc: mxs-mmc: have dma_channel than dma_res in mxs_mmc_host mmc: mxs-mmc: use devm_* helper to make cleanup simpler mmc: mxs-mmc: move header from mach into linux folder mmc: mxs-mmc: get rid of the use of cpu_is_xxx mmc: mxs-mmc: let ssp_is_old take host as parameter mmc: mxs-mmc: use global stmp_device functionality ARM: mxs: add gpio support for device tree boot gpio/mxs: add device tree probe gpio/mxs: get rid of the use of cpu_is_xxx gpio/mxs: use devm_* helpers to make error handling simple ARM: mxs: add mxs-dma dt support ARM: mxs: do not add dma device by default dma: mxs-dma: add device tree probe support ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/mxs/Makefile8
-rw-r--r--drivers/clk/mxs/clk-div.c110
-rw-r--r--drivers/clk/mxs/clk-frac.c139
-rw-r--r--drivers/clk/mxs/clk-imx23.c205
-rw-r--r--drivers/clk/mxs/clk-imx28.c338
-rw-r--r--drivers/clk/mxs/clk-pll.c116
-rw-r--r--drivers/clk/mxs/clk-ref.c154
-rw-r--r--drivers/clk/mxs/clk.c28
-rw-r--r--drivers/clk/mxs/clk.h66
-rw-r--r--drivers/dma/Kconfig1
-rw-r--r--drivers/dma/mxs-dma.c188
-rw-r--r--drivers/gpio/gpio-mxs.c156
-rw-r--r--drivers/i2c/busses/i2c-imx.c8
-rw-r--r--drivers/i2c/busses/i2c-mxs.c19
-rw-r--r--drivers/mmc/host/mxs-mmc.c203
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c9
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c9
-rw-r--r--drivers/net/can/flexcan.c6
-rw-r--r--drivers/net/ethernet/freescale/fec.c9
-rw-r--r--drivers/spi/spi-imx.c8
-rw-r--r--drivers/tty/serial/amba-pl011.c8
-rw-r--r--drivers/tty/serial/imx.c8
-rw-r--r--drivers/tty/serial/mxs-auart.c8
-rw-r--r--drivers/video/mxsfb.c9
25 files changed, 1607 insertions, 208 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1f736bc11c4b..a576f5447d38 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -2,3 +2,5 @@
2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o 2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
3obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ 3obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
4 clk-mux.o clk-divider.o 4 clk-mux.o clk-divider.o
5
6obj-$(CONFIG_ARCH_MXS) += mxs/
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile
new file mode 100644
index 000000000000..7bedeec08524
--- /dev/null
+++ b/drivers/clk/mxs/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for mxs specific clk
3#
4
5obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o
6
7obj-$(CONFIG_SOC_IMX23) += clk-imx23.o
8obj-$(CONFIG_SOC_IMX28) += clk-imx28.o
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
new file mode 100644
index 000000000000..90e1da93877e
--- /dev/null
+++ b/drivers/clk/mxs/clk-div.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/slab.h>
16#include "clk.h"
17
18/**
19 * struct clk_div - mxs integer divider clock
20 * @divider: the parent class
21 * @ops: pointer to clk_ops of parent class
22 * @reg: register address
23 * @busy: busy bit shift
24 *
25 * The mxs divider clock is a subclass of basic clk_divider with an
26 * addtional busy bit.
27 */
28struct clk_div {
29 struct clk_divider divider;
30 const struct clk_ops *ops;
31 void __iomem *reg;
32 u8 busy;
33};
34
35static inline struct clk_div *to_clk_div(struct clk_hw *hw)
36{
37 struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
38
39 return container_of(divider, struct clk_div, divider);
40}
41
42static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
43 unsigned long parent_rate)
44{
45 struct clk_div *div = to_clk_div(hw);
46
47 return div->ops->recalc_rate(&div->divider.hw, parent_rate);
48}
49
50static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
51 unsigned long *prate)
52{
53 struct clk_div *div = to_clk_div(hw);
54
55 return div->ops->round_rate(&div->divider.hw, rate, prate);
56}
57
58static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long parent_rate)
60{
61 struct clk_div *div = to_clk_div(hw);
62 int ret;
63
64 ret = div->ops->set_rate(&div->divider.hw, rate, parent_rate);
65 if (!ret)
66 ret = mxs_clk_wait(div->reg, div->busy);
67
68 return ret;
69}
70
71static struct clk_ops clk_div_ops = {
72 .recalc_rate = clk_div_recalc_rate,
73 .round_rate = clk_div_round_rate,
74 .set_rate = clk_div_set_rate,
75};
76
77struct clk *mxs_clk_div(const char *name, const char *parent_name,
78 void __iomem *reg, u8 shift, u8 width, u8 busy)
79{
80 struct clk_div *div;
81 struct clk *clk;
82 struct clk_init_data init;
83
84 div = kzalloc(sizeof(*div), GFP_KERNEL);
85 if (!div)
86 return ERR_PTR(-ENOMEM);
87
88 init.name = name;
89 init.ops = &clk_div_ops;
90 init.flags = CLK_SET_RATE_PARENT;
91 init.parent_names = (parent_name ? &parent_name: NULL);
92 init.num_parents = (parent_name ? 1 : 0);
93
94 div->reg = reg;
95 div->busy = busy;
96
97 div->divider.reg = reg;
98 div->divider.shift = shift;
99 div->divider.width = width;
100 div->divider.flags = CLK_DIVIDER_ONE_BASED;
101 div->divider.lock = &mxs_lock;
102 div->divider.hw.init = &init;
103 div->ops = &clk_divider_ops;
104
105 clk = clk_register(NULL, &div->divider.hw);
106 if (IS_ERR(clk))
107 kfree(div);
108
109 return clk;
110}
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
new file mode 100644
index 000000000000..e6aa6b567d68
--- /dev/null
+++ b/drivers/clk/mxs/clk-frac.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include "clk.h"
18
19/**
20 * struct clk_frac - mxs fractional divider clock
21 * @hw: clk_hw for the fractional divider clock
22 * @reg: register address
23 * @shift: the divider bit shift
24 * @width: the divider bit width
25 * @busy: busy bit shift
26 *
27 * The clock is an adjustable fractional divider with a busy bit to wait
28 * when the divider is adjusted.
29 */
30struct clk_frac {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 shift;
34 u8 width;
35 u8 busy;
36};
37
38#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
39
40static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
41 unsigned long parent_rate)
42{
43 struct clk_frac *frac = to_clk_frac(hw);
44 u32 div;
45
46 div = readl_relaxed(frac->reg) >> frac->shift;
47 div &= (1 << frac->width) - 1;
48
49 return (parent_rate >> frac->width) * div;
50}
51
52static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
53 unsigned long *prate)
54{
55 struct clk_frac *frac = to_clk_frac(hw);
56 unsigned long parent_rate = *prate;
57 u32 div;
58 u64 tmp;
59
60 if (rate > parent_rate)
61 return -EINVAL;
62
63 tmp = rate;
64 tmp <<= frac->width;
65 do_div(tmp, parent_rate);
66 div = tmp;
67
68 if (!div)
69 return -EINVAL;
70
71 return (parent_rate >> frac->width) * div;
72}
73
74static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
75 unsigned long parent_rate)
76{
77 struct clk_frac *frac = to_clk_frac(hw);
78 unsigned long flags;
79 u32 div, val;
80 u64 tmp;
81
82 if (rate > parent_rate)
83 return -EINVAL;
84
85 tmp = rate;
86 tmp <<= frac->width;
87 do_div(tmp, parent_rate);
88 div = tmp;
89
90 if (!div)
91 return -EINVAL;
92
93 spin_lock_irqsave(&mxs_lock, flags);
94
95 val = readl_relaxed(frac->reg);
96 val &= ~(((1 << frac->width) - 1) << frac->shift);
97 val |= div << frac->shift;
98 writel_relaxed(val, frac->reg);
99
100 spin_unlock_irqrestore(&mxs_lock, flags);
101
102 return mxs_clk_wait(frac->reg, frac->busy);
103}
104
105static struct clk_ops clk_frac_ops = {
106 .recalc_rate = clk_frac_recalc_rate,
107 .round_rate = clk_frac_round_rate,
108 .set_rate = clk_frac_set_rate,
109};
110
111struct clk *mxs_clk_frac(const char *name, const char *parent_name,
112 void __iomem *reg, u8 shift, u8 width, u8 busy)
113{
114 struct clk_frac *frac;
115 struct clk *clk;
116 struct clk_init_data init;
117
118 frac = kzalloc(sizeof(*frac), GFP_KERNEL);
119 if (!frac)
120 return ERR_PTR(-ENOMEM);
121
122 init.name = name;
123 init.ops = &clk_frac_ops;
124 init.flags = CLK_SET_RATE_PARENT;
125 init.parent_names = (parent_name ? &parent_name: NULL);
126 init.num_parents = (parent_name ? 1 : 0);
127
128 frac->reg = reg;
129 frac->shift = shift;
130 frac->width = width;
131 frac->busy = busy;
132 frac->hw.init = &init;
133
134 clk = clk_register(NULL, &frac->hw);
135 if (IS_ERR(clk))
136 kfree(frac);
137
138 return clk;
139}
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c
new file mode 100644
index 000000000000..f7be225f544c
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx23.c
@@ -0,0 +1,205 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <mach/common.h>
18#include <mach/mx23.h>
19#include "clk.h"
20
21#define DIGCTRL MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
22#define CLKCTRL MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
23#define PLLCTRL0 (CLKCTRL + 0x0000)
24#define CPU (CLKCTRL + 0x0020)
25#define HBUS (CLKCTRL + 0x0030)
26#define XBUS (CLKCTRL + 0x0040)
27#define XTAL (CLKCTRL + 0x0050)
28#define PIX (CLKCTRL + 0x0060)
29#define SSP (CLKCTRL + 0x0070)
30#define GPMI (CLKCTRL + 0x0080)
31#define SPDIF (CLKCTRL + 0x0090)
32#define EMI (CLKCTRL + 0x00a0)
33#define SAIF (CLKCTRL + 0x00c0)
34#define TV (CLKCTRL + 0x00d0)
35#define ETM (CLKCTRL + 0x00e0)
36#define FRAC (CLKCTRL + 0x00f0)
37#define CLKSEQ (CLKCTRL + 0x0110)
38
39#define BP_CPU_INTERRUPT_WAIT 12
40#define BP_CLKSEQ_BYPASS_SAIF 0
41#define BP_CLKSEQ_BYPASS_SSP 5
42#define BP_SAIF_DIV_FRAC_EN 16
43#define BP_FRAC_IOFRAC 24
44
45static void __init clk_misc_init(void)
46{
47 u32 val;
48
49 /* Gate off cpu clock in WFI for power saving */
50 __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
51
52 /* Clear BYPASS for SAIF */
53 __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ);
54
55 /* SAIF has to use frac div for functional operation */
56 val = readl_relaxed(SAIF);
57 val |= 1 << BP_SAIF_DIV_FRAC_EN;
58 writel_relaxed(val, SAIF);
59
60 /*
61 * Source ssp clock from ref_io than ref_xtal,
62 * as ref_xtal only provides 24 MHz as maximum.
63 */
64 __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ);
65
66 /*
67 * 480 MHz seems too high to be ssp clock source directly,
68 * so set frac to get a 288 MHz ref_io.
69 */
70 __mxs_clrl(0x3f << BP_FRAC_IOFRAC, FRAC);
71 __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC);
72}
73
74static struct clk_lookup uart_lookups[] __initdata = {
75 { .dev_id = "duart", },
76 { .dev_id = "mxs-auart.0", },
77 { .dev_id = "mxs-auart.1", },
78 { .dev_id = "8006c000.serial", },
79 { .dev_id = "8006e000.serial", },
80 { .dev_id = "80070000.serial", },
81};
82
83static struct clk_lookup hbus_lookups[] __initdata = {
84 { .dev_id = "imx23-dma-apbh", },
85 { .dev_id = "80004000.dma-apbh", },
86};
87
88static struct clk_lookup xbus_lookups[] __initdata = {
89 { .dev_id = "duart", .con_id = "apb_pclk"},
90 { .dev_id = "80070000.serial", .con_id = "apb_pclk"},
91 { .dev_id = "imx23-dma-apbx", },
92 { .dev_id = "80024000.dma-apbx", },
93};
94
95static struct clk_lookup ssp_lookups[] __initdata = {
96 { .dev_id = "imx23-mmc.0", },
97 { .dev_id = "imx23-mmc.1", },
98 { .dev_id = "80010000.ssp", },
99 { .dev_id = "80034000.ssp", },
100};
101
102static struct clk_lookup lcdif_lookups[] __initdata = {
103 { .dev_id = "imx23-fb", },
104 { .dev_id = "80030000.lcdif", },
105};
106
107static struct clk_lookup gpmi_lookups[] __initdata = {
108 { .dev_id = "imx23-gpmi-nand", },
109 { .dev_id = "8000c000.gpmi", },
110};
111
112static const char *sel_pll[] __initconst = { "pll", "ref_xtal", };
113static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
114static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
115static const char *sel_io[] __initconst = { "ref_io", "ref_xtal", };
116static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
117static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
118
119enum imx23_clk {
120 ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
121 lcdif_sel, gpmi_sel, ssp_sel, emi_sel, cpu, etm_sel, cpu_pll,
122 cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll,
123 emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div,
124 clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif,
125 lcdif, etm, usb, usb_pwr,
126 clk_max
127};
128
129static struct clk *clks[clk_max];
130
131static enum imx23_clk clks_init_on[] __initdata = {
132 cpu, hbus, xbus, emi, uart,
133};
134
135int __init mx23_clocks_init(void)
136{
137 int i;
138
139 clk_misc_init();
140
141 clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
142 clks[pll] = mxs_clk_pll("pll", "ref_xtal", PLLCTRL0, 16, 480000000);
143 clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll", FRAC, 0);
144 clks[ref_emi] = mxs_clk_ref("ref_emi", "pll", FRAC, 1);
145 clks[ref_pix] = mxs_clk_ref("ref_pix", "pll", FRAC, 2);
146 clks[ref_io] = mxs_clk_ref("ref_io", "pll", FRAC, 3);
147 clks[saif_sel] = mxs_clk_mux("saif_sel", CLKSEQ, 0, 1, sel_pll, ARRAY_SIZE(sel_pll));
148 clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 1, 1, sel_pix, ARRAY_SIZE(sel_pix));
149 clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 4, 1, sel_io, ARRAY_SIZE(sel_io));
150 clks[ssp_sel] = mxs_clk_mux("ssp_sel", CLKSEQ, 5, 1, sel_io, ARRAY_SIZE(sel_io));
151 clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 6, 1, emi_sels, ARRAY_SIZE(emi_sels));
152 clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 7, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
153 clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
154 clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
155 clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
156 clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 29);
157 clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
158 clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", PIX, 0, 12, 29);
159 clks[ssp_div] = mxs_clk_div("ssp_div", "ssp_sel", SSP, 0, 9, 29);
160 clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
161 clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
162 clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
163 clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 6, 29);
164 clks[saif_div] = mxs_clk_frac("saif_div", "saif_sel", SAIF, 0, 16, 29);
165 clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
166 clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
167 clks[adc] = mxs_clk_fixed_factor("adc", "clk32k", 1, 16);
168 clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll", 1, 4);
169 clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
170 clks[dri] = mxs_clk_gate("dri", "ref_xtal", XTAL, 28);
171 clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
172 clks[filt] = mxs_clk_gate("filt", "ref_xtal", XTAL, 30);
173 clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
174 clks[ssp] = mxs_clk_gate("ssp", "ssp_div", SSP, 31);
175 clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
176 clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
177 clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
178 clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31);
179 clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31);
180 clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
181 clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2);
182 clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock);
183
184 for (i = 0; i < ARRAY_SIZE(clks); i++)
185 if (IS_ERR(clks[i])) {
186 pr_err("i.MX23 clk %d: register failed with %ld\n",
187 i, PTR_ERR(clks[i]));
188 return PTR_ERR(clks[i]);
189 }
190
191 clk_register_clkdev(clks[clk32k], NULL, "timrot");
192 clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
193 clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
194 clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
195 clk_register_clkdevs(clks[ssp], ssp_lookups, ARRAY_SIZE(ssp_lookups));
196 clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
197 clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
198
199 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
200 clk_prepare_enable(clks[clks_init_on[i]]);
201
202 mxs_timer_init(MX23_INT_TIMER0);
203
204 return 0;
205}
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
new file mode 100644
index 000000000000..2826a2606a29
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -0,0 +1,338 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <mach/common.h>
18#include <mach/mx28.h>
19#include "clk.h"
20
21#define CLKCTRL MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
22#define PLL0CTRL0 (CLKCTRL + 0x0000)
23#define PLL1CTRL0 (CLKCTRL + 0x0020)
24#define PLL2CTRL0 (CLKCTRL + 0x0040)
25#define CPU (CLKCTRL + 0x0050)
26#define HBUS (CLKCTRL + 0x0060)
27#define XBUS (CLKCTRL + 0x0070)
28#define XTAL (CLKCTRL + 0x0080)
29#define SSP0 (CLKCTRL + 0x0090)
30#define SSP1 (CLKCTRL + 0x00a0)
31#define SSP2 (CLKCTRL + 0x00b0)
32#define SSP3 (CLKCTRL + 0x00c0)
33#define GPMI (CLKCTRL + 0x00d0)
34#define SPDIF (CLKCTRL + 0x00e0)
35#define EMI (CLKCTRL + 0x00f0)
36#define SAIF0 (CLKCTRL + 0x0100)
37#define SAIF1 (CLKCTRL + 0x0110)
38#define LCDIF (CLKCTRL + 0x0120)
39#define ETM (CLKCTRL + 0x0130)
40#define ENET (CLKCTRL + 0x0140)
41#define FLEXCAN (CLKCTRL + 0x0160)
42#define FRAC0 (CLKCTRL + 0x01b0)
43#define FRAC1 (CLKCTRL + 0x01c0)
44#define CLKSEQ (CLKCTRL + 0x01d0)
45
46#define BP_CPU_INTERRUPT_WAIT 12
47#define BP_SAIF_DIV_FRAC_EN 16
48#define BP_ENET_DIV_TIME 21
49#define BP_ENET_SLEEP 31
50#define BP_CLKSEQ_BYPASS_SAIF0 0
51#define BP_CLKSEQ_BYPASS_SSP0 3
52#define BP_FRAC0_IO1FRAC 16
53#define BP_FRAC0_IO0FRAC 24
54
55#define DIGCTRL MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
56#define BP_SAIF_CLKMUX 10
57
58/*
59 * HW_SAIF_CLKMUX_SEL:
60 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
61 * clock pins selected for SAIF1 input clocks.
62 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
63 * SAIF0 clock inputs selected for SAIF1 input clocks.
64 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
65 * clocks.
66 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
67 * clocks.
68 */
69int mxs_saif_clkmux_select(unsigned int clkmux)
70{
71 if (clkmux > 0x3)
72 return -EINVAL;
73
74 __mxs_clrl(0x3 << BP_SAIF_CLKMUX, DIGCTRL);
75 __mxs_setl(clkmux << BP_SAIF_CLKMUX, DIGCTRL);
76
77 return 0;
78}
79
80static void __init clk_misc_init(void)
81{
82 u32 val;
83
84 /* Gate off cpu clock in WFI for power saving */
85 __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
86
87 /* 0 is a bad default value for a divider */
88 __mxs_setl(1 << BP_ENET_DIV_TIME, ENET);
89
90 /* Clear BYPASS for SAIF */
91 __mxs_clrl(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ);
92
93 /* SAIF has to use frac div for functional operation */
94 val = readl_relaxed(SAIF0);
95 val |= 1 << BP_SAIF_DIV_FRAC_EN;
96 writel_relaxed(val, SAIF0);
97
98 val = readl_relaxed(SAIF1);
99 val |= 1 << BP_SAIF_DIV_FRAC_EN;
100 writel_relaxed(val, SAIF1);
101
102 /* Extra fec clock setting */
103 val = readl_relaxed(ENET);
104 val &= ~(1 << BP_ENET_SLEEP);
105 writel_relaxed(val, ENET);
106
107 /*
108 * Source ssp clock from ref_io than ref_xtal,
109 * as ref_xtal only provides 24 MHz as maximum.
110 */
111 __mxs_clrl(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ);
112
113 /*
114 * 480 MHz seems too high to be ssp clock source directly,
115 * so set frac0 to get a 288 MHz ref_io0.
116 */
117 val = readl_relaxed(FRAC0);
118 val &= ~(0x3f << BP_FRAC0_IO0FRAC);
119 val |= 30 << BP_FRAC0_IO0FRAC;
120 writel_relaxed(val, FRAC0);
121}
122
123static struct clk_lookup uart_lookups[] __initdata = {
124 { .dev_id = "duart", },
125 { .dev_id = "mxs-auart.0", },
126 { .dev_id = "mxs-auart.1", },
127 { .dev_id = "mxs-auart.2", },
128 { .dev_id = "mxs-auart.3", },
129 { .dev_id = "mxs-auart.4", },
130 { .dev_id = "8006a000.serial", },
131 { .dev_id = "8006c000.serial", },
132 { .dev_id = "8006e000.serial", },
133 { .dev_id = "80070000.serial", },
134 { .dev_id = "80072000.serial", },
135 { .dev_id = "80074000.serial", },
136};
137
138static struct clk_lookup hbus_lookups[] __initdata = {
139 { .dev_id = "imx28-dma-apbh", },
140 { .dev_id = "80004000.dma-apbh", },
141};
142
143static struct clk_lookup xbus_lookups[] __initdata = {
144 { .dev_id = "duart", .con_id = "apb_pclk"},
145 { .dev_id = "80074000.serial", .con_id = "apb_pclk"},
146 { .dev_id = "imx28-dma-apbx", },
147 { .dev_id = "80024000.dma-apbx", },
148};
149
150static struct clk_lookup ssp0_lookups[] __initdata = {
151 { .dev_id = "imx28-mmc.0", },
152 { .dev_id = "80010000.ssp", },
153};
154
155static struct clk_lookup ssp1_lookups[] __initdata = {
156 { .dev_id = "imx28-mmc.1", },
157 { .dev_id = "80012000.ssp", },
158};
159
160static struct clk_lookup ssp2_lookups[] __initdata = {
161 { .dev_id = "imx28-mmc.2", },
162 { .dev_id = "80014000.ssp", },
163};
164
165static struct clk_lookup ssp3_lookups[] __initdata = {
166 { .dev_id = "imx28-mmc.3", },
167 { .dev_id = "80016000.ssp", },
168};
169
170static struct clk_lookup lcdif_lookups[] __initdata = {
171 { .dev_id = "imx28-fb", },
172 { .dev_id = "80030000.lcdif", },
173};
174
175static struct clk_lookup gpmi_lookups[] __initdata = {
176 { .dev_id = "imx28-gpmi-nand", },
177 { .dev_id = "8000c000.gpmi", },
178};
179
180static struct clk_lookup fec_lookups[] __initdata = {
181 { .dev_id = "imx28-fec.0", },
182 { .dev_id = "imx28-fec.1", },
183 { .dev_id = "800f0000.ethernet", },
184 { .dev_id = "800f4000.ethernet", },
185};
186
187static struct clk_lookup can0_lookups[] __initdata = {
188 { .dev_id = "flexcan.0", },
189 { .dev_id = "80032000.can", },
190};
191
192static struct clk_lookup can1_lookups[] __initdata = {
193 { .dev_id = "flexcan.1", },
194 { .dev_id = "80034000.can", },
195};
196
197static struct clk_lookup saif0_lookups[] __initdata = {
198 { .dev_id = "mxs-saif.0", },
199 { .dev_id = "80042000.saif", },
200};
201
202static struct clk_lookup saif1_lookups[] __initdata = {
203 { .dev_id = "mxs-saif.1", },
204 { .dev_id = "80046000.saif", },
205};
206
207static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
208static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", };
209static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", };
210static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
211static const char *sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", };
212static const char *sel_pll0[] __initconst = { "pll0", "ref_xtal", };
213static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
214static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
215static const char *ptp_sels[] __initconst = { "ref_xtal", "pll0", };
216
217enum imx28_clk {
218 ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
219 ref_pix, ref_hsadc, ref_gpmi, saif0_sel, saif1_sel, gpmi_sel,
220 ssp0_sel, ssp1_sel, ssp2_sel, ssp3_sel, emi_sel, etm_sel,
221 lcdif_sel, cpu, ptp_sel, cpu_pll, cpu_xtal, hbus, xbus,
222 ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
223 emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
224 clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
225 ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
226 fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
227 clk_max
228};
229
230static struct clk *clks[clk_max];
231
232static enum imx28_clk clks_init_on[] __initdata = {
233 cpu, hbus, xbus, emi, uart,
234};
235
236int __init mx28_clocks_init(void)
237{
238 int i;
239
240 clk_misc_init();
241
242 clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
243 clks[pll0] = mxs_clk_pll("pll0", "ref_xtal", PLL0CTRL0, 17, 480000000);
244 clks[pll1] = mxs_clk_pll("pll1", "ref_xtal", PLL1CTRL0, 17, 480000000);
245 clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000);
246 clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0);
247 clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1);
248 clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2);
249 clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3);
250 clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0);
251 clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1);
252 clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2);
253 clks[saif0_sel] = mxs_clk_mux("saif0_sel", CLKSEQ, 0, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
254 clks[saif1_sel] = mxs_clk_mux("saif1_sel", CLKSEQ, 1, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
255 clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 2, 1, sel_gpmi, ARRAY_SIZE(sel_gpmi));
256 clks[ssp0_sel] = mxs_clk_mux("ssp0_sel", CLKSEQ, 3, 1, sel_io0, ARRAY_SIZE(sel_io0));
257 clks[ssp1_sel] = mxs_clk_mux("ssp1_sel", CLKSEQ, 4, 1, sel_io0, ARRAY_SIZE(sel_io0));
258 clks[ssp2_sel] = mxs_clk_mux("ssp2_sel", CLKSEQ, 5, 1, sel_io1, ARRAY_SIZE(sel_io1));
259 clks[ssp3_sel] = mxs_clk_mux("ssp3_sel", CLKSEQ, 6, 1, sel_io1, ARRAY_SIZE(sel_io1));
260 clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 7, 1, emi_sels, ARRAY_SIZE(emi_sels));
261 clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
262 clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 14, 1, sel_pix, ARRAY_SIZE(sel_pix));
263 clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 18, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
264 clks[ptp_sel] = mxs_clk_mux("ptp_sel", ENET, 19, 1, ptp_sels, ARRAY_SIZE(ptp_sels));
265 clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
266 clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
267 clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 31);
268 clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
269 clks[ssp0_div] = mxs_clk_div("ssp0_div", "ssp0_sel", SSP0, 0, 9, 29);
270 clks[ssp1_div] = mxs_clk_div("ssp1_div", "ssp1_sel", SSP1, 0, 9, 29);
271 clks[ssp2_div] = mxs_clk_div("ssp2_div", "ssp2_sel", SSP2, 0, 9, 29);
272 clks[ssp3_div] = mxs_clk_div("ssp3_div", "ssp3_sel", SSP3, 0, 9, 29);
273 clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
274 clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
275 clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
276 clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", LCDIF, 0, 13, 29);
277 clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 7, 29);
278 clks[ptp] = mxs_clk_div("ptp", "ptp_sel", ENET, 21, 6, 27);
279 clks[saif0_div] = mxs_clk_frac("saif0_div", "saif0_sel", SAIF0, 0, 16, 29);
280 clks[saif1_div] = mxs_clk_frac("saif1_div", "saif1_sel", SAIF1, 0, 16, 29);
281 clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
282 clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
283 clks[lradc] = mxs_clk_fixed_factor("lradc", "clk32k", 1, 16);
284 clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll0", 1, 4);
285 clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
286 clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
287 clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
288 clks[ssp0] = mxs_clk_gate("ssp0", "ssp0_div", SSP0, 31);
289 clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
290 clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
291 clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
292 clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
293 clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
294 clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
295 clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);
296 clks[saif1] = mxs_clk_gate("saif1", "saif1_div", SAIF1, 31);
297 clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", LCDIF, 31);
298 clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
299 clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30);
300 clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30);
301 clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28);
302 clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2);
303 clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16);
304 clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock);
305 clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock);
306 clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock);
307
308 for (i = 0; i < ARRAY_SIZE(clks); i++)
309 if (IS_ERR(clks[i])) {
310 pr_err("i.MX28 clk %d: register failed with %ld\n",
311 i, PTR_ERR(clks[i]));
312 return PTR_ERR(clks[i]);
313 }
314
315 clk_register_clkdev(clks[clk32k], NULL, "timrot");
316 clk_register_clkdev(clks[enet_out], NULL, "enet_out");
317 clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
318 clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
319 clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
320 clk_register_clkdevs(clks[ssp0], ssp0_lookups, ARRAY_SIZE(ssp0_lookups));
321 clk_register_clkdevs(clks[ssp1], ssp1_lookups, ARRAY_SIZE(ssp1_lookups));
322 clk_register_clkdevs(clks[ssp2], ssp2_lookups, ARRAY_SIZE(ssp2_lookups));
323 clk_register_clkdevs(clks[ssp3], ssp3_lookups, ARRAY_SIZE(ssp3_lookups));
324 clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
325 clk_register_clkdevs(clks[saif0], saif0_lookups, ARRAY_SIZE(saif0_lookups));
326 clk_register_clkdevs(clks[saif1], saif1_lookups, ARRAY_SIZE(saif1_lookups));
327 clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
328 clk_register_clkdevs(clks[fec], fec_lookups, ARRAY_SIZE(fec_lookups));
329 clk_register_clkdevs(clks[can0], can0_lookups, ARRAY_SIZE(can0_lookups));
330 clk_register_clkdevs(clks[can1], can1_lookups, ARRAY_SIZE(can1_lookups));
331
332 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
333 clk_prepare_enable(clks[clks_init_on[i]]);
334
335 mxs_timer_init(MX28_INT_TIMER0);
336
337 return 0;
338}
diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c
new file mode 100644
index 000000000000..fadae41833ec
--- /dev/null
+++ b/drivers/clk/mxs/clk-pll.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include "clk.h"
19
20/**
21 * struct clk_pll - mxs pll clock
22 * @hw: clk_hw for the pll
23 * @base: base address of the pll
24 * @power: the shift of power bit
25 * @rate: the clock rate of the pll
26 *
27 * The mxs pll is a fixed rate clock with power and gate control,
28 * and the shift of gate bit is always 31.
29 */
30struct clk_pll {
31 struct clk_hw hw;
32 void __iomem *base;
33 u8 power;
34 unsigned long rate;
35};
36
37#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
38
39static int clk_pll_prepare(struct clk_hw *hw)
40{
41 struct clk_pll *pll = to_clk_pll(hw);
42
43 writel_relaxed(1 << pll->power, pll->base + SET);
44
45 udelay(10);
46
47 return 0;
48}
49
50static void clk_pll_unprepare(struct clk_hw *hw)
51{
52 struct clk_pll *pll = to_clk_pll(hw);
53
54 writel_relaxed(1 << pll->power, pll->base + CLR);
55}
56
57static int clk_pll_enable(struct clk_hw *hw)
58{
59 struct clk_pll *pll = to_clk_pll(hw);
60
61 writel_relaxed(1 << 31, pll->base + CLR);
62
63 return 0;
64}
65
66static void clk_pll_disable(struct clk_hw *hw)
67{
68 struct clk_pll *pll = to_clk_pll(hw);
69
70 writel_relaxed(1 << 31, pll->base + SET);
71}
72
73static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75{
76 struct clk_pll *pll = to_clk_pll(hw);
77
78 return pll->rate;
79}
80
81static const struct clk_ops clk_pll_ops = {
82 .prepare = clk_pll_prepare,
83 .unprepare = clk_pll_unprepare,
84 .enable = clk_pll_enable,
85 .disable = clk_pll_disable,
86 .recalc_rate = clk_pll_recalc_rate,
87};
88
89struct clk *mxs_clk_pll(const char *name, const char *parent_name,
90 void __iomem *base, u8 power, unsigned long rate)
91{
92 struct clk_pll *pll;
93 struct clk *clk;
94 struct clk_init_data init;
95
96 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
97 if (!pll)
98 return ERR_PTR(-ENOMEM);
99
100 init.name = name;
101 init.ops = &clk_pll_ops;
102 init.flags = 0;
103 init.parent_names = (parent_name ? &parent_name: NULL);
104 init.num_parents = (parent_name ? 1 : 0);
105
106 pll->base = base;
107 pll->rate = rate;
108 pll->power = power;
109 pll->hw.init = &init;
110
111 clk = clk_register(NULL, &pll->hw);
112 if (IS_ERR(clk))
113 kfree(pll);
114
115 return clk;
116}
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
new file mode 100644
index 000000000000..4adeed6c2f94
--- /dev/null
+++ b/drivers/clk/mxs/clk-ref.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include "clk.h"
18
19/**
20 * struct clk_ref - mxs reference clock
21 * @hw: clk_hw for the reference clock
22 * @reg: register address
23 * @idx: the index of the reference clock within the same register
24 *
25 * The mxs reference clock sources from pll. Every 4 reference clocks share
26 * one register space, and @idx is used to identify them. Each reference
27 * clock has a gate control and a fractional * divider. The rate is calculated
28 * as pll rate * (18 / FRAC), where FRAC = 18 ~ 35.
29 */
30struct clk_ref {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 idx;
34};
35
36#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, hw)
37
38static int clk_ref_enable(struct clk_hw *hw)
39{
40 struct clk_ref *ref = to_clk_ref(hw);
41
42 writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + CLR);
43
44 return 0;
45}
46
47static void clk_ref_disable(struct clk_hw *hw)
48{
49 struct clk_ref *ref = to_clk_ref(hw);
50
51 writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + SET);
52}
53
54static unsigned long clk_ref_recalc_rate(struct clk_hw *hw,
55 unsigned long parent_rate)
56{
57 struct clk_ref *ref = to_clk_ref(hw);
58 u64 tmp = parent_rate;
59 u8 frac = (readl_relaxed(ref->reg) >> (ref->idx * 8)) & 0x3f;
60
61 tmp *= 18;
62 do_div(tmp, frac);
63
64 return tmp;
65}
66
67static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
68 unsigned long *prate)
69{
70 unsigned long parent_rate = *prate;
71 u64 tmp = parent_rate;
72 u8 frac;
73
74 tmp = tmp * 18 + rate / 2;
75 do_div(tmp, rate);
76 frac = tmp;
77
78 if (frac < 18)
79 frac = 18;
80 else if (frac > 35)
81 frac = 35;
82
83 tmp = parent_rate;
84 tmp *= 18;
85 do_div(tmp, frac);
86
87 return tmp;
88}
89
90static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate,
91 unsigned long parent_rate)
92{
93 struct clk_ref *ref = to_clk_ref(hw);
94 unsigned long flags;
95 u64 tmp = parent_rate;
96 u32 val;
97 u8 frac, shift = ref->idx * 8;
98
99 tmp = tmp * 18 + rate / 2;
100 do_div(tmp, rate);
101 frac = tmp;
102
103 if (frac < 18)
104 frac = 18;
105 else if (frac > 35)
106 frac = 35;
107
108 spin_lock_irqsave(&mxs_lock, flags);
109
110 val = readl_relaxed(ref->reg);
111 val &= ~(0x3f << shift);
112 val |= frac << shift;
113 writel_relaxed(val, ref->reg);
114
115 spin_unlock_irqrestore(&mxs_lock, flags);
116
117 return 0;
118}
119
120static const struct clk_ops clk_ref_ops = {
121 .enable = clk_ref_enable,
122 .disable = clk_ref_disable,
123 .recalc_rate = clk_ref_recalc_rate,
124 .round_rate = clk_ref_round_rate,
125 .set_rate = clk_ref_set_rate,
126};
127
128struct clk *mxs_clk_ref(const char *name, const char *parent_name,
129 void __iomem *reg, u8 idx)
130{
131 struct clk_ref *ref;
132 struct clk *clk;
133 struct clk_init_data init;
134
135 ref = kzalloc(sizeof(*ref), GFP_KERNEL);
136 if (!ref)
137 return ERR_PTR(-ENOMEM);
138
139 init.name = name;
140 init.ops = &clk_ref_ops;
141 init.flags = 0;
142 init.parent_names = (parent_name ? &parent_name: NULL);
143 init.num_parents = (parent_name ? 1 : 0);
144
145 ref->reg = reg;
146 ref->idx = idx;
147 ref->hw.init = &init;
148
149 clk = clk_register(NULL, &ref->hw);
150 if (IS_ERR(clk))
151 kfree(ref);
152
153 return clk;
154}
diff --git a/drivers/clk/mxs/clk.c b/drivers/clk/mxs/clk.c
new file mode 100644
index 000000000000..b24d56067c80
--- /dev/null
+++ b/drivers/clk/mxs/clk.c
@@ -0,0 +1,28 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/jiffies.h>
15#include <linux/spinlock.h>
16
17DEFINE_SPINLOCK(mxs_lock);
18
19int mxs_clk_wait(void __iomem *reg, u8 shift)
20{
21 unsigned long timeout = jiffies + msecs_to_jiffies(10);
22
23 while (readl_relaxed(reg) & (1 << shift))
24 if (time_after(jiffies, timeout))
25 return -ETIMEDOUT;
26
27 return 0;
28}
diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h
new file mode 100644
index 000000000000..81421e28e69c
--- /dev/null
+++ b/drivers/clk/mxs/clk.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#ifndef __MXS_CLK_H
13#define __MXS_CLK_H
14
15#include <linux/clk.h>
16#include <linux/clk-provider.h>
17#include <linux/spinlock.h>
18
19#define SET 0x4
20#define CLR 0x8
21
22extern spinlock_t mxs_lock;
23
24int mxs_clk_wait(void __iomem *reg, u8 shift);
25
26struct clk *mxs_clk_pll(const char *name, const char *parent_name,
27 void __iomem *base, u8 power, unsigned long rate);
28
29struct clk *mxs_clk_ref(const char *name, const char *parent_name,
30 void __iomem *reg, u8 idx);
31
32struct clk *mxs_clk_div(const char *name, const char *parent_name,
33 void __iomem *reg, u8 shift, u8 width, u8 busy);
34
35struct clk *mxs_clk_frac(const char *name, const char *parent_name,
36 void __iomem *reg, u8 shift, u8 width, u8 busy);
37
38static inline struct clk *mxs_clk_fixed(const char *name, int rate)
39{
40 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
41}
42
43static inline struct clk *mxs_clk_gate(const char *name,
44 const char *parent_name, void __iomem *reg, u8 shift)
45{
46 return clk_register_gate(NULL, name, parent_name, CLK_SET_RATE_PARENT,
47 reg, shift, CLK_GATE_SET_TO_DISABLE,
48 &mxs_lock);
49}
50
51static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
52 u8 shift, u8 width, const char **parent_names, int num_parents)
53{
54 return clk_register_mux(NULL, name, parent_names, num_parents,
55 CLK_SET_RATE_PARENT, reg, shift, width,
56 0, &mxs_lock);
57}
58
59static inline struct clk *mxs_clk_fixed_factor(const char *name,
60 const char *parent_name, unsigned int mult, unsigned int div)
61{
62 return clk_register_fixed_factor(NULL, name, parent_name,
63 CLK_SET_RATE_PARENT, mult, div);
64}
65
66#endif /* __MXS_CLK_H */
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index ef378b5b17e4..aadeb5be9dba 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -238,6 +238,7 @@ config IMX_DMA
238config MXS_DMA 238config MXS_DMA
239 bool "MXS DMA support" 239 bool "MXS DMA support"
240 depends on SOC_IMX23 || SOC_IMX28 240 depends on SOC_IMX23 || SOC_IMX28
241 select STMP_DEVICE
241 select DMA_ENGINE 242 select DMA_ENGINE
242 help 243 help
243 Support the MXS DMA engine. This engine including APBH-DMA 244 Support the MXS DMA engine. This engine including APBH-DMA
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 655d4ce6ed0d..1cb9b974493f 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -22,11 +22,14 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/dmaengine.h> 23#include <linux/dmaengine.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/module.h>
25#include <linux/fsl/mxs-dma.h> 26#include <linux/fsl/mxs-dma.h>
27#include <linux/stmp_device.h>
28#include <linux/of.h>
29#include <linux/of_device.h>
26 30
27#include <asm/irq.h> 31#include <asm/irq.h>
28#include <mach/mxs.h> 32#include <mach/mxs.h>
29#include <mach/common.h>
30 33
31#include "dmaengine.h" 34#include "dmaengine.h"
32 35
@@ -36,12 +39,8 @@
36 * dma can program the controller registers of peripheral devices. 39 * dma can program the controller registers of peripheral devices.
37 */ 40 */
38 41
39#define MXS_DMA_APBH 0 42#define dma_is_apbh(mxs_dma) ((mxs_dma)->type == MXS_DMA_APBH)
40#define MXS_DMA_APBX 1 43#define apbh_is_old(mxs_dma) ((mxs_dma)->dev_id == IMX23_DMA)
41#define dma_is_apbh() (mxs_dma->dev_id == MXS_DMA_APBH)
42
43#define APBH_VERSION_LATEST 3
44#define apbh_is_old() (mxs_dma->version < APBH_VERSION_LATEST)
45 44
46#define HW_APBHX_CTRL0 0x000 45#define HW_APBHX_CTRL0 0x000
47#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29) 46#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
@@ -51,13 +50,14 @@
51#define HW_APBHX_CTRL2 0x020 50#define HW_APBHX_CTRL2 0x020
52#define HW_APBHX_CHANNEL_CTRL 0x030 51#define HW_APBHX_CHANNEL_CTRL 0x030
53#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16 52#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16
54#define HW_APBH_VERSION (cpu_is_mx23() ? 0x3f0 : 0x800) 53/*
55#define HW_APBX_VERSION 0x800 54 * The offset of NXTCMDAR register is different per both dma type and version,
56#define BP_APBHX_VERSION_MAJOR 24 55 * while stride for each channel is all the same 0x70.
57#define HW_APBHX_CHn_NXTCMDAR(n) \ 56 */
58 (((dma_is_apbh() && apbh_is_old()) ? 0x050 : 0x110) + (n) * 0x70) 57#define HW_APBHX_CHn_NXTCMDAR(d, n) \
59#define HW_APBHX_CHn_SEMA(n) \ 58 (((dma_is_apbh(d) && apbh_is_old(d)) ? 0x050 : 0x110) + (n) * 0x70)
60 (((dma_is_apbh() && apbh_is_old()) ? 0x080 : 0x140) + (n) * 0x70) 59#define HW_APBHX_CHn_SEMA(d, n) \
60 (((dma_is_apbh(d) && apbh_is_old(d)) ? 0x080 : 0x140) + (n) * 0x70)
61 61
62/* 62/*
63 * ccw bits definitions 63 * ccw bits definitions
@@ -121,9 +121,19 @@ struct mxs_dma_chan {
121#define MXS_DMA_CHANNELS 16 121#define MXS_DMA_CHANNELS 16
122#define MXS_DMA_CHANNELS_MASK 0xffff 122#define MXS_DMA_CHANNELS_MASK 0xffff
123 123
124enum mxs_dma_devtype {
125 MXS_DMA_APBH,
126 MXS_DMA_APBX,
127};
128
129enum mxs_dma_id {
130 IMX23_DMA,
131 IMX28_DMA,
132};
133
124struct mxs_dma_engine { 134struct mxs_dma_engine {
125 int dev_id; 135 enum mxs_dma_id dev_id;
126 unsigned int version; 136 enum mxs_dma_devtype type;
127 void __iomem *base; 137 void __iomem *base;
128 struct clk *clk; 138 struct clk *clk;
129 struct dma_device dma_device; 139 struct dma_device dma_device;
@@ -131,17 +141,86 @@ struct mxs_dma_engine {
131 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; 141 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
132}; 142};
133 143
144struct mxs_dma_type {
145 enum mxs_dma_id id;
146 enum mxs_dma_devtype type;
147};
148
149static struct mxs_dma_type mxs_dma_types[] = {
150 {
151 .id = IMX23_DMA,
152 .type = MXS_DMA_APBH,
153 }, {
154 .id = IMX23_DMA,
155 .type = MXS_DMA_APBX,
156 }, {
157 .id = IMX28_DMA,
158 .type = MXS_DMA_APBH,
159 }, {
160 .id = IMX28_DMA,
161 .type = MXS_DMA_APBX,
162 }
163};
164
165static struct platform_device_id mxs_dma_ids[] = {
166 {
167 .name = "imx23-dma-apbh",
168 .driver_data = (kernel_ulong_t) &mxs_dma_types[0],
169 }, {
170 .name = "imx23-dma-apbx",
171 .driver_data = (kernel_ulong_t) &mxs_dma_types[1],
172 }, {
173 .name = "imx28-dma-apbh",
174 .driver_data = (kernel_ulong_t) &mxs_dma_types[2],
175 }, {
176 .name = "imx28-dma-apbx",
177 .driver_data = (kernel_ulong_t) &mxs_dma_types[3],
178 }, {
179 /* end of list */
180 }
181};
182
183static const struct of_device_id mxs_dma_dt_ids[] = {
184 { .compatible = "fsl,imx23-dma-apbh", .data = &mxs_dma_ids[0], },
185 { .compatible = "fsl,imx23-dma-apbx", .data = &mxs_dma_ids[1], },
186 { .compatible = "fsl,imx28-dma-apbh", .data = &mxs_dma_ids[2], },
187 { .compatible = "fsl,imx28-dma-apbx", .data = &mxs_dma_ids[3], },
188 { /* sentinel */ }
189};
190MODULE_DEVICE_TABLE(of, mxs_dma_dt_ids);
191
192static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
193{
194 return container_of(chan, struct mxs_dma_chan, chan);
195}
196
197int mxs_dma_is_apbh(struct dma_chan *chan)
198{
199 struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
200 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
201
202 return dma_is_apbh(mxs_dma);
203}
204
205int mxs_dma_is_apbx(struct dma_chan *chan)
206{
207 struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
208 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
209
210 return !dma_is_apbh(mxs_dma);
211}
212
134static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan) 213static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
135{ 214{
136 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 215 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
137 int chan_id = mxs_chan->chan.chan_id; 216 int chan_id = mxs_chan->chan.chan_id;
138 217
139 if (dma_is_apbh() && apbh_is_old()) 218 if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
140 writel(1 << (chan_id + BP_APBH_CTRL0_RESET_CHANNEL), 219 writel(1 << (chan_id + BP_APBH_CTRL0_RESET_CHANNEL),
141 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 220 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
142 else 221 else
143 writel(1 << (chan_id + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL), 222 writel(1 << (chan_id + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL),
144 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR); 223 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
145} 224}
146 225
147static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan) 226static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
@@ -151,10 +230,10 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
151 230
152 /* set cmd_addr up */ 231 /* set cmd_addr up */
153 writel(mxs_chan->ccw_phys, 232 writel(mxs_chan->ccw_phys,
154 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id)); 233 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(mxs_dma, chan_id));
155 234
156 /* write 1 to SEMA to kick off the channel */ 235 /* write 1 to SEMA to kick off the channel */
157 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id)); 236 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(mxs_dma, chan_id));
158} 237}
159 238
160static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan) 239static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
@@ -168,12 +247,12 @@ static void mxs_dma_pause_chan(struct mxs_dma_chan *mxs_chan)
168 int chan_id = mxs_chan->chan.chan_id; 247 int chan_id = mxs_chan->chan.chan_id;
169 248
170 /* freeze the channel */ 249 /* freeze the channel */
171 if (dma_is_apbh() && apbh_is_old()) 250 if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
172 writel(1 << chan_id, 251 writel(1 << chan_id,
173 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 252 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
174 else 253 else
175 writel(1 << chan_id, 254 writel(1 << chan_id,
176 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR); 255 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
177 256
178 mxs_chan->status = DMA_PAUSED; 257 mxs_chan->status = DMA_PAUSED;
179} 258}
@@ -184,21 +263,16 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
184 int chan_id = mxs_chan->chan.chan_id; 263 int chan_id = mxs_chan->chan.chan_id;
185 264
186 /* unfreeze the channel */ 265 /* unfreeze the channel */
187 if (dma_is_apbh() && apbh_is_old()) 266 if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
188 writel(1 << chan_id, 267 writel(1 << chan_id,
189 mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR); 268 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR);
190 else 269 else
191 writel(1 << chan_id, 270 writel(1 << chan_id,
192 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_CLR_ADDR); 271 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_CLR);
193 272
194 mxs_chan->status = DMA_IN_PROGRESS; 273 mxs_chan->status = DMA_IN_PROGRESS;
195} 274}
196 275
197static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
198{
199 return container_of(chan, struct mxs_dma_chan, chan);
200}
201
202static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx) 276static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
203{ 277{
204 return dma_cookie_assign(tx); 278 return dma_cookie_assign(tx);
@@ -220,11 +294,11 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
220 /* completion status */ 294 /* completion status */
221 stat1 = readl(mxs_dma->base + HW_APBHX_CTRL1); 295 stat1 = readl(mxs_dma->base + HW_APBHX_CTRL1);
222 stat1 &= MXS_DMA_CHANNELS_MASK; 296 stat1 &= MXS_DMA_CHANNELS_MASK;
223 writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + MXS_CLR_ADDR); 297 writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR);
224 298
225 /* error status */ 299 /* error status */
226 stat2 = readl(mxs_dma->base + HW_APBHX_CTRL2); 300 stat2 = readl(mxs_dma->base + HW_APBHX_CTRL2);
227 writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + MXS_CLR_ADDR); 301 writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + STMP_OFFSET_REG_CLR);
228 302
229 /* 303 /*
230 * When both completion and error of termination bits set at the 304 * When both completion and error of termination bits set at the
@@ -567,27 +641,21 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
567 if (ret) 641 if (ret)
568 return ret; 642 return ret;
569 643
570 ret = mxs_reset_block(mxs_dma->base); 644 ret = stmp_reset_block(mxs_dma->base);
571 if (ret) 645 if (ret)
572 goto err_out; 646 goto err_out;
573 647
574 /* only major version matters */
575 mxs_dma->version = readl(mxs_dma->base +
576 ((mxs_dma->dev_id == MXS_DMA_APBX) ?
577 HW_APBX_VERSION : HW_APBH_VERSION)) >>
578 BP_APBHX_VERSION_MAJOR;
579
580 /* enable apbh burst */ 648 /* enable apbh burst */
581 if (dma_is_apbh()) { 649 if (dma_is_apbh(mxs_dma)) {
582 writel(BM_APBH_CTRL0_APB_BURST_EN, 650 writel(BM_APBH_CTRL0_APB_BURST_EN,
583 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 651 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
584 writel(BM_APBH_CTRL0_APB_BURST8_EN, 652 writel(BM_APBH_CTRL0_APB_BURST8_EN,
585 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 653 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
586 } 654 }
587 655
588 /* enable irq for all the channels */ 656 /* enable irq for all the channels */
589 writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS, 657 writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS,
590 mxs_dma->base + HW_APBHX_CTRL1 + MXS_SET_ADDR); 658 mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET);
591 659
592err_out: 660err_out:
593 clk_disable_unprepare(mxs_dma->clk); 661 clk_disable_unprepare(mxs_dma->clk);
@@ -596,8 +664,9 @@ err_out:
596 664
597static int __init mxs_dma_probe(struct platform_device *pdev) 665static int __init mxs_dma_probe(struct platform_device *pdev)
598{ 666{
599 const struct platform_device_id *id_entry = 667 const struct platform_device_id *id_entry;
600 platform_get_device_id(pdev); 668 const struct of_device_id *of_id;
669 const struct mxs_dma_type *dma_type;
601 struct mxs_dma_engine *mxs_dma; 670 struct mxs_dma_engine *mxs_dma;
602 struct resource *iores; 671 struct resource *iores;
603 int ret, i; 672 int ret, i;
@@ -606,7 +675,15 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
606 if (!mxs_dma) 675 if (!mxs_dma)
607 return -ENOMEM; 676 return -ENOMEM;
608 677
609 mxs_dma->dev_id = id_entry->driver_data; 678 of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev);
679 if (of_id)
680 id_entry = of_id->data;
681 else
682 id_entry = platform_get_device_id(pdev);
683
684 dma_type = (struct mxs_dma_type *)id_entry->driver_data;
685 mxs_dma->type = dma_type->type;
686 mxs_dma->dev_id = dma_type->id;
610 687
611 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 688 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
612 689
@@ -689,23 +766,12 @@ err_request_region:
689 return ret; 766 return ret;
690} 767}
691 768
692static struct platform_device_id mxs_dma_type[] = {
693 {
694 .name = "mxs-dma-apbh",
695 .driver_data = MXS_DMA_APBH,
696 }, {
697 .name = "mxs-dma-apbx",
698 .driver_data = MXS_DMA_APBX,
699 }, {
700 /* end of list */
701 }
702};
703
704static struct platform_driver mxs_dma_driver = { 769static struct platform_driver mxs_dma_driver = {
705 .driver = { 770 .driver = {
706 .name = "mxs-dma", 771 .name = "mxs-dma",
772 .of_match_table = mxs_dma_dt_ids,
707 }, 773 },
708 .id_table = mxs_dma_type, 774 .id_table = mxs_dma_ids,
709}; 775};
710 776
711static int __init mxs_dma_module_init(void) 777static int __init mxs_dma_module_init(void)
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 385c58e8405b..429228b52acd 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -25,23 +25,25 @@
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/irq.h> 26#include <linux/irq.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/of.h>
29#include <linux/of_address.h>
30#include <linux/of_device.h>
28#include <linux/platform_device.h> 31#include <linux/platform_device.h>
29#include <linux/slab.h> 32#include <linux/slab.h>
30#include <linux/basic_mmio_gpio.h> 33#include <linux/basic_mmio_gpio.h>
31#include <linux/module.h> 34#include <linux/module.h>
32#include <mach/mxs.h>
33 35
34#define MXS_SET 0x4 36#define MXS_SET 0x4
35#define MXS_CLR 0x8 37#define MXS_CLR 0x8
36 38
37#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) 39#define PINCTRL_DOUT(p) ((is_imx23_gpio(p) ? 0x0500 : 0x0700) + (p->id) * 0x10)
38#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) 40#define PINCTRL_DIN(p) ((is_imx23_gpio(p) ? 0x0600 : 0x0900) + (p->id) * 0x10)
39#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10) 41#define PINCTRL_DOE(p) ((is_imx23_gpio(p) ? 0x0700 : 0x0b00) + (p->id) * 0x10)
40#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10) 42#define PINCTRL_PIN2IRQ(p) ((is_imx23_gpio(p) ? 0x0800 : 0x1000) + (p->id) * 0x10)
41#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10) 43#define PINCTRL_IRQEN(p) ((is_imx23_gpio(p) ? 0x0900 : 0x1100) + (p->id) * 0x10)
42#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10) 44#define PINCTRL_IRQLEV(p) ((is_imx23_gpio(p) ? 0x0a00 : 0x1200) + (p->id) * 0x10)
43#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10) 45#define PINCTRL_IRQPOL(p) ((is_imx23_gpio(p) ? 0x0b00 : 0x1300) + (p->id) * 0x10)
44#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10) 46#define PINCTRL_IRQSTAT(p) ((is_imx23_gpio(p) ? 0x0c00 : 0x1400) + (p->id) * 0x10)
45 47
46#define GPIO_INT_FALL_EDGE 0x0 48#define GPIO_INT_FALL_EDGE 0x0
47#define GPIO_INT_LOW_LEV 0x1 49#define GPIO_INT_LOW_LEV 0x1
@@ -52,14 +54,30 @@
52 54
53#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) 55#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
54 56
57enum mxs_gpio_id {
58 IMX23_GPIO,
59 IMX28_GPIO,
60};
61
55struct mxs_gpio_port { 62struct mxs_gpio_port {
56 void __iomem *base; 63 void __iomem *base;
57 int id; 64 int id;
58 int irq; 65 int irq;
59 int virtual_irq_start; 66 int virtual_irq_start;
60 struct bgpio_chip bgc; 67 struct bgpio_chip bgc;
68 enum mxs_gpio_id devid;
61}; 69};
62 70
71static inline int is_imx23_gpio(struct mxs_gpio_port *port)
72{
73 return port->devid == IMX23_GPIO;
74}
75
76static inline int is_imx28_gpio(struct mxs_gpio_port *port)
77{
78 return port->devid == IMX28_GPIO;
79}
80
63/* Note: This driver assumes 32 GPIOs are handled in one register */ 81/* Note: This driver assumes 32 GPIOs are handled in one register */
64 82
65static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) 83static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
@@ -89,21 +107,21 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
89 } 107 }
90 108
91 /* set level or edge */ 109 /* set level or edge */
92 pin_addr = port->base + PINCTRL_IRQLEV(port->id); 110 pin_addr = port->base + PINCTRL_IRQLEV(port);
93 if (edge & GPIO_INT_LEV_MASK) 111 if (edge & GPIO_INT_LEV_MASK)
94 writel(pin_mask, pin_addr + MXS_SET); 112 writel(pin_mask, pin_addr + MXS_SET);
95 else 113 else
96 writel(pin_mask, pin_addr + MXS_CLR); 114 writel(pin_mask, pin_addr + MXS_CLR);
97 115
98 /* set polarity */ 116 /* set polarity */
99 pin_addr = port->base + PINCTRL_IRQPOL(port->id); 117 pin_addr = port->base + PINCTRL_IRQPOL(port);
100 if (edge & GPIO_INT_POL_MASK) 118 if (edge & GPIO_INT_POL_MASK)
101 writel(pin_mask, pin_addr + MXS_SET); 119 writel(pin_mask, pin_addr + MXS_SET);
102 else 120 else
103 writel(pin_mask, pin_addr + MXS_CLR); 121 writel(pin_mask, pin_addr + MXS_CLR);
104 122
105 writel(1 << (gpio & 0x1f), 123 writel(1 << (gpio & 0x1f),
106 port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 124 port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
107 125
108 return 0; 126 return 0;
109} 127}
@@ -117,8 +135,8 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
117 135
118 desc->irq_data.chip->irq_ack(&desc->irq_data); 136 desc->irq_data.chip->irq_ack(&desc->irq_data);
119 137
120 irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) & 138 irq_stat = readl(port->base + PINCTRL_IRQSTAT(port)) &
121 readl(port->base + PINCTRL_IRQEN(port->id)); 139 readl(port->base + PINCTRL_IRQEN(port));
122 140
123 while (irq_stat != 0) { 141 while (irq_stat != 0) {
124 int irqoffset = fls(irq_stat) - 1; 142 int irqoffset = fls(irq_stat) - 1;
@@ -164,8 +182,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
164 ct->chip.irq_unmask = irq_gc_mask_set_bit; 182 ct->chip.irq_unmask = irq_gc_mask_set_bit;
165 ct->chip.irq_set_type = mxs_gpio_set_irq_type; 183 ct->chip.irq_set_type = mxs_gpio_set_irq_type;
166 ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; 184 ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
167 ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR; 185 ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
168 ct->regs.mask = PINCTRL_IRQEN(port->id); 186 ct->regs.mask = PINCTRL_IRQEN(port);
169 187
170 irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); 188 irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
171} 189}
@@ -179,60 +197,83 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
179 return port->virtual_irq_start + offset; 197 return port->virtual_irq_start + offset;
180} 198}
181 199
200static struct platform_device_id mxs_gpio_ids[] = {
201 {
202 .name = "imx23-gpio",
203 .driver_data = IMX23_GPIO,
204 }, {
205 .name = "imx28-gpio",
206 .driver_data = IMX28_GPIO,
207 }, {
208 /* sentinel */
209 }
210};
211MODULE_DEVICE_TABLE(platform, mxs_gpio_ids);
212
213static const struct of_device_id mxs_gpio_dt_ids[] = {
214 { .compatible = "fsl,imx23-gpio", .data = (void *) IMX23_GPIO, },
215 { .compatible = "fsl,imx28-gpio", .data = (void *) IMX28_GPIO, },
216 { /* sentinel */ }
217};
218MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids);
219
182static int __devinit mxs_gpio_probe(struct platform_device *pdev) 220static int __devinit mxs_gpio_probe(struct platform_device *pdev)
183{ 221{
222 const struct of_device_id *of_id =
223 of_match_device(mxs_gpio_dt_ids, &pdev->dev);
224 struct device_node *np = pdev->dev.of_node;
225 struct device_node *parent;
184 static void __iomem *base; 226 static void __iomem *base;
185 struct mxs_gpio_port *port; 227 struct mxs_gpio_port *port;
186 struct resource *iores = NULL; 228 struct resource *iores = NULL;
187 int err; 229 int err;
188 230
189 port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); 231 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
190 if (!port) 232 if (!port)
191 return -ENOMEM; 233 return -ENOMEM;
192 234
193 port->id = pdev->id; 235 if (np) {
236 port->id = of_alias_get_id(np, "gpio");
237 if (port->id < 0)
238 return port->id;
239 port->devid = (enum mxs_gpio_id) of_id->data;
240 } else {
241 port->id = pdev->id;
242 port->devid = pdev->id_entry->driver_data;
243 }
194 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; 244 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
195 245
246 port->irq = platform_get_irq(pdev, 0);
247 if (port->irq < 0)
248 return port->irq;
249
196 /* 250 /*
197 * map memory region only once, as all the gpio ports 251 * map memory region only once, as all the gpio ports
198 * share the same one 252 * share the same one
199 */ 253 */
200 if (!base) { 254 if (!base) {
201 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 255 if (np) {
202 if (!iores) { 256 parent = of_get_parent(np);
203 err = -ENODEV; 257 base = of_iomap(parent, 0);
204 goto out_kfree; 258 of_node_put(parent);
205 } 259 } else {
206 260 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
207 if (!request_mem_region(iores->start, resource_size(iores), 261 base = devm_request_and_ioremap(&pdev->dev, iores);
208 pdev->name)) {
209 err = -EBUSY;
210 goto out_kfree;
211 }
212
213 base = ioremap(iores->start, resource_size(iores));
214 if (!base) {
215 err = -ENOMEM;
216 goto out_release_mem;
217 } 262 }
263 if (!base)
264 return -EADDRNOTAVAIL;
218 } 265 }
219 port->base = base; 266 port->base = base;
220 267
221 port->irq = platform_get_irq(pdev, 0);
222 if (port->irq < 0) {
223 err = -EINVAL;
224 goto out_iounmap;
225 }
226
227 /* 268 /*
228 * select the pin interrupt functionality but initially 269 * select the pin interrupt functionality but initially
229 * disable the interrupts 270 * disable the interrupts
230 */ 271 */
231 writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id)); 272 writel(~0U, port->base + PINCTRL_PIN2IRQ(port));
232 writel(0, port->base + PINCTRL_IRQEN(port->id)); 273 writel(0, port->base + PINCTRL_IRQEN(port));
233 274
234 /* clear address has to be used to clear IRQSTAT bits */ 275 /* clear address has to be used to clear IRQSTAT bits */
235 writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 276 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
236 277
237 /* gpio-mxs can be a generic irq chip */ 278 /* gpio-mxs can be a generic irq chip */
238 mxs_gpio_init_gc(port); 279 mxs_gpio_init_gc(port);
@@ -242,41 +283,32 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
242 irq_set_handler_data(port->irq, port); 283 irq_set_handler_data(port->irq, port);
243 284
244 err = bgpio_init(&port->bgc, &pdev->dev, 4, 285 err = bgpio_init(&port->bgc, &pdev->dev, 4,
245 port->base + PINCTRL_DIN(port->id), 286 port->base + PINCTRL_DIN(port),
246 port->base + PINCTRL_DOUT(port->id), NULL, 287 port->base + PINCTRL_DOUT(port), NULL,
247 port->base + PINCTRL_DOE(port->id), NULL, false); 288 port->base + PINCTRL_DOE(port), NULL, false);
248 if (err) 289 if (err)
249 goto out_iounmap; 290 return err;
250 291
251 port->bgc.gc.to_irq = mxs_gpio_to_irq; 292 port->bgc.gc.to_irq = mxs_gpio_to_irq;
252 port->bgc.gc.base = port->id * 32; 293 port->bgc.gc.base = port->id * 32;
253 294
254 err = gpiochip_add(&port->bgc.gc); 295 err = gpiochip_add(&port->bgc.gc);
255 if (err) 296 if (err) {
256 goto out_bgpio_remove; 297 bgpio_remove(&port->bgc);
298 return err;
299 }
257 300
258 return 0; 301 return 0;
259
260out_bgpio_remove:
261 bgpio_remove(&port->bgc);
262out_iounmap:
263 if (iores)
264 iounmap(port->base);
265out_release_mem:
266 if (iores)
267 release_mem_region(iores->start, resource_size(iores));
268out_kfree:
269 kfree(port);
270 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
271 return err;
272} 302}
273 303
274static struct platform_driver mxs_gpio_driver = { 304static struct platform_driver mxs_gpio_driver = {
275 .driver = { 305 .driver = {
276 .name = "gpio-mxs", 306 .name = "gpio-mxs",
277 .owner = THIS_MODULE, 307 .owner = THIS_MODULE,
308 .of_match_table = mxs_gpio_dt_ids,
278 }, 309 },
279 .probe = mxs_gpio_probe, 310 .probe = mxs_gpio_probe,
311 .id_table = mxs_gpio_ids,
280}; 312};
281 313
282static int __init mxs_gpio_init(void) 314static int __init mxs_gpio_init(void)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index dfb84b7ee550..56bce9a8bcbb 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -51,6 +51,7 @@
51#include <linux/of.h> 51#include <linux/of.h>
52#include <linux/of_device.h> 52#include <linux/of_device.h>
53#include <linux/of_i2c.h> 53#include <linux/of_i2c.h>
54#include <linux/pinctrl/consumer.h>
54 55
55#include <mach/irqs.h> 56#include <mach/irqs.h>
56#include <mach/hardware.h> 57#include <mach/hardware.h>
@@ -470,6 +471,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
470 struct imx_i2c_struct *i2c_imx; 471 struct imx_i2c_struct *i2c_imx;
471 struct resource *res; 472 struct resource *res;
472 struct imxi2c_platform_data *pdata = pdev->dev.platform_data; 473 struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
474 struct pinctrl *pinctrl;
473 void __iomem *base; 475 void __iomem *base;
474 resource_size_t res_size; 476 resource_size_t res_size;
475 int irq, bitrate; 477 int irq, bitrate;
@@ -520,6 +522,12 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
520 i2c_imx->base = base; 522 i2c_imx->base = base;
521 i2c_imx->res = res; 523 i2c_imx->res = res;
522 524
525 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
526 if (IS_ERR(pinctrl)) {
527 ret = PTR_ERR(pinctrl);
528 goto fail3;
529 }
530
523 /* Get I2C clock */ 531 /* Get I2C clock */
524 i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk"); 532 i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
525 if (IS_ERR(i2c_imx->clk)) { 533 if (IS_ERR(i2c_imx->clk)) {
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 76b8af44f634..7dca58b0e746 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -26,6 +26,10 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/pinctrl/consumer.h>
30#include <linux/of.h>
31#include <linux/of_device.h>
32#include <linux/of_i2c.h>
29 33
30#include <mach/common.h> 34#include <mach/common.h>
31 35
@@ -325,10 +329,15 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
325 struct device *dev = &pdev->dev; 329 struct device *dev = &pdev->dev;
326 struct mxs_i2c_dev *i2c; 330 struct mxs_i2c_dev *i2c;
327 struct i2c_adapter *adap; 331 struct i2c_adapter *adap;
332 struct pinctrl *pinctrl;
328 struct resource *res; 333 struct resource *res;
329 resource_size_t res_size; 334 resource_size_t res_size;
330 int err, irq; 335 int err, irq;
331 336
337 pinctrl = devm_pinctrl_get_select_default(dev);
338 if (IS_ERR(pinctrl))
339 return PTR_ERR(pinctrl);
340
332 i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL); 341 i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
333 if (!i2c) 342 if (!i2c)
334 return -ENOMEM; 343 return -ENOMEM;
@@ -365,6 +374,7 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
365 adap->algo = &mxs_i2c_algo; 374 adap->algo = &mxs_i2c_algo;
366 adap->dev.parent = dev; 375 adap->dev.parent = dev;
367 adap->nr = pdev->id; 376 adap->nr = pdev->id;
377 adap->dev.of_node = pdev->dev.of_node;
368 i2c_set_adapdata(adap, i2c); 378 i2c_set_adapdata(adap, i2c);
369 err = i2c_add_numbered_adapter(adap); 379 err = i2c_add_numbered_adapter(adap);
370 if (err) { 380 if (err) {
@@ -374,6 +384,8 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
374 return err; 384 return err;
375 } 385 }
376 386
387 of_i2c_register_devices(adap);
388
377 return 0; 389 return 0;
378} 390}
379 391
@@ -393,10 +405,17 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
393 return 0; 405 return 0;
394} 406}
395 407
408static const struct of_device_id mxs_i2c_dt_ids[] = {
409 { .compatible = "fsl,imx28-i2c", },
410 { /* sentinel */ }
411};
412MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
413
396static struct platform_driver mxs_i2c_driver = { 414static struct platform_driver mxs_i2c_driver = {
397 .driver = { 415 .driver = {
398 .name = DRIVER_NAME, 416 .name = DRIVER_NAME,
399 .owner = THIS_MODULE, 417 .owner = THIS_MODULE,
418 .of_match_table = mxs_i2c_dt_ids,
400 }, 419 },
401 .remove = __devexit_p(mxs_i2c_remove), 420 .remove = __devexit_p(mxs_i2c_remove),
402}; 421};
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index e3f5af96ab87..34a90266ab11 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -23,6 +23,9 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/of_gpio.h>
26#include <linux/platform_device.h> 29#include <linux/platform_device.h>
27#include <linux/delay.h> 30#include <linux/delay.h>
28#include <linux/interrupt.h> 31#include <linux/interrupt.h>
@@ -39,18 +42,16 @@
39#include <linux/regulator/consumer.h> 42#include <linux/regulator/consumer.h>
40#include <linux/module.h> 43#include <linux/module.h>
41#include <linux/fsl/mxs-dma.h> 44#include <linux/fsl/mxs-dma.h>
42 45#include <linux/pinctrl/consumer.h>
43#include <mach/mxs.h> 46#include <linux/stmp_device.h>
44#include <mach/common.h> 47#include <linux/mmc/mxs-mmc.h>
45#include <mach/mmc.h>
46 48
47#define DRIVER_NAME "mxs-mmc" 49#define DRIVER_NAME "mxs-mmc"
48 50
49/* card detect polling timeout */ 51/* card detect polling timeout */
50#define MXS_MMC_DETECT_TIMEOUT (HZ/2) 52#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
51 53
52#define SSP_VERSION_LATEST 4 54#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
53#define ssp_is_old() (host->version < SSP_VERSION_LATEST)
54 55
55/* SSP registers */ 56/* SSP registers */
56#define HW_SSP_CTRL0 0x000 57#define HW_SSP_CTRL0 0x000
@@ -85,14 +86,14 @@
85#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) 86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
86#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0) 87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
87#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf) 88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
88#define HW_SSP_TIMING (ssp_is_old() ? 0x050 : 0x070) 89#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
89#define BP_SSP_TIMING_TIMEOUT (16) 90#define BP_SSP_TIMING_TIMEOUT (16)
90#define BM_SSP_TIMING_TIMEOUT (0xffff << 16) 91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
91#define BP_SSP_TIMING_CLOCK_DIVIDE (8) 92#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
92#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) 93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
93#define BP_SSP_TIMING_CLOCK_RATE (0) 94#define BP_SSP_TIMING_CLOCK_RATE (0)
94#define BM_SSP_TIMING_CLOCK_RATE (0xff) 95#define BM_SSP_TIMING_CLOCK_RATE (0xff)
95#define HW_SSP_CTRL1 (ssp_is_old() ? 0x060 : 0x080) 96#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
96#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) 97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
97#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) 98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
98#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) 99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
@@ -115,15 +116,13 @@
115#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) 116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
116#define BP_SSP_CTRL1_SSP_MODE (0) 117#define BP_SSP_CTRL1_SSP_MODE (0)
117#define BM_SSP_CTRL1_SSP_MODE (0xf) 118#define BM_SSP_CTRL1_SSP_MODE (0xf)
118#define HW_SSP_SDRESP0 (ssp_is_old() ? 0x080 : 0x0a0) 119#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
119#define HW_SSP_SDRESP1 (ssp_is_old() ? 0x090 : 0x0b0) 120#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
120#define HW_SSP_SDRESP2 (ssp_is_old() ? 0x0a0 : 0x0c0) 121#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
121#define HW_SSP_SDRESP3 (ssp_is_old() ? 0x0b0 : 0x0d0) 122#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
122#define HW_SSP_STATUS (ssp_is_old() ? 0x0c0 : 0x100) 123#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
123#define BM_SSP_STATUS_CARD_DETECT (1 << 28) 124#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
124#define BM_SSP_STATUS_SDIO_IRQ (1 << 17) 125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
125#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130)
126#define BP_SSP_VERSION_MAJOR (24)
127 126
128#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field) 127#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
129 128
@@ -138,6 +137,11 @@
138 137
139#define SSP_PIO_NUM 3 138#define SSP_PIO_NUM 3
140 139
140enum mxs_mmc_id {
141 IMX23_MMC,
142 IMX28_MMC,
143};
144
141struct mxs_mmc_host { 145struct mxs_mmc_host {
142 struct mmc_host *mmc; 146 struct mmc_host *mmc;
143 struct mmc_request *mrq; 147 struct mmc_request *mrq;
@@ -145,9 +149,7 @@ struct mxs_mmc_host {
145 struct mmc_data *data; 149 struct mmc_data *data;
146 150
147 void __iomem *base; 151 void __iomem *base;
148 int irq; 152 int dma_channel;
149 struct resource *res;
150 struct resource *dma_res;
151 struct clk *clk; 153 struct clk *clk;
152 unsigned int clk_rate; 154 unsigned int clk_rate;
153 155
@@ -157,32 +159,28 @@ struct mxs_mmc_host {
157 enum dma_transfer_direction slave_dirn; 159 enum dma_transfer_direction slave_dirn;
158 u32 ssp_pio_words[SSP_PIO_NUM]; 160 u32 ssp_pio_words[SSP_PIO_NUM];
159 161
160 unsigned int version; 162 enum mxs_mmc_id devid;
161 unsigned char bus_width; 163 unsigned char bus_width;
162 spinlock_t lock; 164 spinlock_t lock;
163 int sdio_irq_en; 165 int sdio_irq_en;
166 int wp_gpio;
164}; 167};
165 168
166static int mxs_mmc_get_ro(struct mmc_host *mmc) 169static int mxs_mmc_get_ro(struct mmc_host *mmc)
167{ 170{
168 struct mxs_mmc_host *host = mmc_priv(mmc); 171 struct mxs_mmc_host *host = mmc_priv(mmc);
169 struct mxs_mmc_platform_data *pdata =
170 mmc_dev(host->mmc)->platform_data;
171
172 if (!pdata)
173 return -EFAULT;
174 172
175 if (!gpio_is_valid(pdata->wp_gpio)) 173 if (!gpio_is_valid(host->wp_gpio))
176 return -EINVAL; 174 return -EINVAL;
177 175
178 return gpio_get_value(pdata->wp_gpio); 176 return gpio_get_value(host->wp_gpio);
179} 177}
180 178
181static int mxs_mmc_get_cd(struct mmc_host *mmc) 179static int mxs_mmc_get_cd(struct mmc_host *mmc)
182{ 180{
183 struct mxs_mmc_host *host = mmc_priv(mmc); 181 struct mxs_mmc_host *host = mmc_priv(mmc);
184 182
185 return !(readl(host->base + HW_SSP_STATUS) & 183 return !(readl(host->base + HW_SSP_STATUS(host)) &
186 BM_SSP_STATUS_CARD_DETECT); 184 BM_SSP_STATUS_CARD_DETECT);
187} 185}
188 186
@@ -190,7 +188,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
190{ 188{
191 u32 ctrl0, ctrl1; 189 u32 ctrl0, ctrl1;
192 190
193 mxs_reset_block(host->base); 191 stmp_reset_block(host->base);
194 192
195 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; 193 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
196 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | 194 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -206,7 +204,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
206 writel(BF_SSP(0xffff, TIMING_TIMEOUT) | 204 writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
207 BF_SSP(2, TIMING_CLOCK_DIVIDE) | 205 BF_SSP(2, TIMING_CLOCK_DIVIDE) |
208 BF_SSP(0, TIMING_CLOCK_RATE), 206 BF_SSP(0, TIMING_CLOCK_RATE),
209 host->base + HW_SSP_TIMING); 207 host->base + HW_SSP_TIMING(host));
210 208
211 if (host->sdio_irq_en) { 209 if (host->sdio_irq_en) {
212 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; 210 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
@@ -214,7 +212,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
214 } 212 }
215 213
216 writel(ctrl0, host->base + HW_SSP_CTRL0); 214 writel(ctrl0, host->base + HW_SSP_CTRL0);
217 writel(ctrl1, host->base + HW_SSP_CTRL1); 215 writel(ctrl1, host->base + HW_SSP_CTRL1(host));
218} 216}
219 217
220static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, 218static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -228,12 +226,12 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
228 226
229 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { 227 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
230 if (mmc_resp_type(cmd) & MMC_RSP_136) { 228 if (mmc_resp_type(cmd) & MMC_RSP_136) {
231 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0); 229 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
232 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1); 230 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
233 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2); 231 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3); 232 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
235 } else { 233 } else {
236 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0); 234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
237 } 235 }
238 } 236 }
239 237
@@ -276,9 +274,9 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
276 274
277 spin_lock(&host->lock); 275 spin_lock(&host->lock);
278 276
279 stat = readl(host->base + HW_SSP_CTRL1); 277 stat = readl(host->base + HW_SSP_CTRL1(host));
280 writel(stat & MXS_MMC_IRQ_BITS, 278 writel(stat & MXS_MMC_IRQ_BITS,
281 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 279 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
282 280
283 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) 281 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
284 mmc_signal_sdio_irq(host->mmc); 282 mmc_signal_sdio_irq(host->mmc);
@@ -484,7 +482,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
484 blocks = 1; 482 blocks = 1;
485 483
486 /* xfer count, block size and count need to be set differently */ 484 /* xfer count, block size and count need to be set differently */
487 if (ssp_is_old()) { 485 if (ssp_is_old(host)) {
488 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); 486 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
489 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | 487 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
490 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); 488 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
@@ -508,10 +506,10 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
508 506
509 /* set the timeout count */ 507 /* set the timeout count */
510 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns); 508 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
511 val = readl(host->base + HW_SSP_TIMING); 509 val = readl(host->base + HW_SSP_TIMING(host));
512 val &= ~(BM_SSP_TIMING_TIMEOUT); 510 val &= ~(BM_SSP_TIMING_TIMEOUT);
513 val |= BF_SSP(timeout, TIMING_TIMEOUT); 511 val |= BF_SSP(timeout, TIMING_TIMEOUT);
514 writel(val, host->base + HW_SSP_TIMING); 512 writel(val, host->base + HW_SSP_TIMING(host));
515 513
516 /* pio */ 514 /* pio */
517 host->ssp_pio_words[0] = ctrl0; 515 host->ssp_pio_words[0] = ctrl0;
@@ -597,11 +595,11 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
597 595
598 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); 596 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
599 597
600 val = readl(host->base + HW_SSP_TIMING); 598 val = readl(host->base + HW_SSP_TIMING(host));
601 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); 599 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
602 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); 600 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
603 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); 601 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
604 writel(val, host->base + HW_SSP_TIMING); 602 writel(val, host->base + HW_SSP_TIMING(host));
605 603
606 host->clk_rate = ssp_sck; 604 host->clk_rate = ssp_sck;
607 605
@@ -636,18 +634,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
636 634
637 if (enable) { 635 if (enable) {
638 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 636 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
639 host->base + HW_SSP_CTRL0 + MXS_SET_ADDR); 637 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
640 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 638 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
641 host->base + HW_SSP_CTRL1 + MXS_SET_ADDR); 639 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
642 640
643 if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ) 641 if (readl(host->base + HW_SSP_STATUS(host)) &
642 BM_SSP_STATUS_SDIO_IRQ)
644 mmc_signal_sdio_irq(host->mmc); 643 mmc_signal_sdio_irq(host->mmc);
645 644
646 } else { 645 } else {
647 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 646 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
648 host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR); 647 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
649 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 648 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
650 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 649 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
651 } 650 }
652 651
653 spin_unlock_irqrestore(&host->lock, flags); 652 spin_unlock_irqrestore(&host->lock, flags);
@@ -668,7 +667,7 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
668 if (!mxs_dma_is_apbh(chan)) 667 if (!mxs_dma_is_apbh(chan))
669 return false; 668 return false;
670 669
671 if (chan->chan_id != host->dma_res->start) 670 if (chan->chan_id != host->dma_channel)
672 return false; 671 return false;
673 672
674 chan->private = &host->dma_data; 673 chan->private = &host->dma_data;
@@ -676,12 +675,36 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
676 return true; 675 return true;
677} 676}
678 677
678static struct platform_device_id mxs_mmc_ids[] = {
679 {
680 .name = "imx23-mmc",
681 .driver_data = IMX23_MMC,
682 }, {
683 .name = "imx28-mmc",
684 .driver_data = IMX28_MMC,
685 }, {
686 /* sentinel */
687 }
688};
689MODULE_DEVICE_TABLE(platform, mxs_mmc_ids);
690
691static const struct of_device_id mxs_mmc_dt_ids[] = {
692 { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, },
693 { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, },
694 { /* sentinel */ }
695};
696MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
697
679static int mxs_mmc_probe(struct platform_device *pdev) 698static int mxs_mmc_probe(struct platform_device *pdev)
680{ 699{
700 const struct of_device_id *of_id =
701 of_match_device(mxs_mmc_dt_ids, &pdev->dev);
702 struct device_node *np = pdev->dev.of_node;
681 struct mxs_mmc_host *host; 703 struct mxs_mmc_host *host;
682 struct mmc_host *mmc; 704 struct mmc_host *mmc;
683 struct resource *iores, *dmares, *r; 705 struct resource *iores, *dmares;
684 struct mxs_mmc_platform_data *pdata; 706 struct mxs_mmc_platform_data *pdata;
707 struct pinctrl *pinctrl;
685 int ret = 0, irq_err, irq_dma; 708 int ret = 0, irq_err, irq_dma;
686 dma_cap_mask_t mask; 709 dma_cap_mask_t mask;
687 710
@@ -689,40 +712,51 @@ static int mxs_mmc_probe(struct platform_device *pdev)
689 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 712 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
690 irq_err = platform_get_irq(pdev, 0); 713 irq_err = platform_get_irq(pdev, 0);
691 irq_dma = platform_get_irq(pdev, 1); 714 irq_dma = platform_get_irq(pdev, 1);
692 if (!iores || !dmares || irq_err < 0 || irq_dma < 0) 715 if (!iores || irq_err < 0 || irq_dma < 0)
693 return -EINVAL; 716 return -EINVAL;
694 717
695 r = request_mem_region(iores->start, resource_size(iores), pdev->name);
696 if (!r)
697 return -EBUSY;
698
699 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); 718 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
700 if (!mmc) { 719 if (!mmc)
701 ret = -ENOMEM; 720 return -ENOMEM;
702 goto out_release_mem;
703 }
704 721
705 host = mmc_priv(mmc); 722 host = mmc_priv(mmc);
706 host->base = ioremap(r->start, resource_size(r)); 723 host->base = devm_request_and_ioremap(&pdev->dev, iores);
707 if (!host->base) { 724 if (!host->base) {
708 ret = -ENOMEM; 725 ret = -EADDRNOTAVAIL;
709 goto out_mmc_free; 726 goto out_mmc_free;
710 } 727 }
711 728
712 /* only major verion does matter */ 729 if (np) {
713 host->version = readl(host->base + HW_SSP_VERSION) >> 730 host->devid = (enum mxs_mmc_id) of_id->data;
714 BP_SSP_VERSION_MAJOR; 731 /*
732 * TODO: This is a temporary solution and should be changed
733 * to use generic DMA binding later when the helpers get in.
734 */
735 ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
736 &host->dma_channel);
737 if (ret) {
738 dev_err(mmc_dev(host->mmc),
739 "failed to get dma channel\n");
740 goto out_mmc_free;
741 }
742 } else {
743 host->devid = pdev->id_entry->driver_data;
744 host->dma_channel = dmares->start;
745 }
715 746
716 host->mmc = mmc; 747 host->mmc = mmc;
717 host->res = r;
718 host->dma_res = dmares;
719 host->irq = irq_err;
720 host->sdio_irq_en = 0; 748 host->sdio_irq_en = 0;
721 749
750 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
751 if (IS_ERR(pinctrl)) {
752 ret = PTR_ERR(pinctrl);
753 goto out_mmc_free;
754 }
755
722 host->clk = clk_get(&pdev->dev, NULL); 756 host->clk = clk_get(&pdev->dev, NULL);
723 if (IS_ERR(host->clk)) { 757 if (IS_ERR(host->clk)) {
724 ret = PTR_ERR(host->clk); 758 ret = PTR_ERR(host->clk);
725 goto out_iounmap; 759 goto out_mmc_free;
726 } 760 }
727 clk_prepare_enable(host->clk); 761 clk_prepare_enable(host->clk);
728 762
@@ -744,11 +778,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
744 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; 778 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
745 779
746 pdata = mmc_dev(host->mmc)->platform_data; 780 pdata = mmc_dev(host->mmc)->platform_data;
747 if (pdata) { 781 if (!pdata) {
782 u32 bus_width = 0;
783 of_property_read_u32(np, "bus-width", &bus_width);
784 if (bus_width == 4)
785 mmc->caps |= MMC_CAP_4_BIT_DATA;
786 else if (bus_width == 8)
787 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
788 host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
789 } else {
748 if (pdata->flags & SLOTF_8_BIT_CAPABLE) 790 if (pdata->flags & SLOTF_8_BIT_CAPABLE)
749 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; 791 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
750 if (pdata->flags & SLOTF_4_BIT_CAPABLE) 792 if (pdata->flags & SLOTF_4_BIT_CAPABLE)
751 mmc->caps |= MMC_CAP_4_BIT_DATA; 793 mmc->caps |= MMC_CAP_4_BIT_DATA;
794 host->wp_gpio = pdata->wp_gpio;
752 } 795 }
753 796
754 mmc->f_min = 400000; 797 mmc->f_min = 400000;
@@ -757,13 +800,14 @@ static int mxs_mmc_probe(struct platform_device *pdev)
757 800
758 mmc->max_segs = 52; 801 mmc->max_segs = 52;
759 mmc->max_blk_size = 1 << 0xf; 802 mmc->max_blk_size = 1 << 0xf;
760 mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff; 803 mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
761 mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff; 804 mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
762 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); 805 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
763 806
764 platform_set_drvdata(pdev, mmc); 807 platform_set_drvdata(pdev, mmc);
765 808
766 ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host); 809 ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
810 DRIVER_NAME, host);
767 if (ret) 811 if (ret)
768 goto out_free_dma; 812 goto out_free_dma;
769 813
@@ -771,26 +815,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
771 815
772 ret = mmc_add_host(mmc); 816 ret = mmc_add_host(mmc);
773 if (ret) 817 if (ret)
774 goto out_free_irq; 818 goto out_free_dma;
775 819
776 dev_info(mmc_dev(host->mmc), "initialized\n"); 820 dev_info(mmc_dev(host->mmc), "initialized\n");
777 821
778 return 0; 822 return 0;
779 823
780out_free_irq:
781 free_irq(host->irq, host);
782out_free_dma: 824out_free_dma:
783 if (host->dmach) 825 if (host->dmach)
784 dma_release_channel(host->dmach); 826 dma_release_channel(host->dmach);
785out_clk_put: 827out_clk_put:
786 clk_disable_unprepare(host->clk); 828 clk_disable_unprepare(host->clk);
787 clk_put(host->clk); 829 clk_put(host->clk);
788out_iounmap:
789 iounmap(host->base);
790out_mmc_free: 830out_mmc_free:
791 mmc_free_host(mmc); 831 mmc_free_host(mmc);
792out_release_mem:
793 release_mem_region(iores->start, resource_size(iores));
794 return ret; 832 return ret;
795} 833}
796 834
@@ -798,12 +836,9 @@ static int mxs_mmc_remove(struct platform_device *pdev)
798{ 836{
799 struct mmc_host *mmc = platform_get_drvdata(pdev); 837 struct mmc_host *mmc = platform_get_drvdata(pdev);
800 struct mxs_mmc_host *host = mmc_priv(mmc); 838 struct mxs_mmc_host *host = mmc_priv(mmc);
801 struct resource *res = host->res;
802 839
803 mmc_remove_host(mmc); 840 mmc_remove_host(mmc);
804 841
805 free_irq(host->irq, host);
806
807 platform_set_drvdata(pdev, NULL); 842 platform_set_drvdata(pdev, NULL);
808 843
809 if (host->dmach) 844 if (host->dmach)
@@ -812,12 +847,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
812 clk_disable_unprepare(host->clk); 847 clk_disable_unprepare(host->clk);
813 clk_put(host->clk); 848 clk_put(host->clk);
814 849
815 iounmap(host->base);
816
817 mmc_free_host(mmc); 850 mmc_free_host(mmc);
818 851
819 release_mem_region(res->start, resource_size(res));
820
821 return 0; 852 return 0;
822} 853}
823 854
@@ -857,11 +888,13 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
857static struct platform_driver mxs_mmc_driver = { 888static struct platform_driver mxs_mmc_driver = {
858 .probe = mxs_mmc_probe, 889 .probe = mxs_mmc_probe,
859 .remove = mxs_mmc_remove, 890 .remove = mxs_mmc_remove,
891 .id_table = mxs_mmc_ids,
860 .driver = { 892 .driver = {
861 .name = DRIVER_NAME, 893 .name = DRIVER_NAME,
862 .owner = THIS_MODULE, 894 .owner = THIS_MODULE,
863#ifdef CONFIG_PM 895#ifdef CONFIG_PM
864 .pm = &mxs_mmc_pm_ops, 896 .pm = &mxs_mmc_pm_ops,
897 .of_match_table = mxs_mmc_dt_ids,
865#endif 898#endif
866 }, 899 },
867}; 900};
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 8abdaf6697a8..d190d04636a7 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -24,6 +24,7 @@
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_device.h> 25#include <linux/of_device.h>
26#include <linux/of_gpio.h> 26#include <linux/of_gpio.h>
27#include <linux/pinctrl/consumer.h>
27#include <mach/esdhc.h> 28#include <mach/esdhc.h>
28#include "sdhci-pltfm.h" 29#include "sdhci-pltfm.h"
29#include "sdhci-esdhc.h" 30#include "sdhci-esdhc.h"
@@ -68,6 +69,7 @@ struct pltfm_imx_data {
68 int flags; 69 int flags;
69 u32 scratchpad; 70 u32 scratchpad;
70 enum imx_esdhc_type devtype; 71 enum imx_esdhc_type devtype;
72 struct pinctrl *pinctrl;
71 struct esdhc_platform_data boarddata; 73 struct esdhc_platform_data boarddata;
72}; 74};
73 75
@@ -467,6 +469,12 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
467 clk_prepare_enable(clk); 469 clk_prepare_enable(clk);
468 pltfm_host->clk = clk; 470 pltfm_host->clk = clk;
469 471
472 imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
473 if (IS_ERR(imx_data->pinctrl)) {
474 err = PTR_ERR(imx_data->pinctrl);
475 goto pin_err;
476 }
477
470 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 478 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
471 479
472 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) 480 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
@@ -558,6 +566,7 @@ no_card_detect_irq:
558 gpio_free(boarddata->wp_gpio); 566 gpio_free(boarddata->wp_gpio);
559no_card_detect_pin: 567no_card_detect_pin:
560no_board_data: 568no_board_data:
569pin_err:
561 clk_disable_unprepare(pltfm_host->clk); 570 clk_disable_unprepare(pltfm_host->clk);
562 clk_put(pltfm_host->clk); 571 clk_put(pltfm_host->clk);
563err_clk_get: 572err_clk_get:
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 9ec51cec2e14..8478fd9701a3 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -24,6 +24,7 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/mtd/gpmi-nand.h> 25#include <linux/mtd/gpmi-nand.h>
26#include <linux/mtd/partitions.h> 26#include <linux/mtd/partitions.h>
27#include <linux/pinctrl/consumer.h>
27#include "gpmi-nand.h" 28#include "gpmi-nand.h"
28 29
29/* add our owner bbt descriptor */ 30/* add our owner bbt descriptor */
@@ -476,6 +477,7 @@ acquire_err:
476static int __devinit acquire_resources(struct gpmi_nand_data *this) 477static int __devinit acquire_resources(struct gpmi_nand_data *this)
477{ 478{
478 struct resources *res = &this->resources; 479 struct resources *res = &this->resources;
480 struct pinctrl *pinctrl;
479 int ret; 481 int ret;
480 482
481 ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME); 483 ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME);
@@ -494,6 +496,12 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
494 if (ret) 496 if (ret)
495 goto exit_dma_channels; 497 goto exit_dma_channels;
496 498
499 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
500 if (IS_ERR(pinctrl)) {
501 ret = PTR_ERR(pinctrl);
502 goto exit_pin;
503 }
504
497 res->clock = clk_get(&this->pdev->dev, NULL); 505 res->clock = clk_get(&this->pdev->dev, NULL);
498 if (IS_ERR(res->clock)) { 506 if (IS_ERR(res->clock)) {
499 pr_err("can not get the clock\n"); 507 pr_err("can not get the clock\n");
@@ -503,6 +511,7 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
503 return 0; 511 return 0;
504 512
505exit_clock: 513exit_clock:
514exit_pin:
506 release_dma_channels(this); 515 release_dma_channels(this);
507exit_dma_channels: 516exit_dma_channels:
508 release_bch_irq(this); 517 release_bch_irq(this);
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1efb08386c61..38c0690df5c8 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/pinctrl/consumer.h>
38 39
39#define DRV_NAME "flexcan" 40#define DRV_NAME "flexcan"
40 41
@@ -927,11 +928,16 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
927 struct flexcan_priv *priv; 928 struct flexcan_priv *priv;
928 struct resource *mem; 929 struct resource *mem;
929 struct clk *clk = NULL; 930 struct clk *clk = NULL;
931 struct pinctrl *pinctrl;
930 void __iomem *base; 932 void __iomem *base;
931 resource_size_t mem_size; 933 resource_size_t mem_size;
932 int err, irq; 934 int err, irq;
933 u32 clock_freq = 0; 935 u32 clock_freq = 0;
934 936
937 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
938 if (IS_ERR(pinctrl))
939 return PTR_ERR(pinctrl);
940
935 if (pdev->dev.of_node) { 941 if (pdev->dev.of_node) {
936 const u32 *clock_freq_p; 942 const u32 *clock_freq_p;
937 943
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a12b3f5bc025..500c106af86e 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -48,6 +48,7 @@
48#include <linux/of_device.h> 48#include <linux/of_device.h>
49#include <linux/of_gpio.h> 49#include <linux/of_gpio.h>
50#include <linux/of_net.h> 50#include <linux/of_net.h>
51#include <linux/pinctrl/consumer.h>
51 52
52#include <asm/cacheflush.h> 53#include <asm/cacheflush.h>
53 54
@@ -1542,6 +1543,7 @@ fec_probe(struct platform_device *pdev)
1542 struct resource *r; 1543 struct resource *r;
1543 const struct of_device_id *of_id; 1544 const struct of_device_id *of_id;
1544 static int dev_id; 1545 static int dev_id;
1546 struct pinctrl *pinctrl;
1545 1547
1546 of_id = of_match_device(fec_dt_ids, &pdev->dev); 1548 of_id = of_match_device(fec_dt_ids, &pdev->dev);
1547 if (of_id) 1549 if (of_id)
@@ -1609,6 +1611,12 @@ fec_probe(struct platform_device *pdev)
1609 } 1611 }
1610 } 1612 }
1611 1613
1614 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
1615 if (IS_ERR(pinctrl)) {
1616 ret = PTR_ERR(pinctrl);
1617 goto failed_pin;
1618 }
1619
1612 fep->clk = clk_get(&pdev->dev, NULL); 1620 fep->clk = clk_get(&pdev->dev, NULL);
1613 if (IS_ERR(fep->clk)) { 1621 if (IS_ERR(fep->clk)) {
1614 ret = PTR_ERR(fep->clk); 1622 ret = PTR_ERR(fep->clk);
@@ -1639,6 +1647,7 @@ failed_mii_init:
1639failed_init: 1647failed_init:
1640 clk_disable_unprepare(fep->clk); 1648 clk_disable_unprepare(fep->clk);
1641 clk_put(fep->clk); 1649 clk_put(fep->clk);
1650failed_pin:
1642failed_clk: 1651failed_clk:
1643 for (i = 0; i < FEC_IRQ_NUM; i++) { 1652 for (i = 0; i < FEC_IRQ_NUM; i++) {
1644 irq = platform_get_irq(pdev, i); 1653 irq = platform_get_irq(pdev, i);
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 570f22053be8..69c9a6601f45 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -37,6 +37,7 @@
37#include <linux/of.h> 37#include <linux/of.h>
38#include <linux/of_device.h> 38#include <linux/of_device.h>
39#include <linux/of_gpio.h> 39#include <linux/of_gpio.h>
40#include <linux/pinctrl/consumer.h>
40 41
41#include <mach/spi.h> 42#include <mach/spi.h>
42 43
@@ -758,6 +759,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
758 struct spi_master *master; 759 struct spi_master *master;
759 struct spi_imx_data *spi_imx; 760 struct spi_imx_data *spi_imx;
760 struct resource *res; 761 struct resource *res;
762 struct pinctrl *pinctrl;
761 int i, ret, num_cs; 763 int i, ret, num_cs;
762 764
763 if (!np && !mxc_platform_info) { 765 if (!np && !mxc_platform_info) {
@@ -845,6 +847,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
845 goto out_iounmap; 847 goto out_iounmap;
846 } 848 }
847 849
850 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
851 if (IS_ERR(pinctrl)) {
852 ret = PTR_ERR(pinctrl);
853 goto out_free_irq;
854 }
855
848 spi_imx->clk = clk_get(&pdev->dev, NULL); 856 spi_imx->clk = clk_get(&pdev->dev, NULL);
849 if (IS_ERR(spi_imx->clk)) { 857 if (IS_ERR(spi_imx->clk)) {
850 dev_err(&pdev->dev, "unable to get clock\n"); 858 dev_err(&pdev->dev, "unable to get clock\n");
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 3d569cd68f58..062ef8c2b3cb 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -52,6 +52,7 @@
52#include <linux/scatterlist.h> 52#include <linux/scatterlist.h>
53#include <linux/delay.h> 53#include <linux/delay.h>
54#include <linux/types.h> 54#include <linux/types.h>
55#include <linux/pinctrl/consumer.h>
55 56
56#include <asm/io.h> 57#include <asm/io.h>
57#include <asm/sizes.h> 58#include <asm/sizes.h>
@@ -1916,6 +1917,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
1916{ 1917{
1917 struct uart_amba_port *uap; 1918 struct uart_amba_port *uap;
1918 struct vendor_data *vendor = id->data; 1919 struct vendor_data *vendor = id->data;
1920 struct pinctrl *pinctrl;
1919 void __iomem *base; 1921 void __iomem *base;
1920 int i, ret; 1922 int i, ret;
1921 1923
@@ -1940,6 +1942,12 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
1940 goto free; 1942 goto free;
1941 } 1943 }
1942 1944
1945 pinctrl = devm_pinctrl_get_select_default(&dev->dev);
1946 if (IS_ERR(pinctrl)) {
1947 ret = PTR_ERR(pinctrl);
1948 goto unmap;
1949 }
1950
1943 uap->clk = clk_get(&dev->dev, NULL); 1951 uap->clk = clk_get(&dev->dev, NULL);
1944 if (IS_ERR(uap->clk)) { 1952 if (IS_ERR(uap->clk)) {
1945 ret = PTR_ERR(uap->clk); 1953 ret = PTR_ERR(uap->clk);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e7feceeebc2f..ec206732f68c 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -47,6 +47,7 @@
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/of.h> 48#include <linux/of.h>
49#include <linux/of_device.h> 49#include <linux/of_device.h>
50#include <linux/pinctrl/consumer.h>
50 51
51#include <asm/io.h> 52#include <asm/io.h>
52#include <asm/irq.h> 53#include <asm/irq.h>
@@ -1464,6 +1465,7 @@ static int serial_imx_probe(struct platform_device *pdev)
1464 void __iomem *base; 1465 void __iomem *base;
1465 int ret = 0; 1466 int ret = 0;
1466 struct resource *res; 1467 struct resource *res;
1468 struct pinctrl *pinctrl;
1467 1469
1468 sport = kzalloc(sizeof(*sport), GFP_KERNEL); 1470 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
1469 if (!sport) 1471 if (!sport)
@@ -1503,6 +1505,12 @@ static int serial_imx_probe(struct platform_device *pdev)
1503 sport->timer.function = imx_timeout; 1505 sport->timer.function = imx_timeout;
1504 sport->timer.data = (unsigned long)sport; 1506 sport->timer.data = (unsigned long)sport;
1505 1507
1508 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
1509 if (IS_ERR(pinctrl)) {
1510 ret = PTR_ERR(pinctrl);
1511 goto unmap;
1512 }
1513
1506 sport->clk = clk_get(&pdev->dev, "uart"); 1514 sport->clk = clk_get(&pdev->dev, "uart");
1507 if (IS_ERR(sport->clk)) { 1515 if (IS_ERR(sport->clk)) {
1508 ret = PTR_ERR(sport->clk); 1516 ret = PTR_ERR(sport->clk);
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 55fd362b9879..7081600bede4 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -32,6 +32,7 @@
32#include <linux/clk.h> 32#include <linux/clk.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/io.h> 34#include <linux/io.h>
35#include <linux/pinctrl/consumer.h>
35 36
36#include <asm/cacheflush.h> 37#include <asm/cacheflush.h>
37 38
@@ -678,6 +679,7 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
678 u32 version; 679 u32 version;
679 int ret = 0; 680 int ret = 0;
680 struct resource *r; 681 struct resource *r;
682 struct pinctrl *pinctrl;
681 683
682 s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL); 684 s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
683 if (!s) { 685 if (!s) {
@@ -685,6 +687,12 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
685 goto out; 687 goto out;
686 } 688 }
687 689
690 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
691 if (IS_ERR(pinctrl)) {
692 ret = PTR_ERR(pinctrl);
693 goto out_free;
694 }
695
688 s->clk = clk_get(&pdev->dev, NULL); 696 s->clk = clk_get(&pdev->dev, NULL);
689 if (IS_ERR(s->clk)) { 697 if (IS_ERR(s->clk)) {
690 ret = PTR_ERR(s->clk); 698 ret = PTR_ERR(s->clk);
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 4a89f889852d..6c6bc578d0fc 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -45,6 +45,7 @@
45#include <linux/clk.h> 45#include <linux/clk.h>
46#include <linux/dma-mapping.h> 46#include <linux/dma-mapping.h>
47#include <linux/io.h> 47#include <linux/io.h>
48#include <linux/pinctrl/consumer.h>
48#include <mach/mxsfb.h> 49#include <mach/mxsfb.h>
49 50
50#define REG_SET 4 51#define REG_SET 4
@@ -756,6 +757,7 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
756 struct mxsfb_info *host; 757 struct mxsfb_info *host;
757 struct fb_info *fb_info; 758 struct fb_info *fb_info;
758 struct fb_modelist *modelist; 759 struct fb_modelist *modelist;
760 struct pinctrl *pinctrl;
759 int i, ret; 761 int i, ret;
760 762
761 if (!pdata) { 763 if (!pdata) {
@@ -793,6 +795,12 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
793 795
794 host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; 796 host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
795 797
798 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
799 if (IS_ERR(pinctrl)) {
800 ret = PTR_ERR(pinctrl);
801 goto error_getpin;
802 }
803
796 host->clk = clk_get(&host->pdev->dev, NULL); 804 host->clk = clk_get(&host->pdev->dev, NULL);
797 if (IS_ERR(host->clk)) { 805 if (IS_ERR(host->clk)) {
798 ret = PTR_ERR(host->clk); 806 ret = PTR_ERR(host->clk);
@@ -848,6 +856,7 @@ error_init_fb:
848error_pseudo_pallette: 856error_pseudo_pallette:
849 clk_put(host->clk); 857 clk_put(host->clk);
850error_getclock: 858error_getclock:
859error_getpin:
851 iounmap(host->base); 860 iounmap(host->base);
852error_ioremap: 861error_ioremap:
853 framebuffer_release(fb_info); 862 framebuffer_release(fb_info);