diff options
Diffstat (limited to 'arch/arm/mach-tegra')
22 files changed, 72 insertions, 2510 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 9077aaa398d9..5f3c03b61f8e 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -34,7 +34,6 @@ config ARCH_TEGRA_3x_SOC | |||
34 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | 34 | select USB_ARCH_HAS_EHCI if USB_SUPPORT |
35 | select USB_ULPI if USB | 35 | select USB_ULPI if USB |
36 | select USB_ULPI_VIEWPORT if USB_SUPPORT | 36 | select USB_ULPI_VIEWPORT if USB_SUPPORT |
37 | select USE_OF | ||
38 | select ARM_ERRATA_743622 | 37 | select ARM_ERRATA_743622 |
39 | select ARM_ERRATA_751472 | 38 | select ARM_ERRATA_751472 |
40 | select ARM_ERRATA_754322 | 39 | select ARM_ERRATA_754322 |
@@ -60,25 +59,6 @@ config TEGRA_AHB | |||
60 | 59 | ||
61 | comment "Tegra board type" | 60 | comment "Tegra board type" |
62 | 61 | ||
63 | config MACH_HARMONY | ||
64 | bool "Harmony board" | ||
65 | depends on ARCH_TEGRA_2x_SOC | ||
66 | help | ||
67 | Support for nVidia Harmony development platform | ||
68 | |||
69 | config MACH_PAZ00 | ||
70 | bool "Paz00 board" | ||
71 | depends on ARCH_TEGRA_2x_SOC | ||
72 | help | ||
73 | Support for the Toshiba AC100/Dynabook AZ netbook | ||
74 | |||
75 | config MACH_TRIMSLICE | ||
76 | bool "TrimSlice board" | ||
77 | depends on ARCH_TEGRA_2x_SOC | ||
78 | select TEGRA_PCI | ||
79 | help | ||
80 | Support for CompuLab TrimSlice platform | ||
81 | |||
82 | choice | 62 | choice |
83 | prompt "Default low-level debug console UART" | 63 | prompt "Default low-level debug console UART" |
84 | default TEGRA_DEBUG_UART_NONE | 64 | default TEGRA_DEBUG_UART_NONE |
@@ -130,13 +110,6 @@ config TEGRA_DEBUG_UART_AUTO_SCRATCH | |||
130 | 110 | ||
131 | endchoice | 111 | endchoice |
132 | 112 | ||
133 | config TEGRA_SYSTEM_DMA | ||
134 | bool "Enable system DMA driver for NVIDIA Tegra SoCs" | ||
135 | default y | ||
136 | help | ||
137 | Adds system DMA functionality for NVIDIA Tegra SoCs, used by | ||
138 | several Tegra device drivers | ||
139 | |||
140 | config TEGRA_EMC_SCALING_ENABLE | 113 | config TEGRA_EMC_SCALING_ENABLE |
141 | bool "Enable scaling the memory frequency" | 114 | bool "Enable scaling the memory frequency" |
142 | 115 | ||
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 84d21f514418..04eb74e3f601 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -22,7 +22,6 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-t30.o | |||
22 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 22 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
23 | obj-$(CONFIG_SMP) += reset.o | 23 | obj-$(CONFIG_SMP) += reset.o |
24 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 24 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
25 | obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o | ||
26 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o | 25 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o |
27 | obj-$(CONFIG_TEGRA_PCI) += pcie.o | 26 | obj-$(CONFIG_TEGRA_PCI) += pcie.o |
28 | obj-$(CONFIG_USB_SUPPORT) += usb_phy.o | 27 | obj-$(CONFIG_USB_SUPPORT) += usb_phy.o |
@@ -30,13 +29,6 @@ obj-$(CONFIG_USB_SUPPORT) += usb_phy.o | |||
30 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o | 29 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o |
31 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o | 30 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o |
32 | 31 | ||
33 | obj-$(CONFIG_MACH_HARMONY) += board-harmony.o | 32 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-harmony-pcie.o |
34 | obj-$(CONFIG_MACH_HARMONY) += board-harmony-pinmux.o | ||
35 | obj-$(CONFIG_MACH_HARMONY) += board-harmony-pcie.o | ||
36 | obj-$(CONFIG_MACH_HARMONY) += board-harmony-power.o | ||
37 | 33 | ||
38 | obj-$(CONFIG_MACH_PAZ00) += board-paz00.o | 34 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o |
39 | obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o | ||
40 | |||
41 | obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o | ||
42 | obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o | ||
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index 7a1bb62ddcf0..54c16aade475 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot | |||
@@ -3,9 +3,13 @@ params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 | |||
3 | initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 | 3 | initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 |
4 | 4 | ||
5 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-harmony.dtb | 5 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-harmony.dtb |
6 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-medcom-wide.dtb | ||
6 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-paz00.dtb | 7 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-paz00.dtb |
8 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-plutux.dtb | ||
7 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-seaboard.dtb | 9 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-seaboard.dtb |
10 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-tec.dtb | ||
8 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-trimslice.dtb | 11 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-trimslice.dtb |
9 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-ventana.dtb | 12 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-ventana.dtb |
10 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-whistler.dtb | 13 | dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-whistler.dtb |
11 | dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30-cardhu.dtb | 14 | dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30-cardhu-a02.dtb |
15 | dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30-cardhu-a04.dtb | ||
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c index dc0fe389be56..b5015d0f1912 100644 --- a/arch/arm/mach-tegra/apbio.c +++ b/arch/arm/mach-tegra/apbio.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #include "apbio.h" | 29 | #include "apbio.h" |
30 | 30 | ||
31 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) || defined(CONFIG_TEGRA20_APB_DMA) | 31 | #if defined(CONFIG_TEGRA20_APB_DMA) |
32 | static DEFINE_MUTEX(tegra_apb_dma_lock); | 32 | static DEFINE_MUTEX(tegra_apb_dma_lock); |
33 | static u32 *tegra_apb_bb; | 33 | static u32 *tegra_apb_bb; |
34 | static dma_addr_t tegra_apb_bb_phys; | 34 | static dma_addr_t tegra_apb_bb_phys; |
@@ -37,121 +37,6 @@ static DECLARE_COMPLETION(tegra_apb_wait); | |||
37 | static u32 tegra_apb_readl_direct(unsigned long offset); | 37 | static u32 tegra_apb_readl_direct(unsigned long offset); |
38 | static void tegra_apb_writel_direct(u32 value, unsigned long offset); | 38 | static void tegra_apb_writel_direct(u32 value, unsigned long offset); |
39 | 39 | ||
40 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
41 | static struct tegra_dma_channel *tegra_apb_dma; | ||
42 | |||
43 | bool tegra_apb_init(void) | ||
44 | { | ||
45 | struct tegra_dma_channel *ch; | ||
46 | |||
47 | mutex_lock(&tegra_apb_dma_lock); | ||
48 | |||
49 | /* Check to see if we raced to setup */ | ||
50 | if (tegra_apb_dma) | ||
51 | goto out; | ||
52 | |||
53 | ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT | | ||
54 | TEGRA_DMA_SHARED); | ||
55 | |||
56 | if (!ch) | ||
57 | goto out_fail; | ||
58 | |||
59 | tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32), | ||
60 | &tegra_apb_bb_phys, GFP_KERNEL); | ||
61 | if (!tegra_apb_bb) { | ||
62 | pr_err("%s: can not allocate bounce buffer\n", __func__); | ||
63 | tegra_dma_free_channel(ch); | ||
64 | goto out_fail; | ||
65 | } | ||
66 | |||
67 | tegra_apb_dma = ch; | ||
68 | out: | ||
69 | mutex_unlock(&tegra_apb_dma_lock); | ||
70 | return true; | ||
71 | |||
72 | out_fail: | ||
73 | mutex_unlock(&tegra_apb_dma_lock); | ||
74 | return false; | ||
75 | } | ||
76 | |||
77 | static void apb_dma_complete(struct tegra_dma_req *req) | ||
78 | { | ||
79 | complete(&tegra_apb_wait); | ||
80 | } | ||
81 | |||
82 | static u32 tegra_apb_readl_using_dma(unsigned long offset) | ||
83 | { | ||
84 | struct tegra_dma_req req; | ||
85 | int ret; | ||
86 | |||
87 | if (!tegra_apb_dma && !tegra_apb_init()) | ||
88 | return tegra_apb_readl_direct(offset); | ||
89 | |||
90 | mutex_lock(&tegra_apb_dma_lock); | ||
91 | req.complete = apb_dma_complete; | ||
92 | req.to_memory = 1; | ||
93 | req.dest_addr = tegra_apb_bb_phys; | ||
94 | req.dest_bus_width = 32; | ||
95 | req.dest_wrap = 1; | ||
96 | req.source_addr = offset; | ||
97 | req.source_bus_width = 32; | ||
98 | req.source_wrap = 4; | ||
99 | req.req_sel = TEGRA_DMA_REQ_SEL_CNTR; | ||
100 | req.size = 4; | ||
101 | |||
102 | INIT_COMPLETION(tegra_apb_wait); | ||
103 | |||
104 | tegra_dma_enqueue_req(tegra_apb_dma, &req); | ||
105 | |||
106 | ret = wait_for_completion_timeout(&tegra_apb_wait, | ||
107 | msecs_to_jiffies(50)); | ||
108 | |||
109 | if (WARN(ret == 0, "apb read dma timed out")) { | ||
110 | tegra_dma_dequeue_req(tegra_apb_dma, &req); | ||
111 | *(u32 *)tegra_apb_bb = 0; | ||
112 | } | ||
113 | |||
114 | mutex_unlock(&tegra_apb_dma_lock); | ||
115 | return *((u32 *)tegra_apb_bb); | ||
116 | } | ||
117 | |||
118 | static void tegra_apb_writel_using_dma(u32 value, unsigned long offset) | ||
119 | { | ||
120 | struct tegra_dma_req req; | ||
121 | int ret; | ||
122 | |||
123 | if (!tegra_apb_dma && !tegra_apb_init()) { | ||
124 | tegra_apb_writel_direct(value, offset); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | mutex_lock(&tegra_apb_dma_lock); | ||
129 | *((u32 *)tegra_apb_bb) = value; | ||
130 | req.complete = apb_dma_complete; | ||
131 | req.to_memory = 0; | ||
132 | req.dest_addr = offset; | ||
133 | req.dest_wrap = 4; | ||
134 | req.dest_bus_width = 32; | ||
135 | req.source_addr = tegra_apb_bb_phys; | ||
136 | req.source_bus_width = 32; | ||
137 | req.source_wrap = 1; | ||
138 | req.req_sel = TEGRA_DMA_REQ_SEL_CNTR; | ||
139 | req.size = 4; | ||
140 | |||
141 | INIT_COMPLETION(tegra_apb_wait); | ||
142 | |||
143 | tegra_dma_enqueue_req(tegra_apb_dma, &req); | ||
144 | |||
145 | ret = wait_for_completion_timeout(&tegra_apb_wait, | ||
146 | msecs_to_jiffies(50)); | ||
147 | |||
148 | if (WARN(ret == 0, "apb write dma timed out")) | ||
149 | tegra_dma_dequeue_req(tegra_apb_dma, &req); | ||
150 | |||
151 | mutex_unlock(&tegra_apb_dma_lock); | ||
152 | } | ||
153 | |||
154 | #else | ||
155 | static struct dma_chan *tegra_apb_dma_chan; | 40 | static struct dma_chan *tegra_apb_dma_chan; |
156 | static struct dma_slave_config dma_sconfig; | 41 | static struct dma_slave_config dma_sconfig; |
157 | 42 | ||
@@ -279,7 +164,6 @@ static void tegra_apb_writel_using_dma(u32 value, unsigned long offset) | |||
279 | pr_err("error in writing offset 0x%08lx using dma\n", offset); | 164 | pr_err("error in writing offset 0x%08lx using dma\n", offset); |
280 | mutex_unlock(&tegra_apb_dma_lock); | 165 | mutex_unlock(&tegra_apb_dma_lock); |
281 | } | 166 | } |
282 | #endif | ||
283 | #else | 167 | #else |
284 | #define tegra_apb_readl_using_dma tegra_apb_readl_direct | 168 | #define tegra_apb_readl_using_dma tegra_apb_readl_direct |
285 | #define tegra_apb_writel_using_dma tegra_apb_writel_direct | 169 | #define tegra_apb_writel_using_dma tegra_apb_writel_direct |
@@ -293,12 +177,12 @@ static apbio_write_fptr apbio_write; | |||
293 | 177 | ||
294 | static u32 tegra_apb_readl_direct(unsigned long offset) | 178 | static u32 tegra_apb_readl_direct(unsigned long offset) |
295 | { | 179 | { |
296 | return readl(IO_TO_VIRT(offset)); | 180 | return readl(IO_ADDRESS(offset)); |
297 | } | 181 | } |
298 | 182 | ||
299 | static void tegra_apb_writel_direct(u32 value, unsigned long offset) | 183 | static void tegra_apb_writel_direct(u32 value, unsigned long offset) |
300 | { | 184 | { |
301 | writel(value, IO_TO_VIRT(offset)); | 185 | writel(value, IO_ADDRESS(offset)); |
302 | } | 186 | } |
303 | 187 | ||
304 | void tegra_apb_io_init(void) | 188 | void tegra_apb_io_init(void) |
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index b4e7cc14713c..5957ffbd4af6 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <mach/irqs.h> | 42 | #include <mach/irqs.h> |
43 | 43 | ||
44 | #include "board.h" | 44 | #include "board.h" |
45 | #include "board-harmony.h" | ||
46 | #include "clock.h" | 45 | #include "clock.h" |
47 | #include "devices.h" | 46 | #include "devices.h" |
48 | 47 | ||
@@ -96,54 +95,40 @@ static void __init tegra_dt_init(void) | |||
96 | tegra20_auxdata_lookup, NULL); | 95 | tegra20_auxdata_lookup, NULL); |
97 | } | 96 | } |
98 | 97 | ||
99 | #ifdef CONFIG_MACH_TRIMSLICE | ||
100 | static void __init trimslice_init(void) | 98 | static void __init trimslice_init(void) |
101 | { | 99 | { |
100 | #ifdef CONFIG_TEGRA_PCI | ||
102 | int ret; | 101 | int ret; |
103 | 102 | ||
104 | ret = tegra_pcie_init(true, true); | 103 | ret = tegra_pcie_init(true, true); |
105 | if (ret) | 104 | if (ret) |
106 | pr_err("tegra_pci_init() failed: %d\n", ret); | 105 | pr_err("tegra_pci_init() failed: %d\n", ret); |
107 | } | ||
108 | #endif | 106 | #endif |
107 | } | ||
109 | 108 | ||
110 | #ifdef CONFIG_MACH_HARMONY | ||
111 | static void __init harmony_init(void) | 109 | static void __init harmony_init(void) |
112 | { | 110 | { |
111 | #ifdef CONFIG_TEGRA_PCI | ||
113 | int ret; | 112 | int ret; |
114 | 113 | ||
115 | ret = harmony_regulator_init(); | ||
116 | if (ret) { | ||
117 | pr_err("harmony_regulator_init() failed: %d\n", ret); | ||
118 | return; | ||
119 | } | ||
120 | |||
121 | ret = harmony_pcie_init(); | 114 | ret = harmony_pcie_init(); |
122 | if (ret) | 115 | if (ret) |
123 | pr_err("harmony_pcie_init() failed: %d\n", ret); | 116 | pr_err("harmony_pcie_init() failed: %d\n", ret); |
124 | } | ||
125 | #endif | 117 | #endif |
118 | } | ||
126 | 119 | ||
127 | #ifdef CONFIG_MACH_PAZ00 | ||
128 | static void __init paz00_init(void) | 120 | static void __init paz00_init(void) |
129 | { | 121 | { |
130 | tegra_paz00_wifikill_init(); | 122 | tegra_paz00_wifikill_init(); |
131 | } | 123 | } |
132 | #endif | ||
133 | 124 | ||
134 | static struct { | 125 | static struct { |
135 | char *machine; | 126 | char *machine; |
136 | void (*init)(void); | 127 | void (*init)(void); |
137 | } board_init_funcs[] = { | 128 | } board_init_funcs[] = { |
138 | #ifdef CONFIG_MACH_TRIMSLICE | ||
139 | { "compulab,trimslice", trimslice_init }, | 129 | { "compulab,trimslice", trimslice_init }, |
140 | #endif | ||
141 | #ifdef CONFIG_MACH_HARMONY | ||
142 | { "nvidia,harmony", harmony_init }, | 130 | { "nvidia,harmony", harmony_init }, |
143 | #endif | ||
144 | #ifdef CONFIG_MACH_PAZ00 | ||
145 | { "compal,paz00", paz00_init }, | 131 | { "compal,paz00", paz00_init }, |
146 | #endif | ||
147 | }; | 132 | }; |
148 | 133 | ||
149 | static void __init tegra_dt_init_late(void) | 134 | static void __init tegra_dt_init_late(void) |
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c index e8c3fda9bec2..3cdc1bb8254c 100644 --- a/arch/arm/mach-tegra/board-harmony-pcie.c +++ b/arch/arm/mach-tegra/board-harmony-pcie.c | |||
@@ -18,35 +18,57 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/of_gpio.h> | ||
21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
22 | 23 | ||
23 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
24 | 25 | ||
25 | #include "board.h" | 26 | #include "board.h" |
26 | #include "board-harmony.h" | ||
27 | 27 | ||
28 | #ifdef CONFIG_TEGRA_PCI | 28 | #ifdef CONFIG_TEGRA_PCI |
29 | 29 | ||
30 | int __init harmony_pcie_init(void) | 30 | int __init harmony_pcie_init(void) |
31 | { | 31 | { |
32 | struct device_node *np; | ||
33 | int en_vdd_1v05; | ||
32 | struct regulator *regulator = NULL; | 34 | struct regulator *regulator = NULL; |
33 | int err; | 35 | int err; |
34 | 36 | ||
35 | err = gpio_request(TEGRA_GPIO_EN_VDD_1V05_GPIO, "EN_VDD_1V05"); | 37 | np = of_find_node_by_path("/regulators/regulator@3"); |
36 | if (err) | 38 | if (!np) { |
39 | pr_err("%s: of_find_node_by_path failed\n", __func__); | ||
40 | return -ENODEV; | ||
41 | } | ||
42 | |||
43 | en_vdd_1v05 = of_get_named_gpio(np, "gpio", 0); | ||
44 | if (en_vdd_1v05 < 0) { | ||
45 | pr_err("%s: of_get_named_gpio failed: %d\n", __func__, | ||
46 | en_vdd_1v05); | ||
47 | return en_vdd_1v05; | ||
48 | } | ||
49 | |||
50 | err = gpio_request(en_vdd_1v05, "EN_VDD_1V05"); | ||
51 | if (err) { | ||
52 | pr_err("%s: gpio_request failed: %d\n", __func__, err); | ||
37 | return err; | 53 | return err; |
54 | } | ||
38 | 55 | ||
39 | gpio_direction_output(TEGRA_GPIO_EN_VDD_1V05_GPIO, 1); | 56 | gpio_direction_output(en_vdd_1v05, 1); |
40 | 57 | ||
41 | regulator = regulator_get(NULL, "pex_clk"); | 58 | regulator = regulator_get(NULL, "vdd_ldo0,vddio_pex_clk"); |
42 | if (IS_ERR_OR_NULL(regulator)) | 59 | if (IS_ERR_OR_NULL(regulator)) { |
60 | pr_err("%s: regulator_get failed: %d\n", __func__, | ||
61 | (int)PTR_ERR(regulator)); | ||
43 | goto err_reg; | 62 | goto err_reg; |
63 | } | ||
44 | 64 | ||
45 | regulator_enable(regulator); | 65 | regulator_enable(regulator); |
46 | 66 | ||
47 | err = tegra_pcie_init(true, true); | 67 | err = tegra_pcie_init(true, true); |
48 | if (err) | 68 | if (err) { |
69 | pr_err("%s: tegra_pcie_init failed: %d\n", __func__, err); | ||
49 | goto err_pcie; | 70 | goto err_pcie; |
71 | } | ||
50 | 72 | ||
51 | return 0; | 73 | return 0; |
52 | 74 | ||
@@ -54,20 +76,9 @@ err_pcie: | |||
54 | regulator_disable(regulator); | 76 | regulator_disable(regulator); |
55 | regulator_put(regulator); | 77 | regulator_put(regulator); |
56 | err_reg: | 78 | err_reg: |
57 | gpio_free(TEGRA_GPIO_EN_VDD_1V05_GPIO); | 79 | gpio_free(en_vdd_1v05); |
58 | 80 | ||
59 | return err; | 81 | return err; |
60 | } | 82 | } |
61 | 83 | ||
62 | static int __init harmony_pcie_initcall(void) | ||
63 | { | ||
64 | if (!machine_is_harmony()) | ||
65 | return 0; | ||
66 | |||
67 | return harmony_pcie_init(); | ||
68 | } | ||
69 | |||
70 | /* PCI should be initialized after I2C, mfd and regulators */ | ||
71 | subsys_initcall_sync(harmony_pcie_initcall); | ||
72 | |||
73 | #endif | 84 | #endif |
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c deleted file mode 100644 index 83d420fbc58c..000000000000 --- a/arch/arm/mach-tegra/board-harmony-pinmux.c +++ /dev/null | |||
@@ -1,156 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-harmony-pinmux.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | |||
20 | #include "board-harmony.h" | ||
21 | #include "board-pinmux.h" | ||
22 | |||
23 | static struct pinctrl_map harmony_map[] = { | ||
24 | TEGRA_MAP_MUXCONF("ata", "ide", none, driven), | ||
25 | TEGRA_MAP_MUXCONF("atb", "sdio4", none, driven), | ||
26 | TEGRA_MAP_MUXCONF("atc", "nand", none, driven), | ||
27 | TEGRA_MAP_MUXCONF("atd", "gmi", none, driven), | ||
28 | TEGRA_MAP_MUXCONF("ate", "gmi", none, driven), | ||
29 | TEGRA_MAP_MUXCONF("cdev1", "plla_out", none, driven), | ||
30 | TEGRA_MAP_MUXCONF("cdev2", "pllp_out4", down, tristate), | ||
31 | TEGRA_MAP_MUXCONF("crtp", "crt", none, tristate), | ||
32 | TEGRA_MAP_MUXCONF("csus", "vi_sensor_clk", down, tristate), | ||
33 | TEGRA_MAP_MUXCONF("dap1", "dap1", none, driven), | ||
34 | TEGRA_MAP_MUXCONF("dap2", "dap2", none, tristate), | ||
35 | TEGRA_MAP_MUXCONF("dap3", "dap3", none, tristate), | ||
36 | TEGRA_MAP_MUXCONF("dap4", "dap4", none, tristate), | ||
37 | TEGRA_MAP_MUXCONF("ddc", "i2c2", up, driven), | ||
38 | TEGRA_MAP_MUXCONF("dta", "sdio2", up, driven), | ||
39 | TEGRA_MAP_MUXCONF("dtb", "rsvd1", none, driven), | ||
40 | TEGRA_MAP_MUXCONF("dtc", "rsvd1", none, tristate), | ||
41 | TEGRA_MAP_MUXCONF("dtd", "sdio2", up, driven), | ||
42 | TEGRA_MAP_MUXCONF("dte", "rsvd1", none, tristate), | ||
43 | TEGRA_MAP_MUXCONF("dtf", "i2c3", none, tristate), | ||
44 | TEGRA_MAP_MUXCONF("gma", "sdio4", none, driven), | ||
45 | TEGRA_MAP_MUXCONF("gmb", "gmi", none, driven), | ||
46 | TEGRA_MAP_MUXCONF("gmc", "uartd", none, driven), | ||
47 | TEGRA_MAP_MUXCONF("gmd", "gmi", none, driven), | ||
48 | TEGRA_MAP_MUXCONF("gme", "sdio4", none, driven), | ||
49 | TEGRA_MAP_MUXCONF("gpu", "gmi", none, tristate), | ||
50 | TEGRA_MAP_MUXCONF("gpu7", "rtck", none, driven), | ||
51 | TEGRA_MAP_MUXCONF("gpv", "pcie", none, driven), | ||
52 | TEGRA_MAP_MUXCONF("hdint", "hdmi", na, tristate), | ||
53 | TEGRA_MAP_MUXCONF("i2cp", "i2cp", none, driven), | ||
54 | TEGRA_MAP_MUXCONF("irrx", "uarta", up, tristate), | ||
55 | TEGRA_MAP_MUXCONF("irtx", "uarta", up, tristate), | ||
56 | TEGRA_MAP_MUXCONF("kbca", "kbc", up, driven), | ||
57 | TEGRA_MAP_MUXCONF("kbcb", "kbc", up, driven), | ||
58 | TEGRA_MAP_MUXCONF("kbcc", "kbc", up, driven), | ||
59 | TEGRA_MAP_MUXCONF("kbcd", "kbc", up, driven), | ||
60 | TEGRA_MAP_MUXCONF("kbce", "kbc", up, driven), | ||
61 | TEGRA_MAP_MUXCONF("kbcf", "kbc", up, driven), | ||
62 | TEGRA_MAP_MUXCONF("lcsn", "displaya", na, tristate), | ||
63 | TEGRA_MAP_MUXCONF("ld0", "displaya", na, driven), | ||
64 | TEGRA_MAP_MUXCONF("ld1", "displaya", na, driven), | ||
65 | TEGRA_MAP_MUXCONF("ld10", "displaya", na, driven), | ||
66 | TEGRA_MAP_MUXCONF("ld11", "displaya", na, driven), | ||
67 | TEGRA_MAP_MUXCONF("ld12", "displaya", na, driven), | ||
68 | TEGRA_MAP_MUXCONF("ld13", "displaya", na, driven), | ||
69 | TEGRA_MAP_MUXCONF("ld14", "displaya", na, driven), | ||
70 | TEGRA_MAP_MUXCONF("ld15", "displaya", na, driven), | ||
71 | TEGRA_MAP_MUXCONF("ld16", "displaya", na, driven), | ||
72 | TEGRA_MAP_MUXCONF("ld17", "displaya", na, driven), | ||
73 | TEGRA_MAP_MUXCONF("ld2", "displaya", na, driven), | ||
74 | TEGRA_MAP_MUXCONF("ld3", "displaya", na, driven), | ||
75 | TEGRA_MAP_MUXCONF("ld4", "displaya", na, driven), | ||
76 | TEGRA_MAP_MUXCONF("ld5", "displaya", na, driven), | ||
77 | TEGRA_MAP_MUXCONF("ld6", "displaya", na, driven), | ||
78 | TEGRA_MAP_MUXCONF("ld7", "displaya", na, driven), | ||
79 | TEGRA_MAP_MUXCONF("ld8", "displaya", na, driven), | ||
80 | TEGRA_MAP_MUXCONF("ld9", "displaya", na, driven), | ||
81 | TEGRA_MAP_MUXCONF("ldc", "displaya", na, tristate), | ||
82 | TEGRA_MAP_MUXCONF("ldi", "displaya", na, driven), | ||
83 | TEGRA_MAP_MUXCONF("lhp0", "displaya", na, driven), | ||
84 | TEGRA_MAP_MUXCONF("lhp1", "displaya", na, driven), | ||
85 | TEGRA_MAP_MUXCONF("lhp2", "displaya", na, driven), | ||
86 | TEGRA_MAP_MUXCONF("lhs", "displaya", na, driven), | ||
87 | TEGRA_MAP_MUXCONF("lm0", "displaya", na, driven), | ||
88 | TEGRA_MAP_MUXCONF("lm1", "displaya", na, tristate), | ||
89 | TEGRA_MAP_MUXCONF("lpp", "displaya", na, driven), | ||
90 | TEGRA_MAP_MUXCONF("lpw0", "displaya", na, driven), | ||
91 | TEGRA_MAP_MUXCONF("lpw1", "displaya", na, tristate), | ||
92 | TEGRA_MAP_MUXCONF("lpw2", "displaya", na, driven), | ||
93 | TEGRA_MAP_MUXCONF("lsc0", "displaya", na, driven), | ||
94 | TEGRA_MAP_MUXCONF("lsc1", "displaya", na, tristate), | ||
95 | TEGRA_MAP_MUXCONF("lsck", "displaya", na, tristate), | ||
96 | TEGRA_MAP_MUXCONF("lsda", "displaya", na, tristate), | ||
97 | TEGRA_MAP_MUXCONF("lsdi", "displaya", na, tristate), | ||
98 | TEGRA_MAP_MUXCONF("lspi", "displaya", na, driven), | ||
99 | TEGRA_MAP_MUXCONF("lvp0", "displaya", na, tristate), | ||
100 | TEGRA_MAP_MUXCONF("lvp1", "displaya", na, driven), | ||
101 | TEGRA_MAP_MUXCONF("lvs", "displaya", na, driven), | ||
102 | TEGRA_MAP_MUXCONF("owc", "rsvd2", na, tristate), | ||
103 | TEGRA_MAP_MUXCONF("pmc", "pwr_on", na, driven), | ||
104 | TEGRA_MAP_MUXCONF("pta", "hdmi", none, driven), | ||
105 | TEGRA_MAP_MUXCONF("rm", "i2c1", none, driven), | ||
106 | TEGRA_MAP_MUXCONF("sdb", "pwm", na, tristate), | ||
107 | TEGRA_MAP_MUXCONF("sdc", "pwm", up, driven), | ||
108 | TEGRA_MAP_MUXCONF("sdd", "pwm", up, tristate), | ||
109 | TEGRA_MAP_MUXCONF("sdio1", "sdio1", none, tristate), | ||
110 | TEGRA_MAP_MUXCONF("slxa", "pcie", none, driven), | ||
111 | TEGRA_MAP_MUXCONF("slxc", "spdif", none, tristate), | ||
112 | TEGRA_MAP_MUXCONF("slxd", "spdif", none, tristate), | ||
113 | TEGRA_MAP_MUXCONF("slxk", "pcie", none, driven), | ||
114 | TEGRA_MAP_MUXCONF("spdi", "rsvd2", none, tristate), | ||
115 | TEGRA_MAP_MUXCONF("spdo", "rsvd2", none, tristate), | ||
116 | TEGRA_MAP_MUXCONF("spia", "gmi", none, driven), | ||
117 | TEGRA_MAP_MUXCONF("spib", "gmi", none, driven), | ||
118 | TEGRA_MAP_MUXCONF("spic", "gmi", up, tristate), | ||
119 | TEGRA_MAP_MUXCONF("spid", "spi1", down, tristate), | ||
120 | TEGRA_MAP_MUXCONF("spie", "spi1", up, tristate), | ||
121 | TEGRA_MAP_MUXCONF("spif", "spi1", down, tristate), | ||
122 | TEGRA_MAP_MUXCONF("spig", "spi2_alt", none, tristate), | ||
123 | TEGRA_MAP_MUXCONF("spih", "spi2_alt", up, tristate), | ||
124 | TEGRA_MAP_MUXCONF("uaa", "ulpi", up, tristate), | ||
125 | TEGRA_MAP_MUXCONF("uab", "ulpi", up, tristate), | ||
126 | TEGRA_MAP_MUXCONF("uac", "rsvd2", none, tristate), | ||
127 | TEGRA_MAP_MUXCONF("uad", "irda", up, tristate), | ||
128 | TEGRA_MAP_MUXCONF("uca", "uartc", up, tristate), | ||
129 | TEGRA_MAP_MUXCONF("ucb", "uartc", up, tristate), | ||
130 | TEGRA_MAP_MUXCONF("uda", "ulpi", none, tristate), | ||
131 | TEGRA_MAP_CONF("ck32", none, na), | ||
132 | TEGRA_MAP_CONF("ddrc", none, na), | ||
133 | TEGRA_MAP_CONF("pmca", none, na), | ||
134 | TEGRA_MAP_CONF("pmcb", none, na), | ||
135 | TEGRA_MAP_CONF("pmcc", none, na), | ||
136 | TEGRA_MAP_CONF("pmcd", none, na), | ||
137 | TEGRA_MAP_CONF("pmce", none, na), | ||
138 | TEGRA_MAP_CONF("xm2c", none, na), | ||
139 | TEGRA_MAP_CONF("xm2d", none, na), | ||
140 | TEGRA_MAP_CONF("ls", up, na), | ||
141 | TEGRA_MAP_CONF("lc", up, na), | ||
142 | TEGRA_MAP_CONF("ld17_0", down, na), | ||
143 | TEGRA_MAP_CONF("ld19_18", down, na), | ||
144 | TEGRA_MAP_CONF("ld21_20", down, na), | ||
145 | TEGRA_MAP_CONF("ld23_22", down, na), | ||
146 | }; | ||
147 | |||
148 | static struct tegra_board_pinmux_conf conf = { | ||
149 | .maps = harmony_map, | ||
150 | .map_count = ARRAY_SIZE(harmony_map), | ||
151 | }; | ||
152 | |||
153 | void harmony_pinmux_init(void) | ||
154 | { | ||
155 | tegra_board_pinmux_init(&conf, NULL); | ||
156 | } | ||
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c deleted file mode 100644 index b7344beec102..000000000000 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 NVIDIA, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
16 | * 02111-1307, USA | ||
17 | */ | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/regulator/machine.h> | ||
22 | #include <linux/regulator/fixed.h> | ||
23 | #include <linux/mfd/tps6586x.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/of_i2c.h> | ||
26 | |||
27 | #include <asm/mach-types.h> | ||
28 | |||
29 | #include <mach/irqs.h> | ||
30 | |||
31 | #include "board-harmony.h" | ||
32 | |||
33 | static struct regulator_consumer_supply tps658621_ldo0_supply[] = { | ||
34 | REGULATOR_SUPPLY("pex_clk", NULL), | ||
35 | }; | ||
36 | |||
37 | static struct regulator_init_data ldo0_data = { | ||
38 | .supply_regulator = "vdd_sm2", | ||
39 | .constraints = { | ||
40 | .name = "vdd_ldo0", | ||
41 | .min_uV = 3300 * 1000, | ||
42 | .max_uV = 3300 * 1000, | ||
43 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | | ||
44 | REGULATOR_MODE_STANDBY), | ||
45 | .valid_ops_mask = (REGULATOR_CHANGE_MODE | | ||
46 | REGULATOR_CHANGE_STATUS | | ||
47 | REGULATOR_CHANGE_VOLTAGE), | ||
48 | .apply_uV = 1, | ||
49 | }, | ||
50 | .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply), | ||
51 | .consumer_supplies = tps658621_ldo0_supply, | ||
52 | }; | ||
53 | |||
54 | #define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv, _on)\ | ||
55 | static struct regulator_init_data _id##_data = { \ | ||
56 | .supply_regulator = _supply, \ | ||
57 | .constraints = { \ | ||
58 | .name = _name, \ | ||
59 | .min_uV = (_minmv)*1000, \ | ||
60 | .max_uV = (_maxmv)*1000, \ | ||
61 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | \ | ||
62 | REGULATOR_MODE_STANDBY), \ | ||
63 | .valid_ops_mask = (REGULATOR_CHANGE_MODE | \ | ||
64 | REGULATOR_CHANGE_STATUS | \ | ||
65 | REGULATOR_CHANGE_VOLTAGE), \ | ||
66 | .always_on = _on, \ | ||
67 | }, \ | ||
68 | } | ||
69 | |||
70 | HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500, 1); | ||
71 | HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500, 1); | ||
72 | HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550, 1); | ||
73 | HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1); | ||
74 | HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0); | ||
75 | HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1); | ||
76 | HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1); | ||
77 | HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300, 1); | ||
78 | HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0); | ||
79 | HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0); | ||
80 | HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0); | ||
81 | HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1); | ||
82 | |||
83 | #define TPS_REG(_id, _data) \ | ||
84 | { \ | ||
85 | .id = TPS6586X_ID_##_id, \ | ||
86 | .name = "tps6586x-regulator", \ | ||
87 | .platform_data = _data, \ | ||
88 | } | ||
89 | |||
90 | static struct tps6586x_subdev_info tps_devs[] = { | ||
91 | TPS_REG(SM_0, &sm0_data), | ||
92 | TPS_REG(SM_1, &sm1_data), | ||
93 | TPS_REG(SM_2, &sm2_data), | ||
94 | TPS_REG(LDO_0, &ldo0_data), | ||
95 | TPS_REG(LDO_1, &ldo1_data), | ||
96 | TPS_REG(LDO_2, &ldo2_data), | ||
97 | TPS_REG(LDO_3, &ldo3_data), | ||
98 | TPS_REG(LDO_4, &ldo4_data), | ||
99 | TPS_REG(LDO_5, &ldo5_data), | ||
100 | TPS_REG(LDO_6, &ldo6_data), | ||
101 | TPS_REG(LDO_7, &ldo7_data), | ||
102 | TPS_REG(LDO_8, &ldo8_data), | ||
103 | TPS_REG(LDO_9, &ldo9_data), | ||
104 | }; | ||
105 | |||
106 | static struct tps6586x_platform_data tps_platform = { | ||
107 | .irq_base = TEGRA_NR_IRQS, | ||
108 | .num_subdevs = ARRAY_SIZE(tps_devs), | ||
109 | .subdevs = tps_devs, | ||
110 | .gpio_base = HARMONY_GPIO_TPS6586X(0), | ||
111 | }; | ||
112 | |||
113 | static struct i2c_board_info __initdata harmony_regulators[] = { | ||
114 | { | ||
115 | I2C_BOARD_INFO("tps6586x", 0x34), | ||
116 | .irq = INT_EXTERNAL_PMU, | ||
117 | .platform_data = &tps_platform, | ||
118 | }, | ||
119 | }; | ||
120 | |||
121 | int __init harmony_regulator_init(void) | ||
122 | { | ||
123 | regulator_register_always_on(0, "vdd_sys", | ||
124 | NULL, 0, 5000000); | ||
125 | |||
126 | if (machine_is_harmony()) { | ||
127 | i2c_register_board_info(3, harmony_regulators, 1); | ||
128 | } else { /* Harmony, booted using device tree */ | ||
129 | struct device_node *np; | ||
130 | struct i2c_adapter *adapter; | ||
131 | |||
132 | np = of_find_node_by_path("/i2c@7000d000"); | ||
133 | if (np == NULL) { | ||
134 | pr_err("Could not find device_node for DVC I2C\n"); | ||
135 | return -ENODEV; | ||
136 | } | ||
137 | |||
138 | adapter = of_find_i2c_adapter_by_node(np); | ||
139 | if (!adapter) { | ||
140 | pr_err("Could not find i2c_adapter for DVC I2C\n"); | ||
141 | return -ENODEV; | ||
142 | } | ||
143 | |||
144 | i2c_new_device(adapter, harmony_regulators); | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c deleted file mode 100644 index e65e837f4013..000000000000 --- a/arch/arm/mach-tegra/board-harmony.c +++ /dev/null | |||
@@ -1,197 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-harmony.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Copyright (C) 2011 NVIDIA, Inc. | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/serial_8250.h> | ||
22 | #include <linux/of_serial.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/pda_power.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/i2c.h> | ||
29 | |||
30 | #include <sound/wm8903.h> | ||
31 | |||
32 | #include <asm/mach-types.h> | ||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/time.h> | ||
35 | #include <asm/hardware/gic.h> | ||
36 | #include <asm/setup.h> | ||
37 | |||
38 | #include <mach/tegra_wm8903_pdata.h> | ||
39 | #include <mach/iomap.h> | ||
40 | #include <mach/irqs.h> | ||
41 | #include <mach/sdhci.h> | ||
42 | |||
43 | #include "board.h" | ||
44 | #include "board-harmony.h" | ||
45 | #include "clock.h" | ||
46 | #include "devices.h" | ||
47 | #include "gpio-names.h" | ||
48 | |||
49 | static struct plat_serial8250_port debug_uart_platform_data[] = { | ||
50 | { | ||
51 | .membase = IO_ADDRESS(TEGRA_UARTD_BASE), | ||
52 | .mapbase = TEGRA_UARTD_BASE, | ||
53 | .irq = INT_UARTD, | ||
54 | .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, | ||
55 | .type = PORT_TEGRA, | ||
56 | .handle_break = tegra_serial_handle_break, | ||
57 | .iotype = UPIO_MEM, | ||
58 | .regshift = 2, | ||
59 | .uartclk = 216000000, | ||
60 | }, { | ||
61 | .flags = 0 | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | static struct platform_device debug_uart = { | ||
66 | .name = "serial8250", | ||
67 | .id = PLAT8250_DEV_PLATFORM, | ||
68 | .dev = { | ||
69 | .platform_data = debug_uart_platform_data, | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static struct tegra_wm8903_platform_data harmony_audio_pdata = { | ||
74 | .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, | ||
75 | .gpio_hp_det = TEGRA_GPIO_HP_DET, | ||
76 | .gpio_hp_mute = -1, | ||
77 | .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN, | ||
78 | .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN, | ||
79 | }; | ||
80 | |||
81 | static struct platform_device harmony_audio_device = { | ||
82 | .name = "tegra-snd-wm8903", | ||
83 | .id = 0, | ||
84 | .dev = { | ||
85 | .platform_data = &harmony_audio_pdata, | ||
86 | }, | ||
87 | }; | ||
88 | |||
89 | static struct wm8903_platform_data harmony_wm8903_pdata = { | ||
90 | .irq_active_low = 0, | ||
91 | .micdet_cfg = 0, | ||
92 | .micdet_delay = 100, | ||
93 | .gpio_base = HARMONY_GPIO_WM8903(0), | ||
94 | .gpio_cfg = { | ||
95 | 0, | ||
96 | 0, | ||
97 | WM8903_GPIO_CONFIG_ZERO, | ||
98 | 0, | ||
99 | 0, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static struct i2c_board_info __initdata wm8903_board_info = { | ||
104 | I2C_BOARD_INFO("wm8903", 0x1a), | ||
105 | .platform_data = &harmony_wm8903_pdata, | ||
106 | }; | ||
107 | |||
108 | static void __init harmony_i2c_init(void) | ||
109 | { | ||
110 | platform_device_register(&tegra_i2c_device1); | ||
111 | platform_device_register(&tegra_i2c_device2); | ||
112 | platform_device_register(&tegra_i2c_device3); | ||
113 | platform_device_register(&tegra_i2c_device4); | ||
114 | |||
115 | wm8903_board_info.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ); | ||
116 | i2c_register_board_info(0, &wm8903_board_info, 1); | ||
117 | } | ||
118 | |||
119 | static struct platform_device *harmony_devices[] __initdata = { | ||
120 | &debug_uart, | ||
121 | &tegra_sdhci_device1, | ||
122 | &tegra_sdhci_device2, | ||
123 | &tegra_sdhci_device4, | ||
124 | &tegra_ehci3_device, | ||
125 | &tegra_i2s_device1, | ||
126 | &tegra_das_device, | ||
127 | &harmony_audio_device, | ||
128 | }; | ||
129 | |||
130 | static void __init tegra_harmony_fixup(struct tag *tags, char **cmdline, | ||
131 | struct meminfo *mi) | ||
132 | { | ||
133 | mi->nr_banks = 2; | ||
134 | mi->bank[0].start = PHYS_OFFSET; | ||
135 | mi->bank[0].size = 448 * SZ_1M; | ||
136 | mi->bank[1].start = SZ_512M; | ||
137 | mi->bank[1].size = SZ_512M; | ||
138 | } | ||
139 | |||
140 | static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = { | ||
141 | /* name parent rate enabled */ | ||
142 | { "uartd", "pll_p", 216000000, true }, | ||
143 | { "pll_a", "pll_p_out1", 56448000, true }, | ||
144 | { "pll_a_out0", "pll_a", 11289600, true }, | ||
145 | { "cdev1", NULL, 0, true }, | ||
146 | { "i2s1", "pll_a_out0", 11289600, false}, | ||
147 | { "usb3", "clk_m", 12000000, true }, | ||
148 | { NULL, NULL, 0, 0}, | ||
149 | }; | ||
150 | |||
151 | |||
152 | static struct tegra_sdhci_platform_data sdhci_pdata1 = { | ||
153 | .cd_gpio = -1, | ||
154 | .wp_gpio = -1, | ||
155 | .power_gpio = -1, | ||
156 | }; | ||
157 | |||
158 | static struct tegra_sdhci_platform_data sdhci_pdata2 = { | ||
159 | .cd_gpio = TEGRA_GPIO_SD2_CD, | ||
160 | .wp_gpio = TEGRA_GPIO_SD2_WP, | ||
161 | .power_gpio = TEGRA_GPIO_SD2_POWER, | ||
162 | }; | ||
163 | |||
164 | static struct tegra_sdhci_platform_data sdhci_pdata4 = { | ||
165 | .cd_gpio = TEGRA_GPIO_SD4_CD, | ||
166 | .wp_gpio = TEGRA_GPIO_SD4_WP, | ||
167 | .power_gpio = TEGRA_GPIO_SD4_POWER, | ||
168 | .is_8bit = 1, | ||
169 | }; | ||
170 | |||
171 | static void __init tegra_harmony_init(void) | ||
172 | { | ||
173 | tegra_clk_init_from_table(harmony_clk_init_table); | ||
174 | |||
175 | harmony_pinmux_init(); | ||
176 | |||
177 | tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; | ||
178 | tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2; | ||
179 | tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; | ||
180 | |||
181 | platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); | ||
182 | harmony_i2c_init(); | ||
183 | harmony_regulator_init(); | ||
184 | } | ||
185 | |||
186 | MACHINE_START(HARMONY, "harmony") | ||
187 | .atag_offset = 0x100, | ||
188 | .fixup = tegra_harmony_fixup, | ||
189 | .map_io = tegra_map_common_io, | ||
190 | .init_early = tegra20_init_early, | ||
191 | .init_irq = tegra_init_irq, | ||
192 | .handle_irq = gic_handle_irq, | ||
193 | .timer = &tegra_timer, | ||
194 | .init_machine = tegra_harmony_init, | ||
195 | .init_late = tegra_init_late, | ||
196 | .restart = tegra_assert_system_reset, | ||
197 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h deleted file mode 100644 index 139d96c93843..000000000000 --- a/arch/arm/mach-tegra/board-harmony.h +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-harmony.h | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #ifndef _MACH_TEGRA_BOARD_HARMONY_H | ||
18 | #define _MACH_TEGRA_BOARD_HARMONY_H | ||
19 | |||
20 | #include <mach/gpio-tegra.h> | ||
21 | |||
22 | #define HARMONY_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_)) | ||
23 | #define HARMONY_GPIO_WM8903(_x_) (HARMONY_GPIO_TPS6586X(4) + (_x_)) | ||
24 | |||
25 | #define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5 | ||
26 | #define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1 | ||
27 | #define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PT3 | ||
28 | #define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2 | ||
29 | #define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3 | ||
30 | #define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6 | ||
31 | #define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3 | ||
32 | #define TEGRA_GPIO_SPKR_EN HARMONY_GPIO_WM8903(2) | ||
33 | #define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2 | ||
34 | #define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PX0 | ||
35 | #define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1 | ||
36 | #define TEGRA_GPIO_EN_VDD_1V05_GPIO HARMONY_GPIO_TPS6586X(2) | ||
37 | |||
38 | void harmony_pinmux_init(void); | ||
39 | int harmony_regulator_init(void); | ||
40 | |||
41 | #endif | ||
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c deleted file mode 100644 index 6f1111b48e7c..000000000000 --- a/arch/arm/mach-tegra/board-paz00-pinmux.c +++ /dev/null | |||
@@ -1,156 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-paz00-pinmux.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de> | ||
5 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | |||
20 | #include "board-paz00.h" | ||
21 | #include "board-pinmux.h" | ||
22 | |||
23 | static struct pinctrl_map paz00_map[] = { | ||
24 | TEGRA_MAP_MUXCONF("ata", "gmi", none, driven), | ||
25 | TEGRA_MAP_MUXCONF("atb", "sdio4", none, driven), | ||
26 | TEGRA_MAP_MUXCONF("atc", "gmi", none, driven), | ||
27 | TEGRA_MAP_MUXCONF("atd", "gmi", none, driven), | ||
28 | TEGRA_MAP_MUXCONF("ate", "gmi", none, driven), | ||
29 | TEGRA_MAP_MUXCONF("cdev1", "plla_out", none, driven), | ||
30 | TEGRA_MAP_MUXCONF("cdev2", "pllp_out4", down, driven), | ||
31 | TEGRA_MAP_MUXCONF("crtp", "crt", none, tristate), | ||
32 | TEGRA_MAP_MUXCONF("csus", "pllc_out1", down, tristate), | ||
33 | TEGRA_MAP_MUXCONF("dap1", "dap1", none, driven), | ||
34 | TEGRA_MAP_MUXCONF("dap2", "gmi", none, driven), | ||
35 | TEGRA_MAP_MUXCONF("dap3", "dap3", none, tristate), | ||
36 | TEGRA_MAP_MUXCONF("dap4", "dap4", none, tristate), | ||
37 | TEGRA_MAP_MUXCONF("ddc", "i2c2", up, driven), | ||
38 | TEGRA_MAP_MUXCONF("dta", "rsvd1", up, tristate), | ||
39 | TEGRA_MAP_MUXCONF("dtb", "rsvd1", none, tristate), | ||
40 | TEGRA_MAP_MUXCONF("dtc", "rsvd1", none, tristate), | ||
41 | TEGRA_MAP_MUXCONF("dtd", "rsvd1", up, tristate), | ||
42 | TEGRA_MAP_MUXCONF("dte", "rsvd1", none, tristate), | ||
43 | TEGRA_MAP_MUXCONF("dtf", "i2c3", none, driven), | ||
44 | TEGRA_MAP_MUXCONF("gma", "sdio4", none, driven), | ||
45 | TEGRA_MAP_MUXCONF("gmb", "gmi", none, driven), | ||
46 | TEGRA_MAP_MUXCONF("gmc", "gmi", none, driven), | ||
47 | TEGRA_MAP_MUXCONF("gmd", "gmi", none, driven), | ||
48 | TEGRA_MAP_MUXCONF("gme", "sdio4", none, driven), | ||
49 | TEGRA_MAP_MUXCONF("gpu", "pwm", none, driven), | ||
50 | TEGRA_MAP_MUXCONF("gpu7", "rtck", none, driven), | ||
51 | TEGRA_MAP_MUXCONF("gpv", "pcie", none, driven), | ||
52 | TEGRA_MAP_MUXCONF("hdint", "hdmi", na, driven), | ||
53 | TEGRA_MAP_MUXCONF("i2cp", "i2cp", none, driven), | ||
54 | TEGRA_MAP_MUXCONF("irrx", "uarta", up, driven), | ||
55 | TEGRA_MAP_MUXCONF("irtx", "uarta", up, driven), | ||
56 | TEGRA_MAP_MUXCONF("kbca", "kbc", up, driven), | ||
57 | TEGRA_MAP_MUXCONF("kbcb", "sdio2", up, driven), | ||
58 | TEGRA_MAP_MUXCONF("kbcc", "kbc", up, driven), | ||
59 | TEGRA_MAP_MUXCONF("kbcd", "sdio2", up, driven), | ||
60 | TEGRA_MAP_MUXCONF("kbce", "kbc", up, driven), | ||
61 | TEGRA_MAP_MUXCONF("kbcf", "kbc", up, driven), | ||
62 | TEGRA_MAP_MUXCONF("lcsn", "displaya", na, tristate), | ||
63 | TEGRA_MAP_MUXCONF("ld0", "displaya", na, driven), | ||
64 | TEGRA_MAP_MUXCONF("ld1", "displaya", na, driven), | ||
65 | TEGRA_MAP_MUXCONF("ld10", "displaya", na, driven), | ||
66 | TEGRA_MAP_MUXCONF("ld11", "displaya", na, driven), | ||
67 | TEGRA_MAP_MUXCONF("ld12", "displaya", na, driven), | ||
68 | TEGRA_MAP_MUXCONF("ld13", "displaya", na, driven), | ||
69 | TEGRA_MAP_MUXCONF("ld14", "displaya", na, driven), | ||
70 | TEGRA_MAP_MUXCONF("ld15", "displaya", na, driven), | ||
71 | TEGRA_MAP_MUXCONF("ld16", "displaya", na, driven), | ||
72 | TEGRA_MAP_MUXCONF("ld17", "displaya", na, driven), | ||
73 | TEGRA_MAP_MUXCONF("ld2", "displaya", na, driven), | ||
74 | TEGRA_MAP_MUXCONF("ld3", "displaya", na, driven), | ||
75 | TEGRA_MAP_MUXCONF("ld4", "displaya", na, driven), | ||
76 | TEGRA_MAP_MUXCONF("ld5", "displaya", na, driven), | ||
77 | TEGRA_MAP_MUXCONF("ld6", "displaya", na, driven), | ||
78 | TEGRA_MAP_MUXCONF("ld7", "displaya", na, driven), | ||
79 | TEGRA_MAP_MUXCONF("ld8", "displaya", na, driven), | ||
80 | TEGRA_MAP_MUXCONF("ld9", "displaya", na, driven), | ||
81 | TEGRA_MAP_MUXCONF("ldc", "displaya", na, driven), | ||
82 | TEGRA_MAP_MUXCONF("ldi", "displaya", na, driven), | ||
83 | TEGRA_MAP_MUXCONF("lhp0", "displaya", na, tristate), | ||
84 | TEGRA_MAP_MUXCONF("lhp1", "displaya", na, tristate), | ||
85 | TEGRA_MAP_MUXCONF("lhp2", "displaya", na, tristate), | ||
86 | TEGRA_MAP_MUXCONF("lhs", "displaya", na, driven), | ||
87 | TEGRA_MAP_MUXCONF("lm0", "displaya", na, tristate), | ||
88 | TEGRA_MAP_MUXCONF("lm1", "displaya", na, tristate), | ||
89 | TEGRA_MAP_MUXCONF("lpp", "displaya", na, tristate), | ||
90 | TEGRA_MAP_MUXCONF("lpw0", "displaya", na, tristate), | ||
91 | TEGRA_MAP_MUXCONF("lpw1", "displaya", na, tristate), | ||
92 | TEGRA_MAP_MUXCONF("lpw2", "displaya", na, tristate), | ||
93 | TEGRA_MAP_MUXCONF("lsc0", "displaya", na, driven), | ||
94 | TEGRA_MAP_MUXCONF("lsc1", "displaya", na, tristate), | ||
95 | TEGRA_MAP_MUXCONF("lsck", "displaya", na, tristate), | ||
96 | TEGRA_MAP_MUXCONF("lsda", "displaya", na, tristate), | ||
97 | TEGRA_MAP_MUXCONF("lsdi", "displaya", na, tristate), | ||
98 | TEGRA_MAP_MUXCONF("lspi", "displaya", na, driven), | ||
99 | TEGRA_MAP_MUXCONF("lvp0", "displaya", na, tristate), | ||
100 | TEGRA_MAP_MUXCONF("lvp1", "displaya", na, tristate), | ||
101 | TEGRA_MAP_MUXCONF("lvs", "displaya", na, driven), | ||
102 | TEGRA_MAP_MUXCONF("owc", "owr", up, tristate), | ||
103 | TEGRA_MAP_MUXCONF("pmc", "pwr_on", na, driven), | ||
104 | TEGRA_MAP_MUXCONF("pta", "hdmi", none, driven), | ||
105 | TEGRA_MAP_MUXCONF("rm", "i2c1", none, driven), | ||
106 | TEGRA_MAP_MUXCONF("sdb", "pwm", na, tristate), | ||
107 | TEGRA_MAP_MUXCONF("sdc", "twc", up, tristate), | ||
108 | TEGRA_MAP_MUXCONF("sdd", "pwm", up, tristate), | ||
109 | TEGRA_MAP_MUXCONF("sdio1", "sdio1", none, driven), | ||
110 | TEGRA_MAP_MUXCONF("slxa", "pcie", none, tristate), | ||
111 | TEGRA_MAP_MUXCONF("slxc", "spi4", none, tristate), | ||
112 | TEGRA_MAP_MUXCONF("slxd", "spi4", none, tristate), | ||
113 | TEGRA_MAP_MUXCONF("slxk", "pcie", none, driven), | ||
114 | TEGRA_MAP_MUXCONF("spdi", "rsvd2", none, tristate), | ||
115 | TEGRA_MAP_MUXCONF("spdo", "rsvd2", none, driven), | ||
116 | TEGRA_MAP_MUXCONF("spia", "gmi", down, tristate), | ||
117 | TEGRA_MAP_MUXCONF("spib", "gmi", down, tristate), | ||
118 | TEGRA_MAP_MUXCONF("spic", "gmi", up, driven), | ||
119 | TEGRA_MAP_MUXCONF("spid", "gmi", down, tristate), | ||
120 | TEGRA_MAP_MUXCONF("spie", "gmi", up, tristate), | ||
121 | TEGRA_MAP_MUXCONF("spif", "rsvd4", down, tristate), | ||
122 | TEGRA_MAP_MUXCONF("spig", "spi2_alt", up, driven), | ||
123 | TEGRA_MAP_MUXCONF("spih", "spi2_alt", up, tristate), | ||
124 | TEGRA_MAP_MUXCONF("uaa", "ulpi", up, driven), | ||
125 | TEGRA_MAP_MUXCONF("uab", "ulpi", up, driven), | ||
126 | TEGRA_MAP_MUXCONF("uac", "rsvd4", none, driven), | ||
127 | TEGRA_MAP_MUXCONF("uad", "spdif", up, tristate), | ||
128 | TEGRA_MAP_MUXCONF("uca", "uartc", up, tristate), | ||
129 | TEGRA_MAP_MUXCONF("ucb", "uartc", up, tristate), | ||
130 | TEGRA_MAP_MUXCONF("uda", "ulpi", none, driven), | ||
131 | TEGRA_MAP_CONF("ck32", none, na), | ||
132 | TEGRA_MAP_CONF("ddrc", none, na), | ||
133 | TEGRA_MAP_CONF("pmca", none, na), | ||
134 | TEGRA_MAP_CONF("pmcb", none, na), | ||
135 | TEGRA_MAP_CONF("pmcc", none, na), | ||
136 | TEGRA_MAP_CONF("pmcd", none, na), | ||
137 | TEGRA_MAP_CONF("pmce", none, na), | ||
138 | TEGRA_MAP_CONF("xm2c", none, na), | ||
139 | TEGRA_MAP_CONF("xm2d", none, na), | ||
140 | TEGRA_MAP_CONF("ls", up, na), | ||
141 | TEGRA_MAP_CONF("lc", up, na), | ||
142 | TEGRA_MAP_CONF("ld17_0", down, na), | ||
143 | TEGRA_MAP_CONF("ld19_18", down, na), | ||
144 | TEGRA_MAP_CONF("ld21_20", down, na), | ||
145 | TEGRA_MAP_CONF("ld23_22", down, na), | ||
146 | }; | ||
147 | |||
148 | static struct tegra_board_pinmux_conf conf = { | ||
149 | .maps = paz00_map, | ||
150 | .map_count = ARRAY_SIZE(paz00_map), | ||
151 | }; | ||
152 | |||
153 | void paz00_pinmux_init(void) | ||
154 | { | ||
155 | tegra_board_pinmux_init(&conf, NULL); | ||
156 | } | ||
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 4b64af5cab27..59305516fadb 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c | |||
@@ -17,72 +17,10 @@ | |||
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
23 | #include <linux/serial_8250.h> | ||
24 | #include <linux/of_serial.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | #include <linux/gpio_keys.h> | ||
28 | #include <linux/pda_power.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/i2c.h> | ||
32 | #include <linux/gpio.h> | ||
33 | #include <linux/rfkill-gpio.h> | 21 | #include <linux/rfkill-gpio.h> |
34 | 22 | ||
35 | #include <asm/hardware/gic.h> | ||
36 | #include <asm/mach-types.h> | ||
37 | #include <asm/mach/arch.h> | ||
38 | #include <asm/mach/time.h> | ||
39 | #include <asm/setup.h> | ||
40 | |||
41 | #include <mach/iomap.h> | ||
42 | #include <mach/irqs.h> | ||
43 | #include <mach/sdhci.h> | ||
44 | |||
45 | #include "board.h" | ||
46 | #include "board-paz00.h" | 23 | #include "board-paz00.h" |
47 | #include "clock.h" | ||
48 | #include "devices.h" | ||
49 | #include "gpio-names.h" | ||
50 | |||
51 | static struct plat_serial8250_port debug_uart_platform_data[] = { | ||
52 | { | ||
53 | /* serial port on JP1 */ | ||
54 | .membase = IO_ADDRESS(TEGRA_UARTA_BASE), | ||
55 | .mapbase = TEGRA_UARTA_BASE, | ||
56 | .irq = INT_UARTA, | ||
57 | .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, | ||
58 | .type = PORT_TEGRA, | ||
59 | .handle_break = tegra_serial_handle_break, | ||
60 | .iotype = UPIO_MEM, | ||
61 | .regshift = 2, | ||
62 | .uartclk = 216000000, | ||
63 | }, { | ||
64 | /* serial port on mini-pcie */ | ||
65 | .membase = IO_ADDRESS(TEGRA_UARTC_BASE), | ||
66 | .mapbase = TEGRA_UARTC_BASE, | ||
67 | .irq = INT_UARTC, | ||
68 | .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, | ||
69 | .type = PORT_TEGRA, | ||
70 | .handle_break = tegra_serial_handle_break, | ||
71 | .iotype = UPIO_MEM, | ||
72 | .regshift = 2, | ||
73 | .uartclk = 216000000, | ||
74 | }, { | ||
75 | .flags = 0 | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | static struct platform_device debug_uart = { | ||
80 | .name = "serial8250", | ||
81 | .id = PLAT8250_DEV_PLATFORM, | ||
82 | .dev = { | ||
83 | .platform_data = debug_uart_platform_data, | ||
84 | }, | ||
85 | }; | ||
86 | 24 | ||
87 | static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = { | 25 | static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = { |
88 | .name = "wifi_rfkill", | 26 | .name = "wifi_rfkill", |
@@ -99,137 +37,7 @@ static struct platform_device wifi_rfkill_device = { | |||
99 | }, | 37 | }, |
100 | }; | 38 | }; |
101 | 39 | ||
102 | static struct gpio_led gpio_leds[] = { | ||
103 | { | ||
104 | .name = "wifi-led", | ||
105 | .default_trigger = "rfkill0", | ||
106 | .gpio = TEGRA_WIFI_LED, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | static struct gpio_led_platform_data gpio_led_info = { | ||
111 | .leds = gpio_leds, | ||
112 | .num_leds = ARRAY_SIZE(gpio_leds), | ||
113 | }; | ||
114 | |||
115 | static struct platform_device leds_gpio = { | ||
116 | .name = "leds-gpio", | ||
117 | .id = -1, | ||
118 | .dev = { | ||
119 | .platform_data = &gpio_led_info, | ||
120 | }, | ||
121 | }; | ||
122 | |||
123 | static struct gpio_keys_button paz00_gpio_keys_buttons[] = { | ||
124 | { | ||
125 | .code = KEY_POWER, | ||
126 | .gpio = TEGRA_GPIO_POWERKEY, | ||
127 | .active_low = 1, | ||
128 | .desc = "Power", | ||
129 | .type = EV_KEY, | ||
130 | .wakeup = 1, | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | static struct gpio_keys_platform_data paz00_gpio_keys = { | ||
135 | .buttons = paz00_gpio_keys_buttons, | ||
136 | .nbuttons = ARRAY_SIZE(paz00_gpio_keys_buttons), | ||
137 | }; | ||
138 | |||
139 | static struct platform_device gpio_keys_device = { | ||
140 | .name = "gpio-keys", | ||
141 | .id = -1, | ||
142 | .dev = { | ||
143 | .platform_data = &paz00_gpio_keys, | ||
144 | }, | ||
145 | }; | ||
146 | |||
147 | static struct platform_device *paz00_devices[] __initdata = { | ||
148 | &debug_uart, | ||
149 | &tegra_sdhci_device4, | ||
150 | &tegra_sdhci_device1, | ||
151 | &leds_gpio, | ||
152 | &gpio_keys_device, | ||
153 | }; | ||
154 | |||
155 | static void paz00_i2c_init(void) | ||
156 | { | ||
157 | platform_device_register(&tegra_i2c_device1); | ||
158 | platform_device_register(&tegra_i2c_device2); | ||
159 | platform_device_register(&tegra_i2c_device4); | ||
160 | } | ||
161 | |||
162 | static void paz00_usb_init(void) | ||
163 | { | ||
164 | tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_ULPI_RST; | ||
165 | |||
166 | platform_device_register(&tegra_ehci2_device); | ||
167 | platform_device_register(&tegra_ehci3_device); | ||
168 | } | ||
169 | |||
170 | static void __init tegra_paz00_fixup(struct tag *tags, char **cmdline, | ||
171 | struct meminfo *mi) | ||
172 | { | ||
173 | mi->nr_banks = 1; | ||
174 | mi->bank[0].start = PHYS_OFFSET; | ||
175 | mi->bank[0].size = 448 * SZ_1M; | ||
176 | } | ||
177 | |||
178 | static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = { | ||
179 | /* name parent rate enabled */ | ||
180 | { "uarta", "pll_p", 216000000, true }, | ||
181 | { "uartc", "pll_p", 216000000, true }, | ||
182 | |||
183 | { "usbd", "clk_m", 12000000, false }, | ||
184 | { "usb2", "clk_m", 12000000, false }, | ||
185 | { "usb3", "clk_m", 12000000, false }, | ||
186 | |||
187 | { NULL, NULL, 0, 0}, | ||
188 | }; | ||
189 | |||
190 | static struct tegra_sdhci_platform_data sdhci_pdata1 = { | ||
191 | .cd_gpio = TEGRA_GPIO_SD1_CD, | ||
192 | .wp_gpio = TEGRA_GPIO_SD1_WP, | ||
193 | .power_gpio = TEGRA_GPIO_SD1_POWER, | ||
194 | }; | ||
195 | |||
196 | static struct tegra_sdhci_platform_data sdhci_pdata4 = { | ||
197 | .cd_gpio = -1, | ||
198 | .wp_gpio = -1, | ||
199 | .power_gpio = -1, | ||
200 | .is_8bit = 1, | ||
201 | }; | ||
202 | |||
203 | void __init tegra_paz00_wifikill_init(void) | 40 | void __init tegra_paz00_wifikill_init(void) |
204 | { | 41 | { |
205 | platform_device_register(&wifi_rfkill_device); | 42 | platform_device_register(&wifi_rfkill_device); |
206 | } | 43 | } |
207 | |||
208 | static void __init tegra_paz00_init(void) | ||
209 | { | ||
210 | tegra_clk_init_from_table(paz00_clk_init_table); | ||
211 | |||
212 | paz00_pinmux_init(); | ||
213 | |||
214 | tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; | ||
215 | tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; | ||
216 | |||
217 | platform_add_devices(paz00_devices, ARRAY_SIZE(paz00_devices)); | ||
218 | tegra_paz00_wifikill_init(); | ||
219 | |||
220 | paz00_i2c_init(); | ||
221 | paz00_usb_init(); | ||
222 | } | ||
223 | |||
224 | MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ") | ||
225 | .atag_offset = 0x100, | ||
226 | .fixup = tegra_paz00_fixup, | ||
227 | .map_io = tegra_map_common_io, | ||
228 | .init_early = tegra20_init_early, | ||
229 | .init_irq = tegra_init_irq, | ||
230 | .handle_irq = gic_handle_irq, | ||
231 | .timer = &tegra_timer, | ||
232 | .init_machine = tegra_paz00_init, | ||
233 | .init_late = tegra_init_late, | ||
234 | .restart = tegra_assert_system_reset, | ||
235 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h index 3c9f8da37ea3..25c08ecef52f 100644 --- a/arch/arm/mach-tegra/board-paz00.h +++ b/arch/arm/mach-tegra/board-paz00.h | |||
@@ -17,24 +17,9 @@ | |||
17 | #ifndef _MACH_TEGRA_BOARD_PAZ00_H | 17 | #ifndef _MACH_TEGRA_BOARD_PAZ00_H |
18 | #define _MACH_TEGRA_BOARD_PAZ00_H | 18 | #define _MACH_TEGRA_BOARD_PAZ00_H |
19 | 19 | ||
20 | #include <mach/gpio-tegra.h> | 20 | #include "gpio-names.h" |
21 | 21 | ||
22 | /* SDCARD */ | ||
23 | #define TEGRA_GPIO_SD1_CD TEGRA_GPIO_PV5 | ||
24 | #define TEGRA_GPIO_SD1_WP TEGRA_GPIO_PH1 | ||
25 | #define TEGRA_GPIO_SD1_POWER TEGRA_GPIO_PV1 | ||
26 | |||
27 | /* ULPI */ | ||
28 | #define TEGRA_ULPI_RST TEGRA_GPIO_PV0 | ||
29 | |||
30 | /* WIFI */ | ||
31 | #define TEGRA_WIFI_PWRN TEGRA_GPIO_PK5 | 22 | #define TEGRA_WIFI_PWRN TEGRA_GPIO_PK5 |
32 | #define TEGRA_WIFI_RST TEGRA_GPIO_PD1 | 23 | #define TEGRA_WIFI_RST TEGRA_GPIO_PD1 |
33 | #define TEGRA_WIFI_LED TEGRA_GPIO_PD0 | ||
34 | |||
35 | /* WakeUp */ | ||
36 | #define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PJ7 | ||
37 | |||
38 | void paz00_pinmux_init(void); | ||
39 | 24 | ||
40 | #endif | 25 | #endif |
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c deleted file mode 100644 index 7b39511c0d4d..000000000000 --- a/arch/arm/mach-tegra/board-trimslice-pinmux.c +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-trimslice-pinmux.c | ||
3 | * | ||
4 | * Copyright (C) 2011 CompuLab, Ltd. | ||
5 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/kernel.h> | ||
18 | |||
19 | #include "board-trimslice.h" | ||
20 | #include "board-pinmux.h" | ||
21 | |||
22 | static struct pinctrl_map trimslice_map[] = { | ||
23 | TEGRA_MAP_MUXCONF("ata", "ide", none, tristate), | ||
24 | TEGRA_MAP_MUXCONF("atb", "sdio4", none, driven), | ||
25 | TEGRA_MAP_MUXCONF("atc", "nand", none, tristate), | ||
26 | TEGRA_MAP_MUXCONF("atd", "gmi", none, tristate), | ||
27 | TEGRA_MAP_MUXCONF("ate", "gmi", none, tristate), | ||
28 | TEGRA_MAP_MUXCONF("cdev1", "plla_out", none, driven), | ||
29 | TEGRA_MAP_MUXCONF("cdev2", "pllp_out4", down, tristate), | ||
30 | TEGRA_MAP_MUXCONF("crtp", "crt", none, tristate), | ||
31 | TEGRA_MAP_MUXCONF("csus", "vi_sensor_clk", down, tristate), | ||
32 | TEGRA_MAP_MUXCONF("dap1", "dap1", none, driven), | ||
33 | TEGRA_MAP_MUXCONF("dap2", "dap2", none, tristate), | ||
34 | TEGRA_MAP_MUXCONF("dap3", "dap3", none, tristate), | ||
35 | TEGRA_MAP_MUXCONF("dap4", "dap4", none, tristate), | ||
36 | TEGRA_MAP_MUXCONF("ddc", "i2c2", up, driven), | ||
37 | TEGRA_MAP_MUXCONF("dta", "vi", none, tristate), | ||
38 | TEGRA_MAP_MUXCONF("dtb", "vi", none, tristate), | ||
39 | TEGRA_MAP_MUXCONF("dtc", "vi", none, tristate), | ||
40 | TEGRA_MAP_MUXCONF("dtd", "vi", none, tristate), | ||
41 | TEGRA_MAP_MUXCONF("dte", "vi", none, tristate), | ||
42 | TEGRA_MAP_MUXCONF("dtf", "i2c3", up, driven), | ||
43 | TEGRA_MAP_MUXCONF("gma", "sdio4", none, driven), | ||
44 | TEGRA_MAP_MUXCONF("gmb", "nand", none, tristate), | ||
45 | TEGRA_MAP_MUXCONF("gmc", "sflash", none, driven), | ||
46 | TEGRA_MAP_MUXCONF("gmd", "sflash", none, driven), | ||
47 | TEGRA_MAP_MUXCONF("gme", "gmi", none, tristate), | ||
48 | TEGRA_MAP_MUXCONF("gpu", "uarta", none, driven), | ||
49 | TEGRA_MAP_MUXCONF("gpu7", "rtck", none, driven), | ||
50 | TEGRA_MAP_MUXCONF("gpv", "pcie", none, driven), | ||
51 | TEGRA_MAP_MUXCONF("hdint", "hdmi", na, tristate), | ||
52 | TEGRA_MAP_MUXCONF("i2cp", "i2cp", none, tristate), | ||
53 | TEGRA_MAP_MUXCONF("irrx", "uartb", up, tristate), | ||
54 | TEGRA_MAP_MUXCONF("irtx", "uartb", up, tristate), | ||
55 | TEGRA_MAP_MUXCONF("kbca", "kbc", up, tristate), | ||
56 | TEGRA_MAP_MUXCONF("kbcb", "kbc", up, tristate), | ||
57 | TEGRA_MAP_MUXCONF("kbcc", "kbc", up, tristate), | ||
58 | TEGRA_MAP_MUXCONF("kbcd", "kbc", up, tristate), | ||
59 | TEGRA_MAP_MUXCONF("kbce", "kbc", up, tristate), | ||
60 | TEGRA_MAP_MUXCONF("kbcf", "kbc", up, tristate), | ||
61 | TEGRA_MAP_MUXCONF("lcsn", "displaya", na, tristate), | ||
62 | TEGRA_MAP_MUXCONF("ld0", "displaya", na, driven), | ||
63 | TEGRA_MAP_MUXCONF("ld1", "displaya", na, driven), | ||
64 | TEGRA_MAP_MUXCONF("ld10", "displaya", na, driven), | ||
65 | TEGRA_MAP_MUXCONF("ld11", "displaya", na, driven), | ||
66 | TEGRA_MAP_MUXCONF("ld12", "displaya", na, driven), | ||
67 | TEGRA_MAP_MUXCONF("ld13", "displaya", na, driven), | ||
68 | TEGRA_MAP_MUXCONF("ld14", "displaya", na, driven), | ||
69 | TEGRA_MAP_MUXCONF("ld15", "displaya", na, driven), | ||
70 | TEGRA_MAP_MUXCONF("ld16", "displaya", na, driven), | ||
71 | TEGRA_MAP_MUXCONF("ld17", "displaya", na, driven), | ||
72 | TEGRA_MAP_MUXCONF("ld2", "displaya", na, driven), | ||
73 | TEGRA_MAP_MUXCONF("ld3", "displaya", na, driven), | ||
74 | TEGRA_MAP_MUXCONF("ld4", "displaya", na, driven), | ||
75 | TEGRA_MAP_MUXCONF("ld5", "displaya", na, driven), | ||
76 | TEGRA_MAP_MUXCONF("ld6", "displaya", na, driven), | ||
77 | TEGRA_MAP_MUXCONF("ld7", "displaya", na, driven), | ||
78 | TEGRA_MAP_MUXCONF("ld8", "displaya", na, driven), | ||
79 | TEGRA_MAP_MUXCONF("ld9", "displaya", na, driven), | ||
80 | TEGRA_MAP_MUXCONF("ldc", "displaya", na, tristate), | ||
81 | TEGRA_MAP_MUXCONF("ldi", "displaya", na, driven), | ||
82 | TEGRA_MAP_MUXCONF("lhp0", "displaya", na, driven), | ||
83 | TEGRA_MAP_MUXCONF("lhp1", "displaya", na, driven), | ||
84 | TEGRA_MAP_MUXCONF("lhp2", "displaya", na, driven), | ||
85 | TEGRA_MAP_MUXCONF("lhs", "displaya", na, driven), | ||
86 | TEGRA_MAP_MUXCONF("lm0", "displaya", na, driven), | ||
87 | TEGRA_MAP_MUXCONF("lm1", "displaya", na, tristate), | ||
88 | TEGRA_MAP_MUXCONF("lpp", "displaya", na, driven), | ||
89 | TEGRA_MAP_MUXCONF("lpw0", "displaya", na, driven), | ||
90 | TEGRA_MAP_MUXCONF("lpw1", "displaya", na, tristate), | ||
91 | TEGRA_MAP_MUXCONF("lpw2", "displaya", na, driven), | ||
92 | TEGRA_MAP_MUXCONF("lsc0", "displaya", na, driven), | ||
93 | TEGRA_MAP_MUXCONF("lsc1", "displaya", na, tristate), | ||
94 | TEGRA_MAP_MUXCONF("lsck", "displaya", na, tristate), | ||
95 | TEGRA_MAP_MUXCONF("lsda", "displaya", na, tristate), | ||
96 | TEGRA_MAP_MUXCONF("lsdi", "displaya", na, tristate), | ||
97 | TEGRA_MAP_MUXCONF("lspi", "displaya", na, driven), | ||
98 | TEGRA_MAP_MUXCONF("lvp0", "displaya", na, tristate), | ||
99 | TEGRA_MAP_MUXCONF("lvp1", "displaya", na, driven), | ||
100 | TEGRA_MAP_MUXCONF("lvs", "displaya", na, driven), | ||
101 | TEGRA_MAP_MUXCONF("owc", "rsvd2", up, tristate), | ||
102 | TEGRA_MAP_MUXCONF("pmc", "pwr_on", na, tristate), | ||
103 | TEGRA_MAP_MUXCONF("pta", "gmi", none, tristate), | ||
104 | TEGRA_MAP_MUXCONF("rm", "i2c1", up, driven), | ||
105 | TEGRA_MAP_MUXCONF("sdb", "pwm", na, driven), | ||
106 | TEGRA_MAP_MUXCONF("sdc", "pwm", up, driven), | ||
107 | TEGRA_MAP_MUXCONF("sdd", "pwm", up, driven), | ||
108 | TEGRA_MAP_MUXCONF("sdio1", "sdio1", none, driven), | ||
109 | TEGRA_MAP_MUXCONF("slxa", "pcie", none, driven), | ||
110 | TEGRA_MAP_MUXCONF("slxc", "sdio3", none, tristate), | ||
111 | TEGRA_MAP_MUXCONF("slxd", "sdio3", none, tristate), | ||
112 | TEGRA_MAP_MUXCONF("slxk", "pcie", none, driven), | ||
113 | TEGRA_MAP_MUXCONF("spdi", "spdif", none, tristate), | ||
114 | TEGRA_MAP_MUXCONF("spdo", "spdif", none, tristate), | ||
115 | TEGRA_MAP_MUXCONF("spia", "spi2", down, tristate), | ||
116 | TEGRA_MAP_MUXCONF("spib", "spi2", down, tristate), | ||
117 | TEGRA_MAP_MUXCONF("spic", "spi2", up, tristate), | ||
118 | TEGRA_MAP_MUXCONF("spid", "spi1", down, tristate), | ||
119 | TEGRA_MAP_MUXCONF("spie", "spi1", up, tristate), | ||
120 | TEGRA_MAP_MUXCONF("spif", "spi1", down, tristate), | ||
121 | TEGRA_MAP_MUXCONF("spig", "spi2_alt", up, tristate), | ||
122 | TEGRA_MAP_MUXCONF("spih", "spi2_alt", up, tristate), | ||
123 | TEGRA_MAP_MUXCONF("uaa", "ulpi", up, tristate), | ||
124 | TEGRA_MAP_MUXCONF("uab", "ulpi", up, tristate), | ||
125 | TEGRA_MAP_MUXCONF("uac", "rsvd2", none, driven), | ||
126 | TEGRA_MAP_MUXCONF("uad", "irda", up, tristate), | ||
127 | TEGRA_MAP_MUXCONF("uca", "uartc", up, tristate), | ||
128 | TEGRA_MAP_MUXCONF("ucb", "uartc", up, tristate), | ||
129 | TEGRA_MAP_MUXCONF("uda", "ulpi", none, tristate), | ||
130 | TEGRA_MAP_CONF("ck32", none, na), | ||
131 | TEGRA_MAP_CONF("ddrc", none, na), | ||
132 | TEGRA_MAP_CONF("pmca", none, na), | ||
133 | TEGRA_MAP_CONF("pmcb", none, na), | ||
134 | TEGRA_MAP_CONF("pmcc", none, na), | ||
135 | TEGRA_MAP_CONF("pmcd", none, na), | ||
136 | TEGRA_MAP_CONF("pmce", none, na), | ||
137 | TEGRA_MAP_CONF("xm2c", none, na), | ||
138 | TEGRA_MAP_CONF("xm2d", none, na), | ||
139 | TEGRA_MAP_CONF("ls", up, na), | ||
140 | TEGRA_MAP_CONF("lc", up, na), | ||
141 | TEGRA_MAP_CONF("ld17_0", down, na), | ||
142 | TEGRA_MAP_CONF("ld19_18", down, na), | ||
143 | TEGRA_MAP_CONF("ld21_20", down, na), | ||
144 | TEGRA_MAP_CONF("ld23_22", down, na), | ||
145 | }; | ||
146 | |||
147 | static struct tegra_board_pinmux_conf conf = { | ||
148 | .maps = trimslice_map, | ||
149 | .map_count = ARRAY_SIZE(trimslice_map), | ||
150 | }; | ||
151 | |||
152 | void trimslice_pinmux_init(void) | ||
153 | { | ||
154 | tegra_board_pinmux_init(&conf, NULL); | ||
155 | } | ||
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c deleted file mode 100644 index 776aa9564d5d..000000000000 --- a/arch/arm/mach-tegra/board-trimslice.c +++ /dev/null | |||
@@ -1,183 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-trimslice.c | ||
3 | * | ||
4 | * Copyright (C) 2011 CompuLab, Ltd. | ||
5 | * Author: Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * Based on board-harmony.c | ||
8 | * Copyright (C) 2010 Google, Inc. | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/serial_8250.h> | ||
25 | #include <linux/of_serial.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/gpio.h> | ||
29 | #include <linux/platform_data/tegra_usb.h> | ||
30 | |||
31 | #include <asm/hardware/gic.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/setup.h> | ||
35 | |||
36 | #include <mach/iomap.h> | ||
37 | #include <mach/sdhci.h> | ||
38 | |||
39 | #include "board.h" | ||
40 | #include "clock.h" | ||
41 | #include "devices.h" | ||
42 | #include "gpio-names.h" | ||
43 | |||
44 | #include "board-trimslice.h" | ||
45 | |||
46 | static struct plat_serial8250_port debug_uart_platform_data[] = { | ||
47 | { | ||
48 | .membase = IO_ADDRESS(TEGRA_UARTA_BASE), | ||
49 | .mapbase = TEGRA_UARTA_BASE, | ||
50 | .irq = INT_UARTA, | ||
51 | .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, | ||
52 | .type = PORT_TEGRA, | ||
53 | .handle_break = tegra_serial_handle_break, | ||
54 | .iotype = UPIO_MEM, | ||
55 | .regshift = 2, | ||
56 | .uartclk = 216000000, | ||
57 | }, { | ||
58 | .flags = 0 | ||
59 | } | ||
60 | }; | ||
61 | |||
62 | static struct platform_device debug_uart = { | ||
63 | .name = "serial8250", | ||
64 | .id = PLAT8250_DEV_PLATFORM, | ||
65 | .dev = { | ||
66 | .platform_data = debug_uart_platform_data, | ||
67 | }, | ||
68 | }; | ||
69 | static struct tegra_sdhci_platform_data sdhci_pdata1 = { | ||
70 | .cd_gpio = -1, | ||
71 | .wp_gpio = -1, | ||
72 | .power_gpio = -1, | ||
73 | }; | ||
74 | |||
75 | static struct tegra_sdhci_platform_data sdhci_pdata4 = { | ||
76 | .cd_gpio = TRIMSLICE_GPIO_SD4_CD, | ||
77 | .wp_gpio = TRIMSLICE_GPIO_SD4_WP, | ||
78 | .power_gpio = -1, | ||
79 | }; | ||
80 | |||
81 | static struct platform_device trimslice_audio_device = { | ||
82 | .name = "tegra-snd-trimslice", | ||
83 | .id = 0, | ||
84 | }; | ||
85 | |||
86 | static struct platform_device *trimslice_devices[] __initdata = { | ||
87 | &debug_uart, | ||
88 | &tegra_sdhci_device1, | ||
89 | &tegra_sdhci_device4, | ||
90 | &tegra_i2s_device1, | ||
91 | &tegra_das_device, | ||
92 | &trimslice_audio_device, | ||
93 | }; | ||
94 | |||
95 | static struct i2c_board_info trimslice_i2c3_board_info[] = { | ||
96 | { | ||
97 | I2C_BOARD_INFO("tlv320aic23", 0x1a), | ||
98 | }, | ||
99 | { | ||
100 | I2C_BOARD_INFO("em3027", 0x56), | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static void trimslice_i2c_init(void) | ||
105 | { | ||
106 | platform_device_register(&tegra_i2c_device1); | ||
107 | platform_device_register(&tegra_i2c_device2); | ||
108 | platform_device_register(&tegra_i2c_device3); | ||
109 | |||
110 | i2c_register_board_info(2, trimslice_i2c3_board_info, | ||
111 | ARRAY_SIZE(trimslice_i2c3_board_info)); | ||
112 | } | ||
113 | |||
114 | static void trimslice_usb_init(void) | ||
115 | { | ||
116 | struct tegra_ehci_platform_data *pdata; | ||
117 | |||
118 | pdata = tegra_ehci1_device.dev.platform_data; | ||
119 | pdata->vbus_gpio = TRIMSLICE_GPIO_USB1_MODE; | ||
120 | |||
121 | tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_GPIO_PV0; | ||
122 | |||
123 | platform_device_register(&tegra_ehci3_device); | ||
124 | platform_device_register(&tegra_ehci2_device); | ||
125 | platform_device_register(&tegra_ehci1_device); | ||
126 | } | ||
127 | |||
128 | static void __init tegra_trimslice_fixup(struct tag *tags, char **cmdline, | ||
129 | struct meminfo *mi) | ||
130 | { | ||
131 | mi->nr_banks = 2; | ||
132 | mi->bank[0].start = PHYS_OFFSET; | ||
133 | mi->bank[0].size = 448 * SZ_1M; | ||
134 | mi->bank[1].start = SZ_512M; | ||
135 | mi->bank[1].size = SZ_512M; | ||
136 | } | ||
137 | |||
138 | static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = { | ||
139 | /* name parent rate enabled */ | ||
140 | { "uarta", "pll_p", 216000000, true }, | ||
141 | { "pll_a", "pll_p_out1", 56448000, true }, | ||
142 | { "pll_a_out0", "pll_a", 11289600, true }, | ||
143 | { "cdev1", NULL, 0, true }, | ||
144 | { "i2s1", "pll_a_out0", 11289600, false}, | ||
145 | { NULL, NULL, 0, 0}, | ||
146 | }; | ||
147 | |||
148 | static int __init tegra_trimslice_pci_init(void) | ||
149 | { | ||
150 | if (!machine_is_trimslice()) | ||
151 | return 0; | ||
152 | |||
153 | return tegra_pcie_init(true, true); | ||
154 | } | ||
155 | subsys_initcall(tegra_trimslice_pci_init); | ||
156 | |||
157 | static void __init tegra_trimslice_init(void) | ||
158 | { | ||
159 | tegra_clk_init_from_table(trimslice_clk_init_table); | ||
160 | |||
161 | trimslice_pinmux_init(); | ||
162 | |||
163 | tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; | ||
164 | tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; | ||
165 | |||
166 | platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices)); | ||
167 | |||
168 | trimslice_i2c_init(); | ||
169 | trimslice_usb_init(); | ||
170 | } | ||
171 | |||
172 | MACHINE_START(TRIMSLICE, "trimslice") | ||
173 | .atag_offset = 0x100, | ||
174 | .fixup = tegra_trimslice_fixup, | ||
175 | .map_io = tegra_map_common_io, | ||
176 | .init_early = tegra20_init_early, | ||
177 | .init_irq = tegra_init_irq, | ||
178 | .handle_irq = gic_handle_irq, | ||
179 | .timer = &tegra_timer, | ||
180 | .init_machine = tegra_trimslice_init, | ||
181 | .init_late = tegra_init_late, | ||
182 | .restart = tegra_assert_system_reset, | ||
183 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h deleted file mode 100644 index 50f128d87779..000000000000 --- a/arch/arm/mach-tegra/board-trimslice.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-trimslice.h | ||
3 | * | ||
4 | * Copyright (C) 2011 CompuLab, Ltd. | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #ifndef _MACH_TEGRA_BOARD_TRIMSLICE_H | ||
18 | #define _MACH_TEGRA_BOARD_TRIMSLICE_H | ||
19 | |||
20 | #include <mach/gpio-tegra.h> | ||
21 | |||
22 | #define TRIMSLICE_GPIO_SD4_CD TEGRA_GPIO_PP1 /* mmc4 cd */ | ||
23 | #define TRIMSLICE_GPIO_SD4_WP TEGRA_GPIO_PP2 /* mmc4 wp */ | ||
24 | |||
25 | #define TRIMSLICE_GPIO_USB1_MODE TEGRA_GPIO_PV2 /* USB1 mode */ | ||
26 | #define TRIMSLICE_GPIO_USB2_RST TEGRA_GPIO_PV0 /* USB2 PHY reset */ | ||
27 | |||
28 | void trimslice_pinmux_init(void); | ||
29 | |||
30 | #endif | ||
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c deleted file mode 100644 index 29c5114d607c..000000000000 --- a/arch/arm/mach-tegra/dma.c +++ /dev/null | |||
@@ -1,823 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/dma.c | ||
3 | * | ||
4 | * System DMA driver for NVIDIA Tegra SoCs | ||
5 | * | ||
6 | * Copyright (c) 2008-2009, NVIDIA Corporation. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/io.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <mach/dma.h> | ||
32 | #include <mach/irqs.h> | ||
33 | #include <mach/iomap.h> | ||
34 | #include <mach/suspend.h> | ||
35 | |||
36 | #include "apbio.h" | ||
37 | |||
38 | #define APB_DMA_GEN 0x000 | ||
39 | #define GEN_ENABLE (1<<31) | ||
40 | |||
41 | #define APB_DMA_CNTRL 0x010 | ||
42 | |||
43 | #define APB_DMA_IRQ_MASK 0x01c | ||
44 | |||
45 | #define APB_DMA_IRQ_MASK_SET 0x020 | ||
46 | |||
47 | #define APB_DMA_CHAN_CSR 0x000 | ||
48 | #define CSR_ENB (1<<31) | ||
49 | #define CSR_IE_EOC (1<<30) | ||
50 | #define CSR_HOLD (1<<29) | ||
51 | #define CSR_DIR (1<<28) | ||
52 | #define CSR_ONCE (1<<27) | ||
53 | #define CSR_FLOW (1<<21) | ||
54 | #define CSR_REQ_SEL_SHIFT 16 | ||
55 | #define CSR_WCOUNT_SHIFT 2 | ||
56 | #define CSR_WCOUNT_MASK 0xFFFC | ||
57 | |||
58 | #define APB_DMA_CHAN_STA 0x004 | ||
59 | #define STA_BUSY (1<<31) | ||
60 | #define STA_ISE_EOC (1<<30) | ||
61 | #define STA_HALT (1<<29) | ||
62 | #define STA_PING_PONG (1<<28) | ||
63 | #define STA_COUNT_SHIFT 2 | ||
64 | #define STA_COUNT_MASK 0xFFFC | ||
65 | |||
66 | #define APB_DMA_CHAN_AHB_PTR 0x010 | ||
67 | |||
68 | #define APB_DMA_CHAN_AHB_SEQ 0x014 | ||
69 | #define AHB_SEQ_INTR_ENB (1<<31) | ||
70 | #define AHB_SEQ_BUS_WIDTH_SHIFT 28 | ||
71 | #define AHB_SEQ_BUS_WIDTH_MASK (0x7<<AHB_SEQ_BUS_WIDTH_SHIFT) | ||
72 | #define AHB_SEQ_BUS_WIDTH_8 (0<<AHB_SEQ_BUS_WIDTH_SHIFT) | ||
73 | #define AHB_SEQ_BUS_WIDTH_16 (1<<AHB_SEQ_BUS_WIDTH_SHIFT) | ||
74 | #define AHB_SEQ_BUS_WIDTH_32 (2<<AHB_SEQ_BUS_WIDTH_SHIFT) | ||
75 | #define AHB_SEQ_BUS_WIDTH_64 (3<<AHB_SEQ_BUS_WIDTH_SHIFT) | ||
76 | #define AHB_SEQ_BUS_WIDTH_128 (4<<AHB_SEQ_BUS_WIDTH_SHIFT) | ||
77 | #define AHB_SEQ_DATA_SWAP (1<<27) | ||
78 | #define AHB_SEQ_BURST_MASK (0x7<<24) | ||
79 | #define AHB_SEQ_BURST_1 (4<<24) | ||
80 | #define AHB_SEQ_BURST_4 (5<<24) | ||
81 | #define AHB_SEQ_BURST_8 (6<<24) | ||
82 | #define AHB_SEQ_DBL_BUF (1<<19) | ||
83 | #define AHB_SEQ_WRAP_SHIFT 16 | ||
84 | #define AHB_SEQ_WRAP_MASK (0x7<<AHB_SEQ_WRAP_SHIFT) | ||
85 | |||
86 | #define APB_DMA_CHAN_APB_PTR 0x018 | ||
87 | |||
88 | #define APB_DMA_CHAN_APB_SEQ 0x01c | ||
89 | #define APB_SEQ_BUS_WIDTH_SHIFT 28 | ||
90 | #define APB_SEQ_BUS_WIDTH_MASK (0x7<<APB_SEQ_BUS_WIDTH_SHIFT) | ||
91 | #define APB_SEQ_BUS_WIDTH_8 (0<<APB_SEQ_BUS_WIDTH_SHIFT) | ||
92 | #define APB_SEQ_BUS_WIDTH_16 (1<<APB_SEQ_BUS_WIDTH_SHIFT) | ||
93 | #define APB_SEQ_BUS_WIDTH_32 (2<<APB_SEQ_BUS_WIDTH_SHIFT) | ||
94 | #define APB_SEQ_BUS_WIDTH_64 (3<<APB_SEQ_BUS_WIDTH_SHIFT) | ||
95 | #define APB_SEQ_BUS_WIDTH_128 (4<<APB_SEQ_BUS_WIDTH_SHIFT) | ||
96 | #define APB_SEQ_DATA_SWAP (1<<27) | ||
97 | #define APB_SEQ_WRAP_SHIFT 16 | ||
98 | #define APB_SEQ_WRAP_MASK (0x7<<APB_SEQ_WRAP_SHIFT) | ||
99 | |||
100 | #define TEGRA_SYSTEM_DMA_CH_NR 16 | ||
101 | #define TEGRA_SYSTEM_DMA_AVP_CH_NUM 4 | ||
102 | #define TEGRA_SYSTEM_DMA_CH_MIN 0 | ||
103 | #define TEGRA_SYSTEM_DMA_CH_MAX \ | ||
104 | (TEGRA_SYSTEM_DMA_CH_NR - TEGRA_SYSTEM_DMA_AVP_CH_NUM - 1) | ||
105 | |||
106 | #define NV_DMA_MAX_TRASFER_SIZE 0x10000 | ||
107 | |||
108 | static const unsigned int ahb_addr_wrap_table[8] = { | ||
109 | 0, 32, 64, 128, 256, 512, 1024, 2048 | ||
110 | }; | ||
111 | |||
112 | static const unsigned int apb_addr_wrap_table[8] = { | ||
113 | 0, 1, 2, 4, 8, 16, 32, 64 | ||
114 | }; | ||
115 | |||
116 | static const unsigned int bus_width_table[5] = { | ||
117 | 8, 16, 32, 64, 128 | ||
118 | }; | ||
119 | |||
120 | #define TEGRA_DMA_NAME_SIZE 16 | ||
121 | struct tegra_dma_channel { | ||
122 | struct list_head list; | ||
123 | int id; | ||
124 | spinlock_t lock; | ||
125 | char name[TEGRA_DMA_NAME_SIZE]; | ||
126 | void __iomem *addr; | ||
127 | int mode; | ||
128 | int irq; | ||
129 | int req_transfer_count; | ||
130 | }; | ||
131 | |||
132 | #define NV_DMA_MAX_CHANNELS 32 | ||
133 | |||
134 | static bool tegra_dma_initialized; | ||
135 | static DEFINE_MUTEX(tegra_dma_lock); | ||
136 | static DEFINE_SPINLOCK(enable_lock); | ||
137 | |||
138 | static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS); | ||
139 | static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS]; | ||
140 | |||
141 | static void tegra_dma_update_hw(struct tegra_dma_channel *ch, | ||
142 | struct tegra_dma_req *req); | ||
143 | static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch, | ||
144 | struct tegra_dma_req *req); | ||
145 | static void tegra_dma_stop(struct tegra_dma_channel *ch); | ||
146 | |||
147 | void tegra_dma_flush(struct tegra_dma_channel *ch) | ||
148 | { | ||
149 | } | ||
150 | EXPORT_SYMBOL(tegra_dma_flush); | ||
151 | |||
152 | void tegra_dma_dequeue(struct tegra_dma_channel *ch) | ||
153 | { | ||
154 | struct tegra_dma_req *req; | ||
155 | |||
156 | if (tegra_dma_is_empty(ch)) | ||
157 | return; | ||
158 | |||
159 | req = list_entry(ch->list.next, typeof(*req), node); | ||
160 | |||
161 | tegra_dma_dequeue_req(ch, req); | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | static void tegra_dma_stop(struct tegra_dma_channel *ch) | ||
166 | { | ||
167 | u32 csr; | ||
168 | u32 status; | ||
169 | |||
170 | csr = readl(ch->addr + APB_DMA_CHAN_CSR); | ||
171 | csr &= ~CSR_IE_EOC; | ||
172 | writel(csr, ch->addr + APB_DMA_CHAN_CSR); | ||
173 | |||
174 | csr &= ~CSR_ENB; | ||
175 | writel(csr, ch->addr + APB_DMA_CHAN_CSR); | ||
176 | |||
177 | status = readl(ch->addr + APB_DMA_CHAN_STA); | ||
178 | if (status & STA_ISE_EOC) | ||
179 | writel(status, ch->addr + APB_DMA_CHAN_STA); | ||
180 | } | ||
181 | |||
182 | static int tegra_dma_cancel(struct tegra_dma_channel *ch) | ||
183 | { | ||
184 | unsigned long irq_flags; | ||
185 | |||
186 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
187 | while (!list_empty(&ch->list)) | ||
188 | list_del(ch->list.next); | ||
189 | |||
190 | tegra_dma_stop(ch); | ||
191 | |||
192 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static unsigned int get_channel_status(struct tegra_dma_channel *ch, | ||
197 | struct tegra_dma_req *req, bool is_stop_dma) | ||
198 | { | ||
199 | void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); | ||
200 | unsigned int status; | ||
201 | |||
202 | if (is_stop_dma) { | ||
203 | /* | ||
204 | * STOP the DMA and get the transfer count. | ||
205 | * Getting the transfer count is tricky. | ||
206 | * - Globally disable DMA on all channels | ||
207 | * - Read the channel's status register to know the number | ||
208 | * of pending bytes to be transfered. | ||
209 | * - Stop the dma channel | ||
210 | * - Globally re-enable DMA to resume other transfers | ||
211 | */ | ||
212 | spin_lock(&enable_lock); | ||
213 | writel(0, addr + APB_DMA_GEN); | ||
214 | udelay(20); | ||
215 | status = readl(ch->addr + APB_DMA_CHAN_STA); | ||
216 | tegra_dma_stop(ch); | ||
217 | writel(GEN_ENABLE, addr + APB_DMA_GEN); | ||
218 | spin_unlock(&enable_lock); | ||
219 | if (status & STA_ISE_EOC) { | ||
220 | pr_err("Got Dma Int here clearing"); | ||
221 | writel(status, ch->addr + APB_DMA_CHAN_STA); | ||
222 | } | ||
223 | req->status = TEGRA_DMA_REQ_ERROR_ABORTED; | ||
224 | } else { | ||
225 | status = readl(ch->addr + APB_DMA_CHAN_STA); | ||
226 | } | ||
227 | return status; | ||
228 | } | ||
229 | |||
230 | /* should be called with the channel lock held */ | ||
231 | static unsigned int dma_active_count(struct tegra_dma_channel *ch, | ||
232 | struct tegra_dma_req *req, unsigned int status) | ||
233 | { | ||
234 | unsigned int to_transfer; | ||
235 | unsigned int req_transfer_count; | ||
236 | unsigned int bytes_transferred; | ||
237 | |||
238 | to_transfer = ((status & STA_COUNT_MASK) >> STA_COUNT_SHIFT) + 1; | ||
239 | req_transfer_count = ch->req_transfer_count + 1; | ||
240 | bytes_transferred = req_transfer_count; | ||
241 | if (status & STA_BUSY) | ||
242 | bytes_transferred -= to_transfer; | ||
243 | /* | ||
244 | * In continuous transfer mode, DMA only tracks the count of the | ||
245 | * half DMA buffer. So, if the DMA already finished half the DMA | ||
246 | * then add the half buffer to the completed count. | ||
247 | */ | ||
248 | if (ch->mode & TEGRA_DMA_MODE_CONTINOUS) { | ||
249 | if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) | ||
250 | bytes_transferred += req_transfer_count; | ||
251 | if (status & STA_ISE_EOC) | ||
252 | bytes_transferred += req_transfer_count; | ||
253 | } | ||
254 | bytes_transferred *= 4; | ||
255 | return bytes_transferred; | ||
256 | } | ||
257 | |||
258 | int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, | ||
259 | struct tegra_dma_req *_req) | ||
260 | { | ||
261 | unsigned int status; | ||
262 | struct tegra_dma_req *req = NULL; | ||
263 | int found = 0; | ||
264 | unsigned long irq_flags; | ||
265 | int stop = 0; | ||
266 | |||
267 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
268 | |||
269 | if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req) | ||
270 | stop = 1; | ||
271 | |||
272 | list_for_each_entry(req, &ch->list, node) { | ||
273 | if (req == _req) { | ||
274 | list_del(&req->node); | ||
275 | found = 1; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | if (!found) { | ||
280 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | if (!stop) | ||
285 | goto skip_stop_dma; | ||
286 | |||
287 | status = get_channel_status(ch, req, true); | ||
288 | req->bytes_transferred = dma_active_count(ch, req, status); | ||
289 | |||
290 | if (!list_empty(&ch->list)) { | ||
291 | /* if the list is not empty, queue the next request */ | ||
292 | struct tegra_dma_req *next_req; | ||
293 | next_req = list_entry(ch->list.next, | ||
294 | typeof(*next_req), node); | ||
295 | tegra_dma_update_hw(ch, next_req); | ||
296 | } | ||
297 | |||
298 | skip_stop_dma: | ||
299 | req->status = -TEGRA_DMA_REQ_ERROR_ABORTED; | ||
300 | |||
301 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
302 | |||
303 | /* Callback should be called without any lock */ | ||
304 | req->complete(req); | ||
305 | return 0; | ||
306 | } | ||
307 | EXPORT_SYMBOL(tegra_dma_dequeue_req); | ||
308 | |||
309 | bool tegra_dma_is_empty(struct tegra_dma_channel *ch) | ||
310 | { | ||
311 | unsigned long irq_flags; | ||
312 | bool is_empty; | ||
313 | |||
314 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
315 | if (list_empty(&ch->list)) | ||
316 | is_empty = true; | ||
317 | else | ||
318 | is_empty = false; | ||
319 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
320 | return is_empty; | ||
321 | } | ||
322 | EXPORT_SYMBOL(tegra_dma_is_empty); | ||
323 | |||
324 | bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch, | ||
325 | struct tegra_dma_req *_req) | ||
326 | { | ||
327 | unsigned long irq_flags; | ||
328 | struct tegra_dma_req *req; | ||
329 | |||
330 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
331 | list_for_each_entry(req, &ch->list, node) { | ||
332 | if (req == _req) { | ||
333 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
334 | return true; | ||
335 | } | ||
336 | } | ||
337 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
338 | return false; | ||
339 | } | ||
340 | EXPORT_SYMBOL(tegra_dma_is_req_inflight); | ||
341 | |||
342 | int tegra_dma_enqueue_req(struct tegra_dma_channel *ch, | ||
343 | struct tegra_dma_req *req) | ||
344 | { | ||
345 | unsigned long irq_flags; | ||
346 | struct tegra_dma_req *_req; | ||
347 | int start_dma = 0; | ||
348 | |||
349 | if (req->size > NV_DMA_MAX_TRASFER_SIZE || | ||
350 | req->source_addr & 0x3 || req->dest_addr & 0x3) { | ||
351 | pr_err("Invalid DMA request for channel %d\n", ch->id); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
356 | |||
357 | list_for_each_entry(_req, &ch->list, node) { | ||
358 | if (req == _req) { | ||
359 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
360 | return -EEXIST; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | req->bytes_transferred = 0; | ||
365 | req->status = 0; | ||
366 | req->buffer_status = 0; | ||
367 | if (list_empty(&ch->list)) | ||
368 | start_dma = 1; | ||
369 | |||
370 | list_add_tail(&req->node, &ch->list); | ||
371 | |||
372 | if (start_dma) | ||
373 | tegra_dma_update_hw(ch, req); | ||
374 | |||
375 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | EXPORT_SYMBOL(tegra_dma_enqueue_req); | ||
380 | |||
381 | struct tegra_dma_channel *tegra_dma_allocate_channel(int mode) | ||
382 | { | ||
383 | int channel; | ||
384 | struct tegra_dma_channel *ch = NULL; | ||
385 | |||
386 | if (!tegra_dma_initialized) | ||
387 | return NULL; | ||
388 | |||
389 | mutex_lock(&tegra_dma_lock); | ||
390 | |||
391 | /* first channel is the shared channel */ | ||
392 | if (mode & TEGRA_DMA_SHARED) { | ||
393 | channel = TEGRA_SYSTEM_DMA_CH_MIN; | ||
394 | } else { | ||
395 | channel = find_first_zero_bit(channel_usage, | ||
396 | ARRAY_SIZE(dma_channels)); | ||
397 | if (channel >= ARRAY_SIZE(dma_channels)) | ||
398 | goto out; | ||
399 | } | ||
400 | __set_bit(channel, channel_usage); | ||
401 | ch = &dma_channels[channel]; | ||
402 | ch->mode = mode; | ||
403 | |||
404 | out: | ||
405 | mutex_unlock(&tegra_dma_lock); | ||
406 | return ch; | ||
407 | } | ||
408 | EXPORT_SYMBOL(tegra_dma_allocate_channel); | ||
409 | |||
410 | void tegra_dma_free_channel(struct tegra_dma_channel *ch) | ||
411 | { | ||
412 | if (ch->mode & TEGRA_DMA_SHARED) | ||
413 | return; | ||
414 | tegra_dma_cancel(ch); | ||
415 | mutex_lock(&tegra_dma_lock); | ||
416 | __clear_bit(ch->id, channel_usage); | ||
417 | mutex_unlock(&tegra_dma_lock); | ||
418 | } | ||
419 | EXPORT_SYMBOL(tegra_dma_free_channel); | ||
420 | |||
421 | static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch, | ||
422 | struct tegra_dma_req *req) | ||
423 | { | ||
424 | u32 apb_ptr; | ||
425 | u32 ahb_ptr; | ||
426 | |||
427 | if (req->to_memory) { | ||
428 | apb_ptr = req->source_addr; | ||
429 | ahb_ptr = req->dest_addr; | ||
430 | } else { | ||
431 | apb_ptr = req->dest_addr; | ||
432 | ahb_ptr = req->source_addr; | ||
433 | } | ||
434 | writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR); | ||
435 | writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR); | ||
436 | |||
437 | req->status = TEGRA_DMA_REQ_INFLIGHT; | ||
438 | return; | ||
439 | } | ||
440 | |||
441 | static void tegra_dma_update_hw(struct tegra_dma_channel *ch, | ||
442 | struct tegra_dma_req *req) | ||
443 | { | ||
444 | int ahb_addr_wrap; | ||
445 | int apb_addr_wrap; | ||
446 | int ahb_bus_width; | ||
447 | int apb_bus_width; | ||
448 | int index; | ||
449 | |||
450 | u32 ahb_seq; | ||
451 | u32 apb_seq; | ||
452 | u32 ahb_ptr; | ||
453 | u32 apb_ptr; | ||
454 | u32 csr; | ||
455 | |||
456 | csr = CSR_IE_EOC | CSR_FLOW; | ||
457 | ahb_seq = AHB_SEQ_INTR_ENB | AHB_SEQ_BURST_1; | ||
458 | apb_seq = 0; | ||
459 | |||
460 | csr |= req->req_sel << CSR_REQ_SEL_SHIFT; | ||
461 | |||
462 | /* One shot mode is always single buffered, | ||
463 | * continuous mode is always double buffered | ||
464 | * */ | ||
465 | if (ch->mode & TEGRA_DMA_MODE_ONESHOT) { | ||
466 | csr |= CSR_ONCE; | ||
467 | ch->req_transfer_count = (req->size >> 2) - 1; | ||
468 | } else { | ||
469 | ahb_seq |= AHB_SEQ_DBL_BUF; | ||
470 | |||
471 | /* In double buffered mode, we set the size to half the | ||
472 | * requested size and interrupt when half the buffer | ||
473 | * is full */ | ||
474 | ch->req_transfer_count = (req->size >> 3) - 1; | ||
475 | } | ||
476 | |||
477 | csr |= ch->req_transfer_count << CSR_WCOUNT_SHIFT; | ||
478 | |||
479 | if (req->to_memory) { | ||
480 | apb_ptr = req->source_addr; | ||
481 | ahb_ptr = req->dest_addr; | ||
482 | |||
483 | apb_addr_wrap = req->source_wrap; | ||
484 | ahb_addr_wrap = req->dest_wrap; | ||
485 | apb_bus_width = req->source_bus_width; | ||
486 | ahb_bus_width = req->dest_bus_width; | ||
487 | |||
488 | } else { | ||
489 | csr |= CSR_DIR; | ||
490 | apb_ptr = req->dest_addr; | ||
491 | ahb_ptr = req->source_addr; | ||
492 | |||
493 | apb_addr_wrap = req->dest_wrap; | ||
494 | ahb_addr_wrap = req->source_wrap; | ||
495 | apb_bus_width = req->dest_bus_width; | ||
496 | ahb_bus_width = req->source_bus_width; | ||
497 | } | ||
498 | |||
499 | apb_addr_wrap >>= 2; | ||
500 | ahb_addr_wrap >>= 2; | ||
501 | |||
502 | /* set address wrap for APB size */ | ||
503 | index = 0; | ||
504 | do { | ||
505 | if (apb_addr_wrap_table[index] == apb_addr_wrap) | ||
506 | break; | ||
507 | index++; | ||
508 | } while (index < ARRAY_SIZE(apb_addr_wrap_table)); | ||
509 | BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table)); | ||
510 | apb_seq |= index << APB_SEQ_WRAP_SHIFT; | ||
511 | |||
512 | /* set address wrap for AHB size */ | ||
513 | index = 0; | ||
514 | do { | ||
515 | if (ahb_addr_wrap_table[index] == ahb_addr_wrap) | ||
516 | break; | ||
517 | index++; | ||
518 | } while (index < ARRAY_SIZE(ahb_addr_wrap_table)); | ||
519 | BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table)); | ||
520 | ahb_seq |= index << AHB_SEQ_WRAP_SHIFT; | ||
521 | |||
522 | for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) { | ||
523 | if (bus_width_table[index] == ahb_bus_width) | ||
524 | break; | ||
525 | } | ||
526 | BUG_ON(index == ARRAY_SIZE(bus_width_table)); | ||
527 | ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT; | ||
528 | |||
529 | for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) { | ||
530 | if (bus_width_table[index] == apb_bus_width) | ||
531 | break; | ||
532 | } | ||
533 | BUG_ON(index == ARRAY_SIZE(bus_width_table)); | ||
534 | apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT; | ||
535 | |||
536 | writel(csr, ch->addr + APB_DMA_CHAN_CSR); | ||
537 | writel(apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ); | ||
538 | writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR); | ||
539 | writel(ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ); | ||
540 | writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR); | ||
541 | |||
542 | csr |= CSR_ENB; | ||
543 | writel(csr, ch->addr + APB_DMA_CHAN_CSR); | ||
544 | |||
545 | req->status = TEGRA_DMA_REQ_INFLIGHT; | ||
546 | } | ||
547 | |||
548 | static void handle_oneshot_dma(struct tegra_dma_channel *ch) | ||
549 | { | ||
550 | struct tegra_dma_req *req; | ||
551 | unsigned long irq_flags; | ||
552 | |||
553 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
554 | if (list_empty(&ch->list)) { | ||
555 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
556 | return; | ||
557 | } | ||
558 | |||
559 | req = list_entry(ch->list.next, typeof(*req), node); | ||
560 | if (req) { | ||
561 | int bytes_transferred; | ||
562 | |||
563 | bytes_transferred = ch->req_transfer_count; | ||
564 | bytes_transferred += 1; | ||
565 | bytes_transferred <<= 2; | ||
566 | |||
567 | list_del(&req->node); | ||
568 | req->bytes_transferred = bytes_transferred; | ||
569 | req->status = TEGRA_DMA_REQ_SUCCESS; | ||
570 | |||
571 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
572 | /* Callback should be called without any lock */ | ||
573 | pr_debug("%s: transferred %d bytes\n", __func__, | ||
574 | req->bytes_transferred); | ||
575 | req->complete(req); | ||
576 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
577 | } | ||
578 | |||
579 | if (!list_empty(&ch->list)) { | ||
580 | req = list_entry(ch->list.next, typeof(*req), node); | ||
581 | /* the complete function we just called may have enqueued | ||
582 | another req, in which case dma has already started */ | ||
583 | if (req->status != TEGRA_DMA_REQ_INFLIGHT) | ||
584 | tegra_dma_update_hw(ch, req); | ||
585 | } | ||
586 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
587 | } | ||
588 | |||
589 | static void handle_continuous_dma(struct tegra_dma_channel *ch) | ||
590 | { | ||
591 | struct tegra_dma_req *req; | ||
592 | unsigned long irq_flags; | ||
593 | |||
594 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
595 | if (list_empty(&ch->list)) { | ||
596 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | req = list_entry(ch->list.next, typeof(*req), node); | ||
601 | if (req) { | ||
602 | if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) { | ||
603 | bool is_dma_ping_complete; | ||
604 | is_dma_ping_complete = (readl(ch->addr + APB_DMA_CHAN_STA) | ||
605 | & STA_PING_PONG) ? true : false; | ||
606 | if (req->to_memory) | ||
607 | is_dma_ping_complete = !is_dma_ping_complete; | ||
608 | /* Out of sync - Release current buffer */ | ||
609 | if (!is_dma_ping_complete) { | ||
610 | int bytes_transferred; | ||
611 | |||
612 | bytes_transferred = ch->req_transfer_count; | ||
613 | bytes_transferred += 1; | ||
614 | bytes_transferred <<= 3; | ||
615 | req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL; | ||
616 | req->bytes_transferred = bytes_transferred; | ||
617 | req->status = TEGRA_DMA_REQ_SUCCESS; | ||
618 | tegra_dma_stop(ch); | ||
619 | |||
620 | if (!list_is_last(&req->node, &ch->list)) { | ||
621 | struct tegra_dma_req *next_req; | ||
622 | |||
623 | next_req = list_entry(req->node.next, | ||
624 | typeof(*next_req), node); | ||
625 | tegra_dma_update_hw(ch, next_req); | ||
626 | } | ||
627 | |||
628 | list_del(&req->node); | ||
629 | |||
630 | /* DMA lock is NOT held when callbak is called */ | ||
631 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
632 | req->complete(req); | ||
633 | return; | ||
634 | } | ||
635 | /* Load the next request into the hardware, if available | ||
636 | * */ | ||
637 | if (!list_is_last(&req->node, &ch->list)) { | ||
638 | struct tegra_dma_req *next_req; | ||
639 | |||
640 | next_req = list_entry(req->node.next, | ||
641 | typeof(*next_req), node); | ||
642 | tegra_dma_update_hw_partial(ch, next_req); | ||
643 | } | ||
644 | req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL; | ||
645 | req->status = TEGRA_DMA_REQ_SUCCESS; | ||
646 | /* DMA lock is NOT held when callback is called */ | ||
647 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
648 | if (likely(req->threshold)) | ||
649 | req->threshold(req); | ||
650 | return; | ||
651 | |||
652 | } else if (req->buffer_status == | ||
653 | TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) { | ||
654 | /* Callback when the buffer is completely full (i.e on | ||
655 | * the second interrupt */ | ||
656 | int bytes_transferred; | ||
657 | |||
658 | bytes_transferred = ch->req_transfer_count; | ||
659 | bytes_transferred += 1; | ||
660 | bytes_transferred <<= 3; | ||
661 | |||
662 | req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL; | ||
663 | req->bytes_transferred = bytes_transferred; | ||
664 | req->status = TEGRA_DMA_REQ_SUCCESS; | ||
665 | list_del(&req->node); | ||
666 | |||
667 | /* DMA lock is NOT held when callbak is called */ | ||
668 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
669 | req->complete(req); | ||
670 | return; | ||
671 | |||
672 | } else { | ||
673 | BUG(); | ||
674 | } | ||
675 | } | ||
676 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
677 | } | ||
678 | |||
679 | static irqreturn_t dma_isr(int irq, void *data) | ||
680 | { | ||
681 | struct tegra_dma_channel *ch = data; | ||
682 | unsigned long status; | ||
683 | |||
684 | status = readl(ch->addr + APB_DMA_CHAN_STA); | ||
685 | if (status & STA_ISE_EOC) | ||
686 | writel(status, ch->addr + APB_DMA_CHAN_STA); | ||
687 | else { | ||
688 | pr_warning("Got a spurious ISR for DMA channel %d\n", ch->id); | ||
689 | return IRQ_HANDLED; | ||
690 | } | ||
691 | return IRQ_WAKE_THREAD; | ||
692 | } | ||
693 | |||
694 | static irqreturn_t dma_thread_fn(int irq, void *data) | ||
695 | { | ||
696 | struct tegra_dma_channel *ch = data; | ||
697 | |||
698 | if (ch->mode & TEGRA_DMA_MODE_ONESHOT) | ||
699 | handle_oneshot_dma(ch); | ||
700 | else | ||
701 | handle_continuous_dma(ch); | ||
702 | |||
703 | |||
704 | return IRQ_HANDLED; | ||
705 | } | ||
706 | |||
707 | int __init tegra_dma_init(void) | ||
708 | { | ||
709 | int ret = 0; | ||
710 | int i; | ||
711 | unsigned int irq; | ||
712 | void __iomem *addr; | ||
713 | struct clk *c; | ||
714 | |||
715 | bitmap_fill(channel_usage, NV_DMA_MAX_CHANNELS); | ||
716 | |||
717 | c = clk_get_sys("tegra-apbdma", NULL); | ||
718 | if (IS_ERR(c)) { | ||
719 | pr_err("Unable to get clock for APB DMA\n"); | ||
720 | ret = PTR_ERR(c); | ||
721 | goto fail; | ||
722 | } | ||
723 | ret = clk_prepare_enable(c); | ||
724 | if (ret != 0) { | ||
725 | pr_err("Unable to enable clock for APB DMA\n"); | ||
726 | goto fail; | ||
727 | } | ||
728 | |||
729 | addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); | ||
730 | writel(GEN_ENABLE, addr + APB_DMA_GEN); | ||
731 | writel(0, addr + APB_DMA_CNTRL); | ||
732 | writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX), | ||
733 | addr + APB_DMA_IRQ_MASK_SET); | ||
734 | |||
735 | for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { | ||
736 | struct tegra_dma_channel *ch = &dma_channels[i]; | ||
737 | |||
738 | ch->id = i; | ||
739 | snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i); | ||
740 | |||
741 | ch->addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + | ||
742 | TEGRA_APB_DMA_CH0_SIZE * i); | ||
743 | |||
744 | spin_lock_init(&ch->lock); | ||
745 | INIT_LIST_HEAD(&ch->list); | ||
746 | |||
747 | irq = INT_APB_DMA_CH0 + i; | ||
748 | ret = request_threaded_irq(irq, dma_isr, dma_thread_fn, 0, | ||
749 | dma_channels[i].name, ch); | ||
750 | if (ret) { | ||
751 | pr_err("Failed to register IRQ %d for DMA %d\n", | ||
752 | irq, i); | ||
753 | goto fail; | ||
754 | } | ||
755 | ch->irq = irq; | ||
756 | |||
757 | __clear_bit(i, channel_usage); | ||
758 | } | ||
759 | /* mark the shared channel allocated */ | ||
760 | __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage); | ||
761 | |||
762 | tegra_dma_initialized = true; | ||
763 | |||
764 | return 0; | ||
765 | fail: | ||
766 | writel(0, addr + APB_DMA_GEN); | ||
767 | for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { | ||
768 | struct tegra_dma_channel *ch = &dma_channels[i]; | ||
769 | if (ch->irq) | ||
770 | free_irq(ch->irq, ch); | ||
771 | } | ||
772 | return ret; | ||
773 | } | ||
774 | postcore_initcall(tegra_dma_init); | ||
775 | |||
776 | #ifdef CONFIG_PM | ||
777 | static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3]; | ||
778 | |||
779 | void tegra_dma_suspend(void) | ||
780 | { | ||
781 | void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); | ||
782 | u32 *ctx = apb_dma; | ||
783 | int i; | ||
784 | |||
785 | *ctx++ = readl(addr + APB_DMA_GEN); | ||
786 | *ctx++ = readl(addr + APB_DMA_CNTRL); | ||
787 | *ctx++ = readl(addr + APB_DMA_IRQ_MASK); | ||
788 | |||
789 | for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) { | ||
790 | addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + | ||
791 | TEGRA_APB_DMA_CH0_SIZE * i); | ||
792 | |||
793 | *ctx++ = readl(addr + APB_DMA_CHAN_CSR); | ||
794 | *ctx++ = readl(addr + APB_DMA_CHAN_AHB_PTR); | ||
795 | *ctx++ = readl(addr + APB_DMA_CHAN_AHB_SEQ); | ||
796 | *ctx++ = readl(addr + APB_DMA_CHAN_APB_PTR); | ||
797 | *ctx++ = readl(addr + APB_DMA_CHAN_APB_SEQ); | ||
798 | } | ||
799 | } | ||
800 | |||
801 | void tegra_dma_resume(void) | ||
802 | { | ||
803 | void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); | ||
804 | u32 *ctx = apb_dma; | ||
805 | int i; | ||
806 | |||
807 | writel(*ctx++, addr + APB_DMA_GEN); | ||
808 | writel(*ctx++, addr + APB_DMA_CNTRL); | ||
809 | writel(*ctx++, addr + APB_DMA_IRQ_MASK); | ||
810 | |||
811 | for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) { | ||
812 | addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + | ||
813 | TEGRA_APB_DMA_CH0_SIZE * i); | ||
814 | |||
815 | writel(*ctx++, addr + APB_DMA_CHAN_CSR); | ||
816 | writel(*ctx++, addr + APB_DMA_CHAN_AHB_PTR); | ||
817 | writel(*ctx++, addr + APB_DMA_CHAN_AHB_SEQ); | ||
818 | writel(*ctx++, addr + APB_DMA_CHAN_APB_PTR); | ||
819 | writel(*ctx++, addr + APB_DMA_CHAN_APB_SEQ); | ||
820 | } | ||
821 | } | ||
822 | |||
823 | #endif | ||
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c index f946d129423c..0b7db174a5de 100644 --- a/arch/arm/mach-tegra/fuse.c +++ b/arch/arm/mach-tegra/fuse.c | |||
@@ -93,9 +93,9 @@ void tegra_init_fuse(void) | |||
93 | { | 93 | { |
94 | u32 id; | 94 | u32 id; |
95 | 95 | ||
96 | u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); | 96 | u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48)); |
97 | reg |= 1 << 28; | 97 | reg |= 1 << 28; |
98 | writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); | 98 | writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48)); |
99 | 99 | ||
100 | reg = tegra_fuse_readl(FUSE_SKU_INFO); | 100 | reg = tegra_fuse_readl(FUSE_SKU_INFO); |
101 | tegra_sku_id = reg & 0xFF; | 101 | tegra_sku_id = reg & 0xFF; |
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h index 9077092812c0..3081cc6dda3b 100644 --- a/arch/arm/mach-tegra/include/mach/dma.h +++ b/arch/arm/mach-tegra/include/mach/dma.h | |||
@@ -51,101 +51,4 @@ | |||
51 | #define TEGRA_DMA_REQ_SEL_OWR 25 | 51 | #define TEGRA_DMA_REQ_SEL_OWR 25 |
52 | #define TEGRA_DMA_REQ_SEL_INVALID 31 | 52 | #define TEGRA_DMA_REQ_SEL_INVALID 31 |
53 | 53 | ||
54 | struct tegra_dma_req; | ||
55 | struct tegra_dma_channel; | ||
56 | |||
57 | enum tegra_dma_mode { | ||
58 | TEGRA_DMA_SHARED = 1, | ||
59 | TEGRA_DMA_MODE_CONTINOUS = 2, | ||
60 | TEGRA_DMA_MODE_ONESHOT = 4, | ||
61 | }; | ||
62 | |||
63 | enum tegra_dma_req_error { | ||
64 | TEGRA_DMA_REQ_SUCCESS = 0, | ||
65 | TEGRA_DMA_REQ_ERROR_ABORTED, | ||
66 | TEGRA_DMA_REQ_INFLIGHT, | ||
67 | }; | ||
68 | |||
69 | enum tegra_dma_req_buff_status { | ||
70 | TEGRA_DMA_REQ_BUF_STATUS_EMPTY = 0, | ||
71 | TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL, | ||
72 | TEGRA_DMA_REQ_BUF_STATUS_FULL, | ||
73 | }; | ||
74 | |||
75 | struct tegra_dma_req { | ||
76 | struct list_head node; | ||
77 | unsigned int modid; | ||
78 | int instance; | ||
79 | |||
80 | /* Called when the req is complete and from the DMA ISR context. | ||
81 | * When this is called the req structure is no longer queued by | ||
82 | * the DMA channel. | ||
83 | * | ||
84 | * State of the DMA depends on the number of req it has. If there are | ||
85 | * no DMA requests queued up, then it will STOP the DMA. It there are | ||
86 | * more requests in the DMA, then it will queue the next request. | ||
87 | */ | ||
88 | void (*complete)(struct tegra_dma_req *req); | ||
89 | |||
90 | /* This is a called from the DMA ISR context when the DMA is still in | ||
91 | * progress and is actively filling same buffer. | ||
92 | * | ||
93 | * In case of continuous mode receive, this threshold is 1/2 the buffer | ||
94 | * size. In other cases, this will not even be called as there is no | ||
95 | * hardware support for it. | ||
96 | * | ||
97 | * In the case of continuous mode receive, if there is next req already | ||
98 | * queued, DMA programs the HW to use that req when this req is | ||
99 | * completed. If there is no "next req" queued, then DMA ISR doesn't do | ||
100 | * anything before calling this callback. | ||
101 | * | ||
102 | * This is mainly used by the cases, where the clients has queued | ||
103 | * only one req and want to get some sort of DMA threshold | ||
104 | * callback to program the next buffer. | ||
105 | * | ||
106 | */ | ||
107 | void (*threshold)(struct tegra_dma_req *req); | ||
108 | |||
109 | /* 1 to copy to memory. | ||
110 | * 0 to copy from the memory to device FIFO */ | ||
111 | int to_memory; | ||
112 | |||
113 | void *virt_addr; | ||
114 | |||
115 | unsigned long source_addr; | ||
116 | unsigned long dest_addr; | ||
117 | unsigned long dest_wrap; | ||
118 | unsigned long source_wrap; | ||
119 | unsigned long source_bus_width; | ||
120 | unsigned long dest_bus_width; | ||
121 | unsigned long req_sel; | ||
122 | unsigned int size; | ||
123 | |||
124 | /* Updated by the DMA driver on the conpletion of the request. */ | ||
125 | int bytes_transferred; | ||
126 | int status; | ||
127 | |||
128 | /* DMA completion tracking information */ | ||
129 | int buffer_status; | ||
130 | |||
131 | /* Client specific data */ | ||
132 | void *dev; | ||
133 | }; | ||
134 | |||
135 | int tegra_dma_enqueue_req(struct tegra_dma_channel *ch, | ||
136 | struct tegra_dma_req *req); | ||
137 | int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, | ||
138 | struct tegra_dma_req *req); | ||
139 | void tegra_dma_dequeue(struct tegra_dma_channel *ch); | ||
140 | void tegra_dma_flush(struct tegra_dma_channel *ch); | ||
141 | |||
142 | bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch, | ||
143 | struct tegra_dma_req *req); | ||
144 | bool tegra_dma_is_empty(struct tegra_dma_channel *ch); | ||
145 | |||
146 | struct tegra_dma_channel *tegra_dma_allocate_channel(int mode); | ||
147 | void tegra_dma_free_channel(struct tegra_dma_channel *ch); | ||
148 | |||
149 | int __init tegra_dma_init(void); | ||
150 | |||
151 | #endif | 54 | #endif |
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h deleted file mode 100644 index fe700f9ce7dc..000000000000 --- a/arch/arm/mach-tegra/include/mach/io.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/include/mach/io.h | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * | ||
6 | * Author: | ||
7 | * Colin Cross <ccross@google.com> | ||
8 | * Erik Gilling <konkers@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifndef __MACH_TEGRA_IO_H | ||
22 | #define __MACH_TEGRA_IO_H | ||
23 | |||
24 | #define IO_SPACE_LIMIT 0xffff | ||
25 | |||
26 | #ifndef __ASSEMBLER__ | ||
27 | |||
28 | #ifdef CONFIG_TEGRA_PCI | ||
29 | extern void __iomem *tegra_pcie_io_base; | ||
30 | |||
31 | static inline void __iomem *__io(unsigned long addr) | ||
32 | { | ||
33 | return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT); | ||
34 | } | ||
35 | #else | ||
36 | static inline void __iomem *__io(unsigned long addr) | ||
37 | { | ||
38 | return (void __iomem *)addr; | ||
39 | } | ||
40 | #endif | ||
41 | |||
42 | #define __io(a) __io(a) | ||
43 | |||
44 | #endif | ||
45 | |||
46 | #endif | ||
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h index 7e76da73121c..fee3a94c4549 100644 --- a/arch/arm/mach-tegra/include/mach/iomap.h +++ b/arch/arm/mach-tegra/include/mach/iomap.h | |||
@@ -303,6 +303,9 @@ | |||
303 | #define IO_APB_VIRT IOMEM(0xFE300000) | 303 | #define IO_APB_VIRT IOMEM(0xFE300000) |
304 | #define IO_APB_SIZE SZ_1M | 304 | #define IO_APB_SIZE SZ_1M |
305 | 305 | ||
306 | #define TEGRA_PCIE_BASE 0x80000000 | ||
307 | #define TEGRA_PCIE_IO_BASE (TEGRA_PCIE_BASE + SZ_4M) | ||
308 | |||
306 | #define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) | 309 | #define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) |
307 | #define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) | 310 | #define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) |
308 | 311 | ||
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index d3ad5150d660..3463fb5b79c7 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c | |||
@@ -171,8 +171,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); | |||
171 | * 0x90000000 - 0x9fffffff - non-prefetchable memory | 171 | * 0x90000000 - 0x9fffffff - non-prefetchable memory |
172 | * 0xa0000000 - 0xbfffffff - prefetchable memory | 172 | * 0xa0000000 - 0xbfffffff - prefetchable memory |
173 | */ | 173 | */ |
174 | #define TEGRA_PCIE_BASE 0x80000000 | ||
175 | |||
176 | #define PCIE_REGS_SZ SZ_16K | 174 | #define PCIE_REGS_SZ SZ_16K |
177 | #define PCIE_CFG_OFF PCIE_REGS_SZ | 175 | #define PCIE_CFG_OFF PCIE_REGS_SZ |
178 | #define PCIE_CFG_SZ SZ_1M | 176 | #define PCIE_CFG_SZ SZ_1M |
@@ -180,8 +178,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); | |||
180 | #define PCIE_EXT_CFG_SZ SZ_1M | 178 | #define PCIE_EXT_CFG_SZ SZ_1M |
181 | #define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ) | 179 | #define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ) |
182 | 180 | ||
183 | #define MMIO_BASE (TEGRA_PCIE_BASE + SZ_4M) | ||
184 | #define MMIO_SIZE SZ_64K | ||
185 | #define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M) | 181 | #define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M) |
186 | #define MEM_SIZE_0 SZ_128M | 182 | #define MEM_SIZE_0 SZ_128M |
187 | #define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0) | 183 | #define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0) |
@@ -204,10 +200,9 @@ struct tegra_pcie_port { | |||
204 | 200 | ||
205 | bool link_up; | 201 | bool link_up; |
206 | 202 | ||
207 | char io_space_name[16]; | ||
208 | char mem_space_name[16]; | 203 | char mem_space_name[16]; |
209 | char prefetch_space_name[20]; | 204 | char prefetch_space_name[20]; |
210 | struct resource res[3]; | 205 | struct resource res[2]; |
211 | }; | 206 | }; |
212 | 207 | ||
213 | struct tegra_pcie_info { | 208 | struct tegra_pcie_info { |
@@ -223,17 +218,7 @@ struct tegra_pcie_info { | |||
223 | struct clk *pll_e; | 218 | struct clk *pll_e; |
224 | }; | 219 | }; |
225 | 220 | ||
226 | static struct tegra_pcie_info tegra_pcie = { | 221 | static struct tegra_pcie_info tegra_pcie; |
227 | .res_mmio = { | ||
228 | .name = "PCI IO", | ||
229 | .start = MMIO_BASE, | ||
230 | .end = MMIO_BASE + MMIO_SIZE - 1, | ||
231 | .flags = IORESOURCE_MEM, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | void __iomem *tegra_pcie_io_base; | ||
236 | EXPORT_SYMBOL(tegra_pcie_io_base); | ||
237 | 222 | ||
238 | static inline void afi_writel(u32 value, unsigned long offset) | 223 | static inline void afi_writel(u32 value, unsigned long offset) |
239 | { | 224 | { |
@@ -391,24 +376,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
391 | pp = tegra_pcie.port + nr; | 376 | pp = tegra_pcie.port + nr; |
392 | pp->root_bus_nr = sys->busnr; | 377 | pp->root_bus_nr = sys->busnr; |
393 | 378 | ||
394 | /* | 379 | pci_ioremap_io(nr * SZ_64K, TEGRA_PCIE_IO_BASE); |
395 | * IORESOURCE_IO | ||
396 | */ | ||
397 | snprintf(pp->io_space_name, sizeof(pp->io_space_name), | ||
398 | "PCIe %d I/O", pp->index); | ||
399 | pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0; | ||
400 | pp->res[0].name = pp->io_space_name; | ||
401 | if (pp->index == 0) { | ||
402 | pp->res[0].start = PCIBIOS_MIN_IO; | ||
403 | pp->res[0].end = pp->res[0].start + SZ_32K - 1; | ||
404 | } else { | ||
405 | pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K; | ||
406 | pp->res[0].end = IO_SPACE_LIMIT; | ||
407 | } | ||
408 | pp->res[0].flags = IORESOURCE_IO; | ||
409 | if (request_resource(&ioport_resource, &pp->res[0])) | ||
410 | panic("Request PCIe IO resource failed\n"); | ||
411 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); | ||
412 | 380 | ||
413 | /* | 381 | /* |
414 | * IORESOURCE_MEM | 382 | * IORESOURCE_MEM |
@@ -416,18 +384,18 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
416 | snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), | 384 | snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), |
417 | "PCIe %d MEM", pp->index); | 385 | "PCIe %d MEM", pp->index); |
418 | pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; | 386 | pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; |
419 | pp->res[1].name = pp->mem_space_name; | 387 | pp->res[0].name = pp->mem_space_name; |
420 | if (pp->index == 0) { | 388 | if (pp->index == 0) { |
421 | pp->res[1].start = MEM_BASE_0; | 389 | pp->res[0].start = MEM_BASE_0; |
422 | pp->res[1].end = pp->res[1].start + MEM_SIZE_0 - 1; | 390 | pp->res[0].end = pp->res[0].start + MEM_SIZE_0 - 1; |
423 | } else { | 391 | } else { |
424 | pp->res[1].start = MEM_BASE_1; | 392 | pp->res[0].start = MEM_BASE_1; |
425 | pp->res[1].end = pp->res[1].start + MEM_SIZE_1 - 1; | 393 | pp->res[0].end = pp->res[0].start + MEM_SIZE_1 - 1; |
426 | } | 394 | } |
427 | pp->res[1].flags = IORESOURCE_MEM; | 395 | pp->res[0].flags = IORESOURCE_MEM; |
428 | if (request_resource(&iomem_resource, &pp->res[1])) | 396 | if (request_resource(&iomem_resource, &pp->res[0])) |
429 | panic("Request PCIe Memory resource failed\n"); | 397 | panic("Request PCIe Memory resource failed\n"); |
430 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); | 398 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->mem_offset); |
431 | 399 | ||
432 | /* | 400 | /* |
433 | * IORESOURCE_MEM | IORESOURCE_PREFETCH | 401 | * IORESOURCE_MEM | IORESOURCE_PREFETCH |
@@ -435,18 +403,18 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
435 | snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name), | 403 | snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name), |
436 | "PCIe %d PREFETCH MEM", pp->index); | 404 | "PCIe %d PREFETCH MEM", pp->index); |
437 | pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0; | 405 | pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0; |
438 | pp->res[2].name = pp->prefetch_space_name; | 406 | pp->res[1].name = pp->prefetch_space_name; |
439 | if (pp->index == 0) { | 407 | if (pp->index == 0) { |
440 | pp->res[2].start = PREFETCH_MEM_BASE_0; | 408 | pp->res[1].start = PREFETCH_MEM_BASE_0; |
441 | pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_0 - 1; | 409 | pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_0 - 1; |
442 | } else { | 410 | } else { |
443 | pp->res[2].start = PREFETCH_MEM_BASE_1; | 411 | pp->res[1].start = PREFETCH_MEM_BASE_1; |
444 | pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_1 - 1; | 412 | pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_1 - 1; |
445 | } | 413 | } |
446 | pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; | 414 | pp->res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
447 | if (request_resource(&iomem_resource, &pp->res[2])) | 415 | if (request_resource(&iomem_resource, &pp->res[1])) |
448 | panic("Request PCIe Prefetch Memory resource failed\n"); | 416 | panic("Request PCIe Prefetch Memory resource failed\n"); |
449 | pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset); | 417 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); |
450 | 418 | ||
451 | return 1; | 419 | return 1; |
452 | } | 420 | } |
@@ -541,8 +509,8 @@ static void tegra_pcie_setup_translations(void) | |||
541 | 509 | ||
542 | /* Bar 2: downstream IO bar */ | 510 | /* Bar 2: downstream IO bar */ |
543 | fpci_bar = ((__u32)0xfdfc << 16); | 511 | fpci_bar = ((__u32)0xfdfc << 16); |
544 | size = MMIO_SIZE; | 512 | size = SZ_128K; |
545 | axi_address = MMIO_BASE; | 513 | axi_address = TEGRA_PCIE_IO_BASE; |
546 | afi_writel(axi_address, AFI_AXI_BAR2_START); | 514 | afi_writel(axi_address, AFI_AXI_BAR2_START); |
547 | afi_writel(size >> 12, AFI_AXI_BAR2_SZ); | 515 | afi_writel(size >> 12, AFI_AXI_BAR2_SZ); |
548 | afi_writel(fpci_bar, AFI_FPCI_BAR2); | 516 | afi_writel(fpci_bar, AFI_FPCI_BAR2); |
@@ -776,7 +744,6 @@ static void tegra_pcie_clocks_put(void) | |||
776 | 744 | ||
777 | static int __init tegra_pcie_get_resources(void) | 745 | static int __init tegra_pcie_get_resources(void) |
778 | { | 746 | { |
779 | struct resource *res_mmio = &tegra_pcie.res_mmio; | ||
780 | int err; | 747 | int err; |
781 | 748 | ||
782 | err = tegra_pcie_clocks_get(); | 749 | err = tegra_pcie_clocks_get(); |
@@ -798,34 +765,16 @@ static int __init tegra_pcie_get_resources(void) | |||
798 | goto err_map_reg; | 765 | goto err_map_reg; |
799 | } | 766 | } |
800 | 767 | ||
801 | err = request_resource(&iomem_resource, res_mmio); | ||
802 | if (err) { | ||
803 | pr_err("PCIE: Failed to request resources: %d\n", err); | ||
804 | goto err_req_io; | ||
805 | } | ||
806 | |||
807 | tegra_pcie_io_base = ioremap_nocache(res_mmio->start, | ||
808 | resource_size(res_mmio)); | ||
809 | if (tegra_pcie_io_base == NULL) { | ||
810 | pr_err("PCIE: Failed to map IO\n"); | ||
811 | err = -ENOMEM; | ||
812 | goto err_map_io; | ||
813 | } | ||
814 | |||
815 | err = request_irq(INT_PCIE_INTR, tegra_pcie_isr, | 768 | err = request_irq(INT_PCIE_INTR, tegra_pcie_isr, |
816 | IRQF_SHARED, "PCIE", &tegra_pcie); | 769 | IRQF_SHARED, "PCIE", &tegra_pcie); |
817 | if (err) { | 770 | if (err) { |
818 | pr_err("PCIE: Failed to register IRQ: %d\n", err); | 771 | pr_err("PCIE: Failed to register IRQ: %d\n", err); |
819 | goto err_irq; | 772 | goto err_req_io; |
820 | } | 773 | } |
821 | set_irq_flags(INT_PCIE_INTR, IRQF_VALID); | 774 | set_irq_flags(INT_PCIE_INTR, IRQF_VALID); |
822 | 775 | ||
823 | return 0; | 776 | return 0; |
824 | 777 | ||
825 | err_irq: | ||
826 | iounmap(tegra_pcie_io_base); | ||
827 | err_map_io: | ||
828 | release_resource(&tegra_pcie.res_mmio); | ||
829 | err_req_io: | 778 | err_req_io: |
830 | iounmap(tegra_pcie.regs); | 779 | iounmap(tegra_pcie.regs); |
831 | err_map_reg: | 780 | err_map_reg: |