aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s5p
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-s5p')
-rw-r--r--arch/arm/plat-s5p/Kconfig26
-rw-r--r--arch/arm/plat-s5p/Makefile3
-rw-r--r--arch/arm/plat-s5p/cpu.c5
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c34
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c34
-rw-r--r--arch/arm/plat-s5p/include/plat/csis.h28
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h1
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-srom.h54
-rw-r--r--arch/arm/plat-s5p/include/plat/sysmmu.h23
-rw-r--r--arch/arm/plat-s5p/irq-eint.c86
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c50
-rw-r--r--arch/arm/plat-s5p/irq-pm.c6
-rw-r--r--arch/arm/plat-s5p/sysmmu.c328
13 files changed, 608 insertions, 70 deletions
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 65dbfa8e0a86..deb39951a22e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -56,3 +56,29 @@ config S5P_DEV_ONENAND
56 bool 56 bool
57 help 57 help
58 Compile in platform device definition for OneNAND controller 58 Compile in platform device definition for OneNAND controller
59
60config S5P_DEV_CSIS0
61 bool
62 help
63 Compile in platform device definitions for MIPI-CSIS channel 0
64
65config S5P_DEV_CSIS1
66 bool
67 help
68 Compile in platform device definitions for MIPI-CSIS channel 1
69
70menuconfig S5P_SYSMMU
71 bool "SYSMMU support"
72 depends on ARCH_S5PV310
73 help
74 This is a System MMU driver for Samsung ARM based Soc.
75
76if S5P_SYSMMU
77
78config S5P_SYSMMU_DEBUG
79 bool "Enables debug messages"
80 depends on S5P_SYSMMU
81 help
82 This enables SYSMMU driver debug massages.
83
84endif
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index de65238a7aef..92efe1adcfd6 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -28,3 +28,6 @@ obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
28obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o 28obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
29obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o 29obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
30obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o 30obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
31obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
32obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
33obj-$(CONFIG_S5P_SYSMMU) += sysmmu.o
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index 74f7f5a5446c..047d31c1bbd8 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -108,6 +108,11 @@ static struct map_desc s5p_iodesc[] __initdata = {
108 .pfn = __phys_to_pfn(S3C_PA_WDT), 108 .pfn = __phys_to_pfn(S3C_PA_WDT),
109 .length = SZ_4K, 109 .length = SZ_4K,
110 .type = MT_DEVICE, 110 .type = MT_DEVICE,
111 }, {
112 .virtual = (unsigned long)S5P_VA_SROMC,
113 .pfn = __phys_to_pfn(S5P_PA_SROMC),
114 .length = SZ_4K,
115 .type = MT_DEVICE,
111 }, 116 },
112}; 117};
113 118
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
new file mode 100644
index 000000000000..dfab1c85f54f
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 *
4 * S5P series device definition for MIPI-CSIS channel 0
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis0_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS0,
19 .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS0,
24 .end = IRQ_MIPI_CSIS0,
25 .flags = IORESOURCE_IRQ,
26 }
27};
28
29struct platform_device s5p_device_mipi_csis0 = {
30 .name = "s5p-mipi-csis",
31 .id = 0,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
33 .resource = s5p_mipi_csis0_resource,
34};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
new file mode 100644
index 000000000000..e3053f27fbbf
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 *
4 * S5P series device definition for MIPI-CSIS channel 1
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis1_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS1,
19 .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS1,
24 .end = IRQ_MIPI_CSIS1,
25 .flags = IORESOURCE_IRQ,
26 },
27};
28
29struct platform_device s5p_device_mipi_csis1 = {
30 .name = "s5p-mipi-csis",
31 .id = 1,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
33 .resource = s5p_mipi_csis1_resource,
34};
diff --git a/arch/arm/plat-s5p/include/plat/csis.h b/arch/arm/plat-s5p/include/plat/csis.h
new file mode 100644
index 000000000000..51e308c7981d
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/csis.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 *
4 * S5P series MIPI CSI slave device support
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef PLAT_S5P_CSIS_H_
12#define PLAT_S5P_CSIS_H_ __FILE__
13
14/**
15 * struct s5p_platform_mipi_csis - platform data for MIPI-CSIS
16 * @clk_rate: bus clock frequency
17 * @lanes: number of data lanes used
18 * @alignment: data alignment in bits
19 * @hs_settle: HS-RX settle time
20 */
21struct s5p_platform_mipi_csis {
22 unsigned long clk_rate;
23 u8 lanes;
24 u8 alignment;
25 u8 hs_settle;
26};
27
28#endif /* PLAT_S5P_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index fef353d44513..d973d39666a3 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -15,6 +15,7 @@
15 15
16#define S5P_VA_CHIPID S3C_ADDR(0x02000000) 16#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
17#define S5P_VA_CMU S3C_ADDR(0x02100000) 17#define S5P_VA_CMU S3C_ADDR(0x02100000)
18#define S5P_VA_PMU S3C_ADDR(0x02180000)
18#define S5P_VA_GPIO S3C_ADDR(0x02200000) 19#define S5P_VA_GPIO S3C_ADDR(0x02200000)
19#define S5P_VA_GPIO1 S5P_VA_GPIO 20#define S5P_VA_GPIO1 S5P_VA_GPIO
20#define S5P_VA_GPIO2 S3C_ADDR(0x02240000) 21#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-s5p/include/plat/regs-srom.h
new file mode 100644
index 000000000000..f121ab5e76cb
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-srom.h
@@ -0,0 +1,54 @@
1/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P SROMC register definitions
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_S5P_REGS_SROM_H
14#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_SROMREG(x) (S5P_VA_SROMC + (x))
19
20#define S5P_SROM_BW S5P_SROMREG(0x0)
21#define S5P_SROM_BC0 S5P_SROMREG(0x4)
22#define S5P_SROM_BC1 S5P_SROMREG(0x8)
23#define S5P_SROM_BC2 S5P_SROMREG(0xc)
24#define S5P_SROM_BC3 S5P_SROMREG(0x10)
25#define S5P_SROM_BC4 S5P_SROMREG(0x14)
26#define S5P_SROM_BC5 S5P_SROMREG(0x18)
27
28/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
29
30#define S5P_SROM_BW__DATAWIDTH__SHIFT 0
31#define S5P_SROM_BW__ADDRMODE__SHIFT 1
32#define S5P_SROM_BW__WAITENABLE__SHIFT 2
33#define S5P_SROM_BW__BYTEENABLE__SHIFT 3
34
35#define S5P_SROM_BW__CS_MASK 0xf
36
37#define S5P_SROM_BW__NCS0__SHIFT 0
38#define S5P_SROM_BW__NCS1__SHIFT 4
39#define S5P_SROM_BW__NCS2__SHIFT 8
40#define S5P_SROM_BW__NCS3__SHIFT 12
41#define S5P_SROM_BW__NCS4__SHIFT 16
42#define S5P_SROM_BW__NCS5__SHIFT 20
43
44/* applies to same to BCS0 - BCS3 */
45
46#define S5P_SROM_BCX__PMC__SHIFT 0
47#define S5P_SROM_BCX__TACP__SHIFT 4
48#define S5P_SROM_BCX__TCAH__SHIFT 8
49#define S5P_SROM_BCX__TCOH__SHIFT 12
50#define S5P_SROM_BCX__TACC__SHIFT 16
51#define S5P_SROM_BCX__TCOS__SHIFT 24
52#define S5P_SROM_BCX__TACS__SHIFT 28
53
54#endif /* __ASM_PLAT_S5P_REGS_SROM_H */
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
new file mode 100644
index 000000000000..db298fc5438a
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/sysmmu.h
@@ -0,0 +1,23 @@
1/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Samsung sysmmu driver
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_S5P_SYSMMU_H
14#define __ASM_PLAT_S5P_SYSMMU_H __FILE__
15
16/* debug macro */
17#ifdef CONFIG_S5P_SYSMMU_DEBUG
18#define sysmmu_debug(fmt, arg...) printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
19#else
20#define sysmmu_debug(fmt, arg...) do { } while (0)
21#endif
22
23#endif /* __ASM_PLAT_S5P_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index 752f1a645f9d..225aa25405db 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -28,39 +28,40 @@
28#include <plat/gpio-cfg.h> 28#include <plat/gpio-cfg.h>
29#include <mach/regs-gpio.h> 29#include <mach/regs-gpio.h>
30 30
31static inline void s5p_irq_eint_mask(unsigned int irq) 31static inline void s5p_irq_eint_mask(struct irq_data *data)
32{ 32{
33 u32 mask; 33 u32 mask;
34 34
35 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq))); 35 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
36 mask |= eint_irq_to_bit(irq); 36 mask |= eint_irq_to_bit(data->irq);
37 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq))); 37 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
38} 38}
39 39
40static void s5p_irq_eint_unmask(unsigned int irq) 40static void s5p_irq_eint_unmask(struct irq_data *data)
41{ 41{
42 u32 mask; 42 u32 mask;
43 43
44 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq))); 44 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
45 mask &= ~(eint_irq_to_bit(irq)); 45 mask &= ~(eint_irq_to_bit(data->irq));
46 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq))); 46 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
47} 47}
48 48
49static inline void s5p_irq_eint_ack(unsigned int irq) 49static inline void s5p_irq_eint_ack(struct irq_data *data)
50{ 50{
51 __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq))); 51 __raw_writel(eint_irq_to_bit(data->irq),
52 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
52} 53}
53 54
54static void s5p_irq_eint_maskack(unsigned int irq) 55static void s5p_irq_eint_maskack(struct irq_data *data)
55{ 56{
56 /* compiler should in-line these */ 57 /* compiler should in-line these */
57 s5p_irq_eint_mask(irq); 58 s5p_irq_eint_mask(data);
58 s5p_irq_eint_ack(irq); 59 s5p_irq_eint_ack(data);
59} 60}
60 61
61static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) 62static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
62{ 63{
63 int offs = EINT_OFFSET(irq); 64 int offs = EINT_OFFSET(data->irq);
64 int shift; 65 int shift;
65 u32 ctrl, mask; 66 u32 ctrl, mask;
66 u32 newvalue = 0; 67 u32 newvalue = 0;
@@ -94,10 +95,10 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
94 shift = (offs & 0x7) * 4; 95 shift = (offs & 0x7) * 4;
95 mask = 0x7 << shift; 96 mask = 0x7 << shift;
96 97
97 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq))); 98 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
98 ctrl &= ~mask; 99 ctrl &= ~mask;
99 ctrl |= newvalue << shift; 100 ctrl |= newvalue << shift;
100 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq))); 101 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
101 102
102 if ((0 <= offs) && (offs < 8)) 103 if ((0 <= offs) && (offs < 8))
103 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); 104 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
@@ -119,13 +120,13 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
119 120
120static struct irq_chip s5p_irq_eint = { 121static struct irq_chip s5p_irq_eint = {
121 .name = "s5p-eint", 122 .name = "s5p-eint",
122 .mask = s5p_irq_eint_mask, 123 .irq_mask = s5p_irq_eint_mask,
123 .unmask = s5p_irq_eint_unmask, 124 .irq_unmask = s5p_irq_eint_unmask,
124 .mask_ack = s5p_irq_eint_maskack, 125 .irq_mask_ack = s5p_irq_eint_maskack,
125 .ack = s5p_irq_eint_ack, 126 .irq_ack = s5p_irq_eint_ack,
126 .set_type = s5p_irq_eint_set_type, 127 .irq_set_type = s5p_irq_eint_set_type,
127#ifdef CONFIG_PM 128#ifdef CONFIG_PM
128 .set_wake = s3c_irqext_wake, 129 .irq_set_wake = s3c_irqext_wake,
129#endif 130#endif
130}; 131};
131 132
@@ -159,42 +160,43 @@ static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
159 s5p_irq_demux_eint(IRQ_EINT(24)); 160 s5p_irq_demux_eint(IRQ_EINT(24));
160} 161}
161 162
162static inline void s5p_irq_vic_eint_mask(unsigned int irq) 163static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
163{ 164{
164 void __iomem *base = get_irq_chip_data(irq); 165 void __iomem *base = irq_data_get_irq_chip_data(data);
165 166
166 s5p_irq_eint_mask(irq); 167 s5p_irq_eint_mask(data);
167 writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE_CLEAR); 168 writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR);
168} 169}
169 170
170static void s5p_irq_vic_eint_unmask(unsigned int irq) 171static void s5p_irq_vic_eint_unmask(struct irq_data *data)
171{ 172{
172 void __iomem *base = get_irq_chip_data(irq); 173 void __iomem *base = irq_data_get_irq_chip_data(data);
173 174
174 s5p_irq_eint_unmask(irq); 175 s5p_irq_eint_unmask(data);
175 writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE); 176 writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE);
176} 177}
177 178
178static inline void s5p_irq_vic_eint_ack(unsigned int irq) 179static inline void s5p_irq_vic_eint_ack(struct irq_data *data)
179{ 180{
180 __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq))); 181 __raw_writel(eint_irq_to_bit(data->irq),
182 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
181} 183}
182 184
183static void s5p_irq_vic_eint_maskack(unsigned int irq) 185static void s5p_irq_vic_eint_maskack(struct irq_data *data)
184{ 186{
185 s5p_irq_vic_eint_mask(irq); 187 s5p_irq_vic_eint_mask(data);
186 s5p_irq_vic_eint_ack(irq); 188 s5p_irq_vic_eint_ack(data);
187} 189}
188 190
189static struct irq_chip s5p_irq_vic_eint = { 191static struct irq_chip s5p_irq_vic_eint = {
190 .name = "s5p_vic_eint", 192 .name = "s5p_vic_eint",
191 .mask = s5p_irq_vic_eint_mask, 193 .irq_mask = s5p_irq_vic_eint_mask,
192 .unmask = s5p_irq_vic_eint_unmask, 194 .irq_unmask = s5p_irq_vic_eint_unmask,
193 .mask_ack = s5p_irq_vic_eint_maskack, 195 .irq_mask_ack = s5p_irq_vic_eint_maskack,
194 .ack = s5p_irq_vic_eint_ack, 196 .irq_ack = s5p_irq_vic_eint_ack,
195 .set_type = s5p_irq_eint_set_type, 197 .irq_set_type = s5p_irq_eint_set_type,
196#ifdef CONFIG_PM 198#ifdef CONFIG_PM
197 .set_wake = s3c_irqext_wake, 199 .irq_set_wake = s3c_irqext_wake,
198#endif 200#endif
199}; 201};
200 202
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 0e5dc8cbf5e3..3b6bf89d1739 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -30,9 +30,9 @@
30 30
31static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR]; 31static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
32 32
33static int s5p_gpioint_get_group(unsigned int irq) 33static int s5p_gpioint_get_group(struct irq_data *data)
34{ 34{
35 struct gpio_chip *chip = get_irq_data(irq); 35 struct gpio_chip *chip = irq_data_get_irq_data(data);
36 struct s3c_gpio_chip *s3c_chip = container_of(chip, 36 struct s3c_gpio_chip *s3c_chip = container_of(chip,
37 struct s3c_gpio_chip, chip); 37 struct s3c_gpio_chip, chip);
38 int group; 38 int group;
@@ -44,22 +44,22 @@ static int s5p_gpioint_get_group(unsigned int irq)
44 return group; 44 return group;
45} 45}
46 46
47static int s5p_gpioint_get_offset(unsigned int irq) 47static int s5p_gpioint_get_offset(struct irq_data *data)
48{ 48{
49 struct gpio_chip *chip = get_irq_data(irq); 49 struct gpio_chip *chip = irq_data_get_irq_data(data);
50 struct s3c_gpio_chip *s3c_chip = container_of(chip, 50 struct s3c_gpio_chip *s3c_chip = container_of(chip,
51 struct s3c_gpio_chip, chip); 51 struct s3c_gpio_chip, chip);
52 52
53 return irq - s3c_chip->irq_base; 53 return data->irq - s3c_chip->irq_base;
54} 54}
55 55
56static void s5p_gpioint_ack(unsigned int irq) 56static void s5p_gpioint_ack(struct irq_data *data)
57{ 57{
58 int group, offset, pend_offset; 58 int group, offset, pend_offset;
59 unsigned int value; 59 unsigned int value;
60 60
61 group = s5p_gpioint_get_group(irq); 61 group = s5p_gpioint_get_group(data);
62 offset = s5p_gpioint_get_offset(irq); 62 offset = s5p_gpioint_get_offset(data);
63 pend_offset = group << 2; 63 pend_offset = group << 2;
64 64
65 value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset); 65 value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
@@ -67,13 +67,13 @@ static void s5p_gpioint_ack(unsigned int irq)
67 __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset); 67 __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
68} 68}
69 69
70static void s5p_gpioint_mask(unsigned int irq) 70static void s5p_gpioint_mask(struct irq_data *data)
71{ 71{
72 int group, offset, mask_offset; 72 int group, offset, mask_offset;
73 unsigned int value; 73 unsigned int value;
74 74
75 group = s5p_gpioint_get_group(irq); 75 group = s5p_gpioint_get_group(data);
76 offset = s5p_gpioint_get_offset(irq); 76 offset = s5p_gpioint_get_offset(data);
77 mask_offset = group << 2; 77 mask_offset = group << 2;
78 78
79 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 79 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
@@ -81,13 +81,13 @@ static void s5p_gpioint_mask(unsigned int irq)
81 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 81 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
82} 82}
83 83
84static void s5p_gpioint_unmask(unsigned int irq) 84static void s5p_gpioint_unmask(struct irq_data *data)
85{ 85{
86 int group, offset, mask_offset; 86 int group, offset, mask_offset;
87 unsigned int value; 87 unsigned int value;
88 88
89 group = s5p_gpioint_get_group(irq); 89 group = s5p_gpioint_get_group(data);
90 offset = s5p_gpioint_get_offset(irq); 90 offset = s5p_gpioint_get_offset(data);
91 mask_offset = group << 2; 91 mask_offset = group << 2;
92 92
93 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 93 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
@@ -95,19 +95,19 @@ static void s5p_gpioint_unmask(unsigned int irq)
95 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 95 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
96} 96}
97 97
98static void s5p_gpioint_mask_ack(unsigned int irq) 98static void s5p_gpioint_mask_ack(struct irq_data *data)
99{ 99{
100 s5p_gpioint_mask(irq); 100 s5p_gpioint_mask(data);
101 s5p_gpioint_ack(irq); 101 s5p_gpioint_ack(data);
102} 102}
103 103
104static int s5p_gpioint_set_type(unsigned int irq, unsigned int type) 104static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
105{ 105{
106 int group, offset, con_offset; 106 int group, offset, con_offset;
107 unsigned int value; 107 unsigned int value;
108 108
109 group = s5p_gpioint_get_group(irq); 109 group = s5p_gpioint_get_group(data);
110 offset = s5p_gpioint_get_offset(irq); 110 offset = s5p_gpioint_get_offset(data);
111 con_offset = group << 2; 111 con_offset = group << 2;
112 112
113 switch (type) { 113 switch (type) {
@@ -142,11 +142,11 @@ static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
142 142
143struct irq_chip s5p_gpioint = { 143struct irq_chip s5p_gpioint = {
144 .name = "s5p_gpioint", 144 .name = "s5p_gpioint",
145 .ack = s5p_gpioint_ack, 145 .irq_ack = s5p_gpioint_ack,
146 .mask = s5p_gpioint_mask, 146 .irq_mask = s5p_gpioint_mask,
147 .mask_ack = s5p_gpioint_mask_ack, 147 .irq_mask_ack = s5p_gpioint_mask_ack,
148 .unmask = s5p_gpioint_unmask, 148 .irq_unmask = s5p_gpioint_unmask,
149 .set_type = s5p_gpioint_set_type, 149 .irq_set_type = s5p_gpioint_set_type,
150}; 150};
151 151
152static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) 152static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
index dc33b9ecda45..5259ad458bc8 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -37,14 +37,14 @@
37unsigned long s3c_irqwake_intallow = 0x00000006L; 37unsigned long s3c_irqwake_intallow = 0x00000006L;
38unsigned long s3c_irqwake_eintallow = 0xffffffffL; 38unsigned long s3c_irqwake_eintallow = 0xffffffffL;
39 39
40int s3c_irq_wake(unsigned int irqno, unsigned int state) 40int s3c_irq_wake(struct irq_data *data, unsigned int state)
41{ 41{
42 unsigned long irqbit; 42 unsigned long irqbit;
43 43
44 switch (irqno) { 44 switch (data->irq) {
45 case IRQ_RTC_TIC: 45 case IRQ_RTC_TIC:
46 case IRQ_RTC_ALARM: 46 case IRQ_RTC_ALARM:
47 irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM); 47 irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
48 if (!state) 48 if (!state)
49 s3c_irqwake_intmask |= irqbit; 49 s3c_irqwake_intmask |= irqbit;
50 else 50 else
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
new file mode 100644
index 000000000000..d804914dc2e2
--- /dev/null
+++ b/arch/arm/plat-s5p/sysmmu.c
@@ -0,0 +1,328 @@
1/* linux/arch/arm/plat-s5p/sysmmu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/io.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14
15#include <mach/map.h>
16#include <mach/regs-sysmmu.h>
17#include <mach/sysmmu.h>
18
19#include <plat/sysmmu.h>
20
21struct sysmmu_controller s5p_sysmmu_cntlrs[S5P_SYSMMU_TOTAL_IPNUM];
22
23void s5p_sysmmu_register(struct sysmmu_controller *sysmmuconp)
24{
25 unsigned int reg_mmu_ctrl;
26 unsigned int reg_mmu_status;
27 unsigned int reg_pt_base_addr;
28 unsigned int reg_int_status;
29 unsigned int reg_page_ft_addr;
30
31 reg_int_status = __raw_readl(sysmmuconp->regs + S5P_INT_STATUS);
32 reg_mmu_ctrl = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
33 reg_mmu_status = __raw_readl(sysmmuconp->regs + S5P_MMU_STATUS);
34 reg_pt_base_addr = __raw_readl(sysmmuconp->regs + S5P_PT_BASE_ADDR);
35 reg_page_ft_addr = __raw_readl(sysmmuconp->regs + S5P_PAGE_FAULT_ADDR);
36
37 printk(KERN_INFO "%s: ips:%s\n", __func__, sysmmuconp->name);
38 printk(KERN_INFO "%s: MMU_CTRL:0x%X, ", __func__, reg_mmu_ctrl);
39 printk(KERN_INFO "MMU_STATUS:0x%X, PT_BASE_ADDR:0x%X\n", reg_mmu_status, reg_pt_base_addr);
40 printk(KERN_INFO "%s: INT_STATUS:0x%X, PAGE_FAULT_ADDR:0x%X\n", __func__, reg_int_status, reg_page_ft_addr);
41
42 switch (reg_int_status & 0xFF) {
43 case 0x1:
44 printk(KERN_INFO "%s: Page fault\n", __func__);
45 printk(KERN_INFO "%s: Virtual address causing last page fault or bus error : 0x%x\n", __func__ , reg_page_ft_addr);
46 break;
47 case 0x2:
48 printk(KERN_INFO "%s: AR multi-hit fault\n", __func__);
49 break;
50 case 0x4:
51 printk(KERN_INFO "%s: AW multi-hit fault\n", __func__);
52 break;
53 case 0x8:
54 printk(KERN_INFO "%s: Bus error\n", __func__);
55 break;
56 case 0x10:
57 printk(KERN_INFO "%s: AR Security protection fault\n", __func__);
58 break;
59 case 0x20:
60 printk(KERN_INFO "%s: AR Access protection fault\n", __func__);
61 break;
62 case 0x40:
63 printk(KERN_INFO "%s: AW Security protection fault\n", __func__);
64 break;
65 case 0x80:
66 printk(KERN_INFO "%s: AW Access protection fault\n", __func__);
67 break;
68 }
69}
70
71static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
72{
73 unsigned int i;
74 unsigned int reg_int_status;
75 struct sysmmu_controller *sysmmuconp;
76
77 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
78 sysmmuconp = &s5p_sysmmu_cntlrs[i];
79
80 if (sysmmuconp->enable == true) {
81 reg_int_status = __raw_readl(sysmmuconp->regs + S5P_INT_STATUS);
82
83 if (reg_int_status & 0xFF)
84 s5p_sysmmu_register(sysmmuconp);
85 }
86 }
87 return IRQ_HANDLED;
88}
89
90int s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
91{
92 struct sysmmu_controller *sysmmuconp = NULL;
93
94 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
95
96 if (sysmmuconp == NULL) {
97 printk(KERN_ERR "failed to get ip's sysmmu info\n");
98 return 1;
99 }
100
101 /* Set sysmmu page table base address */
102 __raw_writel(pgd, sysmmuconp->regs + S5P_PT_BASE_ADDR);
103
104 if (s5p_sysmmu_tlb_invalidate(ips) != 0)
105 printk(KERN_ERR "failed s5p_sysmmu_tlb_invalidate\n");
106
107 return 0;
108}
109
110static int s5p_sysmmu_set_tablebase(sysmmu_ips ips)
111{
112 unsigned int pg;
113 struct sysmmu_controller *sysmmuconp;
114
115 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
116
117 if (sysmmuconp == NULL) {
118 printk(KERN_ERR "failed to get ip's sysmmu info\n");
119 return 1;
120 }
121
122 __asm__("mrc p15, 0, %0, c2, c0, 0" \
123 : "=r" (pg) : : "cc"); \
124 pg &= ~0x3fff;
125
126 sysmmu_debug("CP15 TTBR0 : 0x%x\n", pg);
127
128 /* Set sysmmu page table base address */
129 __raw_writel(pg, sysmmuconp->regs + S5P_PT_BASE_ADDR);
130
131 return 0;
132}
133
134int s5p_sysmmu_enable(sysmmu_ips ips)
135{
136 unsigned int reg;
137
138 struct sysmmu_controller *sysmmuconp;
139
140 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
141
142 if (sysmmuconp == NULL) {
143 printk(KERN_ERR "failed to get ip's sysmmu info\n");
144 return 1;
145 }
146
147 s5p_sysmmu_set_tablebase(ips);
148
149 /* replacement policy : LRU */
150 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CFG);
151 reg |= 0x1;
152 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CFG);
153
154 /* Enable interrupt, Enable MMU */
155 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
156 reg |= (0x1 << 2) | (0x1 << 0);
157
158 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
159
160 sysmmuconp->enable = true;
161
162 return 0;
163}
164
165int s5p_sysmmu_disable(sysmmu_ips ips)
166{
167 unsigned int reg;
168
169 struct sysmmu_controller *sysmmuconp = NULL;
170
171 if (ips > S5P_SYSMMU_TOTAL_IPNUM)
172 printk(KERN_ERR "failed to get ips parameter\n");
173
174 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
175
176 if (sysmmuconp == NULL) {
177 printk(KERN_ERR "failed to get ip's sysmmu info\n");
178 return 1;
179 }
180
181 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CFG);
182
183 /* replacement policy : LRU */
184 reg |= 0x1;
185 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CFG);
186
187 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
188
189 /* Disable MMU */
190 reg &= ~0x1;
191 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
192
193 sysmmuconp->enable = false;
194
195 return 0;
196}
197
198int s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
199{
200 unsigned int reg;
201 struct sysmmu_controller *sysmmuconp = NULL;
202
203 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
204
205 if (sysmmuconp == NULL) {
206 printk(KERN_ERR "failed to get ip's sysmmu info\n");
207 return 1;
208 }
209
210 /* set Block MMU for flush TLB */
211 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
212 reg |= 0x1 << 1;
213 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
214
215 /* flush all TLB entry */
216 __raw_writel(0x1, sysmmuconp->regs + S5P_MMU_FLUSH);
217
218 /* set Un-block MMU after flush TLB */
219 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
220 reg &= ~(0x1 << 1);
221 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
222
223 return 0;
224}
225
226static int s5p_sysmmu_probe(struct platform_device *pdev)
227{
228 int i;
229 int ret;
230 struct resource *res;
231 struct sysmmu_controller *sysmmuconp;
232 sysmmu_ips ips;
233
234 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
235 sysmmuconp = &s5p_sysmmu_cntlrs[i];
236 if (sysmmuconp == NULL) {
237 printk(KERN_ERR "failed to get ip's sysmmu info\n");
238 ret = -ENOENT;
239 goto err_res;
240 }
241
242 sysmmuconp->name = sysmmu_ips_name[i];
243
244 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
245 if (!res) {
246 printk(KERN_ERR "failed to get sysmmu resource\n");
247 ret = -ENODEV;
248 goto err_res;
249 }
250
251 sysmmuconp->mem = request_mem_region(res->start,
252 ((res->end) - (res->start)) + 1, pdev->name);
253 if (!sysmmuconp->mem) {
254 pr_err("failed to request sysmmu memory region\n");
255 ret = -EBUSY;
256 goto err_res;
257 }
258
259 sysmmuconp->regs = ioremap(res->start, res->end - res->start + 1);
260 if (!sysmmuconp->regs) {
261 pr_err("failed to sysmmu ioremap\n");
262 ret = -ENXIO;
263 goto err_reg;
264 }
265
266 sysmmuconp->irq = platform_get_irq(pdev, i);
267 if (sysmmuconp->irq <= 0) {
268 pr_err("failed to get sysmmu irq resource\n");
269 ret = -ENOENT;
270 goto err_map;
271 }
272
273 ret = request_irq(sysmmuconp->irq, s5p_sysmmu_irq, IRQF_DISABLED, pdev->name, sysmmuconp);
274 if (ret) {
275 pr_err("failed to request irq\n");
276 ret = -ENOENT;
277 goto err_map;
278 }
279
280 ips = (sysmmu_ips)i;
281
282 sysmmuconp->ips = ips;
283 }
284
285 return 0;
286
287err_reg:
288 release_mem_region((resource_size_t)sysmmuconp->mem, (resource_size_t)((res->end) - (res->start) + 1));
289err_map:
290 iounmap(sysmmuconp->regs);
291err_res:
292 return ret;
293}
294
295static int s5p_sysmmu_remove(struct platform_device *pdev)
296{
297 return 0;
298}
299int s5p_sysmmu_runtime_suspend(struct device *dev)
300{
301 return 0;
302}
303
304int s5p_sysmmu_runtime_resume(struct device *dev)
305{
306 return 0;
307}
308
309const struct dev_pm_ops s5p_sysmmu_pm_ops = {
310 .runtime_suspend = s5p_sysmmu_runtime_suspend,
311 .runtime_resume = s5p_sysmmu_runtime_resume,
312};
313
314static struct platform_driver s5p_sysmmu_driver = {
315 .probe = s5p_sysmmu_probe,
316 .remove = s5p_sysmmu_remove,
317 .driver = {
318 .owner = THIS_MODULE,
319 .name = "s5p-sysmmu",
320 .pm = &s5p_sysmmu_pm_ops,
321 }
322};
323
324static int __init s5p_sysmmu_init(void)
325{
326 return platform_driver_register(&s5p_sysmmu_driver);
327}
328arch_initcall(s5p_sysmmu_init);