diff options
Diffstat (limited to 'arch/arm')
41 files changed, 1888 insertions, 749 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d571cdb79d81..4d1c3093a133 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -798,6 +798,7 @@ config ARCH_U8500 | |||
798 | select GENERIC_CLOCKEVENTS | 798 | select GENERIC_CLOCKEVENTS |
799 | select COMMON_CLKDEV | 799 | select COMMON_CLKDEV |
800 | select ARCH_REQUIRE_GPIOLIB | 800 | select ARCH_REQUIRE_GPIOLIB |
801 | select ARCH_HAS_CPUFREQ | ||
801 | help | 802 | help |
802 | Support for ST-Ericsson's Ux500 architecture | 803 | Support for ST-Ericsson's Ux500 architecture |
803 | 804 | ||
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 9e27a84433cb..12052e8e064c 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -2,14 +2,16 @@ | |||
2 | # Makefile for the linux kernel, U8500 machine. | 2 | # Makefile for the linux kernel, U8500 machine. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := clock.o cpu.o devices.o | 5 | obj-y := clock.o cpu.o devices.o devices-common.o |
6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o | 6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o |
7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o | 7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o |
8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o | 8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o \ |
9 | obj-$(CONFIG_MACH_U5500) += board-u5500.o | 9 | board-mop500-keypads.o |
10 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o | ||
10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 12 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
12 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 13 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o |
13 | obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o | 14 | obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o |
14 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem_irq.o | 15 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o |
15 | obj-$(CONFIG_U5500_MBOX) += mbox.o | 16 | obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o |
17 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | ||
diff --git a/arch/arm/mach-ux500/board-mop500-keypads.c b/arch/arm/mach-ux500/board-mop500-keypads.c new file mode 100644 index 000000000000..70318c354d32 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-keypads.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * Keypad layouts for various boards | ||
7 | */ | ||
8 | |||
9 | #include <linux/i2c.h> | ||
10 | #include <linux/gpio.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mfd/stmpe.h> | ||
14 | #include <linux/mfd/tc3589x.h> | ||
15 | #include <linux/input/matrix_keypad.h> | ||
16 | |||
17 | #include <plat/pincfg.h> | ||
18 | #include <plat/ske.h> | ||
19 | |||
20 | #include <mach/devices.h> | ||
21 | #include <mach/hardware.h> | ||
22 | |||
23 | #include "devices-db8500.h" | ||
24 | #include "board-mop500.h" | ||
25 | |||
26 | /* STMPE/SKE keypad use this key layout */ | ||
27 | static const unsigned int mop500_keymap[] = { | ||
28 | KEY(2, 5, KEY_END), | ||
29 | KEY(4, 1, KEY_POWER), | ||
30 | KEY(3, 5, KEY_VOLUMEDOWN), | ||
31 | KEY(1, 3, KEY_3), | ||
32 | KEY(5, 2, KEY_RIGHT), | ||
33 | KEY(5, 0, KEY_9), | ||
34 | |||
35 | KEY(0, 5, KEY_MENU), | ||
36 | KEY(7, 6, KEY_ENTER), | ||
37 | KEY(4, 5, KEY_0), | ||
38 | KEY(6, 7, KEY_2), | ||
39 | KEY(3, 4, KEY_UP), | ||
40 | KEY(3, 3, KEY_DOWN), | ||
41 | |||
42 | KEY(6, 4, KEY_SEND), | ||
43 | KEY(6, 2, KEY_BACK), | ||
44 | KEY(4, 2, KEY_VOLUMEUP), | ||
45 | KEY(5, 5, KEY_1), | ||
46 | KEY(4, 3, KEY_LEFT), | ||
47 | KEY(3, 2, KEY_7), | ||
48 | }; | ||
49 | |||
50 | static const struct matrix_keymap_data mop500_keymap_data = { | ||
51 | .keymap = mop500_keymap, | ||
52 | .keymap_size = ARRAY_SIZE(mop500_keymap), | ||
53 | }; | ||
54 | |||
55 | /* | ||
56 | * Nomadik SKE keypad | ||
57 | */ | ||
58 | #define ROW_PIN_I0 164 | ||
59 | #define ROW_PIN_I1 163 | ||
60 | #define ROW_PIN_I2 162 | ||
61 | #define ROW_PIN_I3 161 | ||
62 | #define ROW_PIN_I4 156 | ||
63 | #define ROW_PIN_I5 155 | ||
64 | #define ROW_PIN_I6 154 | ||
65 | #define ROW_PIN_I7 153 | ||
66 | #define COL_PIN_O0 168 | ||
67 | #define COL_PIN_O1 167 | ||
68 | #define COL_PIN_O2 166 | ||
69 | #define COL_PIN_O3 165 | ||
70 | #define COL_PIN_O4 160 | ||
71 | #define COL_PIN_O5 159 | ||
72 | #define COL_PIN_O6 158 | ||
73 | #define COL_PIN_O7 157 | ||
74 | |||
75 | #define SKE_KPD_MAX_ROWS 8 | ||
76 | #define SKE_KPD_MAX_COLS 8 | ||
77 | |||
78 | static int ske_kp_rows[] = { | ||
79 | ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, | ||
80 | ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7, | ||
81 | }; | ||
82 | |||
83 | /* | ||
84 | * ske_set_gpio_row: request and set gpio rows | ||
85 | */ | ||
86 | static int ske_set_gpio_row(int gpio) | ||
87 | { | ||
88 | int ret; | ||
89 | |||
90 | ret = gpio_request(gpio, "ske-kp"); | ||
91 | if (ret < 0) { | ||
92 | pr_err("ske_set_gpio_row: gpio request failed\n"); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | ret = gpio_direction_output(gpio, 1); | ||
97 | if (ret < 0) { | ||
98 | pr_err("ske_set_gpio_row: gpio direction failed\n"); | ||
99 | gpio_free(gpio); | ||
100 | } | ||
101 | |||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * ske_kp_init - enable the gpio configuration | ||
107 | */ | ||
108 | static int ske_kp_init(void) | ||
109 | { | ||
110 | int ret, i; | ||
111 | |||
112 | for (i = 0; i < SKE_KPD_MAX_ROWS; i++) { | ||
113 | ret = ske_set_gpio_row(ske_kp_rows[i]); | ||
114 | if (ret < 0) { | ||
115 | pr_err("ske_kp_init: failed init\n"); | ||
116 | return ret; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static struct ske_keypad_platform_data ske_keypad_board = { | ||
124 | .init = ske_kp_init, | ||
125 | .keymap_data = &mop500_keymap_data, | ||
126 | .no_autorepeat = true, | ||
127 | .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */ | ||
128 | .kcol = SKE_KPD_MAX_COLS, | ||
129 | .debounce_ms = 40, /* in millisecs */ | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * STMPE1601 | ||
134 | */ | ||
135 | static struct stmpe_keypad_platform_data stmpe1601_keypad_data = { | ||
136 | .debounce_ms = 64, | ||
137 | .scan_count = 8, | ||
138 | .no_autorepeat = true, | ||
139 | .keymap_data = &mop500_keymap_data, | ||
140 | }; | ||
141 | |||
142 | static struct stmpe_platform_data stmpe1601_data = { | ||
143 | .id = 1, | ||
144 | .blocks = STMPE_BLOCK_KEYPAD, | ||
145 | .irq_trigger = IRQF_TRIGGER_FALLING, | ||
146 | .irq_base = MOP500_STMPE1601_IRQ(0), | ||
147 | .keypad = &stmpe1601_keypad_data, | ||
148 | .autosleep = true, | ||
149 | .autosleep_timeout = 1024, | ||
150 | }; | ||
151 | |||
152 | static struct i2c_board_info mop500_i2c0_devices_stuib[] = { | ||
153 | { | ||
154 | I2C_BOARD_INFO("stmpe1601", 0x40), | ||
155 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
156 | .platform_data = &stmpe1601_data, | ||
157 | .flags = I2C_CLIENT_WAKE, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | /* | ||
162 | * TC35893 | ||
163 | */ | ||
164 | |||
165 | static const unsigned int uib_keymap[] = { | ||
166 | KEY(3, 1, KEY_END), | ||
167 | KEY(4, 1, KEY_POWER), | ||
168 | KEY(6, 4, KEY_VOLUMEDOWN), | ||
169 | KEY(4, 2, KEY_EMAIL), | ||
170 | KEY(3, 3, KEY_RIGHT), | ||
171 | KEY(2, 5, KEY_BACKSPACE), | ||
172 | |||
173 | KEY(6, 7, KEY_MENU), | ||
174 | KEY(5, 0, KEY_ENTER), | ||
175 | KEY(4, 3, KEY_0), | ||
176 | KEY(3, 4, KEY_DOT), | ||
177 | KEY(5, 2, KEY_UP), | ||
178 | KEY(3, 5, KEY_DOWN), | ||
179 | |||
180 | KEY(4, 5, KEY_SEND), | ||
181 | KEY(0, 5, KEY_BACK), | ||
182 | KEY(6, 2, KEY_VOLUMEUP), | ||
183 | KEY(1, 3, KEY_SPACE), | ||
184 | KEY(7, 6, KEY_LEFT), | ||
185 | KEY(5, 5, KEY_SEARCH), | ||
186 | }; | ||
187 | |||
188 | static struct matrix_keymap_data uib_keymap_data = { | ||
189 | .keymap = uib_keymap, | ||
190 | .keymap_size = ARRAY_SIZE(uib_keymap), | ||
191 | }; | ||
192 | |||
193 | static struct tc3589x_keypad_platform_data tc35893_data = { | ||
194 | .krow = TC_KPD_ROWS, | ||
195 | .kcol = TC_KPD_COLUMNS, | ||
196 | .debounce_period = TC_KPD_DEBOUNCE_PERIOD, | ||
197 | .settle_time = TC_KPD_SETTLE_TIME, | ||
198 | .irqtype = IRQF_TRIGGER_FALLING, | ||
199 | .enable_wakeup = true, | ||
200 | .keymap_data = &uib_keymap_data, | ||
201 | .no_autorepeat = true, | ||
202 | }; | ||
203 | |||
204 | static struct tc3589x_platform_data tc3589x_keypad_data = { | ||
205 | .block = TC3589x_BLOCK_KEYPAD, | ||
206 | .keypad = &tc35893_data, | ||
207 | .irq_base = MOP500_EGPIO_IRQ_BASE, | ||
208 | }; | ||
209 | |||
210 | static struct i2c_board_info mop500_i2c0_devices_uib[] = { | ||
211 | { | ||
212 | I2C_BOARD_INFO("tc3589x", 0x44), | ||
213 | .platform_data = &tc3589x_keypad_data, | ||
214 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
215 | .flags = I2C_CLIENT_WAKE, | ||
216 | }, | ||
217 | }; | ||
218 | |||
219 | void mop500_keypad_init(void) | ||
220 | { | ||
221 | db8500_add_ske_keypad(&ske_keypad_board); | ||
222 | |||
223 | i2c_register_board_info(0, mop500_i2c0_devices_stuib, | ||
224 | ARRAY_SIZE(mop500_i2c0_devices_stuib)); | ||
225 | |||
226 | i2c_register_board_info(0, mop500_i2c0_devices_uib, | ||
227 | ARRAY_SIZE(mop500_i2c0_devices_uib)); | ||
228 | |||
229 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index bac995665b58..4b996676594e 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
@@ -16,10 +16,24 @@ | |||
16 | #include <mach/devices.h> | 16 | #include <mach/devices.h> |
17 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
18 | 18 | ||
19 | #include "devices-db8500.h" | ||
19 | #include "pins-db8500.h" | 20 | #include "pins-db8500.h" |
20 | #include "board-mop500.h" | 21 | #include "board-mop500.h" |
21 | 22 | ||
22 | static pin_cfg_t mop500_sdi_pins[] = { | 23 | static pin_cfg_t mop500_sdi_pins[] = { |
24 | /* SDI0 (MicroSD slot) */ | ||
25 | GPIO18_MC0_CMDDIR, | ||
26 | GPIO19_MC0_DAT0DIR, | ||
27 | GPIO20_MC0_DAT2DIR, | ||
28 | GPIO21_MC0_DAT31DIR, | ||
29 | GPIO22_MC0_FBCLK, | ||
30 | GPIO23_MC0_CLK, | ||
31 | GPIO24_MC0_CMD, | ||
32 | GPIO25_MC0_DAT0, | ||
33 | GPIO26_MC0_DAT1, | ||
34 | GPIO27_MC0_DAT2, | ||
35 | GPIO28_MC0_DAT3, | ||
36 | |||
23 | /* SDI4 (on-board eMMC) */ | 37 | /* SDI4 (on-board eMMC) */ |
24 | GPIO197_MC4_DAT3, | 38 | GPIO197_MC4_DAT3, |
25 | GPIO198_MC4_DAT2, | 39 | GPIO198_MC4_DAT2, |
@@ -50,6 +64,55 @@ static pin_cfg_t mop500_sdi2_pins[] = { | |||
50 | }; | 64 | }; |
51 | 65 | ||
52 | /* | 66 | /* |
67 | * SDI 0 (MicroSD slot) | ||
68 | */ | ||
69 | |||
70 | /* MMCIPOWER bits */ | ||
71 | #define MCI_DATA2DIREN (1 << 2) | ||
72 | #define MCI_CMDDIREN (1 << 3) | ||
73 | #define MCI_DATA0DIREN (1 << 4) | ||
74 | #define MCI_DATA31DIREN (1 << 5) | ||
75 | #define MCI_FBCLKEN (1 << 7) | ||
76 | |||
77 | static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | ||
78 | unsigned char power_mode) | ||
79 | { | ||
80 | if (power_mode == MMC_POWER_UP) | ||
81 | gpio_set_value_cansleep(GPIO_SDMMC_EN, 1); | ||
82 | else if (power_mode == MMC_POWER_OFF) | ||
83 | gpio_set_value_cansleep(GPIO_SDMMC_EN, 0); | ||
84 | |||
85 | return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | | ||
86 | MCI_DATA2DIREN | MCI_DATA31DIREN; | ||
87 | } | ||
88 | |||
89 | static struct mmci_platform_data mop500_sdi0_data = { | ||
90 | .vdd_handler = mop500_sdi0_vdd_handler, | ||
91 | .ocr_mask = MMC_VDD_29_30, | ||
92 | .f_max = 100000000, | ||
93 | .capabilities = MMC_CAP_4_BIT_DATA, | ||
94 | .gpio_cd = GPIO_SDMMC_CD, | ||
95 | .gpio_wp = -1, | ||
96 | }; | ||
97 | |||
98 | void mop500_sdi_tc35892_init(void) | ||
99 | { | ||
100 | int ret; | ||
101 | |||
102 | ret = gpio_request(GPIO_SDMMC_EN, "SDMMC_EN"); | ||
103 | if (!ret) | ||
104 | ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL, | ||
105 | "GPIO_SDMMC_1V8_3V_SEL"); | ||
106 | if (ret) | ||
107 | return; | ||
108 | |||
109 | gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1); | ||
110 | gpio_direction_output(GPIO_SDMMC_EN, 0); | ||
111 | |||
112 | db8500_add_sdi0(&mop500_sdi0_data); | ||
113 | } | ||
114 | |||
115 | /* | ||
53 | * SDI 2 (POP eMMC, not on DB8500ed) | 116 | * SDI 2 (POP eMMC, not on DB8500ed) |
54 | */ | 117 | */ |
55 | 118 | ||
@@ -74,18 +137,24 @@ static struct mmci_platform_data mop500_sdi4_data = { | |||
74 | .gpio_wp = -1, | 137 | .gpio_wp = -1, |
75 | }; | 138 | }; |
76 | 139 | ||
77 | void mop500_sdi_init(void) | 140 | void __init mop500_sdi_init(void) |
78 | { | 141 | { |
79 | nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins)); | 142 | nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins)); |
80 | 143 | ||
81 | u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data; | 144 | /* |
82 | u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data; | 145 | * sdi0 will finally be added when the TC35892 initializes and calls |
146 | * mop500_sdi_tc35892_init() above. | ||
147 | */ | ||
83 | 148 | ||
149 | /* PoP:ed eMMC */ | ||
84 | if (!cpu_is_u8500ed()) { | 150 | if (!cpu_is_u8500ed()) { |
85 | nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins)); | 151 | nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins)); |
86 | amba_device_register(&u8500_sdi2_device, &iomem_resource); | 152 | /* POP eMMC on v1.0 has problems with high speed */ |
153 | if (!cpu_is_u8500v10()) | ||
154 | mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; | ||
155 | db8500_add_sdi2(&mop500_sdi2_data); | ||
87 | } | 156 | } |
88 | 157 | ||
89 | /* On-board eMMC */ | 158 | /* On-board eMMC */ |
90 | amba_device_register(&u8500_sdi4_device, &iomem_resource); | 159 | db8500_add_sdi4(&mop500_sdi4_data); |
91 | } | 160 | } |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index cac83a694880..a1c9ea1a66df 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -13,25 +13,26 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/i2c.h> | ||
16 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
17 | #include <linux/amba/bus.h> | 18 | #include <linux/amba/bus.h> |
18 | #include <linux/amba/pl022.h> | 19 | #include <linux/amba/pl022.h> |
19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
20 | #include <linux/mfd/ab8500.h> | 21 | #include <linux/mfd/ab8500.h> |
21 | #include <linux/input/matrix_keypad.h> | 22 | #include <linux/mfd/tc3589x.h> |
22 | 23 | ||
23 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
24 | #include <asm/mach/arch.h> | 25 | #include <asm/mach/arch.h> |
25 | 26 | ||
26 | #include <plat/pincfg.h> | 27 | #include <plat/pincfg.h> |
27 | #include <plat/i2c.h> | 28 | #include <plat/i2c.h> |
28 | #include <plat/ske.h> | ||
29 | 29 | ||
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | #include <mach/setup.h> | 31 | #include <mach/setup.h> |
32 | #include <mach/devices.h> | 32 | #include <mach/devices.h> |
33 | #include <mach/irqs.h> | 33 | #include <mach/irqs.h> |
34 | 34 | ||
35 | #include "devices-db8500.h" | ||
35 | #include "pins-db8500.h" | 36 | #include "pins-db8500.h" |
36 | #include "board-mop500.h" | 37 | #include "board-mop500.h" |
37 | 38 | ||
@@ -69,22 +70,12 @@ static pin_cfg_t mop500_pins[] = { | |||
69 | GPIO166_KP_O2, | 70 | GPIO166_KP_O2, |
70 | GPIO167_KP_O1, | 71 | GPIO167_KP_O1, |
71 | GPIO168_KP_O0, | 72 | GPIO168_KP_O0, |
72 | }; | ||
73 | 73 | ||
74 | static void ab4500_spi_cs_control(u32 command) | 74 | /* GPIO_EXP_INT */ |
75 | { | 75 | GPIO217_GPIO, |
76 | /* set the FRM signal, which is CS - TODO */ | ||
77 | } | ||
78 | 76 | ||
79 | struct pl022_config_chip ab4500_chip_info = { | 77 | /* STMPE1601 IRQ */ |
80 | .com_mode = INTERRUPT_TRANSFER, | 78 | GPIO218_GPIO | PIN_INPUT_PULLUP, |
81 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | ||
82 | /* we can act as master only */ | ||
83 | .hierarchy = SSP_MASTER, | ||
84 | .slave_tx_disable = 0, | ||
85 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | ||
86 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | ||
87 | .cs_control = ab4500_spi_cs_control, | ||
88 | }; | 79 | }; |
89 | 80 | ||
90 | static struct ab8500_platform_data ab8500_platdata = { | 81 | static struct ab8500_platform_data ab8500_platdata = { |
@@ -93,9 +84,9 @@ static struct ab8500_platform_data ab8500_platdata = { | |||
93 | 84 | ||
94 | static struct resource ab8500_resources[] = { | 85 | static struct resource ab8500_resources[] = { |
95 | [0] = { | 86 | [0] = { |
96 | .start = IRQ_AB8500, | 87 | .start = IRQ_DB8500_AB8500, |
97 | .end = IRQ_AB8500, | 88 | .end = IRQ_DB8500_AB8500, |
98 | .flags = IORESOURCE_IRQ | 89 | .flags = IORESOURCE_IRQ |
99 | } | 90 | } |
100 | }; | 91 | }; |
101 | 92 | ||
@@ -109,19 +100,6 @@ struct platform_device ab8500_device = { | |||
109 | .resource = ab8500_resources, | 100 | .resource = ab8500_resources, |
110 | }; | 101 | }; |
111 | 102 | ||
112 | static struct spi_board_info ab8500_spi_devices[] = { | ||
113 | { | ||
114 | .modalias = "ab8500-spi", | ||
115 | .controller_data = &ab4500_chip_info, | ||
116 | .platform_data = &ab8500_platdata, | ||
117 | .max_speed_hz = 12000000, | ||
118 | .bus_num = 0, | ||
119 | .chip_select = 0, | ||
120 | .mode = SPI_MODE_3, | ||
121 | .irq = IRQ_DB8500_AB8500, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static struct pl022_ssp_controller ssp0_platform_data = { | 103 | static struct pl022_ssp_controller ssp0_platform_data = { |
126 | .bus_id = 0, | 104 | .bus_id = 0, |
127 | /* pl022 not yet supports dma */ | 105 | /* pl022 not yet supports dma */ |
@@ -132,6 +110,34 @@ static struct pl022_ssp_controller ssp0_platform_data = { | |||
132 | .num_chipselect = 5, | 110 | .num_chipselect = 5, |
133 | }; | 111 | }; |
134 | 112 | ||
113 | /* | ||
114 | * TC35892 | ||
115 | */ | ||
116 | |||
117 | static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base) | ||
118 | { | ||
119 | mop500_sdi_tc35892_init(); | ||
120 | } | ||
121 | |||
122 | static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = { | ||
123 | .gpio_base = MOP500_EGPIO(0), | ||
124 | .setup = mop500_tc35892_init, | ||
125 | }; | ||
126 | |||
127 | static struct tc3589x_platform_data mop500_tc35892_data = { | ||
128 | .block = TC3589x_BLOCK_GPIO, | ||
129 | .gpio = &mop500_tc35892_gpio_data, | ||
130 | .irq_base = MOP500_EGPIO_IRQ_BASE, | ||
131 | }; | ||
132 | |||
133 | static struct i2c_board_info mop500_i2c0_devices[] = { | ||
134 | { | ||
135 | I2C_BOARD_INFO("tc3589x", 0x42), | ||
136 | .irq = NOMADIK_GPIO_TO_IRQ(217), | ||
137 | .platform_data = &mop500_tc35892_data, | ||
138 | }, | ||
139 | }; | ||
140 | |||
135 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ | 141 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ |
136 | static struct nmk_i2c_controller u8500_i2c##id##_data = { \ | 142 | static struct nmk_i2c_controller u8500_i2c##id##_data = { \ |
137 | /* \ | 143 | /* \ |
@@ -161,159 +167,49 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | |||
161 | U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 167 | U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); |
162 | U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 168 | U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); |
163 | 169 | ||
164 | static struct amba_device *amba_devs[] __initdata = { | 170 | static void __init mop500_i2c_init(void) |
165 | &ux500_uart0_device, | 171 | { |
166 | &ux500_uart1_device, | 172 | db8500_add_i2c0(&u8500_i2c0_data); |
167 | &ux500_uart2_device, | 173 | db8500_add_i2c1(&u8500_i2c1_data); |
168 | &u8500_ssp0_device, | 174 | db8500_add_i2c2(&u8500_i2c2_data); |
169 | }; | 175 | db8500_add_i2c3(&u8500_i2c3_data); |
170 | 176 | } | |
171 | static const unsigned int ux500_keymap[] = { | ||
172 | KEY(2, 5, KEY_END), | ||
173 | KEY(4, 1, KEY_POWER), | ||
174 | KEY(3, 5, KEY_VOLUMEDOWN), | ||
175 | KEY(1, 3, KEY_3), | ||
176 | KEY(5, 2, KEY_RIGHT), | ||
177 | KEY(5, 0, KEY_9), | ||
178 | |||
179 | KEY(0, 5, KEY_MENU), | ||
180 | KEY(7, 6, KEY_ENTER), | ||
181 | KEY(4, 5, KEY_0), | ||
182 | KEY(6, 7, KEY_2), | ||
183 | KEY(3, 4, KEY_UP), | ||
184 | KEY(3, 3, KEY_DOWN), | ||
185 | |||
186 | KEY(6, 4, KEY_SEND), | ||
187 | KEY(6, 2, KEY_BACK), | ||
188 | KEY(4, 2, KEY_VOLUMEUP), | ||
189 | KEY(5, 5, KEY_1), | ||
190 | KEY(4, 3, KEY_LEFT), | ||
191 | KEY(3, 2, KEY_7), | ||
192 | }; | ||
193 | |||
194 | static const struct matrix_keymap_data ux500_keymap_data = { | ||
195 | .keymap = ux500_keymap, | ||
196 | .keymap_size = ARRAY_SIZE(ux500_keymap), | ||
197 | }; | ||
198 | 177 | ||
199 | /* | 178 | /* add any platform devices here - TODO */ |
200 | * Nomadik SKE keypad | 179 | static struct platform_device *platform_devs[] __initdata = { |
201 | */ | ||
202 | #define ROW_PIN_I0 164 | ||
203 | #define ROW_PIN_I1 163 | ||
204 | #define ROW_PIN_I2 162 | ||
205 | #define ROW_PIN_I3 161 | ||
206 | #define ROW_PIN_I4 156 | ||
207 | #define ROW_PIN_I5 155 | ||
208 | #define ROW_PIN_I6 154 | ||
209 | #define ROW_PIN_I7 153 | ||
210 | #define COL_PIN_O0 168 | ||
211 | #define COL_PIN_O1 167 | ||
212 | #define COL_PIN_O2 166 | ||
213 | #define COL_PIN_O3 165 | ||
214 | #define COL_PIN_O4 160 | ||
215 | #define COL_PIN_O5 159 | ||
216 | #define COL_PIN_O6 158 | ||
217 | #define COL_PIN_O7 157 | ||
218 | |||
219 | #define SKE_KPD_MAX_ROWS 8 | ||
220 | #define SKE_KPD_MAX_COLS 8 | ||
221 | |||
222 | static int ske_kp_rows[] = { | ||
223 | ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, | ||
224 | ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7, | ||
225 | }; | 180 | }; |
226 | 181 | ||
227 | /* | 182 | static void __init mop500_spi_init(void) |
228 | * ske_set_gpio_row: request and set gpio rows | ||
229 | */ | ||
230 | static int ske_set_gpio_row(int gpio) | ||
231 | { | 183 | { |
232 | int ret; | 184 | db8500_add_ssp0(&ssp0_platform_data); |
233 | |||
234 | ret = gpio_request(gpio, "ske-kp"); | ||
235 | if (ret < 0) { | ||
236 | pr_err("ske_set_gpio_row: gpio request failed\n"); | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | ret = gpio_direction_output(gpio, 1); | ||
241 | if (ret < 0) { | ||
242 | pr_err("ske_set_gpio_row: gpio direction failed\n"); | ||
243 | gpio_free(gpio); | ||
244 | } | ||
245 | |||
246 | return ret; | ||
247 | } | 185 | } |
248 | 186 | ||
249 | /* | 187 | static void __init mop500_uart_init(void) |
250 | * ske_kp_init - enable the gpio configuration | ||
251 | */ | ||
252 | static int ske_kp_init(void) | ||
253 | { | 188 | { |
254 | int ret, i; | 189 | db8500_add_uart0(); |
255 | 190 | db8500_add_uart1(); | |
256 | for (i = 0; i < SKE_KPD_MAX_ROWS; i++) { | 191 | db8500_add_uart2(); |
257 | ret = ske_set_gpio_row(ske_kp_rows[i]); | ||
258 | if (ret < 0) { | ||
259 | pr_err("ske_kp_init: failed init\n"); | ||
260 | return ret; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | 192 | } |
266 | 193 | ||
267 | static struct ske_keypad_platform_data ske_keypad_board = { | ||
268 | .init = ske_kp_init, | ||
269 | .keymap_data = &ux500_keymap_data, | ||
270 | .no_autorepeat = true, | ||
271 | .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */ | ||
272 | .kcol = SKE_KPD_MAX_COLS, | ||
273 | .debounce_ms = 40, /* in millsecs */ | ||
274 | }; | ||
275 | |||
276 | |||
277 | |||
278 | /* add any platform devices here - TODO */ | ||
279 | static struct platform_device *platform_devs[] __initdata = { | ||
280 | &u8500_i2c0_device, | ||
281 | &ux500_i2c1_device, | ||
282 | &ux500_i2c2_device, | ||
283 | &ux500_i2c3_device, | ||
284 | &ux500_ske_keypad_device, | ||
285 | }; | ||
286 | |||
287 | static void __init u8500_init_machine(void) | 194 | static void __init u8500_init_machine(void) |
288 | { | 195 | { |
289 | int i; | ||
290 | |||
291 | u8500_init_devices(); | 196 | u8500_init_devices(); |
292 | 197 | ||
293 | nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins)); | 198 | nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins)); |
294 | 199 | ||
295 | u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data; | ||
296 | ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data; | ||
297 | ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data; | ||
298 | ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data; | ||
299 | ux500_ske_keypad_device.dev.platform_data = &ske_keypad_board; | ||
300 | |||
301 | u8500_ssp0_device.dev.platform_data = &ssp0_platform_data; | ||
302 | |||
303 | /* Register the active AMBA devices on this board */ | ||
304 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) | ||
305 | amba_device_register(amba_devs[i], &iomem_resource); | ||
306 | |||
307 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 200 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
308 | 201 | ||
202 | mop500_i2c_init(); | ||
309 | mop500_sdi_init(); | 203 | mop500_sdi_init(); |
204 | mop500_spi_init(); | ||
205 | mop500_uart_init(); | ||
206 | |||
207 | mop500_keypad_init(); | ||
208 | |||
209 | platform_device_register(&ab8500_device); | ||
310 | 210 | ||
311 | /* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */ | 211 | i2c_register_board_info(0, mop500_i2c0_devices, |
312 | if (cpu_is_u8500ed() || cpu_is_u8500v10()) | 212 | ARRAY_SIZE(mop500_i2c0_devices)); |
313 | spi_register_board_info(ab8500_spi_devices, | ||
314 | ARRAY_SIZE(ab8500_spi_devices)); | ||
315 | else /* If HW is v.1.1 or later use I2C to access AB8500 */ | ||
316 | platform_device_register(&ab8500_device); | ||
317 | } | 213 | } |
318 | 214 | ||
319 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | 215 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") |
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 2d240322fa6f..3104ae2a02c2 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h | |||
@@ -7,6 +7,15 @@ | |||
7 | #ifndef __BOARD_MOP500_H | 7 | #ifndef __BOARD_MOP500_H |
8 | #define __BOARD_MOP500_H | 8 | #define __BOARD_MOP500_H |
9 | 9 | ||
10 | #define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) | ||
11 | |||
12 | /* GPIOs on the TC35892 expander */ | ||
13 | #define GPIO_SDMMC_CD MOP500_EGPIO(3) | ||
14 | #define GPIO_SDMMC_EN MOP500_EGPIO(17) | ||
15 | #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) | ||
16 | |||
10 | extern void mop500_sdi_init(void); | 17 | extern void mop500_sdi_init(void); |
18 | extern void mop500_sdi_tc35892_init(void); | ||
19 | extern void mop500_keypad_init(void); | ||
11 | 20 | ||
12 | #endif | 21 | #endif |
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c new file mode 100644 index 000000000000..54712acc0394 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-sdi.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Hanumath Prasad <ulf.hansson@stericsson.com> | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/amba/mmci.h> | ||
9 | #include <linux/mmc/host.h> | ||
10 | #include <linux/gpio.h> | ||
11 | |||
12 | #include <plat/pincfg.h> | ||
13 | #include <mach/db5500-regs.h> | ||
14 | #include <plat/ste_dma40.h> | ||
15 | |||
16 | #include "pins-db5500.h" | ||
17 | #include "devices-db5500.h" | ||
18 | #include "ste-dma40-db5500.h" | ||
19 | |||
20 | static pin_cfg_t u5500_sdi_pins[] = { | ||
21 | /* SDI0 (POP eMMC) */ | ||
22 | GPIO5_MC0_DAT0 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
23 | GPIO6_MC0_DAT1 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
24 | GPIO7_MC0_DAT2 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
25 | GPIO8_MC0_DAT3 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
26 | GPIO9_MC0_DAT4 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
27 | GPIO10_MC0_DAT5 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
28 | GPIO11_MC0_DAT6 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
29 | GPIO12_MC0_DAT7 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
30 | GPIO13_MC0_CMD | PIN_DIR_INPUT | PIN_PULL_UP, | ||
31 | GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW, | ||
32 | }; | ||
33 | |||
34 | static struct mmci_platform_data u5500_sdi0_data = { | ||
35 | .ocr_mask = MMC_VDD_165_195, | ||
36 | .f_max = 50000000, | ||
37 | .capabilities = MMC_CAP_4_BIT_DATA | | ||
38 | MMC_CAP_8_BIT_DATA | | ||
39 | MMC_CAP_MMC_HIGHSPEED, | ||
40 | .gpio_cd = -1, | ||
41 | .gpio_wp = -1, | ||
42 | }; | ||
43 | |||
44 | void __init u5500_sdi_init(void) | ||
45 | { | ||
46 | nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); | ||
47 | |||
48 | db5500_add_sdi0(&u5500_sdi0_data); | ||
49 | } | ||
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 1ca094a45e71..39d370c1f3b4 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
10 | #include <linux/amba/bus.h> | 10 | #include <linux/amba/bus.h> |
11 | #include <linux/gpio.h> | 11 | #include <linux/gpio.h> |
12 | #include <linux/irq.h> | ||
12 | 13 | ||
13 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
14 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
@@ -17,20 +18,24 @@ | |||
17 | #include <mach/devices.h> | 18 | #include <mach/devices.h> |
18 | #include <mach/setup.h> | 19 | #include <mach/setup.h> |
19 | 20 | ||
20 | static struct amba_device *amba_board_devs[] __initdata = { | 21 | #include "devices-db5500.h" |
21 | &ux500_uart0_device, | 22 | |
22 | &ux500_uart1_device, | 23 | static void __init u5500_uart_init(void) |
23 | &ux500_uart2_device, | 24 | { |
24 | }; | 25 | db5500_add_uart0(); |
26 | db5500_add_uart1(); | ||
27 | db5500_add_uart2(); | ||
28 | } | ||
25 | 29 | ||
26 | static void __init u5500_init_machine(void) | 30 | static void __init u5500_init_machine(void) |
27 | { | 31 | { |
28 | u5500_init_devices(); | 32 | u5500_init_devices(); |
29 | 33 | ||
30 | amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs)); | 34 | u5500_sdi_init(); |
35 | u5500_uart_init(); | ||
31 | } | 36 | } |
32 | 37 | ||
33 | MACHINE_START(U8500, "ST-Ericsson U5500 Platform") | 38 | MACHINE_START(U5500, "ST-Ericsson U5500 Platform") |
34 | .boot_params = 0x00000100, | 39 | .boot_params = 0x00000100, |
35 | .map_io = u5500_map_io, | 40 | .map_io = u5500_map_io, |
36 | .init_irq = ux500_init_irq, | 41 | .init_irq = ux500_init_irq, |
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 1675047daf20..912d1cc18c57 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c | |||
@@ -20,6 +20,12 @@ | |||
20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
21 | #include "clock.h" | 21 | #include "clock.h" |
22 | 22 | ||
23 | #ifdef CONFIG_DEBUG_FS | ||
24 | #include <linux/debugfs.h> | ||
25 | #include <linux/uaccess.h> /* for copy_from_user */ | ||
26 | static LIST_HEAD(clk_list); | ||
27 | #endif | ||
28 | |||
23 | #define PRCC_PCKEN 0x00 | 29 | #define PRCC_PCKEN 0x00 |
24 | #define PRCC_PCKDIS 0x04 | 30 | #define PRCC_PCKDIS 0x04 |
25 | #define PRCC_KCKEN 0x08 | 31 | #define PRCC_KCKEN 0x08 |
@@ -133,7 +139,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
133 | { | 139 | { |
134 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) | 140 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) |
135 | + PRCM_TCR; | 141 | + PRCM_TCR; |
136 | u32 tcr = readl(addr); | 142 | u32 tcr; |
137 | int mtu = (int) clk->data; | 143 | int mtu = (int) clk->data; |
138 | /* | 144 | /* |
139 | * One of these is selected eventually | 145 | * One of these is selected eventually |
@@ -144,6 +150,14 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
144 | unsigned long mturate; | 150 | unsigned long mturate; |
145 | unsigned long retclk; | 151 | unsigned long retclk; |
146 | 152 | ||
153 | /* | ||
154 | * On a startup, always conifgure the TCR to the doze mode; | ||
155 | * bootloaders do it for us. Do this in the kernel too. | ||
156 | */ | ||
157 | writel(PRCM_TCR_DOZE_MODE, addr); | ||
158 | |||
159 | tcr = readl(addr); | ||
160 | |||
147 | /* Get the rate from the parent as a default */ | 161 | /* Get the rate from the parent as a default */ |
148 | if (clk->parent_periph) | 162 | if (clk->parent_periph) |
149 | mturate = clk_get_rate(clk->parent_periph); | 163 | mturate = clk_get_rate(clk->parent_periph); |
@@ -153,45 +167,6 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
153 | /* We need to be connected SOMEWHERE */ | 167 | /* We need to be connected SOMEWHERE */ |
154 | BUG(); | 168 | BUG(); |
155 | 169 | ||
156 | /* | ||
157 | * Are we in doze mode? | ||
158 | * In this mode the parent peripheral or the fixed 32768 Hz | ||
159 | * clock is fed into the block. | ||
160 | */ | ||
161 | if (!(tcr & PRCM_TCR_DOZE_MODE)) { | ||
162 | /* | ||
163 | * Here we're using the clock input from the APE ULP | ||
164 | * clock domain. But first: are the timers stopped? | ||
165 | */ | ||
166 | if (tcr & PRCM_TCR_STOPPED) { | ||
167 | clk32k = 0; | ||
168 | mturate = 0; | ||
169 | } else { | ||
170 | /* Else default mode: 0 and 2.4 MHz */ | ||
171 | clk32k = 0; | ||
172 | if (cpu_is_u5500()) | ||
173 | /* DB5500 divides by 8 */ | ||
174 | mturate /= 8; | ||
175 | else if (cpu_is_u8500ed()) { | ||
176 | /* | ||
177 | * This clocking setting must not be used | ||
178 | * in the ED chip, it is simply not | ||
179 | * connected anywhere! | ||
180 | */ | ||
181 | mturate = 0; | ||
182 | BUG(); | ||
183 | } else | ||
184 | /* | ||
185 | * In this mode the ulp38m4 clock is divided | ||
186 | * by a factor 16, on the DB8500 typically | ||
187 | * 38400000 / 16 ~ 2.4 MHz. | ||
188 | * TODO: Replace the constant with a reference | ||
189 | * to the ULP source once this is modeled. | ||
190 | */ | ||
191 | mturate = 38400000 / 16; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /* Return the clock selected for this MTU */ | 170 | /* Return the clock selected for this MTU */ |
196 | if (tcr & (1 << mtu)) | 171 | if (tcr & (1 << mtu)) |
197 | retclk = clk32k; | 172 | retclk = clk32k; |
@@ -317,6 +292,7 @@ static struct clkops clk_prcc_ops = { | |||
317 | }; | 292 | }; |
318 | 293 | ||
319 | static struct clk clk_32khz = { | 294 | static struct clk clk_32khz = { |
295 | .name = "clk_32khz", | ||
320 | .rate = 32000, | 296 | .rate = 32000, |
321 | }; | 297 | }; |
322 | 298 | ||
@@ -366,94 +342,96 @@ static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */ | |||
366 | */ | 342 | */ |
367 | 343 | ||
368 | /* Peripheral Cluster #1 */ | 344 | /* Peripheral Cluster #1 */ |
369 | static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); | 345 | static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); |
370 | static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); | 346 | static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); |
371 | static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); | 347 | static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); |
372 | static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); | 348 | static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); |
373 | static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); | 349 | static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); |
374 | static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); | 350 | static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); |
375 | static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); | 351 | static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); |
376 | static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); | 352 | static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); |
377 | static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); | 353 | static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); |
378 | static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); | 354 | static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); |
379 | static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); | 355 | static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); |
380 | static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); | 356 | static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); |
381 | static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); | 357 | static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); |
382 | 358 | ||
383 | /* Peripheral Cluster #2 */ | 359 | /* Peripheral Cluster #2 */ |
384 | 360 | ||
385 | static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); | 361 | static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); |
386 | static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); | 362 | static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); |
387 | static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); | 363 | static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); |
388 | static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); | 364 | static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); |
389 | static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); | 365 | static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); |
390 | static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); | 366 | static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); |
391 | static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); | 367 | static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); |
392 | static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); | 368 | static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); |
393 | static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); | 369 | static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); |
394 | static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); | 370 | static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); |
395 | static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); | 371 | static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); |
396 | static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); | 372 | static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); |
397 | 373 | ||
398 | static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); | 374 | static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); |
399 | static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); | 375 | static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); |
400 | static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); | 376 | static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); |
401 | static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); | 377 | static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); |
402 | static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); | 378 | static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); |
403 | static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); | 379 | static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); |
404 | static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); | 380 | static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); |
405 | static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); | 381 | static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); |
406 | static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); | 382 | static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); |
407 | static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); | 383 | static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); |
408 | static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); | 384 | static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); |
409 | static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); | 385 | static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); |
410 | 386 | ||
411 | /* Peripheral Cluster #3 */ | 387 | /* Peripheral Cluster #3 */ |
412 | static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); | 388 | static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); |
413 | static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); | 389 | static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); |
414 | static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); | 390 | static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); |
415 | static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); | 391 | static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); |
416 | static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); | 392 | static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); |
417 | static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); | 393 | static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); |
418 | static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); | 394 | static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); |
419 | static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); | 395 | static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); |
420 | static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); | 396 | static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); |
421 | static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); | 397 | static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); |
422 | static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); | 398 | static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); |
423 | 399 | ||
424 | /* Peripheral Cluster #4 is in the always on domain */ | 400 | /* Peripheral Cluster #4 is in the always on domain */ |
425 | 401 | ||
426 | /* Peripheral Cluster #5 */ | 402 | /* Peripheral Cluster #5 */ |
427 | static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); | 403 | static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); |
428 | static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); | 404 | static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); |
429 | static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); | 405 | static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); |
430 | 406 | ||
431 | /* Peripheral Cluster #6 */ | 407 | /* Peripheral Cluster #6 */ |
432 | 408 | ||
433 | /* MTU ID in data */ | 409 | /* MTU ID in data */ |
434 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); | 410 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); |
435 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); | 411 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); |
436 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); | 412 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); |
437 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); | 413 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); |
438 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); | 414 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); |
439 | static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); | 415 | static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); |
440 | static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); | 416 | static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); |
441 | static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); | 417 | static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); |
442 | static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); | 418 | static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); |
443 | static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); | 419 | static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); |
444 | static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); | 420 | static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); |
445 | static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); | 421 | static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); |
446 | 422 | ||
447 | /* Peripheral Cluster #7 */ | 423 | /* Peripheral Cluster #7 */ |
448 | 424 | ||
449 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); | 425 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); |
450 | /* MTU ID in data */ | 426 | /* MTU ID in data */ |
451 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); | 427 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); |
452 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); | 428 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); |
453 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); | 429 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); |
454 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); | 430 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); |
455 | 431 | ||
456 | static struct clk clk_dummy_apb_pclk; | 432 | static struct clk clk_dummy_apb_pclk = { |
433 | .name = "apb_pclk", | ||
434 | }; | ||
457 | 435 | ||
458 | static struct clk_lookup u8500_common_clks[] = { | 436 | static struct clk_lookup u8500_common_clks[] = { |
459 | CLK(dummy_apb_pclk, NULL, "apb_pclk"), | 437 | CLK(dummy_apb_pclk, NULL, "apb_pclk"), |
@@ -554,7 +532,7 @@ static struct clk_lookup u8500_ed_clks[] = { | |||
554 | 532 | ||
555 | static struct clk_lookup u8500_v1_clks[] = { | 533 | static struct clk_lookup u8500_v1_clks[] = { |
556 | /* Peripheral Cluster #1 */ | 534 | /* Peripheral Cluster #1 */ |
557 | CLK(i2c4, "nmk-i2c.4", NULL), | 535 | CLK(i2c4, "nmk-i2c.4", NULL), |
558 | CLK(spi3_v1, "spi3", NULL), | 536 | CLK(spi3_v1, "spi3", NULL), |
559 | CLK(msp1_v1, "msp1", NULL), | 537 | CLK(msp1_v1, "msp1", NULL), |
560 | 538 | ||
@@ -599,6 +577,183 @@ static struct clk_lookup u8500_v1_clks[] = { | |||
599 | CLK(uiccclk, "uicc", NULL), | 577 | CLK(uiccclk, "uicc", NULL), |
600 | }; | 578 | }; |
601 | 579 | ||
580 | #ifdef CONFIG_DEBUG_FS | ||
581 | /* | ||
582 | * debugfs support to trace clock tree hierarchy and attributes with | ||
583 | * powerdebug | ||
584 | */ | ||
585 | static struct dentry *clk_debugfs_root; | ||
586 | |||
587 | void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num) | ||
588 | { | ||
589 | while (num--) { | ||
590 | /* Check that the clock has not been already registered */ | ||
591 | if (!(cl->clk->list.prev != cl->clk->list.next)) | ||
592 | list_add_tail(&cl->clk->list, &clk_list); | ||
593 | |||
594 | cl++; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | static ssize_t usecount_dbg_read(struct file *file, char __user *buf, | ||
599 | size_t size, loff_t *off) | ||
600 | { | ||
601 | struct clk *clk = file->f_dentry->d_inode->i_private; | ||
602 | char cusecount[128]; | ||
603 | unsigned int len; | ||
604 | |||
605 | len = sprintf(cusecount, "%u\n", clk->enabled); | ||
606 | return simple_read_from_buffer(buf, size, off, cusecount, len); | ||
607 | } | ||
608 | |||
609 | static ssize_t rate_dbg_read(struct file *file, char __user *buf, | ||
610 | size_t size, loff_t *off) | ||
611 | { | ||
612 | struct clk *clk = file->f_dentry->d_inode->i_private; | ||
613 | char crate[128]; | ||
614 | unsigned int rate; | ||
615 | unsigned int len; | ||
616 | |||
617 | rate = clk_get_rate(clk); | ||
618 | len = sprintf(crate, "%u\n", rate); | ||
619 | return simple_read_from_buffer(buf, size, off, crate, len); | ||
620 | } | ||
621 | |||
622 | static const struct file_operations usecount_fops = { | ||
623 | .read = usecount_dbg_read, | ||
624 | }; | ||
625 | |||
626 | static const struct file_operations set_rate_fops = { | ||
627 | .read = rate_dbg_read, | ||
628 | }; | ||
629 | |||
630 | static struct dentry *clk_debugfs_register_dir(struct clk *c, | ||
631 | struct dentry *p_dentry) | ||
632 | { | ||
633 | struct dentry *d, *clk_d, *child, *child_tmp; | ||
634 | char s[255]; | ||
635 | char *p = s; | ||
636 | |||
637 | if (c->name == NULL) | ||
638 | p += sprintf(p, "BUG"); | ||
639 | else | ||
640 | p += sprintf(p, "%s", c->name); | ||
641 | |||
642 | clk_d = debugfs_create_dir(s, p_dentry); | ||
643 | if (!clk_d) | ||
644 | return NULL; | ||
645 | |||
646 | d = debugfs_create_file("usecount", S_IRUGO, | ||
647 | clk_d, c, &usecount_fops); | ||
648 | if (!d) | ||
649 | goto err_out; | ||
650 | d = debugfs_create_file("rate", S_IRUGO, | ||
651 | clk_d, c, &set_rate_fops); | ||
652 | if (!d) | ||
653 | goto err_out; | ||
654 | /* | ||
655 | * TODO : not currently available in ux500 | ||
656 | * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags); | ||
657 | * if (!d) | ||
658 | * goto err_out; | ||
659 | */ | ||
660 | |||
661 | return clk_d; | ||
662 | |||
663 | err_out: | ||
664 | d = clk_d; | ||
665 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
666 | debugfs_remove(child); | ||
667 | debugfs_remove(clk_d); | ||
668 | return NULL; | ||
669 | } | ||
670 | |||
671 | static void clk_debugfs_remove_dir(struct dentry *cdentry) | ||
672 | { | ||
673 | struct dentry *d, *child, *child_tmp; | ||
674 | |||
675 | d = cdentry; | ||
676 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
677 | debugfs_remove(child); | ||
678 | debugfs_remove(cdentry); | ||
679 | return ; | ||
680 | } | ||
681 | |||
682 | static int clk_debugfs_register_one(struct clk *c) | ||
683 | { | ||
684 | struct clk *pa = c->parent_periph; | ||
685 | struct clk *bpa = c->parent_cluster; | ||
686 | |||
687 | if (!(bpa && !pa)) { | ||
688 | c->dent = clk_debugfs_register_dir(c, | ||
689 | pa ? pa->dent : clk_debugfs_root); | ||
690 | if (!c->dent) | ||
691 | return -ENOMEM; | ||
692 | } | ||
693 | |||
694 | if (bpa) { | ||
695 | c->dent_bus = clk_debugfs_register_dir(c, | ||
696 | bpa->dent_bus ? bpa->dent_bus : bpa->dent); | ||
697 | if ((!c->dent_bus) && (c->dent)) { | ||
698 | clk_debugfs_remove_dir(c->dent); | ||
699 | c->dent = NULL; | ||
700 | return -ENOMEM; | ||
701 | } | ||
702 | } | ||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int clk_debugfs_register(struct clk *c) | ||
707 | { | ||
708 | int err; | ||
709 | struct clk *pa = c->parent_periph; | ||
710 | struct clk *bpa = c->parent_cluster; | ||
711 | |||
712 | if (pa && (!pa->dent && !pa->dent_bus)) { | ||
713 | err = clk_debugfs_register(pa); | ||
714 | if (err) | ||
715 | return err; | ||
716 | } | ||
717 | |||
718 | if (bpa && (!bpa->dent && !bpa->dent_bus)) { | ||
719 | err = clk_debugfs_register(bpa); | ||
720 | if (err) | ||
721 | return err; | ||
722 | } | ||
723 | |||
724 | if ((!c->dent) && (!c->dent_bus)) { | ||
725 | err = clk_debugfs_register_one(c); | ||
726 | if (err) | ||
727 | return err; | ||
728 | } | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static int __init clk_debugfs_init(void) | ||
733 | { | ||
734 | struct clk *c; | ||
735 | struct dentry *d; | ||
736 | int err; | ||
737 | |||
738 | d = debugfs_create_dir("clock", NULL); | ||
739 | if (!d) | ||
740 | return -ENOMEM; | ||
741 | clk_debugfs_root = d; | ||
742 | |||
743 | list_for_each_entry(c, &clk_list, list) { | ||
744 | err = clk_debugfs_register(c); | ||
745 | if (err) | ||
746 | goto err_out; | ||
747 | } | ||
748 | return 0; | ||
749 | err_out: | ||
750 | debugfs_remove_recursive(clk_debugfs_root); | ||
751 | return err; | ||
752 | } | ||
753 | |||
754 | late_initcall(clk_debugfs_init); | ||
755 | #endif /* defined(CONFIG_DEBUG_FS) */ | ||
756 | |||
602 | int __init clk_init(void) | 757 | int __init clk_init(void) |
603 | { | 758 | { |
604 | if (cpu_is_u8500ed()) { | 759 | if (cpu_is_u8500ed()) { |
@@ -609,7 +764,8 @@ int __init clk_init(void) | |||
609 | /* Clock tree for U5500 not implemented yet */ | 764 | /* Clock tree for U5500 not implemented yet */ |
610 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; | 765 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; |
611 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; | 766 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; |
612 | clk_per6clk.rate = 26000000; | 767 | clk_uartclk.rate = 36360000; |
768 | clk_sdmmcclk.rate = 99900000; | ||
613 | } | 769 | } |
614 | 770 | ||
615 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | 771 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); |
@@ -618,5 +774,12 @@ int __init clk_init(void) | |||
618 | else | 774 | else |
619 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | 775 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); |
620 | 776 | ||
777 | #ifdef CONFIG_DEBUG_FS | ||
778 | clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | ||
779 | if (cpu_is_u8500ed()) | ||
780 | clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks)); | ||
781 | else | ||
782 | clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | ||
783 | #endif | ||
621 | return 0; | 784 | return 0; |
622 | } | 785 | } |
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h index a05802501527..074490705229 100644 --- a/arch/arm/mach-ux500/clock.h +++ b/arch/arm/mach-ux500/clock.h | |||
@@ -90,6 +90,10 @@ struct clk { | |||
90 | 90 | ||
91 | struct clk *parent_cluster; | 91 | struct clk *parent_cluster; |
92 | struct clk *parent_periph; | 92 | struct clk *parent_periph; |
93 | #if defined(CONFIG_DEBUG_FS) | ||
94 | struct dentry *dent; /* For visible tree hierarchy */ | ||
95 | struct dentry *dent_bus; /* For visible tree hierarchy */ | ||
96 | #endif | ||
93 | }; | 97 | }; |
94 | 98 | ||
95 | #define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \ | 99 | #define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \ |
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 2f87075e9d6f..acc841e48de4 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c | |||
@@ -8,14 +8,19 @@ | |||
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/amba/bus.h> | 9 | #include <linux/amba/bus.h> |
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/irq.h> | ||
11 | 12 | ||
12 | #include <asm/mach/map.h> | 13 | #include <asm/mach/map.h> |
13 | 14 | ||
15 | #include <plat/gpio.h> | ||
16 | |||
14 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
15 | #include <mach/devices.h> | 18 | #include <mach/devices.h> |
16 | #include <mach/setup.h> | 19 | #include <mach/setup.h> |
17 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
18 | 21 | ||
22 | #include "devices-db5500.h" | ||
23 | |||
19 | static struct map_desc u5500_io_desc[] __initdata = { | 24 | static struct map_desc u5500_io_desc[] __initdata = { |
20 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), | 25 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), |
21 | __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), | 26 | __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), |
@@ -110,19 +115,32 @@ static struct platform_device mbox2_device = { | |||
110 | }; | 115 | }; |
111 | 116 | ||
112 | static struct platform_device *u5500_platform_devs[] __initdata = { | 117 | static struct platform_device *u5500_platform_devs[] __initdata = { |
113 | &u5500_gpio_devs[0], | ||
114 | &u5500_gpio_devs[1], | ||
115 | &u5500_gpio_devs[2], | ||
116 | &u5500_gpio_devs[3], | ||
117 | &u5500_gpio_devs[4], | ||
118 | &u5500_gpio_devs[5], | ||
119 | &u5500_gpio_devs[6], | ||
120 | &u5500_gpio_devs[7], | ||
121 | &mbox0_device, | 118 | &mbox0_device, |
122 | &mbox1_device, | 119 | &mbox1_device, |
123 | &mbox2_device, | 120 | &mbox2_device, |
124 | }; | 121 | }; |
125 | 122 | ||
123 | static resource_size_t __initdata db5500_gpio_base[] = { | ||
124 | U5500_GPIOBANK0_BASE, | ||
125 | U5500_GPIOBANK1_BASE, | ||
126 | U5500_GPIOBANK2_BASE, | ||
127 | U5500_GPIOBANK3_BASE, | ||
128 | U5500_GPIOBANK4_BASE, | ||
129 | U5500_GPIOBANK5_BASE, | ||
130 | U5500_GPIOBANK6_BASE, | ||
131 | U5500_GPIOBANK7_BASE, | ||
132 | }; | ||
133 | |||
134 | static void __init db5500_add_gpios(void) | ||
135 | { | ||
136 | struct nmk_gpio_platform_data pdata = { | ||
137 | /* No custom data yet */ | ||
138 | }; | ||
139 | |||
140 | dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base), | ||
141 | IRQ_DB5500_GPIO0, &pdata); | ||
142 | } | ||
143 | |||
126 | void __init u5500_map_io(void) | 144 | void __init u5500_map_io(void) |
127 | { | 145 | { |
128 | ux500_map_io(); | 146 | ux500_map_io(); |
@@ -132,7 +150,9 @@ void __init u5500_map_io(void) | |||
132 | 150 | ||
133 | void __init u5500_init_devices(void) | 151 | void __init u5500_init_devices(void) |
134 | { | 152 | { |
135 | ux500_init_devices(); | 153 | db5500_add_gpios(); |
154 | db5500_dma_init(); | ||
155 | db5500_add_rtc(); | ||
136 | 156 | ||
137 | platform_add_devices(u5500_platform_devs, | 157 | platform_add_devices(u5500_platform_devs, |
138 | ARRAY_SIZE(u5500_platform_devs)); | 158 | ARRAY_SIZE(u5500_platform_devs)); |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 4acab7544b3c..c0f34a404c53 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -22,23 +22,15 @@ | |||
22 | #include <mach/setup.h> | 22 | #include <mach/setup.h> |
23 | #include <mach/devices.h> | 23 | #include <mach/devices.h> |
24 | 24 | ||
25 | #include "devices-db8500.h" | ||
26 | |||
25 | static struct platform_device *platform_devs[] __initdata = { | 27 | static struct platform_device *platform_devs[] __initdata = { |
26 | &u8500_gpio_devs[0], | ||
27 | &u8500_gpio_devs[1], | ||
28 | &u8500_gpio_devs[2], | ||
29 | &u8500_gpio_devs[3], | ||
30 | &u8500_gpio_devs[4], | ||
31 | &u8500_gpio_devs[5], | ||
32 | &u8500_gpio_devs[6], | ||
33 | &u8500_gpio_devs[7], | ||
34 | &u8500_gpio_devs[8], | ||
35 | &u8500_dma40_device, | 28 | &u8500_dma40_device, |
36 | }; | 29 | }; |
37 | 30 | ||
38 | /* minimum static i/o mapping required to boot U8500 platforms */ | 31 | /* minimum static i/o mapping required to boot U8500 platforms */ |
39 | static struct map_desc u8500_io_desc[] __initdata = { | 32 | static struct map_desc u8500_io_desc[] __initdata = { |
40 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), | 33 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), |
41 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | ||
42 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), | 34 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), |
43 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), | 35 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), |
44 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), | 36 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), |
@@ -46,13 +38,18 @@ static struct map_desc u8500_io_desc[] __initdata = { | |||
46 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), | 38 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), |
47 | }; | 39 | }; |
48 | 40 | ||
49 | static struct map_desc u8500ed_io_desc[] __initdata = { | 41 | static struct map_desc u8500_ed_io_desc[] __initdata = { |
50 | __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), | 42 | __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), |
51 | __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), | 43 | __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), |
52 | }; | 44 | }; |
53 | 45 | ||
54 | static struct map_desc u8500v1_io_desc[] __initdata = { | 46 | static struct map_desc u8500_v1_io_desc[] __initdata = { |
55 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | 47 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), |
48 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE_V1, SZ_4K), | ||
49 | }; | ||
50 | |||
51 | static struct map_desc u8500_v2_io_desc[] __initdata = { | ||
52 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | ||
56 | }; | 53 | }; |
57 | 54 | ||
58 | /* | 55 | /* |
@@ -125,14 +122,38 @@ void __init u8500_map_io(void) | |||
125 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); | 122 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); |
126 | 123 | ||
127 | if (cpu_is_u8500ed()) | 124 | if (cpu_is_u8500ed()) |
128 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); | 125 | iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc)); |
129 | else | 126 | else if (cpu_is_u8500v1()) |
130 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); | 127 | iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc)); |
128 | else if (cpu_is_u8500v2()) | ||
129 | iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); | ||
131 | 130 | ||
132 | /* Read out the ASIC ID as early as we can */ | 131 | /* Read out the ASIC ID as early as we can */ |
133 | get_db8500_asic_id(); | 132 | get_db8500_asic_id(); |
134 | } | 133 | } |
135 | 134 | ||
135 | static resource_size_t __initdata db8500_gpio_base[] = { | ||
136 | U8500_GPIOBANK0_BASE, | ||
137 | U8500_GPIOBANK1_BASE, | ||
138 | U8500_GPIOBANK2_BASE, | ||
139 | U8500_GPIOBANK3_BASE, | ||
140 | U8500_GPIOBANK4_BASE, | ||
141 | U8500_GPIOBANK5_BASE, | ||
142 | U8500_GPIOBANK6_BASE, | ||
143 | U8500_GPIOBANK7_BASE, | ||
144 | U8500_GPIOBANK8_BASE, | ||
145 | }; | ||
146 | |||
147 | static void __init db8500_add_gpios(void) | ||
148 | { | ||
149 | struct nmk_gpio_platform_data pdata = { | ||
150 | /* No custom data yet */ | ||
151 | }; | ||
152 | |||
153 | dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), | ||
154 | IRQ_DB8500_GPIO0, &pdata); | ||
155 | } | ||
156 | |||
136 | /* | 157 | /* |
137 | * This function is called from the board init | 158 | * This function is called from the board init |
138 | */ | 159 | */ |
@@ -152,12 +173,13 @@ void __init u8500_init_devices(void) | |||
152 | else | 173 | else |
153 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); | 174 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); |
154 | 175 | ||
155 | ux500_init_devices(); | ||
156 | |||
157 | if (cpu_is_u8500ed()) | 176 | if (cpu_is_u8500ed()) |
158 | dma40_u8500ed_fixup(); | 177 | dma40_u8500ed_fixup(); |
159 | 178 | ||
160 | /* Register the platform devices */ | 179 | db8500_add_rtc(); |
180 | db8500_add_gpios(); | ||
181 | |||
182 | platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); | ||
161 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 183 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
162 | 184 | ||
163 | return ; | 185 | return ; |
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 608a1372b172..a3700bc374d3 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/amba/bus.h> | ||
10 | #include <linux/io.h> | 9 | #include <linux/io.h> |
11 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
12 | 11 | ||
@@ -20,6 +19,7 @@ | |||
20 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
21 | #include <mach/setup.h> | 20 | #include <mach/setup.h> |
22 | #include <mach/devices.h> | 21 | #include <mach/devices.h> |
22 | #include <mach/prcmu.h> | ||
23 | 23 | ||
24 | #include "clock.h" | 24 | #include "clock.h" |
25 | 25 | ||
@@ -45,20 +45,11 @@ static struct map_desc ux500_io_desc[] __initdata = { | |||
45 | __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), | 45 | __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static struct amba_device *ux500_amba_devs[] __initdata = { | ||
49 | &ux500_pl031_device, | ||
50 | }; | ||
51 | |||
52 | void __init ux500_map_io(void) | 48 | void __init ux500_map_io(void) |
53 | { | 49 | { |
54 | iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); | 50 | iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); |
55 | } | 51 | } |
56 | 52 | ||
57 | void __init ux500_init_devices(void) | ||
58 | { | ||
59 | amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs)); | ||
60 | } | ||
61 | |||
62 | void __init ux500_init_irq(void) | 53 | void __init ux500_init_irq(void) |
63 | { | 54 | { |
64 | gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); | 55 | gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); |
@@ -68,6 +59,8 @@ void __init ux500_init_irq(void) | |||
68 | * Init clocks here so that they are available for system timer | 59 | * Init clocks here so that they are available for system timer |
69 | * initialization. | 60 | * initialization. |
70 | */ | 61 | */ |
62 | if (cpu_is_u8500()) | ||
63 | prcmu_early_init(); | ||
71 | clk_init(); | 64 | clk_init(); |
72 | } | 65 | } |
73 | 66 | ||
diff --git a/arch/arm/mach-ux500/cpufreq.c b/arch/arm/mach-ux500/cpufreq.c new file mode 100644 index 000000000000..5c5b747f134d --- /dev/null +++ b/arch/arm/mach-ux500/cpufreq.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * CPU frequency scaling for u8500 | ||
3 | * Inspired by linux/arch/arm/mach-davinci/cpufreq.c | ||
4 | * | ||
5 | * Copyright (C) STMicroelectronics 2009 | ||
6 | * Copyright (C) ST-Ericsson SA 2010 | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
11 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
12 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/cpufreq.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <mach/hardware.h> | ||
22 | #include <mach/prcmu.h> | ||
23 | #include <mach/prcmu-defs.h> | ||
24 | |||
25 | #define DRIVER_NAME "cpufreq-u8500" | ||
26 | #define CPUFREQ_NAME "u8500" | ||
27 | |||
28 | static struct device *dev; | ||
29 | |||
30 | static struct cpufreq_frequency_table freq_table[] = { | ||
31 | [0] = { | ||
32 | .index = 0, | ||
33 | .frequency = 200000, | ||
34 | }, | ||
35 | [1] = { | ||
36 | .index = 1, | ||
37 | .frequency = 300000, | ||
38 | }, | ||
39 | [2] = { | ||
40 | .index = 2, | ||
41 | .frequency = 600000, | ||
42 | }, | ||
43 | [3] = { | ||
44 | /* Used for CPU_OPP_MAX, if available */ | ||
45 | .index = 3, | ||
46 | .frequency = CPUFREQ_TABLE_END, | ||
47 | }, | ||
48 | [4] = { | ||
49 | .index = 4, | ||
50 | .frequency = CPUFREQ_TABLE_END, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static enum prcmu_cpu_opp index2opp[] = { | ||
55 | CPU_OPP_EXT_CLK, | ||
56 | CPU_OPP_50, | ||
57 | CPU_OPP_100, | ||
58 | CPU_OPP_MAX | ||
59 | }; | ||
60 | |||
61 | static int u8500_cpufreq_verify_speed(struct cpufreq_policy *policy) | ||
62 | { | ||
63 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
64 | } | ||
65 | |||
66 | static int u8500_cpufreq_target(struct cpufreq_policy *policy, | ||
67 | unsigned int target_freq, | ||
68 | unsigned int relation) | ||
69 | { | ||
70 | struct cpufreq_freqs freqs; | ||
71 | unsigned int index; | ||
72 | int ret = 0; | ||
73 | |||
74 | /* | ||
75 | * Ensure desired rate is within allowed range. Some govenors | ||
76 | * (ondemand) will just pass target_freq=0 to get the minimum. | ||
77 | */ | ||
78 | if (target_freq < policy->cpuinfo.min_freq) | ||
79 | target_freq = policy->cpuinfo.min_freq; | ||
80 | if (target_freq > policy->cpuinfo.max_freq) | ||
81 | target_freq = policy->cpuinfo.max_freq; | ||
82 | |||
83 | ret = cpufreq_frequency_table_target(policy, freq_table, | ||
84 | target_freq, relation, &index); | ||
85 | if (ret < 0) { | ||
86 | dev_err(dev, "Could not look up next frequency\n"); | ||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | freqs.old = policy->cur; | ||
91 | freqs.new = freq_table[index].frequency; | ||
92 | freqs.cpu = policy->cpu; | ||
93 | |||
94 | if (freqs.old == freqs.new) { | ||
95 | dev_dbg(dev, "Current and target frequencies are equal\n"); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | dev_dbg(dev, "transition: %u --> %u\n", freqs.old, freqs.new); | ||
100 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
101 | |||
102 | ret = prcmu_set_cpu_opp(index2opp[index]); | ||
103 | if (ret < 0) { | ||
104 | dev_err(dev, "Failed to set OPP level\n"); | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
109 | |||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static unsigned int u8500_cpufreq_getspeed(unsigned int cpu) | ||
114 | { | ||
115 | int i; | ||
116 | |||
117 | for (i = 0; prcmu_get_cpu_opp() != index2opp[i]; i++) | ||
118 | ; | ||
119 | return freq_table[i].frequency; | ||
120 | } | ||
121 | |||
122 | static int __cpuinit u8500_cpu_init(struct cpufreq_policy *policy) | ||
123 | { | ||
124 | int res; | ||
125 | |||
126 | BUILD_BUG_ON(ARRAY_SIZE(index2opp) + 1 != ARRAY_SIZE(freq_table)); | ||
127 | |||
128 | if (cpu_is_u8500v2()) { | ||
129 | freq_table[1].frequency = 400000; | ||
130 | freq_table[2].frequency = 800000; | ||
131 | if (prcmu_has_arm_maxopp()) | ||
132 | freq_table[3].frequency = 1000000; | ||
133 | } | ||
134 | |||
135 | /* get policy fields based on the table */ | ||
136 | res = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
137 | if (!res) | ||
138 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
139 | else { | ||
140 | dev_err(dev, "u8500-cpufreq : Failed to read policy table\n"); | ||
141 | return res; | ||
142 | } | ||
143 | |||
144 | policy->min = policy->cpuinfo.min_freq; | ||
145 | policy->max = policy->cpuinfo.max_freq; | ||
146 | policy->cur = u8500_cpufreq_getspeed(policy->cpu); | ||
147 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
148 | |||
149 | /* | ||
150 | * FIXME : Need to take time measurement across the target() | ||
151 | * function with no/some/all drivers in the notification | ||
152 | * list. | ||
153 | */ | ||
154 | policy->cpuinfo.transition_latency = 200 * 1000; /* in ns */ | ||
155 | |||
156 | /* policy sharing between dual CPUs */ | ||
157 | cpumask_copy(policy->cpus, &cpu_present_map); | ||
158 | |||
159 | policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; | ||
160 | |||
161 | return res; | ||
162 | } | ||
163 | |||
164 | static struct freq_attr *u8500_cpufreq_attr[] = { | ||
165 | &cpufreq_freq_attr_scaling_available_freqs, | ||
166 | NULL, | ||
167 | }; | ||
168 | static int u8500_cpu_exit(struct cpufreq_policy *policy) | ||
169 | { | ||
170 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static struct cpufreq_driver u8500_driver = { | ||
175 | .owner = THIS_MODULE, | ||
176 | .flags = CPUFREQ_STICKY, | ||
177 | .verify = u8500_cpufreq_verify_speed, | ||
178 | .target = u8500_cpufreq_target, | ||
179 | .get = u8500_cpufreq_getspeed, | ||
180 | .init = u8500_cpu_init, | ||
181 | .exit = u8500_cpu_exit, | ||
182 | .name = CPUFREQ_NAME, | ||
183 | .attr = u8500_cpufreq_attr, | ||
184 | }; | ||
185 | |||
186 | static int __init u8500_cpufreq_probe(struct platform_device *pdev) | ||
187 | { | ||
188 | dev = &pdev->dev; | ||
189 | return cpufreq_register_driver(&u8500_driver); | ||
190 | } | ||
191 | |||
192 | static int __exit u8500_cpufreq_remove(struct platform_device *pdev) | ||
193 | { | ||
194 | return cpufreq_unregister_driver(&u8500_driver); | ||
195 | } | ||
196 | |||
197 | static struct platform_driver u8500_cpufreq_driver = { | ||
198 | .driver = { | ||
199 | .name = DRIVER_NAME, | ||
200 | .owner = THIS_MODULE, | ||
201 | }, | ||
202 | .remove = __exit_p(u8500_cpufreq_remove), | ||
203 | }; | ||
204 | |||
205 | static int __init u8500_cpufreq_init(void) | ||
206 | { | ||
207 | return platform_driver_probe(&u8500_cpufreq_driver, | ||
208 | &u8500_cpufreq_probe); | ||
209 | } | ||
210 | |||
211 | device_initcall(u8500_cpufreq_init); | ||
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c new file mode 100644 index 000000000000..fe69f5fac1bb --- /dev/null +++ b/arch/arm/mach-ux500/devices-common.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/dma-mapping.h> | ||
10 | #include <linux/err.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/amba/bus.h> | ||
15 | |||
16 | #include <plat/gpio.h> | ||
17 | |||
18 | #include <mach/hardware.h> | ||
19 | |||
20 | #include "devices-common.h" | ||
21 | |||
22 | struct amba_device * | ||
23 | dbx500_add_amba_device(const char *name, resource_size_t base, | ||
24 | int irq, void *pdata, unsigned int periphid) | ||
25 | { | ||
26 | struct amba_device *dev; | ||
27 | int ret; | ||
28 | |||
29 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | ||
30 | if (!dev) | ||
31 | return ERR_PTR(-ENOMEM); | ||
32 | |||
33 | dev->dev.init_name = name; | ||
34 | |||
35 | dev->res.start = base; | ||
36 | dev->res.end = base + SZ_4K - 1; | ||
37 | dev->res.flags = IORESOURCE_MEM; | ||
38 | |||
39 | dev->dma_mask = DMA_BIT_MASK(32); | ||
40 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
41 | |||
42 | dev->irq[0] = irq; | ||
43 | dev->irq[1] = NO_IRQ; | ||
44 | |||
45 | dev->periphid = periphid; | ||
46 | |||
47 | dev->dev.platform_data = pdata; | ||
48 | |||
49 | ret = amba_device_register(dev, &iomem_resource); | ||
50 | if (ret) { | ||
51 | kfree(dev); | ||
52 | return ERR_PTR(ret); | ||
53 | } | ||
54 | |||
55 | return dev; | ||
56 | } | ||
57 | |||
58 | static struct platform_device * | ||
59 | dbx500_add_platform_device(const char *name, int id, void *pdata, | ||
60 | struct resource *res, int resnum) | ||
61 | { | ||
62 | struct platform_device *dev; | ||
63 | int ret; | ||
64 | |||
65 | dev = platform_device_alloc(name, id); | ||
66 | if (!dev) | ||
67 | return ERR_PTR(-ENOMEM); | ||
68 | |||
69 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
70 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; | ||
71 | |||
72 | ret = platform_device_add_resources(dev, res, resnum); | ||
73 | if (ret) | ||
74 | goto out_free; | ||
75 | |||
76 | dev->dev.platform_data = pdata; | ||
77 | |||
78 | ret = platform_device_add(dev); | ||
79 | if (ret) | ||
80 | goto out_free; | ||
81 | |||
82 | return dev; | ||
83 | |||
84 | out_free: | ||
85 | platform_device_put(dev); | ||
86 | return ERR_PTR(ret); | ||
87 | } | ||
88 | |||
89 | struct platform_device * | ||
90 | dbx500_add_platform_device_4k1irq(const char *name, int id, | ||
91 | resource_size_t base, | ||
92 | int irq, void *pdata) | ||
93 | { | ||
94 | struct resource resources[] = { | ||
95 | [0] = { | ||
96 | .start = base, | ||
97 | .end = base + SZ_4K - 1, | ||
98 | .flags = IORESOURCE_MEM, | ||
99 | }, | ||
100 | [1] = { | ||
101 | .start = irq, | ||
102 | .end = irq, | ||
103 | .flags = IORESOURCE_IRQ, | ||
104 | } | ||
105 | }; | ||
106 | |||
107 | return dbx500_add_platform_device(name, id, pdata, resources, | ||
108 | ARRAY_SIZE(resources)); | ||
109 | } | ||
110 | |||
111 | static struct platform_device * | ||
112 | dbx500_add_gpio(int id, resource_size_t addr, int irq, | ||
113 | struct nmk_gpio_platform_data *pdata) | ||
114 | { | ||
115 | struct resource resources[] = { | ||
116 | { | ||
117 | .start = addr, | ||
118 | .end = addr + 127, | ||
119 | .flags = IORESOURCE_MEM, | ||
120 | }, | ||
121 | { | ||
122 | .start = irq, | ||
123 | .end = irq, | ||
124 | .flags = IORESOURCE_IRQ, | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | return platform_device_register_resndata(NULL, "gpio", id, | ||
129 | resources, ARRAY_SIZE(resources), | ||
130 | pdata, sizeof(*pdata)); | ||
131 | } | ||
132 | |||
133 | void dbx500_add_gpios(resource_size_t *base, int num, int irq, | ||
134 | struct nmk_gpio_platform_data *pdata) | ||
135 | { | ||
136 | int first = 0; | ||
137 | int i; | ||
138 | |||
139 | for (i = 0; i < num; i++, first += 32, irq++) { | ||
140 | pdata->first_gpio = first; | ||
141 | pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); | ||
142 | |||
143 | dbx500_add_gpio(i, base[i], irq, pdata); | ||
144 | } | ||
145 | } | ||
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h new file mode 100644 index 000000000000..cbadc117d2db --- /dev/null +++ b/arch/arm/mach-ux500/devices-common.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DEVICES_COMMON_H | ||
9 | #define __DEVICES_COMMON_H | ||
10 | |||
11 | extern struct amba_device * | ||
12 | dbx500_add_amba_device(const char *name, resource_size_t base, | ||
13 | int irq, void *pdata, unsigned int periphid); | ||
14 | |||
15 | extern struct platform_device * | ||
16 | dbx500_add_platform_device_4k1irq(const char *name, int id, | ||
17 | resource_size_t base, | ||
18 | int irq, void *pdata); | ||
19 | |||
20 | struct spi_master_cntlr; | ||
21 | |||
22 | static inline struct amba_device * | ||
23 | dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, | ||
24 | struct spi_master_cntlr *pdata) | ||
25 | { | ||
26 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | ||
27 | } | ||
28 | |||
29 | static inline struct amba_device * | ||
30 | dbx500_add_spi(const char *name, resource_size_t base, int irq, | ||
31 | struct spi_master_cntlr *pdata) | ||
32 | { | ||
33 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | ||
34 | } | ||
35 | |||
36 | struct mmci_platform_data; | ||
37 | |||
38 | static inline struct amba_device * | ||
39 | dbx500_add_sdi(const char *name, resource_size_t base, int irq, | ||
40 | struct mmci_platform_data *pdata) | ||
41 | { | ||
42 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | ||
43 | } | ||
44 | |||
45 | static inline struct amba_device * | ||
46 | dbx500_add_uart(const char *name, resource_size_t base, int irq) | ||
47 | { | ||
48 | return dbx500_add_amba_device(name, base, irq, NULL, 0); | ||
49 | } | ||
50 | |||
51 | struct nmk_i2c_controller; | ||
52 | |||
53 | static inline struct platform_device * | ||
54 | dbx500_add_i2c(int id, resource_size_t base, int irq, | ||
55 | struct nmk_i2c_controller *pdata) | ||
56 | { | ||
57 | return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq, | ||
58 | pdata); | ||
59 | } | ||
60 | |||
61 | struct msp_i2s_platform_data; | ||
62 | |||
63 | static inline struct platform_device * | ||
64 | dbx500_add_msp_i2s(int id, resource_size_t base, int irq, | ||
65 | struct msp_i2s_platform_data *pdata) | ||
66 | { | ||
67 | return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq, | ||
68 | pdata); | ||
69 | } | ||
70 | |||
71 | static inline struct amba_device * | ||
72 | dbx500_add_rtc(resource_size_t base, int irq) | ||
73 | { | ||
74 | return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0); | ||
75 | } | ||
76 | |||
77 | struct nmk_gpio_platform_data; | ||
78 | |||
79 | void dbx500_add_gpios(resource_size_t *base, int num, int irq, | ||
80 | struct nmk_gpio_platform_data *pdata); | ||
81 | |||
82 | #endif | ||
diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c deleted file mode 100644 index 33e5b56bebb6..000000000000 --- a/arch/arm/mach-ux500/devices-db5500.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/platform_device.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/gpio.h> | ||
11 | |||
12 | #include <mach/hardware.h> | ||
13 | #include <mach/devices.h> | ||
14 | |||
15 | static struct nmk_gpio_platform_data u5500_gpio_data[] = { | ||
16 | GPIO_DATA("GPIO-0-31", 0), | ||
17 | GPIO_DATA("GPIO-32-63", 32), /* 36..63 not routed to pin */ | ||
18 | GPIO_DATA("GPIO-64-95", 64), /* 83..95 not routed to pin */ | ||
19 | GPIO_DATA("GPIO-96-127", 96), /* 102..127 not routed to pin */ | ||
20 | GPIO_DATA("GPIO-128-159", 128), /* 149..159 not routed to pin */ | ||
21 | GPIO_DATA("GPIO-160-191", 160), | ||
22 | GPIO_DATA("GPIO-192-223", 192), | ||
23 | GPIO_DATA("GPIO-224-255", 224), /* 228..255 not routed to pin */ | ||
24 | }; | ||
25 | |||
26 | static struct resource u5500_gpio_resources[] = { | ||
27 | GPIO_RESOURCE(0), | ||
28 | GPIO_RESOURCE(1), | ||
29 | GPIO_RESOURCE(2), | ||
30 | GPIO_RESOURCE(3), | ||
31 | GPIO_RESOURCE(4), | ||
32 | GPIO_RESOURCE(5), | ||
33 | GPIO_RESOURCE(6), | ||
34 | GPIO_RESOURCE(7), | ||
35 | }; | ||
36 | |||
37 | struct platform_device u5500_gpio_devs[] = { | ||
38 | GPIO_DEVICE(0), | ||
39 | GPIO_DEVICE(1), | ||
40 | GPIO_DEVICE(2), | ||
41 | GPIO_DEVICE(3), | ||
42 | GPIO_DEVICE(4), | ||
43 | GPIO_DEVICE(5), | ||
44 | GPIO_DEVICE(6), | ||
45 | GPIO_DEVICE(7), | ||
46 | }; | ||
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h new file mode 100644 index 000000000000..c8d7901c1f2d --- /dev/null +++ b/arch/arm/mach-ux500/devices-db5500.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DEVICES_DB5500_H | ||
9 | #define __DEVICES_DB5500_H | ||
10 | |||
11 | #include "devices-common.h" | ||
12 | |||
13 | #define db5500_add_i2c1(pdata) \ | ||
14 | dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) | ||
15 | #define db5500_add_i2c2(pdata) \ | ||
16 | dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) | ||
17 | #define db5500_add_i2c3(pdata) \ | ||
18 | dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) | ||
19 | |||
20 | #define db5500_add_msp0_i2s(pdata) \ | ||
21 | dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) | ||
22 | #define db5500_add_msp1_i2s(pdata) \ | ||
23 | dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) | ||
24 | #define db5500_add_msp2_i2s(pdata) \ | ||
25 | dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) | ||
26 | |||
27 | #define db5500_add_msp0_spi(pdata) \ | ||
28 | dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) | ||
29 | #define db5500_add_msp1_spi(pdata) \ | ||
30 | dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) | ||
31 | #define db5500_add_msp2_spi(pdata) \ | ||
32 | dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) | ||
33 | |||
34 | #define db5500_add_rtc() \ | ||
35 | dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); | ||
36 | |||
37 | #define db5500_add_sdi0(pdata) \ | ||
38 | dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata) | ||
39 | #define db5500_add_sdi1(pdata) \ | ||
40 | dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata) | ||
41 | #define db5500_add_sdi2(pdata) \ | ||
42 | dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata) | ||
43 | #define db5500_add_sdi3(pdata) \ | ||
44 | dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata) | ||
45 | #define db5500_add_sdi4(pdata) \ | ||
46 | dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata) | ||
47 | |||
48 | #define db5500_add_spi0(pdata) \ | ||
49 | dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata) | ||
50 | #define db5500_add_spi1(pdata) \ | ||
51 | dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata) | ||
52 | #define db5500_add_spi2(pdata) \ | ||
53 | dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata) | ||
54 | #define db5500_add_spi3(pdata) \ | ||
55 | dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata) | ||
56 | |||
57 | #define db5500_add_uart0() \ | ||
58 | dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0) | ||
59 | #define db5500_add_uart1() \ | ||
60 | dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1) | ||
61 | #define db5500_add_uart2() \ | ||
62 | dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2) | ||
63 | #define db5500_add_uart3() \ | ||
64 | dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3) | ||
65 | |||
66 | #endif | ||
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 4a94be3304b9..23c695d54977 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c | |||
@@ -19,173 +19,6 @@ | |||
19 | 19 | ||
20 | #include "ste-dma40-db8500.h" | 20 | #include "ste-dma40-db8500.h" |
21 | 21 | ||
22 | static struct nmk_gpio_platform_data u8500_gpio_data[] = { | ||
23 | GPIO_DATA("GPIO-0-31", 0), | ||
24 | GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ | ||
25 | GPIO_DATA("GPIO-64-95", 64), | ||
26 | GPIO_DATA("GPIO-96-127", 96), /* 98..127 not routed to pin */ | ||
27 | GPIO_DATA("GPIO-128-159", 128), | ||
28 | GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */ | ||
29 | GPIO_DATA("GPIO-192-223", 192), | ||
30 | GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */ | ||
31 | GPIO_DATA("GPIO-256-288", 256), /* 268..288 not routed to pin */ | ||
32 | }; | ||
33 | |||
34 | static struct resource u8500_gpio_resources[] = { | ||
35 | GPIO_RESOURCE(0), | ||
36 | GPIO_RESOURCE(1), | ||
37 | GPIO_RESOURCE(2), | ||
38 | GPIO_RESOURCE(3), | ||
39 | GPIO_RESOURCE(4), | ||
40 | GPIO_RESOURCE(5), | ||
41 | GPIO_RESOURCE(6), | ||
42 | GPIO_RESOURCE(7), | ||
43 | GPIO_RESOURCE(8), | ||
44 | }; | ||
45 | |||
46 | struct platform_device u8500_gpio_devs[] = { | ||
47 | GPIO_DEVICE(0), | ||
48 | GPIO_DEVICE(1), | ||
49 | GPIO_DEVICE(2), | ||
50 | GPIO_DEVICE(3), | ||
51 | GPIO_DEVICE(4), | ||
52 | GPIO_DEVICE(5), | ||
53 | GPIO_DEVICE(6), | ||
54 | GPIO_DEVICE(7), | ||
55 | GPIO_DEVICE(8), | ||
56 | }; | ||
57 | |||
58 | struct amba_device u8500_ssp0_device = { | ||
59 | .dev = { | ||
60 | .coherent_dma_mask = ~0, | ||
61 | .init_name = "ssp0", | ||
62 | }, | ||
63 | .res = { | ||
64 | .start = U8500_SSP0_BASE, | ||
65 | .end = U8500_SSP0_BASE + SZ_4K - 1, | ||
66 | .flags = IORESOURCE_MEM, | ||
67 | }, | ||
68 | .irq = {IRQ_DB8500_SSP0, NO_IRQ }, | ||
69 | /* ST-Ericsson modified id */ | ||
70 | .periphid = SSP_PER_ID, | ||
71 | }; | ||
72 | |||
73 | static struct resource u8500_i2c0_resources[] = { | ||
74 | [0] = { | ||
75 | .start = U8500_I2C0_BASE, | ||
76 | .end = U8500_I2C0_BASE + SZ_4K - 1, | ||
77 | .flags = IORESOURCE_MEM, | ||
78 | }, | ||
79 | [1] = { | ||
80 | .start = IRQ_DB8500_I2C0, | ||
81 | .end = IRQ_DB8500_I2C0, | ||
82 | .flags = IORESOURCE_IRQ, | ||
83 | } | ||
84 | }; | ||
85 | |||
86 | struct platform_device u8500_i2c0_device = { | ||
87 | .name = "nmk-i2c", | ||
88 | .id = 0, | ||
89 | .resource = u8500_i2c0_resources, | ||
90 | .num_resources = ARRAY_SIZE(u8500_i2c0_resources), | ||
91 | }; | ||
92 | |||
93 | static struct resource u8500_i2c4_resources[] = { | ||
94 | [0] = { | ||
95 | .start = U8500_I2C4_BASE, | ||
96 | .end = U8500_I2C4_BASE + SZ_4K - 1, | ||
97 | .flags = IORESOURCE_MEM, | ||
98 | }, | ||
99 | [1] = { | ||
100 | .start = IRQ_DB8500_I2C4, | ||
101 | .end = IRQ_DB8500_I2C4, | ||
102 | .flags = IORESOURCE_IRQ, | ||
103 | } | ||
104 | }; | ||
105 | |||
106 | struct platform_device u8500_i2c4_device = { | ||
107 | .name = "nmk-i2c", | ||
108 | .id = 4, | ||
109 | .resource = u8500_i2c4_resources, | ||
110 | .num_resources = ARRAY_SIZE(u8500_i2c4_resources), | ||
111 | }; | ||
112 | |||
113 | /* | ||
114 | * SD/MMC | ||
115 | */ | ||
116 | |||
117 | struct amba_device u8500_sdi0_device = { | ||
118 | .dev = { | ||
119 | .init_name = "sdi0", | ||
120 | }, | ||
121 | .res = { | ||
122 | .start = U8500_SDI0_BASE, | ||
123 | .end = U8500_SDI0_BASE + SZ_4K - 1, | ||
124 | .flags = IORESOURCE_MEM, | ||
125 | }, | ||
126 | .irq = {IRQ_DB8500_SDMMC0, NO_IRQ}, | ||
127 | }; | ||
128 | |||
129 | struct amba_device u8500_sdi1_device = { | ||
130 | .dev = { | ||
131 | .init_name = "sdi1", | ||
132 | }, | ||
133 | .res = { | ||
134 | .start = U8500_SDI1_BASE, | ||
135 | .end = U8500_SDI1_BASE + SZ_4K - 1, | ||
136 | .flags = IORESOURCE_MEM, | ||
137 | }, | ||
138 | .irq = {IRQ_DB8500_SDMMC1, NO_IRQ}, | ||
139 | }; | ||
140 | |||
141 | struct amba_device u8500_sdi2_device = { | ||
142 | .dev = { | ||
143 | .init_name = "sdi2", | ||
144 | }, | ||
145 | .res = { | ||
146 | .start = U8500_SDI2_BASE, | ||
147 | .end = U8500_SDI2_BASE + SZ_4K - 1, | ||
148 | .flags = IORESOURCE_MEM, | ||
149 | }, | ||
150 | .irq = {IRQ_DB8500_SDMMC2, NO_IRQ}, | ||
151 | }; | ||
152 | |||
153 | struct amba_device u8500_sdi3_device = { | ||
154 | .dev = { | ||
155 | .init_name = "sdi3", | ||
156 | }, | ||
157 | .res = { | ||
158 | .start = U8500_SDI3_BASE, | ||
159 | .end = U8500_SDI3_BASE + SZ_4K - 1, | ||
160 | .flags = IORESOURCE_MEM, | ||
161 | }, | ||
162 | .irq = {IRQ_DB8500_SDMMC3, NO_IRQ}, | ||
163 | }; | ||
164 | |||
165 | struct amba_device u8500_sdi4_device = { | ||
166 | .dev = { | ||
167 | .init_name = "sdi4", | ||
168 | }, | ||
169 | .res = { | ||
170 | .start = U8500_SDI4_BASE, | ||
171 | .end = U8500_SDI4_BASE + SZ_4K - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }, | ||
174 | .irq = {IRQ_DB8500_SDMMC4, NO_IRQ}, | ||
175 | }; | ||
176 | |||
177 | struct amba_device u8500_sdi5_device = { | ||
178 | .dev = { | ||
179 | .init_name = "sdi5", | ||
180 | }, | ||
181 | .res = { | ||
182 | .start = U8500_SDI5_BASE, | ||
183 | .end = U8500_SDI5_BASE + SZ_4K - 1, | ||
184 | .flags = IORESOURCE_MEM, | ||
185 | }, | ||
186 | .irq = {IRQ_DB8500_SDMMC5, NO_IRQ}, | ||
187 | }; | ||
188 | |||
189 | static struct resource dma40_resources[] = { | 22 | static struct resource dma40_resources[] = { |
190 | [0] = { | 23 | [0] = { |
191 | .start = U8500_DMA_BASE, | 24 | .start = U8500_DMA_BASE, |
@@ -295,7 +128,7 @@ struct resource keypad_resources[] = { | |||
295 | }, | 128 | }, |
296 | }; | 129 | }; |
297 | 130 | ||
298 | struct platform_device ux500_ske_keypad_device = { | 131 | struct platform_device u8500_ske_keypad_device = { |
299 | .name = "nmk-ske-keypad", | 132 | .name = "nmk-ske-keypad", |
300 | .id = -1, | 133 | .id = -1, |
301 | .num_resources = ARRAY_SIZE(keypad_resources), | 134 | .num_resources = ARRAY_SIZE(keypad_resources), |
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h new file mode 100644 index 000000000000..3a770c756979 --- /dev/null +++ b/arch/arm/mach-ux500/devices-db8500.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DEVICES_DB8500_H | ||
9 | #define __DEVICES_DB8500_H | ||
10 | |||
11 | #include "devices-common.h" | ||
12 | |||
13 | struct ske_keypad_platform_data; | ||
14 | struct pl022_ssp_controller; | ||
15 | |||
16 | static inline struct platform_device * | ||
17 | db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) | ||
18 | { | ||
19 | return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1, | ||
20 | U8500_SKE_BASE, | ||
21 | IRQ_DB8500_KB, pdata); | ||
22 | } | ||
23 | |||
24 | static inline struct amba_device * | ||
25 | db8500_add_ssp(const char *name, resource_size_t base, int irq, | ||
26 | struct pl022_ssp_controller *pdata) | ||
27 | { | ||
28 | return dbx500_add_amba_device(name, base, irq, pdata, SSP_PER_ID); | ||
29 | } | ||
30 | |||
31 | |||
32 | #define db8500_add_i2c0(pdata) \ | ||
33 | dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) | ||
34 | #define db8500_add_i2c1(pdata) \ | ||
35 | dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) | ||
36 | #define db8500_add_i2c2(pdata) \ | ||
37 | dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) | ||
38 | #define db8500_add_i2c3(pdata) \ | ||
39 | dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) | ||
40 | #define db8500_add_i2c4(pdata) \ | ||
41 | dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) | ||
42 | |||
43 | #define db8500_add_msp0_i2s(pdata) \ | ||
44 | dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) | ||
45 | #define db8500_add_msp1_i2s(pdata) \ | ||
46 | dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) | ||
47 | #define db8500_add_msp2_i2s(pdata) \ | ||
48 | dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) | ||
49 | #define db8500_add_msp3_i2s(pdata) \ | ||
50 | dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) | ||
51 | |||
52 | #define db8500_add_msp0_spi(pdata) \ | ||
53 | dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) | ||
54 | #define db8500_add_msp1_spi(pdata) \ | ||
55 | dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) | ||
56 | #define db8500_add_msp2_spi(pdata) \ | ||
57 | dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) | ||
58 | #define db8500_add_msp3_spi(pdata) \ | ||
59 | dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) | ||
60 | |||
61 | #define db8500_add_rtc() \ | ||
62 | dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); | ||
63 | |||
64 | #define db8500_add_sdi0(pdata) \ | ||
65 | dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata) | ||
66 | #define db8500_add_sdi1(pdata) \ | ||
67 | dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata) | ||
68 | #define db8500_add_sdi2(pdata) \ | ||
69 | dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata) | ||
70 | #define db8500_add_sdi3(pdata) \ | ||
71 | dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata) | ||
72 | #define db8500_add_sdi4(pdata) \ | ||
73 | dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata) | ||
74 | #define db8500_add_sdi5(pdata) \ | ||
75 | dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata) | ||
76 | |||
77 | #define db8500_add_ssp0(pdata) \ | ||
78 | db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) | ||
79 | #define db8500_add_ssp1(pdata) \ | ||
80 | db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) | ||
81 | |||
82 | #define db8500_add_spi0(pdata) \ | ||
83 | dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata) | ||
84 | #define db8500_add_spi1(pdata) \ | ||
85 | dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata) | ||
86 | #define db8500_add_spi2(pdata) \ | ||
87 | dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata) | ||
88 | #define db8500_add_spi3(pdata) \ | ||
89 | dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata) | ||
90 | |||
91 | #define db8500_add_uart0() \ | ||
92 | dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0) | ||
93 | #define db8500_add_uart1() \ | ||
94 | dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1) | ||
95 | #define db8500_add_uart2() \ | ||
96 | dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2) | ||
97 | |||
98 | #endif | ||
diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c index 8a268893cb7f..ea0a2f92ca70 100644 --- a/arch/arm/mach-ux500/devices.c +++ b/arch/arm/mach-ux500/devices.c | |||
@@ -14,69 +14,6 @@ | |||
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | #include <mach/setup.h> | 15 | #include <mach/setup.h> |
16 | 16 | ||
17 | #define __MEM_4K_RESOURCE(x) \ | ||
18 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | ||
19 | |||
20 | struct amba_device ux500_pl031_device = { | ||
21 | .dev = { | ||
22 | .init_name = "pl031", | ||
23 | }, | ||
24 | .res = { | ||
25 | .start = UX500_RTC_BASE, | ||
26 | .end = UX500_RTC_BASE + SZ_4K - 1, | ||
27 | .flags = IORESOURCE_MEM, | ||
28 | }, | ||
29 | .irq = {IRQ_RTC_RTT, NO_IRQ}, | ||
30 | }; | ||
31 | |||
32 | struct amba_device ux500_uart0_device = { | ||
33 | .dev = { .init_name = "uart0" }, | ||
34 | __MEM_4K_RESOURCE(UX500_UART0_BASE), | ||
35 | .irq = {IRQ_UART0, NO_IRQ}, | ||
36 | }; | ||
37 | |||
38 | struct amba_device ux500_uart1_device = { | ||
39 | .dev = { .init_name = "uart1" }, | ||
40 | __MEM_4K_RESOURCE(UX500_UART1_BASE), | ||
41 | .irq = {IRQ_UART1, NO_IRQ}, | ||
42 | }; | ||
43 | |||
44 | struct amba_device ux500_uart2_device = { | ||
45 | .dev = { .init_name = "uart2" }, | ||
46 | __MEM_4K_RESOURCE(UX500_UART2_BASE), | ||
47 | .irq = {IRQ_UART2, NO_IRQ}, | ||
48 | }; | ||
49 | |||
50 | #define UX500_I2C_RESOURCES(id, size) \ | ||
51 | static struct resource ux500_i2c##id##_resources[] = { \ | ||
52 | [0] = { \ | ||
53 | .start = UX500_I2C##id##_BASE, \ | ||
54 | .end = UX500_I2C##id##_BASE + size - 1, \ | ||
55 | .flags = IORESOURCE_MEM, \ | ||
56 | }, \ | ||
57 | [1] = { \ | ||
58 | .start = IRQ_I2C##id, \ | ||
59 | .end = IRQ_I2C##id, \ | ||
60 | .flags = IORESOURCE_IRQ \ | ||
61 | } \ | ||
62 | } | ||
63 | |||
64 | UX500_I2C_RESOURCES(1, SZ_4K); | ||
65 | UX500_I2C_RESOURCES(2, SZ_4K); | ||
66 | UX500_I2C_RESOURCES(3, SZ_4K); | ||
67 | |||
68 | #define UX500_I2C_PDEVICE(cid) \ | ||
69 | struct platform_device ux500_i2c##cid##_device = { \ | ||
70 | .name = "nmk-i2c", \ | ||
71 | .id = cid, \ | ||
72 | .num_resources = 2, \ | ||
73 | .resource = ux500_i2c##cid##_resources, \ | ||
74 | } | ||
75 | |||
76 | UX500_I2C_PDEVICE(1); | ||
77 | UX500_I2C_PDEVICE(2); | ||
78 | UX500_I2C_PDEVICE(3); | ||
79 | |||
80 | void __init amba_add_devices(struct amba_device *devs[], int num) | 17 | void __init amba_add_devices(struct amba_device *devs[], int num) |
81 | { | 18 | { |
82 | int i; | 19 | int i; |
diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c new file mode 100644 index 000000000000..32a061f8a95b --- /dev/null +++ b/arch/arm/mach-ux500/dma-db5500.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson | ||
5 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson | ||
6 | * Author: Rabin Vincent <rabinv.vincent@stericsson.com> for ST-Ericsson | ||
7 | * | ||
8 | * License terms: GNU General Public License (GPL), version 2 | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | |||
14 | #include <plat/ste_dma40.h> | ||
15 | #include <mach/setup.h> | ||
16 | #include <mach/hardware.h> | ||
17 | |||
18 | #include "ste-dma40-db5500.h" | ||
19 | |||
20 | static struct resource dma40_resources[] = { | ||
21 | [0] = { | ||
22 | .start = U5500_DMA_BASE, | ||
23 | .end = U5500_DMA_BASE + SZ_4K - 1, | ||
24 | .flags = IORESOURCE_MEM, | ||
25 | .name = "base", | ||
26 | }, | ||
27 | [1] = { | ||
28 | .start = U5500_DMA_LCPA_BASE, | ||
29 | .end = U5500_DMA_LCPA_BASE + 2 * SZ_1K - 1, | ||
30 | .flags = IORESOURCE_MEM, | ||
31 | .name = "lcpa", | ||
32 | }, | ||
33 | [2] = { | ||
34 | .start = IRQ_DB5500_DMA, | ||
35 | .end = IRQ_DB5500_DMA, | ||
36 | .flags = IORESOURCE_IRQ | ||
37 | } | ||
38 | }; | ||
39 | |||
40 | /* Default configuration for physical memcpy */ | ||
41 | static struct stedma40_chan_cfg dma40_memcpy_conf_phy = { | ||
42 | .mode = STEDMA40_MODE_PHYSICAL, | ||
43 | .dir = STEDMA40_MEM_TO_MEM, | ||
44 | |||
45 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
46 | .src_info.psize = STEDMA40_PSIZE_PHY_1, | ||
47 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
48 | |||
49 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
50 | .dst_info.psize = STEDMA40_PSIZE_PHY_1, | ||
51 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
52 | }; | ||
53 | |||
54 | /* Default configuration for logical memcpy */ | ||
55 | static struct stedma40_chan_cfg dma40_memcpy_conf_log = { | ||
56 | .dir = STEDMA40_MEM_TO_MEM, | ||
57 | |||
58 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
59 | .src_info.psize = STEDMA40_PSIZE_LOG_1, | ||
60 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
61 | |||
62 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
63 | .dst_info.psize = STEDMA40_PSIZE_LOG_1, | ||
64 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | * Mapping between soruce event lines and physical device address This was | ||
69 | * created assuming that the event line is tied to a device and therefore the | ||
70 | * address is constant, however this is not true for at least USB, and the | ||
71 | * values are just placeholders for USB. This table is preserved and used for | ||
72 | * now. | ||
73 | */ | ||
74 | static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = { | ||
75 | [DB5500_DMA_DEV24_SDMMC0_RX] = -1, | ||
76 | }; | ||
77 | |||
78 | /* Mapping between destination event lines and physical device address */ | ||
79 | static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = { | ||
80 | [DB5500_DMA_DEV24_SDMMC0_TX] = -1, | ||
81 | }; | ||
82 | |||
83 | static int dma40_memcpy_event[] = { | ||
84 | DB5500_DMA_MEMCPY_TX_1, | ||
85 | DB5500_DMA_MEMCPY_TX_2, | ||
86 | DB5500_DMA_MEMCPY_TX_3, | ||
87 | DB5500_DMA_MEMCPY_TX_4, | ||
88 | DB5500_DMA_MEMCPY_TX_5, | ||
89 | }; | ||
90 | |||
91 | static struct stedma40_platform_data dma40_plat_data = { | ||
92 | .dev_len = ARRAY_SIZE(dma40_rx_map), | ||
93 | .dev_rx = dma40_rx_map, | ||
94 | .dev_tx = dma40_tx_map, | ||
95 | .memcpy = dma40_memcpy_event, | ||
96 | .memcpy_len = ARRAY_SIZE(dma40_memcpy_event), | ||
97 | .memcpy_conf_phy = &dma40_memcpy_conf_phy, | ||
98 | .memcpy_conf_log = &dma40_memcpy_conf_log, | ||
99 | .disabled_channels = {-1}, | ||
100 | }; | ||
101 | |||
102 | static struct platform_device dma40_device = { | ||
103 | .dev = { | ||
104 | .platform_data = &dma40_plat_data, | ||
105 | }, | ||
106 | .name = "dma40", | ||
107 | .id = 0, | ||
108 | .num_resources = ARRAY_SIZE(dma40_resources), | ||
109 | .resource = dma40_resources | ||
110 | }; | ||
111 | |||
112 | void __init db5500_dma_init(void) | ||
113 | { | ||
114 | int ret; | ||
115 | |||
116 | ret = platform_device_register(&dma40_device); | ||
117 | if (ret) | ||
118 | dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); | ||
119 | |||
120 | } | ||
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h index 3eafc0e24ba5..bd88c1e74060 100644 --- a/arch/arm/mach-ux500/include/mach/db5500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h | |||
@@ -114,4 +114,8 @@ | |||
114 | #define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) | 114 | #define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) |
115 | #define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) | 115 | #define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) |
116 | 116 | ||
117 | #define U5500_ESRAM_BASE 0x40000000 | ||
118 | #define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000 | ||
119 | #define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET) | ||
120 | |||
117 | #endif | 121 | #endif |
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index f07d0986409d..0fefb34c11e4 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h | |||
@@ -92,7 +92,8 @@ | |||
92 | #define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) | 92 | #define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) |
93 | #define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) | 93 | #define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) |
94 | #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) | 94 | #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) |
95 | #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x0f000) | 95 | #define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000) |
96 | #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) | ||
96 | 97 | ||
97 | /* per3 base addresses */ | 98 | /* per3 base addresses */ |
98 | #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) | 99 | #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) |
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index b91a4d1211a2..020b6369a30a 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h | |||
@@ -14,27 +14,10 @@ extern struct platform_device u5500_gpio_devs[]; | |||
14 | extern struct platform_device u8500_gpio_devs[]; | 14 | extern struct platform_device u8500_gpio_devs[]; |
15 | 15 | ||
16 | extern struct amba_device ux500_pl031_device; | 16 | extern struct amba_device ux500_pl031_device; |
17 | extern struct amba_device u8500_ssp0_device; | ||
18 | extern struct amba_device ux500_uart0_device; | ||
19 | extern struct amba_device ux500_uart1_device; | ||
20 | extern struct amba_device ux500_uart2_device; | ||
21 | 17 | ||
22 | extern struct platform_device ux500_i2c1_device; | ||
23 | extern struct platform_device ux500_i2c2_device; | ||
24 | extern struct platform_device ux500_i2c3_device; | ||
25 | |||
26 | extern struct platform_device u8500_i2c0_device; | ||
27 | extern struct platform_device u8500_i2c4_device; | ||
28 | extern struct platform_device u8500_dma40_device; | 18 | extern struct platform_device u8500_dma40_device; |
29 | extern struct platform_device ux500_ske_keypad_device; | 19 | extern struct platform_device ux500_ske_keypad_device; |
30 | 20 | ||
31 | extern struct amba_device u8500_sdi0_device; | ||
32 | extern struct amba_device u8500_sdi1_device; | ||
33 | extern struct amba_device u8500_sdi2_device; | ||
34 | extern struct amba_device u8500_sdi3_device; | ||
35 | extern struct amba_device u8500_sdi4_device; | ||
36 | extern struct amba_device u8500_sdi5_device; | ||
37 | |||
38 | void dma40_u8500ed_fixup(void); | 21 | void dma40_u8500ed_fixup(void); |
39 | 22 | ||
40 | #endif | 23 | #endif |
diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index d548a622e7d2..3c4cd31ad9f7 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h | |||
@@ -9,42 +9,4 @@ | |||
9 | 9 | ||
10 | #include <plat/gpio.h> | 10 | #include <plat/gpio.h> |
11 | 11 | ||
12 | #define __GPIO_RESOURCE(soc, block) \ | ||
13 | { \ | ||
14 | .start = soc##_GPIOBANK##block##_BASE, \ | ||
15 | .end = soc##_GPIOBANK##block##_BASE + 127, \ | ||
16 | .flags = IORESOURCE_MEM, \ | ||
17 | }, \ | ||
18 | { \ | ||
19 | .start = IRQ_GPIO##block, \ | ||
20 | .end = IRQ_GPIO##block, \ | ||
21 | .flags = IORESOURCE_IRQ, \ | ||
22 | } | ||
23 | |||
24 | #define __GPIO_DEVICE(soc, block) \ | ||
25 | { \ | ||
26 | .name = "gpio", \ | ||
27 | .id = block, \ | ||
28 | .num_resources = 2, \ | ||
29 | .resource = &soc##_gpio_resources[block * 2], \ | ||
30 | .dev = { \ | ||
31 | .platform_data = &soc##_gpio_data[block], \ | ||
32 | }, \ | ||
33 | } | ||
34 | |||
35 | #define GPIO_DATA(_name, first) \ | ||
36 | { \ | ||
37 | .name = _name, \ | ||
38 | .first_gpio = first, \ | ||
39 | .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ | ||
40 | } | ||
41 | |||
42 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
43 | #define GPIO_RESOURCE(block) __GPIO_RESOURCE(U8500, block) | ||
44 | #define GPIO_DEVICE(block) __GPIO_DEVICE(u8500, block) | ||
45 | #elif defined(CONFIG_UX500_SOC_DB5500) | ||
46 | #define GPIO_RESOURCE(block) __GPIO_RESOURCE(U5500, block) | ||
47 | #define GPIO_DEVICE(block) __GPIO_DEVICE(u5500, block) | ||
48 | #endif | ||
49 | |||
50 | #endif /* __ASM_ARCH_GPIO_H */ | 12 | #endif /* __ASM_ARCH_GPIO_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 32e883a8f2a2..6295cc581355 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -142,6 +142,8 @@ static inline bool cpu_is_u5500(void) | |||
142 | #endif | 142 | #endif |
143 | } | 143 | } |
144 | 144 | ||
145 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | ||
146 | |||
145 | #endif | 147 | #endif |
146 | 148 | ||
147 | #endif /* __MACH_HARDWARE_H */ | 149 | #endif /* __MACH_HARDWARE_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h index cca4f705601e..7cdeb2af0ebb 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h | |||
@@ -8,12 +8,36 @@ | |||
8 | #ifndef __MACH_IRQS_BOARD_MOP500_H | 8 | #ifndef __MACH_IRQS_BOARD_MOP500_H |
9 | #define __MACH_IRQS_BOARD_MOP500_H | 9 | #define __MACH_IRQS_BOARD_MOP500_H |
10 | 10 | ||
11 | #define AB8500_NR_IRQS 104 | 11 | /* Number of AB8500 irqs is taken from header file */ |
12 | #include <linux/mfd/ab8500.h> | ||
12 | 13 | ||
13 | #define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START | 14 | #define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START |
14 | #define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \ | 15 | #define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \ |
15 | + AB8500_NR_IRQS) | 16 | + AB8500_NR_IRQS) |
16 | #define MOP500_IRQ_END MOP500_AB8500_IRQ_END | 17 | |
18 | /* TC35892 */ | ||
19 | #define TC35892_NR_INTERNAL_IRQS 8 | ||
20 | #define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x)) | ||
21 | #define TC35892_NR_GPIOS 24 | ||
22 | #define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS) | ||
23 | |||
24 | #define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS | ||
25 | |||
26 | #define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END | ||
27 | #define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \ | ||
28 | + MOP500_EGPIO_NR_IRQS) | ||
29 | /* STMPE1601 irqs */ | ||
30 | #define STMPE_NR_INTERNAL_IRQS 9 | ||
31 | #define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x)) | ||
32 | #define STMPE_NR_GPIOS 24 | ||
33 | #define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS) | ||
34 | |||
35 | #define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END | ||
36 | #define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x)) | ||
37 | |||
38 | #define MOP500_NR_IRQS MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS) | ||
39 | |||
40 | #define MOP500_IRQ_END MOP500_NR_IRQS | ||
17 | 41 | ||
18 | #if MOP500_IRQ_END > IRQ_BOARD_END | 42 | #if MOP500_IRQ_END > IRQ_BOARD_END |
19 | #undef IRQ_BOARD_END | 43 | #undef IRQ_BOARD_END |
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 693aa57de88d..880ae45bc235 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h | |||
@@ -21,50 +21,6 @@ | |||
21 | 21 | ||
22 | /* Interrupt numbers generic for shared peripheral */ | 22 | /* Interrupt numbers generic for shared peripheral */ |
23 | #define IRQ_MTU0 (IRQ_SHPI_START + 4) | 23 | #define IRQ_MTU0 (IRQ_SHPI_START + 4) |
24 | #define IRQ_SPI2 (IRQ_SHPI_START + 6) | ||
25 | #define IRQ_SPI0 (IRQ_SHPI_START + 8) | ||
26 | #define IRQ_UART0 (IRQ_SHPI_START + 11) | ||
27 | #define IRQ_I2C3 (IRQ_SHPI_START + 12) | ||
28 | #define IRQ_SSP0 (IRQ_SHPI_START + 14) | ||
29 | #define IRQ_MTU1 (IRQ_SHPI_START + 17) | ||
30 | #define IRQ_RTC_RTT (IRQ_SHPI_START + 18) | ||
31 | #define IRQ_UART1 (IRQ_SHPI_START + 19) | ||
32 | #define IRQ_I2C0 (IRQ_SHPI_START + 21) | ||
33 | #define IRQ_I2C1 (IRQ_SHPI_START + 22) | ||
34 | #define IRQ_USBOTG (IRQ_SHPI_START + 23) | ||
35 | #define IRQ_DMA (IRQ_SHPI_START + 25) | ||
36 | #define IRQ_UART2 (IRQ_SHPI_START + 26) | ||
37 | #define IRQ_HSIR_EXCEP (IRQ_SHPI_START + 29) | ||
38 | #define IRQ_MSP0 (IRQ_SHPI_START + 31) | ||
39 | #define IRQ_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32) | ||
40 | #define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33) | ||
41 | #define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34) | ||
42 | #define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35) | ||
43 | #define IRQ_AB8500 (IRQ_SHPI_START + 40) | ||
44 | #define IRQ_PRCMU (IRQ_SHPI_START + 47) | ||
45 | #define IRQ_DISP (IRQ_SHPI_START + 48) | ||
46 | #define IRQ_SiPI3 (IRQ_SHPI_START + 49) | ||
47 | #define IRQ_I2C4 (IRQ_SHPI_START + 51) | ||
48 | #define IRQ_SSP1 (IRQ_SHPI_START + 52) | ||
49 | #define IRQ_I2C2 (IRQ_SHPI_START + 55) | ||
50 | #define IRQ_SDMMC0 (IRQ_SHPI_START + 60) | ||
51 | #define IRQ_MSP1 (IRQ_SHPI_START + 62) | ||
52 | #define IRQ_SPI1 (IRQ_SHPI_START + 96) | ||
53 | #define IRQ_MSP2 (IRQ_SHPI_START + 98) | ||
54 | #define IRQ_SDMMC4 (IRQ_SHPI_START + 99) | ||
55 | #define IRQ_HSIRD0 (IRQ_SHPI_START + 104) | ||
56 | #define IRQ_HSIRD1 (IRQ_SHPI_START + 105) | ||
57 | #define IRQ_HSITD0 (IRQ_SHPI_START + 106) | ||
58 | #define IRQ_HSITD1 (IRQ_SHPI_START + 107) | ||
59 | #define IRQ_GPIO0 (IRQ_SHPI_START + 119) | ||
60 | #define IRQ_GPIO1 (IRQ_SHPI_START + 120) | ||
61 | #define IRQ_GPIO2 (IRQ_SHPI_START + 121) | ||
62 | #define IRQ_GPIO3 (IRQ_SHPI_START + 122) | ||
63 | #define IRQ_GPIO4 (IRQ_SHPI_START + 123) | ||
64 | #define IRQ_GPIO5 (IRQ_SHPI_START + 124) | ||
65 | #define IRQ_GPIO6 (IRQ_SHPI_START + 125) | ||
66 | #define IRQ_GPIO7 (IRQ_SHPI_START + 126) | ||
67 | #define IRQ_GPIO8 (IRQ_SHPI_START + 127) | ||
68 | 24 | ||
69 | /* There are 128 shared peripheral interrupts assigned to | 25 | /* There are 128 shared peripheral interrupts assigned to |
70 | * INTID[160:32]. The first 32 interrupts are reserved. | 26 | * INTID[160:32]. The first 32 interrupts are reserved. |
diff --git a/arch/arm/mach-ux500/include/mach/mbox.h b/arch/arm/mach-ux500/include/mach/mbox-db5500.h index 7f9da4d2fbda..7f9da4d2fbda 100644 --- a/arch/arm/mach-ux500/include/mach/mbox.h +++ b/arch/arm/mach-ux500/include/mach/mbox-db5500.h | |||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-defs.h b/arch/arm/mach-ux500/include/mach/prcmu-defs.h new file mode 100644 index 000000000000..848ba64b561f --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/prcmu-defs.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
6 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit definitions | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_PRCMU_DEFS_H | ||
14 | #define __MACH_PRCMU_DEFS_H | ||
15 | |||
16 | enum prcmu_cpu_opp { | ||
17 | CPU_OPP_INIT = 0x00, | ||
18 | CPU_OPP_NO_CHANGE = 0x01, | ||
19 | CPU_OPP_100 = 0x02, | ||
20 | CPU_OPP_50 = 0x03, | ||
21 | CPU_OPP_MAX = 0x04, | ||
22 | CPU_OPP_EXT_CLK = 0x07 | ||
23 | }; | ||
24 | enum prcmu_ape_opp { | ||
25 | APE_OPP_NO_CHANGE = 0x00, | ||
26 | APE_OPP_100 = 0x02, | ||
27 | APE_OPP_50 = 0x03, | ||
28 | }; | ||
29 | |||
30 | #endif /* __MACH_PRCMU_DEFS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h index 8885f39a6421..455467e88791 100644 --- a/arch/arm/mach-ux500/include/mach/prcmu-regs.h +++ b/arch/arm/mach-ux500/include/mach/prcmu-regs.h | |||
@@ -1,10 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009 ST-Ericsson SA | 2 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | 5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> |
5 | * it under the terms of the GNU General Public License version 2 | 6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> |
6 | * as published by the Free Software Foundation. | 7 | * |
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit registers | ||
7 | */ | 11 | */ |
12 | |||
8 | #ifndef __MACH_PRCMU_REGS_H | 13 | #ifndef __MACH_PRCMU_REGS_H |
9 | #define __MACH_PRCMU_REGS_H | 14 | #define __MACH_PRCMU_REGS_H |
10 | 15 | ||
@@ -88,4 +93,4 @@ | |||
88 | /* Miscellaneous unit registers */ | 93 | /* Miscellaneous unit registers */ |
89 | #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) | 94 | #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) |
90 | 95 | ||
91 | #endif /* __MACH_PRCMU__REGS_H */ | 96 | #endif /* __MACH_PRCMU_REGS_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h index 549843ff6dbe..c49e456162ef 100644 --- a/arch/arm/mach-ux500/include/mach/prcmu.h +++ b/arch/arm/mach-ux500/include/mach/prcmu.h | |||
@@ -2,14 +2,27 @@ | |||
2 | * Copyright (C) STMicroelectronics 2009 | 2 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | 3 | * Copyright (C) ST-Ericsson SA 2010 |
4 | * | 4 | * |
5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
7 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
8 | * | ||
5 | * License Terms: GNU General Public License v2 | 9 | * License Terms: GNU General Public License v2 |
6 | * | 10 | * |
7 | * PRCMU f/w APIs | 11 | * PRCM Unit f/w API |
8 | */ | 12 | */ |
9 | #ifndef __MACH_PRCMU_H | 13 | #ifndef __MACH_PRCMU_H |
10 | #define __MACH_PRCMU_H | 14 | #define __MACH_PRCMU_H |
15 | #include <mach/prcmu-defs.h> | ||
11 | 16 | ||
17 | void __init prcmu_early_init(void); | ||
12 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | 18 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); |
13 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | 19 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); |
20 | int prcmu_set_ape_opp(enum prcmu_ape_opp opp); | ||
21 | int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); | ||
22 | int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, | ||
23 | enum prcmu_cpu_opp cpu_opp); | ||
24 | int prcmu_get_ape_opp(void); | ||
25 | int prcmu_get_cpu_opp(void); | ||
26 | bool prcmu_has_arm_maxopp(void); | ||
14 | 27 | ||
15 | #endif /* __MACH_PRCMU_H */ | 28 | #endif /* __MACH_PRCMU_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 54bbe648bf58..469877e0de90 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
@@ -18,14 +18,19 @@ extern void __init ux500_map_io(void); | |||
18 | extern void __init u5500_map_io(void); | 18 | extern void __init u5500_map_io(void); |
19 | extern void __init u8500_map_io(void); | 19 | extern void __init u8500_map_io(void); |
20 | 20 | ||
21 | extern void __init ux500_init_devices(void); | ||
22 | extern void __init u5500_init_devices(void); | 21 | extern void __init u5500_init_devices(void); |
23 | extern void __init u8500_init_devices(void); | 22 | extern void __init u8500_init_devices(void); |
24 | 23 | ||
25 | extern void __init ux500_init_irq(void); | 24 | extern void __init ux500_init_irq(void); |
25 | |||
26 | extern void __init u5500_sdi_init(void); | ||
27 | |||
28 | extern void __init db5500_dma_init(void); | ||
29 | |||
26 | /* We re-use nomadik_timer for this platform */ | 30 | /* We re-use nomadik_timer for this platform */ |
27 | extern void nmdk_timer_init(void); | 31 | extern void nmdk_timer_init(void); |
28 | 32 | ||
33 | struct amba_device; | ||
29 | extern void __init amba_add_devices(struct amba_device *devs[], int num); | 34 | extern void __init amba_add_devices(struct amba_device *devs[], int num); |
30 | 35 | ||
31 | struct sys_timer; | 36 | struct sys_timer; |
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h index 0271ca0a83df..9a6614c6808e 100644 --- a/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/arch/arm/mach-ux500/include/mach/uncompress.h | |||
@@ -19,38 +19,43 @@ | |||
19 | #define __ASM_ARCH_UNCOMPRESS_H | 19 | #define __ASM_ARCH_UNCOMPRESS_H |
20 | 20 | ||
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | #include <asm/mach-types.h> | ||
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/amba/serial.h> | ||
23 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
24 | 26 | ||
25 | #define U8500_UART_DR 0x80007000 | 27 | static u32 ux500_uart_base; |
26 | #define U8500_UART_LCRH 0x8000702c | ||
27 | #define U8500_UART_CR 0x80007030 | ||
28 | #define U8500_UART_FR 0x80007018 | ||
29 | 28 | ||
30 | static void putc(const char c) | 29 | static void putc(const char c) |
31 | { | 30 | { |
32 | /* Do nothing if the UART is not enabled. */ | 31 | /* Do nothing if the UART is not enabled. */ |
33 | if (!(__raw_readb(U8500_UART_CR) & 0x1)) | 32 | if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1)) |
34 | return; | 33 | return; |
35 | 34 | ||
36 | if (c == '\n') | 35 | if (c == '\n') |
37 | putc('\r'); | 36 | putc('\r'); |
38 | 37 | ||
39 | while (__raw_readb(U8500_UART_FR) & (1 << 5)) | 38 | while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 5)) |
40 | barrier(); | 39 | barrier(); |
41 | __raw_writeb(c, U8500_UART_DR); | 40 | __raw_writeb(c, ux500_uart_base + UART01x_DR); |
42 | } | 41 | } |
43 | 42 | ||
44 | static void flush(void) | 43 | static void flush(void) |
45 | { | 44 | { |
46 | if (!(__raw_readb(U8500_UART_CR) & 0x1)) | 45 | if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1)) |
47 | return; | 46 | return; |
48 | while (__raw_readb(U8500_UART_FR) & (1 << 3)) | 47 | while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 3)) |
49 | barrier(); | 48 | barrier(); |
50 | } | 49 | } |
51 | 50 | ||
52 | static inline void arch_decomp_setup(void) | 51 | static inline void arch_decomp_setup(void) |
53 | { | 52 | { |
53 | if (machine_is_u8500()) | ||
54 | ux500_uart_base = U8500_UART2_BASE; | ||
55 | else if (machine_is_u5500()) | ||
56 | ux500_uart_base = U5500_UART0_BASE; | ||
57 | else /* not much can be done to help here */ | ||
58 | ux500_uart_base = U8500_UART2_BASE; | ||
54 | } | 59 | } |
55 | 60 | ||
56 | #define arch_decomp_wdog() /* nothing to do here */ | 61 | #define arch_decomp_wdog() /* nothing to do here */ |
diff --git a/arch/arm/mach-ux500/mbox.c b/arch/arm/mach-ux500/mbox-db5500.c index 63435389c544..cbf15718fc3c 100644 --- a/arch/arm/mach-ux500/mbox.c +++ b/arch/arm/mach-ux500/mbox-db5500.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
39 | #include <linux/seq_file.h> | 39 | #include <linux/seq_file.h> |
40 | #include <linux/completion.h> | 40 | #include <linux/completion.h> |
41 | #include <mach/mbox.h> | 41 | #include <mach/mbox-db5500.h> |
42 | 42 | ||
43 | #define MBOX_NAME "mbox" | 43 | #define MBOX_NAME "mbox" |
44 | 44 | ||
diff --git a/arch/arm/mach-ux500/modem_irq.c b/arch/arm/mach-ux500/modem-irq-db5500.c index 3187f8871169..3187f8871169 100644 --- a/arch/arm/mach-ux500/modem_irq.c +++ b/arch/arm/mach-ux500/modem-irq-db5500.c | |||
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 9e4c678de785..ade2e17f253c 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * control for which core is the next to come out of the secondary | 26 | * control for which core is the next to come out of the secondary |
27 | * boot "holding pen" | 27 | * boot "holding pen" |
28 | */ | 28 | */ |
29 | volatile int __cpuinitdata pen_release = -1; | 29 | volatile int pen_release = -1; |
30 | 30 | ||
31 | static unsigned int __init get_core_count(void) | 31 | static unsigned int __init get_core_count(void) |
32 | { | 32 | { |
diff --git a/arch/arm/mach-ux500/prcmu.c b/arch/arm/mach-ux500/prcmu.c index 293274d1342a..c522d26ef348 100644 --- a/arch/arm/mach-ux500/prcmu.c +++ b/arch/arm/mach-ux500/prcmu.c | |||
@@ -1,10 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) ST Ericsson SA 2010 | 2 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | 4 | * |
4 | * License Terms: GNU General Public License v2 | 5 | * License Terms: GNU General Public License v2 |
6 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
7 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
5 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 8 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> |
6 | * | 9 | * |
7 | * U8500 PRCMU driver. | 10 | * U8500 PRCM Unit interface driver |
11 | * | ||
8 | */ | 12 | */ |
9 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -19,11 +23,26 @@ | |||
19 | 23 | ||
20 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
21 | #include <mach/prcmu-regs.h> | 25 | #include <mach/prcmu-regs.h> |
26 | #include <mach/prcmu-defs.h> | ||
27 | |||
28 | /* Global var to runtime determine TCDM base for v2 or v1 */ | ||
29 | static __iomem void *tcdm_base; | ||
30 | |||
31 | #define _MBOX_HEADER (tcdm_base + 0xFE8) | ||
32 | #define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) | ||
33 | |||
34 | #define REQ_MB1 (tcdm_base + 0xFD0) | ||
35 | #define REQ_MB5 (tcdm_base + 0xE44) | ||
22 | 36 | ||
23 | #define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE) | 37 | #define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) |
38 | #define REQ_MB1_APEOPP (REQ_MB1 + 0x1) | ||
39 | #define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) | ||
24 | 40 | ||
25 | #define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44) | 41 | #define ACK_MB1 (tcdm_base + 0xE04) |
26 | #define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4) | 42 | #define ACK_MB5 (tcdm_base + 0xDF4) |
43 | |||
44 | #define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) | ||
45 | #define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) | ||
27 | 46 | ||
28 | #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) | 47 | #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) |
29 | #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) | 48 | #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) |
@@ -33,10 +52,33 @@ | |||
33 | #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) | 52 | #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) |
34 | #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) | 53 | #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) |
35 | 54 | ||
36 | #define I2C_WRITE(slave) ((slave) << 1) | 55 | #define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) |
37 | #define I2C_READ(slave) (((slave) << 1) | BIT(0)) | 56 | #define PRCM_AVS_ISMODEENABLE 7 |
57 | #define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) | ||
58 | |||
59 | #define I2C_WRITE(slave) \ | ||
60 | (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) | ||
61 | #define I2C_READ(slave) \ | ||
62 | (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) | ||
38 | #define I2C_STOP_EN BIT(3) | 63 | #define I2C_STOP_EN BIT(3) |
39 | 64 | ||
65 | enum mb1_h { | ||
66 | MB1H_ARM_OPP = 1, | ||
67 | MB1H_APE_OPP, | ||
68 | MB1H_ARM_APE_OPP, | ||
69 | }; | ||
70 | |||
71 | static struct { | ||
72 | struct mutex lock; | ||
73 | struct completion work; | ||
74 | struct { | ||
75 | u8 arm_opp; | ||
76 | u8 ape_opp; | ||
77 | u8 arm_status; | ||
78 | u8 ape_status; | ||
79 | } ack; | ||
80 | } mb1_transfer; | ||
81 | |||
40 | enum ack_mb5_status { | 82 | enum ack_mb5_status { |
41 | I2C_WR_OK = 0x01, | 83 | I2C_WR_OK = 0x01, |
42 | I2C_RD_OK = 0x02, | 84 | I2C_RD_OK = 0x02, |
@@ -145,6 +187,104 @@ unlock_and_return: | |||
145 | } | 187 | } |
146 | EXPORT_SYMBOL(prcmu_abb_write); | 188 | EXPORT_SYMBOL(prcmu_abb_write); |
147 | 189 | ||
190 | static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, | ||
191 | enum prcmu_cpu_opp cpu_opp) | ||
192 | { | ||
193 | bool do_ape; | ||
194 | bool do_arm; | ||
195 | int err = 0; | ||
196 | |||
197 | do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); | ||
198 | do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); | ||
199 | |||
200 | mutex_lock(&mb1_transfer.lock); | ||
201 | |||
202 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | ||
203 | cpu_relax(); | ||
204 | |||
205 | writeb(0, MBOX_HEADER_REQ_MB0); | ||
206 | writeb(cpu_opp, REQ_MB1_ARMOPP); | ||
207 | writeb(ape_opp, REQ_MB1_APEOPP); | ||
208 | writeb(0, REQ_MB1_BOOSTOPP); | ||
209 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); | ||
210 | wait_for_completion(&mb1_transfer.work); | ||
211 | if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) | ||
212 | err = -EIO; | ||
213 | if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) | ||
214 | err = -EIO; | ||
215 | |||
216 | mutex_unlock(&mb1_transfer.lock); | ||
217 | |||
218 | return err; | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * prcmu_set_ape_opp() - Set the OPP of the APE. | ||
223 | * @opp: The OPP to set. | ||
224 | * | ||
225 | * This function sets the OPP of the APE. | ||
226 | */ | ||
227 | int prcmu_set_ape_opp(enum prcmu_ape_opp opp) | ||
228 | { | ||
229 | return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); | ||
230 | } | ||
231 | EXPORT_SYMBOL(prcmu_set_ape_opp); | ||
232 | |||
233 | /** | ||
234 | * prcmu_set_cpu_opp() - Set the OPP of the CPU. | ||
235 | * @opp: The OPP to set. | ||
236 | * | ||
237 | * This function sets the OPP of the CPU. | ||
238 | */ | ||
239 | int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) | ||
240 | { | ||
241 | return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); | ||
242 | } | ||
243 | EXPORT_SYMBOL(prcmu_set_cpu_opp); | ||
244 | |||
245 | /** | ||
246 | * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. | ||
247 | * @ape_opp: The APE OPP to set. | ||
248 | * @cpu_opp: The CPU OPP to set. | ||
249 | * | ||
250 | * This function sets the OPPs of the APE and the CPU. | ||
251 | */ | ||
252 | int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, | ||
253 | enum prcmu_cpu_opp cpu_opp) | ||
254 | { | ||
255 | return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); | ||
256 | } | ||
257 | EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); | ||
258 | |||
259 | /** | ||
260 | * prcmu_get_ape_opp() - Get the OPP of the APE. | ||
261 | * | ||
262 | * This function gets the OPP of the APE. | ||
263 | */ | ||
264 | enum prcmu_ape_opp prcmu_get_ape_opp(void) | ||
265 | { | ||
266 | return readb(ACK_MB1_CURR_APEOPP); | ||
267 | } | ||
268 | EXPORT_SYMBOL(prcmu_get_ape_opp); | ||
269 | |||
270 | /** | ||
271 | * prcmu_get_cpu_opp() - Get the OPP of the CPU. | ||
272 | * | ||
273 | * This function gets the OPP of the CPU. The OPP is specified in %%. | ||
274 | * PRCMU_OPP_EXT is a special OPP value, not specified in %%. | ||
275 | */ | ||
276 | int prcmu_get_cpu_opp(void) | ||
277 | { | ||
278 | return readb(ACK_MB1_CURR_ARMOPP); | ||
279 | } | ||
280 | EXPORT_SYMBOL(prcmu_get_cpu_opp); | ||
281 | |||
282 | bool prcmu_has_arm_maxopp(void) | ||
283 | { | ||
284 | return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) | ||
285 | == PRCM_AVS_ISMODEENABLE_MASK; | ||
286 | } | ||
287 | |||
148 | static void read_mailbox_0(void) | 288 | static void read_mailbox_0(void) |
149 | { | 289 | { |
150 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); | 290 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); |
@@ -152,6 +292,9 @@ static void read_mailbox_0(void) | |||
152 | 292 | ||
153 | static void read_mailbox_1(void) | 293 | static void read_mailbox_1(void) |
154 | { | 294 | { |
295 | mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); | ||
296 | mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); | ||
297 | complete(&mb1_transfer.work); | ||
155 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); | 298 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); |
156 | } | 299 | } |
157 | 300 | ||
@@ -217,15 +360,35 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data) | |||
217 | return IRQ_HANDLED; | 360 | return IRQ_HANDLED; |
218 | } | 361 | } |
219 | 362 | ||
363 | void __init prcmu_early_init(void) | ||
364 | { | ||
365 | if (cpu_is_u8500v11() || cpu_is_u8500ed()) { | ||
366 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); | ||
367 | } else if (cpu_is_u8500v2()) { | ||
368 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); | ||
369 | } else { | ||
370 | pr_err("prcmu: Unsupported chip version\n"); | ||
371 | BUG(); | ||
372 | } | ||
373 | } | ||
374 | |||
220 | static int __init prcmu_init(void) | 375 | static int __init prcmu_init(void) |
221 | { | 376 | { |
377 | if (cpu_is_u8500ed()) { | ||
378 | pr_err("prcmu: Unsupported chip version\n"); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | mutex_init(&mb1_transfer.lock); | ||
383 | init_completion(&mb1_transfer.work); | ||
222 | mutex_init(&mb5_transfer.lock); | 384 | mutex_init(&mb5_transfer.lock); |
223 | init_completion(&mb5_transfer.work); | 385 | init_completion(&mb5_transfer.work); |
224 | 386 | ||
225 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 387 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
226 | writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); | 388 | writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); |
227 | 389 | ||
228 | return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL); | 390 | return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, |
391 | "prcmu", NULL); | ||
229 | } | 392 | } |
230 | 393 | ||
231 | arch_initcall(prcmu_init); | 394 | arch_initcall(prcmu_init); |
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 85e6fd212a41..eda4e3a11a3d 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -119,7 +119,7 @@ static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
122 | pin_cfg_t cfg) | 122 | pin_cfg_t cfg, bool sleep) |
123 | { | 123 | { |
124 | static const char *afnames[] = { | 124 | static const char *afnames[] = { |
125 | [NMK_GPIO_ALT_GPIO] = "GPIO", | 125 | [NMK_GPIO_ALT_GPIO] = "GPIO", |
@@ -145,11 +145,34 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
145 | int output = PIN_DIR(cfg); | 145 | int output = PIN_DIR(cfg); |
146 | int val = PIN_VAL(cfg); | 146 | int val = PIN_VAL(cfg); |
147 | 147 | ||
148 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n", | 148 | dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", |
149 | pin, afnames[af], pullnames[pull], slpmnames[slpm], | 149 | pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], |
150 | output ? "output " : "input", | 150 | output ? "output " : "input", |
151 | output ? (val ? "high" : "low") : ""); | 151 | output ? (val ? "high" : "low") : ""); |
152 | 152 | ||
153 | if (sleep) { | ||
154 | int slpm_pull = PIN_SLPM_PULL(cfg); | ||
155 | int slpm_output = PIN_SLPM_DIR(cfg); | ||
156 | int slpm_val = PIN_SLPM_VAL(cfg); | ||
157 | |||
158 | /* | ||
159 | * The SLPM_* values are normal values + 1 to allow zero to | ||
160 | * mean "same as normal". | ||
161 | */ | ||
162 | if (slpm_pull) | ||
163 | pull = slpm_pull - 1; | ||
164 | if (slpm_output) | ||
165 | output = slpm_output - 1; | ||
166 | if (slpm_val) | ||
167 | val = slpm_val - 1; | ||
168 | |||
169 | dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", | ||
170 | pin, | ||
171 | slpm_pull ? pullnames[pull] : "same", | ||
172 | slpm_output ? (output ? "output" : "input") : "same", | ||
173 | slpm_val ? (val ? "high" : "low") : "same"); | ||
174 | } | ||
175 | |||
153 | if (output) | 176 | if (output) |
154 | __nmk_gpio_make_output(nmk_chip, offset, val); | 177 | __nmk_gpio_make_output(nmk_chip, offset, val); |
155 | else { | 178 | else { |
@@ -175,7 +198,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
175 | * side-effects. The gpio can be manipulated later using standard GPIO API | 198 | * side-effects. The gpio can be manipulated later using standard GPIO API |
176 | * calls. | 199 | * calls. |
177 | */ | 200 | */ |
178 | int nmk_config_pin(pin_cfg_t cfg) | 201 | int nmk_config_pin(pin_cfg_t cfg, bool sleep) |
179 | { | 202 | { |
180 | struct nmk_gpio_chip *nmk_chip; | 203 | struct nmk_gpio_chip *nmk_chip; |
181 | int gpio = PIN_NUM(cfg); | 204 | int gpio = PIN_NUM(cfg); |
@@ -186,7 +209,7 @@ int nmk_config_pin(pin_cfg_t cfg) | |||
186 | return -EINVAL; | 209 | return -EINVAL; |
187 | 210 | ||
188 | spin_lock_irqsave(&nmk_chip->lock, flags); | 211 | spin_lock_irqsave(&nmk_chip->lock, flags); |
189 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg); | 212 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg, sleep); |
190 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 213 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
191 | 214 | ||
192 | return 0; | 215 | return 0; |
@@ -207,7 +230,7 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) | |||
207 | int i; | 230 | int i; |
208 | 231 | ||
209 | for (i = 0; i < num; i++) { | 232 | for (i = 0; i < num; i++) { |
210 | int ret = nmk_config_pin(cfgs[i]); | 233 | ret = nmk_config_pin(cfgs[i], false); |
211 | if (ret) | 234 | if (ret) |
212 | break; | 235 | break; |
213 | } | 236 | } |
@@ -216,6 +239,21 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) | |||
216 | } | 239 | } |
217 | EXPORT_SYMBOL(nmk_config_pins); | 240 | EXPORT_SYMBOL(nmk_config_pins); |
218 | 241 | ||
242 | int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) | ||
243 | { | ||
244 | int ret = 0; | ||
245 | int i; | ||
246 | |||
247 | for (i = 0; i < num; i++) { | ||
248 | ret = nmk_config_pin(cfgs[i], true); | ||
249 | if (ret) | ||
250 | break; | ||
251 | } | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | EXPORT_SYMBOL(nmk_config_pins_sleep); | ||
256 | |||
219 | /** | 257 | /** |
220 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin | 258 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin |
221 | * @gpio: pin number | 259 | * @gpio: pin number |
@@ -634,7 +672,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
634 | 672 | ||
635 | chip = &nmk_chip->chip; | 673 | chip = &nmk_chip->chip; |
636 | chip->base = pdata->first_gpio; | 674 | chip->base = pdata->first_gpio; |
637 | chip->label = pdata->name; | 675 | chip->label = pdata->name ?: dev_name(&dev->dev); |
638 | chip->dev = &dev->dev; | 676 | chip->dev = &dev->dev; |
639 | chip->owner = THIS_MODULE; | 677 | chip->owner = THIS_MODULE; |
640 | 678 | ||
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h index 8c5ae3f2acf8..05a3936ae6d1 100644 --- a/arch/arm/plat-nomadik/include/plat/pincfg.h +++ b/arch/arm/plat-nomadik/include/plat/pincfg.h | |||
@@ -19,16 +19,22 @@ | |||
19 | * bit 9..10 - Alternate Function Selection | 19 | * bit 9..10 - Alternate Function Selection |
20 | * bit 11..12 - Pull up/down state | 20 | * bit 11..12 - Pull up/down state |
21 | * bit 13 - Sleep mode behaviour | 21 | * bit 13 - Sleep mode behaviour |
22 | * bit 14 - (sleep mode) Direction | 22 | * bit 14 - Direction |
23 | * bit 15 - (sleep mode) Value (if output) | 23 | * bit 15 - Value (if output) |
24 | * bit 16..18 - SLPM pull up/down state | ||
25 | * bit 19..20 - SLPM direction | ||
26 | * bit 21..22 - SLPM Value (if output) | ||
24 | * | 27 | * |
25 | * to facilitate the definition, the following macros are provided | 28 | * to facilitate the definition, the following macros are provided |
26 | * | 29 | * |
27 | * PIN_CFG_DEFAULT - default config (0): | 30 | * PIN_CFG_DEFAULT - default config (0): |
28 | * pull up/down = disabled | 31 | * pull up/down = disabled |
29 | * sleep mode = input/wakeup | 32 | * sleep mode = input/wakeup |
30 | * (sleep mode) direction = input | 33 | * direction = input |
31 | * (sleep mode) value = low | 34 | * value = low |
35 | * SLPM direction = same as normal | ||
36 | * SLPM pull = same as normal | ||
37 | * SLPM value = same as normal | ||
32 | * | 38 | * |
33 | * PIN_CFG - default config with alternate function | 39 | * PIN_CFG - default config with alternate function |
34 | * PIN_CFG_PULL - default config with alternate function and pull up/down | 40 | * PIN_CFG_PULL - default config with alternate function and pull up/down |
@@ -75,30 +81,64 @@ typedef unsigned long pin_cfg_t; | |||
75 | #define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) | 81 | #define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) |
76 | #define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) | 82 | #define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) |
77 | 83 | ||
78 | /* Shortcuts. Use these instead of separate DIR and VAL. */ | 84 | #define PIN_SLPM_PULL_SHIFT 16 |
79 | #define PIN_INPUT PIN_DIR_INPUT | 85 | #define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT) |
86 | #define PIN_SLPM_PULL(x) \ | ||
87 | (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT) | ||
88 | #define PIN_SLPM_PULL_NONE \ | ||
89 | ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT) | ||
90 | #define PIN_SLPM_PULL_UP \ | ||
91 | ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT) | ||
92 | #define PIN_SLPM_PULL_DOWN \ | ||
93 | ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT) | ||
94 | |||
95 | #define PIN_SLPM_DIR_SHIFT 19 | ||
96 | #define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT) | ||
97 | #define PIN_SLPM_DIR(x) \ | ||
98 | (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT) | ||
99 | #define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT) | ||
100 | #define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT) | ||
101 | |||
102 | #define PIN_SLPM_VAL_SHIFT 21 | ||
103 | #define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT) | ||
104 | #define PIN_SLPM_VAL(x) \ | ||
105 | (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT) | ||
106 | #define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT) | ||
107 | #define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT) | ||
108 | |||
109 | /* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ | ||
110 | #define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) | ||
111 | #define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) | ||
112 | #define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE) | ||
80 | #define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) | 113 | #define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) |
81 | #define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) | 114 | #define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) |
82 | 115 | ||
83 | /* | 116 | #define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN) |
84 | * These are the same as the ones above, but should make more sense to the | 117 | #define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP) |
85 | * reader when seen along with a setting a pin to AF mode. | 118 | #define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE) |
86 | */ | 119 | #define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW) |
87 | #define PIN_SLPM_INPUT PIN_INPUT | 120 | #define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH) |
88 | #define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW | ||
89 | #define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH | ||
90 | 121 | ||
91 | #define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) | 122 | #define PIN_CFG_DEFAULT (0) |
92 | 123 | ||
93 | #define PIN_CFG(num, alt) \ | 124 | #define PIN_CFG(num, alt) \ |
94 | (PIN_CFG_DEFAULT |\ | 125 | (PIN_CFG_DEFAULT |\ |
95 | (PIN_NUM(num) | PIN_##alt)) | 126 | (PIN_NUM(num) | PIN_##alt)) |
96 | 127 | ||
128 | #define PIN_CFG_INPUT(num, alt, pull) \ | ||
129 | (PIN_CFG_DEFAULT |\ | ||
130 | (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull)) | ||
131 | |||
132 | #define PIN_CFG_OUTPUT(num, alt, val) \ | ||
133 | (PIN_CFG_DEFAULT |\ | ||
134 | (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) | ||
135 | |||
97 | #define PIN_CFG_PULL(num, alt, pull) \ | 136 | #define PIN_CFG_PULL(num, alt, pull) \ |
98 | ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ | 137 | ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ |
99 | (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) | 138 | (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) |
100 | 139 | ||
101 | extern int nmk_config_pin(pin_cfg_t cfg); | 140 | extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); |
102 | extern int nmk_config_pins(pin_cfg_t *cfgs, int num); | 141 | extern int nmk_config_pins(pin_cfg_t *cfgs, int num); |
142 | extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); | ||
103 | 143 | ||
104 | #endif | 144 | #endif |