diff options
Diffstat (limited to 'arch/mips')
51 files changed, 1332 insertions, 507 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index dba9390d37cf..4183e62f178c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -40,6 +40,8 @@ config MIPS | |||
40 | select HAVE_MOD_ARCH_SPECIFIC | 40 | select HAVE_MOD_ARCH_SPECIFIC |
41 | select MODULES_USE_ELF_REL | 41 | select MODULES_USE_ELF_REL |
42 | select MODULES_USE_ELF_RELA if 64BIT | 42 | select MODULES_USE_ELF_RELA if 64BIT |
43 | select GENERIC_KERNEL_THREAD | ||
44 | select GENERIC_KERNEL_EXECVE | ||
43 | 45 | ||
44 | menu "Machine selection" | 46 | menu "Machine selection" |
45 | 47 | ||
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index 407ebc00e661..cb83d8d21aef 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ | 8 | obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ |
9 | sleeper.o dma.o dbdma.o vss.o irq.o | 9 | sleeper.o dma.o dbdma.o vss.o irq.o usb.o |
10 | 10 | ||
11 | # optional gpiolib support | 11 | # optional gpiolib support |
12 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) | 12 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index c0f3ce6dcb56..7af941d8e717 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/serial_8250.h> | 18 | #include <linux/serial_8250.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/usb/ehci_pdriver.h> | ||
21 | #include <linux/usb/ohci_pdriver.h> | ||
20 | 22 | ||
21 | #include <asm/mach-au1x00/au1000.h> | 23 | #include <asm/mach-au1x00/au1000.h> |
22 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 24 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
@@ -122,6 +124,53 @@ static void __init alchemy_setup_uarts(int ctype) | |||
122 | static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); | 124 | static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); |
123 | static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32); | 125 | static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32); |
124 | 126 | ||
127 | /* Power on callback for the ehci platform driver */ | ||
128 | static int alchemy_ehci_power_on(struct platform_device *pdev) | ||
129 | { | ||
130 | return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); | ||
131 | } | ||
132 | |||
133 | /* Power off/suspend callback for the ehci platform driver */ | ||
134 | static void alchemy_ehci_power_off(struct platform_device *pdev) | ||
135 | { | ||
136 | alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); | ||
137 | } | ||
138 | |||
139 | static struct usb_ehci_pdata alchemy_ehci_pdata = { | ||
140 | .no_io_watchdog = 1, | ||
141 | .power_on = alchemy_ehci_power_on, | ||
142 | .power_off = alchemy_ehci_power_off, | ||
143 | .power_suspend = alchemy_ehci_power_off, | ||
144 | }; | ||
145 | |||
146 | /* Power on callback for the ohci platform driver */ | ||
147 | static int alchemy_ohci_power_on(struct platform_device *pdev) | ||
148 | { | ||
149 | int unit; | ||
150 | |||
151 | unit = (pdev->id == 1) ? | ||
152 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | ||
153 | |||
154 | return alchemy_usb_control(unit, 1); | ||
155 | } | ||
156 | |||
157 | /* Power off/suspend callback for the ohci platform driver */ | ||
158 | static void alchemy_ohci_power_off(struct platform_device *pdev) | ||
159 | { | ||
160 | int unit; | ||
161 | |||
162 | unit = (pdev->id == 1) ? | ||
163 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | ||
164 | |||
165 | alchemy_usb_control(unit, 0); | ||
166 | } | ||
167 | |||
168 | static struct usb_ohci_pdata alchemy_ohci_pdata = { | ||
169 | .power_on = alchemy_ohci_power_on, | ||
170 | .power_off = alchemy_ohci_power_off, | ||
171 | .power_suspend = alchemy_ohci_power_off, | ||
172 | }; | ||
173 | |||
125 | static unsigned long alchemy_ohci_data[][2] __initdata = { | 174 | static unsigned long alchemy_ohci_data[][2] __initdata = { |
126 | [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, | 175 | [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, |
127 | [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, | 176 | [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, |
@@ -169,9 +218,10 @@ static void __init alchemy_setup_usb(int ctype) | |||
169 | res[1].start = alchemy_ohci_data[ctype][1]; | 218 | res[1].start = alchemy_ohci_data[ctype][1]; |
170 | res[1].end = res[1].start; | 219 | res[1].end = res[1].start; |
171 | res[1].flags = IORESOURCE_IRQ; | 220 | res[1].flags = IORESOURCE_IRQ; |
172 | pdev->name = "au1xxx-ohci"; | 221 | pdev->name = "ohci-platform"; |
173 | pdev->id = 0; | 222 | pdev->id = 0; |
174 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; | 223 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; |
224 | pdev->dev.platform_data = &alchemy_ohci_pdata; | ||
175 | 225 | ||
176 | if (platform_device_register(pdev)) | 226 | if (platform_device_register(pdev)) |
177 | printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); | 227 | printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); |
@@ -188,9 +238,10 @@ static void __init alchemy_setup_usb(int ctype) | |||
188 | res[1].start = alchemy_ehci_data[ctype][1]; | 238 | res[1].start = alchemy_ehci_data[ctype][1]; |
189 | res[1].end = res[1].start; | 239 | res[1].end = res[1].start; |
190 | res[1].flags = IORESOURCE_IRQ; | 240 | res[1].flags = IORESOURCE_IRQ; |
191 | pdev->name = "au1xxx-ehci"; | 241 | pdev->name = "ehci-platform"; |
192 | pdev->id = 0; | 242 | pdev->id = 0; |
193 | pdev->dev.dma_mask = &alchemy_ehci_dmamask; | 243 | pdev->dev.dma_mask = &alchemy_ehci_dmamask; |
244 | pdev->dev.platform_data = &alchemy_ehci_pdata; | ||
194 | 245 | ||
195 | if (platform_device_register(pdev)) | 246 | if (platform_device_register(pdev)) |
196 | printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n"); | 247 | printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n"); |
@@ -207,9 +258,10 @@ static void __init alchemy_setup_usb(int ctype) | |||
207 | res[1].start = AU1300_USB_INT; | 258 | res[1].start = AU1300_USB_INT; |
208 | res[1].end = res[1].start; | 259 | res[1].end = res[1].start; |
209 | res[1].flags = IORESOURCE_IRQ; | 260 | res[1].flags = IORESOURCE_IRQ; |
210 | pdev->name = "au1xxx-ohci"; | 261 | pdev->name = "ohci-platform"; |
211 | pdev->id = 1; | 262 | pdev->id = 1; |
212 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; | 263 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; |
264 | pdev->dev.platform_data = &alchemy_ohci_pdata; | ||
213 | 265 | ||
214 | if (platform_device_register(pdev)) | 266 | if (platform_device_register(pdev)) |
215 | printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n"); | 267 | printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n"); |
diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c new file mode 100644 index 000000000000..936af8359fb2 --- /dev/null +++ b/arch/mips/alchemy/common/usb.c | |||
@@ -0,0 +1,614 @@ | |||
1 | /* | ||
2 | * USB block power/access management abstraction. | ||
3 | * | ||
4 | * Au1000+: The OHCI block control register is at the far end of the OHCI memory | ||
5 | * area. Au1550 has OHCI on different base address. No need to handle | ||
6 | * UDC here. | ||
7 | * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG | ||
8 | * as well as the PHY for EHCI and UDC. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/syscore_ops.h> | ||
17 | #include <asm/mach-au1x00/au1000.h> | ||
18 | |||
19 | /* control register offsets */ | ||
20 | #define AU1000_OHCICFG 0x7fffc | ||
21 | #define AU1550_OHCICFG 0x07ffc | ||
22 | #define AU1200_USBCFG 0x04 | ||
23 | |||
24 | /* Au1000 USB block config bits */ | ||
25 | #define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */ | ||
26 | #define USBHEN_CE (1 << 3) /* OHCI block clock enable */ | ||
27 | #define USBHEN_E (1 << 2) /* OHCI block enable */ | ||
28 | #define USBHEN_C (1 << 1) /* OHCI block coherency bit */ | ||
29 | #define USBHEN_BE (1 << 0) /* OHCI Big-Endian */ | ||
30 | |||
31 | /* Au1200 USB config bits */ | ||
32 | #define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */ | ||
33 | #define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */ | ||
34 | #define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */ | ||
35 | #define USBCFG_SSD (1 << 23) /* serial short detect en */ | ||
36 | #define USBCFG_PPE (1 << 19) /* HS PHY PLL */ | ||
37 | #define USBCFG_UCE (1 << 18) /* UDC clock enable */ | ||
38 | #define USBCFG_ECE (1 << 17) /* EHCI clock enable */ | ||
39 | #define USBCFG_OCE (1 << 16) /* OHCI clock enable */ | ||
40 | #define USBCFG_FLA(x) (((x) & 0x3f) << 8) | ||
41 | #define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */ | ||
42 | #define USBCFG_GME (1 << 6) /* OTG mem access */ | ||
43 | #define USBCFG_DBE (1 << 5) /* UDC busmaster enable */ | ||
44 | #define USBCFG_DME (1 << 4) /* UDC mem enable */ | ||
45 | #define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */ | ||
46 | #define USBCFG_EME (1 << 2) /* EHCI mem enable */ | ||
47 | #define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */ | ||
48 | #define USBCFG_OME (1 << 0) /* OHCI mem enable */ | ||
49 | #define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\ | ||
50 | USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \ | ||
51 | USBCFG_GME | USBCFG_DBE | USBCFG_DME | \ | ||
52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ | ||
53 | USBCFG_OME) | ||
54 | |||
55 | /* Au1300 USB config registers */ | ||
56 | #define USB_DWC_CTRL1 0x00 | ||
57 | #define USB_DWC_CTRL2 0x04 | ||
58 | #define USB_VBUS_TIMER 0x10 | ||
59 | #define USB_SBUS_CTRL 0x14 | ||
60 | #define USB_MSR_ERR 0x18 | ||
61 | #define USB_DWC_CTRL3 0x1C | ||
62 | #define USB_DWC_CTRL4 0x20 | ||
63 | #define USB_OTG_STATUS 0x28 | ||
64 | #define USB_DWC_CTRL5 0x2C | ||
65 | #define USB_DWC_CTRL6 0x30 | ||
66 | #define USB_DWC_CTRL7 0x34 | ||
67 | #define USB_PHY_STATUS 0xC0 | ||
68 | #define USB_INT_STATUS 0xC4 | ||
69 | #define USB_INT_ENABLE 0xC8 | ||
70 | |||
71 | #define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */ | ||
72 | #define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */ | ||
73 | #define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */ | ||
74 | |||
75 | #define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */ | ||
76 | #define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */ | ||
77 | #define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */ | ||
78 | |||
79 | #define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19) | ||
80 | #define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18) | ||
81 | #define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17) | ||
82 | #define USB_DWC_CTRL3_OTG0_CKEN (1 << 16) | ||
83 | |||
84 | #define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */ | ||
85 | |||
86 | #define USB_INTEN_FORCE 0x20 | ||
87 | #define USB_INTEN_PHY 0x10 | ||
88 | #define USB_INTEN_UDC 0x08 | ||
89 | #define USB_INTEN_EHCI 0x04 | ||
90 | #define USB_INTEN_OHCI1 0x02 | ||
91 | #define USB_INTEN_OHCI0 0x01 | ||
92 | |||
93 | static DEFINE_SPINLOCK(alchemy_usb_lock); | ||
94 | |||
95 | static inline void __au1300_usb_phyctl(void __iomem *base, int enable) | ||
96 | { | ||
97 | unsigned long r, s; | ||
98 | |||
99 | r = __raw_readl(base + USB_DWC_CTRL2); | ||
100 | s = __raw_readl(base + USB_DWC_CTRL3); | ||
101 | |||
102 | s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN | | ||
103 | USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN; | ||
104 | |||
105 | if (enable) { | ||
106 | /* simply enable all PHYs */ | ||
107 | r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
108 | USB_DWC_CTRL2_PHYRS; | ||
109 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
110 | wmb(); | ||
111 | } else if (!s) { | ||
112 | /* no USB block active, do disable all PHYs */ | ||
113 | r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
114 | USB_DWC_CTRL2_PHYRS); | ||
115 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
116 | wmb(); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static inline void __au1300_ohci_control(void __iomem *base, int enable, int id) | ||
121 | { | ||
122 | unsigned long r; | ||
123 | |||
124 | if (enable) { | ||
125 | __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */ | ||
126 | wmb(); | ||
127 | |||
128 | r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */ | ||
129 | r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
130 | : USB_DWC_CTRL3_OHCI1_CKEN; | ||
131 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
132 | wmb(); | ||
133 | |||
134 | __au1300_usb_phyctl(base, enable); /* power up the PHYs */ | ||
135 | |||
136 | r = __raw_readl(base + USB_INT_ENABLE); | ||
137 | r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1; | ||
138 | __raw_writel(r, base + USB_INT_ENABLE); | ||
139 | wmb(); | ||
140 | |||
141 | /* reset the OHCI start clock bit */ | ||
142 | __raw_writel(0, base + USB_DWC_CTRL7); | ||
143 | wmb(); | ||
144 | } else { | ||
145 | r = __raw_readl(base + USB_INT_ENABLE); | ||
146 | r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1); | ||
147 | __raw_writel(r, base + USB_INT_ENABLE); | ||
148 | wmb(); | ||
149 | |||
150 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
151 | r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
152 | : USB_DWC_CTRL3_OHCI1_CKEN); | ||
153 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
154 | wmb(); | ||
155 | |||
156 | __au1300_usb_phyctl(base, enable); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static inline void __au1300_ehci_control(void __iomem *base, int enable) | ||
161 | { | ||
162 | unsigned long r; | ||
163 | |||
164 | if (enable) { | ||
165 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
166 | r |= USB_DWC_CTRL3_EHCI0_CKEN; | ||
167 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
168 | wmb(); | ||
169 | |||
170 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
171 | r |= USB_DWC_CTRL1_HSTRS; | ||
172 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
173 | wmb(); | ||
174 | |||
175 | __au1300_usb_phyctl(base, enable); | ||
176 | |||
177 | r = __raw_readl(base + USB_INT_ENABLE); | ||
178 | r |= USB_INTEN_EHCI; | ||
179 | __raw_writel(r, base + USB_INT_ENABLE); | ||
180 | wmb(); | ||
181 | } else { | ||
182 | r = __raw_readl(base + USB_INT_ENABLE); | ||
183 | r &= ~USB_INTEN_EHCI; | ||
184 | __raw_writel(r, base + USB_INT_ENABLE); | ||
185 | wmb(); | ||
186 | |||
187 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
188 | r &= ~USB_DWC_CTRL1_HSTRS; | ||
189 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
190 | wmb(); | ||
191 | |||
192 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
193 | r &= ~USB_DWC_CTRL3_EHCI0_CKEN; | ||
194 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
195 | wmb(); | ||
196 | |||
197 | __au1300_usb_phyctl(base, enable); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static inline void __au1300_udc_control(void __iomem *base, int enable) | ||
202 | { | ||
203 | unsigned long r; | ||
204 | |||
205 | if (enable) { | ||
206 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
207 | r |= USB_DWC_CTRL1_DCRS; | ||
208 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
209 | wmb(); | ||
210 | |||
211 | __au1300_usb_phyctl(base, enable); | ||
212 | |||
213 | r = __raw_readl(base + USB_INT_ENABLE); | ||
214 | r |= USB_INTEN_UDC; | ||
215 | __raw_writel(r, base + USB_INT_ENABLE); | ||
216 | wmb(); | ||
217 | } else { | ||
218 | r = __raw_readl(base + USB_INT_ENABLE); | ||
219 | r &= ~USB_INTEN_UDC; | ||
220 | __raw_writel(r, base + USB_INT_ENABLE); | ||
221 | wmb(); | ||
222 | |||
223 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
224 | r &= ~USB_DWC_CTRL1_DCRS; | ||
225 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
226 | wmb(); | ||
227 | |||
228 | __au1300_usb_phyctl(base, enable); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static inline void __au1300_otg_control(void __iomem *base, int enable) | ||
233 | { | ||
234 | unsigned long r; | ||
235 | if (enable) { | ||
236 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
237 | r |= USB_DWC_CTRL3_OTG0_CKEN; | ||
238 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
239 | wmb(); | ||
240 | |||
241 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
242 | r &= ~USB_DWC_CTRL1_OTGD; | ||
243 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
244 | wmb(); | ||
245 | |||
246 | __au1300_usb_phyctl(base, enable); | ||
247 | } else { | ||
248 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
249 | r |= USB_DWC_CTRL1_OTGD; | ||
250 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
251 | wmb(); | ||
252 | |||
253 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
254 | r &= ~USB_DWC_CTRL3_OTG0_CKEN; | ||
255 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
256 | wmb(); | ||
257 | |||
258 | __au1300_usb_phyctl(base, enable); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static inline int au1300_usb_control(int block, int enable) | ||
263 | { | ||
264 | void __iomem *base = | ||
265 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
266 | int ret = 0; | ||
267 | |||
268 | switch (block) { | ||
269 | case ALCHEMY_USB_OHCI0: | ||
270 | __au1300_ohci_control(base, enable, 0); | ||
271 | break; | ||
272 | case ALCHEMY_USB_OHCI1: | ||
273 | __au1300_ohci_control(base, enable, 1); | ||
274 | break; | ||
275 | case ALCHEMY_USB_EHCI0: | ||
276 | __au1300_ehci_control(base, enable); | ||
277 | break; | ||
278 | case ALCHEMY_USB_UDC0: | ||
279 | __au1300_udc_control(base, enable); | ||
280 | break; | ||
281 | case ALCHEMY_USB_OTG0: | ||
282 | __au1300_otg_control(base, enable); | ||
283 | break; | ||
284 | default: | ||
285 | ret = -ENODEV; | ||
286 | } | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | static inline void au1300_usb_init(void) | ||
291 | { | ||
292 | void __iomem *base = | ||
293 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
294 | |||
295 | /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4 | ||
296 | * here at all: Port 2 routing (EHCI or UDC) must be set either | ||
297 | * by boot firmware or platform init code; I can't autodetect | ||
298 | * a sane setting. | ||
299 | */ | ||
300 | __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */ | ||
301 | wmb(); | ||
302 | __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */ | ||
303 | wmb(); | ||
304 | __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */ | ||
305 | wmb(); | ||
306 | __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */ | ||
307 | wmb(); | ||
308 | /* set coherent access bit */ | ||
309 | __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL); | ||
310 | wmb(); | ||
311 | } | ||
312 | |||
313 | static inline void __au1200_ohci_control(void __iomem *base, int enable) | ||
314 | { | ||
315 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
316 | if (enable) { | ||
317 | __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG); | ||
318 | wmb(); | ||
319 | udelay(2000); | ||
320 | } else { | ||
321 | __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG); | ||
322 | wmb(); | ||
323 | udelay(1000); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | static inline void __au1200_ehci_control(void __iomem *base, int enable) | ||
328 | { | ||
329 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
330 | if (enable) { | ||
331 | __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG); | ||
332 | wmb(); | ||
333 | udelay(1000); | ||
334 | } else { | ||
335 | if (!(r & USBCFG_UCE)) /* UDC also off? */ | ||
336 | r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ | ||
337 | __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG); | ||
338 | wmb(); | ||
339 | udelay(1000); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | static inline void __au1200_udc_control(void __iomem *base, int enable) | ||
344 | { | ||
345 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
346 | if (enable) { | ||
347 | __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG); | ||
348 | wmb(); | ||
349 | } else { | ||
350 | if (!(r & USBCFG_ECE)) /* EHCI also off? */ | ||
351 | r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ | ||
352 | __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG); | ||
353 | wmb(); | ||
354 | } | ||
355 | } | ||
356 | |||
357 | static inline int au1200_coherency_bug(void) | ||
358 | { | ||
359 | #if defined(CONFIG_DMA_COHERENT) | ||
360 | /* Au1200 AB USB does not support coherent memory */ | ||
361 | if (!(read_c0_prid() & 0xff)) { | ||
362 | printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n"); | ||
363 | printk(KERN_INFO "Au1200 USB: update your board or re-configure" | ||
364 | " the kernel\n"); | ||
365 | return -ENODEV; | ||
366 | } | ||
367 | #endif | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static inline int au1200_usb_control(int block, int enable) | ||
372 | { | ||
373 | void __iomem *base = | ||
374 | (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); | ||
375 | int ret = 0; | ||
376 | |||
377 | switch (block) { | ||
378 | case ALCHEMY_USB_OHCI0: | ||
379 | ret = au1200_coherency_bug(); | ||
380 | if (ret && enable) | ||
381 | goto out; | ||
382 | __au1200_ohci_control(base, enable); | ||
383 | break; | ||
384 | case ALCHEMY_USB_UDC0: | ||
385 | __au1200_udc_control(base, enable); | ||
386 | break; | ||
387 | case ALCHEMY_USB_EHCI0: | ||
388 | ret = au1200_coherency_bug(); | ||
389 | if (ret && enable) | ||
390 | goto out; | ||
391 | __au1200_ehci_control(base, enable); | ||
392 | break; | ||
393 | default: | ||
394 | ret = -ENODEV; | ||
395 | } | ||
396 | out: | ||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | |||
401 | /* initialize USB block(s) to a known working state */ | ||
402 | static inline void au1200_usb_init(void) | ||
403 | { | ||
404 | void __iomem *base = | ||
405 | (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); | ||
406 | __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG); | ||
407 | wmb(); | ||
408 | udelay(1000); | ||
409 | } | ||
410 | |||
411 | static inline void au1000_usb_init(unsigned long rb, int reg) | ||
412 | { | ||
413 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); | ||
414 | unsigned long r = __raw_readl(base); | ||
415 | |||
416 | #if defined(__BIG_ENDIAN) | ||
417 | r |= USBHEN_BE; | ||
418 | #endif | ||
419 | r |= USBHEN_C; | ||
420 | |||
421 | __raw_writel(r, base); | ||
422 | wmb(); | ||
423 | udelay(1000); | ||
424 | } | ||
425 | |||
426 | |||
427 | static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) | ||
428 | { | ||
429 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb); | ||
430 | unsigned long r = __raw_readl(base + creg); | ||
431 | |||
432 | if (enable) { | ||
433 | __raw_writel(r | USBHEN_CE, base + creg); | ||
434 | wmb(); | ||
435 | udelay(1000); | ||
436 | __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg); | ||
437 | wmb(); | ||
438 | udelay(1000); | ||
439 | |||
440 | /* wait for reset complete (read reg twice: au1500 erratum) */ | ||
441 | while (__raw_readl(base + creg), | ||
442 | !(__raw_readl(base + creg) & USBHEN_RD)) | ||
443 | udelay(1000); | ||
444 | } else { | ||
445 | __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); | ||
446 | wmb(); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | static inline int au1000_usb_control(int block, int enable, unsigned long rb, | ||
451 | int creg) | ||
452 | { | ||
453 | int ret = 0; | ||
454 | |||
455 | switch (block) { | ||
456 | case ALCHEMY_USB_OHCI0: | ||
457 | __au1xx0_ohci_control(enable, rb, creg); | ||
458 | break; | ||
459 | default: | ||
460 | ret = -ENODEV; | ||
461 | } | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * alchemy_usb_control - control Alchemy on-chip USB blocks | ||
467 | * @block: USB block to target | ||
468 | * @enable: set 1 to enable a block, 0 to disable | ||
469 | */ | ||
470 | int alchemy_usb_control(int block, int enable) | ||
471 | { | ||
472 | unsigned long flags; | ||
473 | int ret; | ||
474 | |||
475 | spin_lock_irqsave(&alchemy_usb_lock, flags); | ||
476 | switch (alchemy_get_cputype()) { | ||
477 | case ALCHEMY_CPU_AU1000: | ||
478 | case ALCHEMY_CPU_AU1500: | ||
479 | case ALCHEMY_CPU_AU1100: | ||
480 | ret = au1000_usb_control(block, enable, | ||
481 | AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | ||
482 | break; | ||
483 | case ALCHEMY_CPU_AU1550: | ||
484 | ret = au1000_usb_control(block, enable, | ||
485 | AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | ||
486 | break; | ||
487 | case ALCHEMY_CPU_AU1200: | ||
488 | ret = au1200_usb_control(block, enable); | ||
489 | break; | ||
490 | case ALCHEMY_CPU_AU1300: | ||
491 | ret = au1300_usb_control(block, enable); | ||
492 | break; | ||
493 | default: | ||
494 | ret = -ENODEV; | ||
495 | } | ||
496 | spin_unlock_irqrestore(&alchemy_usb_lock, flags); | ||
497 | return ret; | ||
498 | } | ||
499 | EXPORT_SYMBOL_GPL(alchemy_usb_control); | ||
500 | |||
501 | |||
502 | static unsigned long alchemy_usb_pmdata[2]; | ||
503 | |||
504 | static void au1000_usb_pm(unsigned long br, int creg, int susp) | ||
505 | { | ||
506 | void __iomem *base = (void __iomem *)KSEG1ADDR(br); | ||
507 | |||
508 | if (susp) { | ||
509 | alchemy_usb_pmdata[0] = __raw_readl(base + creg); | ||
510 | /* There appears to be some undocumented reset register.... */ | ||
511 | __raw_writel(0, base + 0x04); | ||
512 | wmb(); | ||
513 | __raw_writel(0, base + creg); | ||
514 | wmb(); | ||
515 | } else { | ||
516 | __raw_writel(alchemy_usb_pmdata[0], base + creg); | ||
517 | wmb(); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void au1200_usb_pm(int susp) | ||
522 | { | ||
523 | void __iomem *base = | ||
524 | (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR); | ||
525 | if (susp) { | ||
526 | /* save OTG_CAP/MUX registers which indicate port routing */ | ||
527 | /* FIXME: write an OTG driver to do that */ | ||
528 | alchemy_usb_pmdata[0] = __raw_readl(base + 0x00); | ||
529 | alchemy_usb_pmdata[1] = __raw_readl(base + 0x04); | ||
530 | } else { | ||
531 | /* restore access to all MMIO areas */ | ||
532 | au1200_usb_init(); | ||
533 | |||
534 | /* restore OTG_CAP/MUX registers */ | ||
535 | __raw_writel(alchemy_usb_pmdata[0], base + 0x00); | ||
536 | __raw_writel(alchemy_usb_pmdata[1], base + 0x04); | ||
537 | wmb(); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | static void au1300_usb_pm(int susp) | ||
542 | { | ||
543 | void __iomem *base = | ||
544 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
545 | /* remember Port2 routing */ | ||
546 | if (susp) { | ||
547 | alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4); | ||
548 | } else { | ||
549 | au1300_usb_init(); | ||
550 | __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4); | ||
551 | wmb(); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | static void alchemy_usb_pm(int susp) | ||
556 | { | ||
557 | switch (alchemy_get_cputype()) { | ||
558 | case ALCHEMY_CPU_AU1000: | ||
559 | case ALCHEMY_CPU_AU1500: | ||
560 | case ALCHEMY_CPU_AU1100: | ||
561 | au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp); | ||
562 | break; | ||
563 | case ALCHEMY_CPU_AU1550: | ||
564 | au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp); | ||
565 | break; | ||
566 | case ALCHEMY_CPU_AU1200: | ||
567 | au1200_usb_pm(susp); | ||
568 | break; | ||
569 | case ALCHEMY_CPU_AU1300: | ||
570 | au1300_usb_pm(susp); | ||
571 | break; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | static int alchemy_usb_suspend(void) | ||
576 | { | ||
577 | alchemy_usb_pm(1); | ||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | static void alchemy_usb_resume(void) | ||
582 | { | ||
583 | alchemy_usb_pm(0); | ||
584 | } | ||
585 | |||
586 | static struct syscore_ops alchemy_usb_pm_ops = { | ||
587 | .suspend = alchemy_usb_suspend, | ||
588 | .resume = alchemy_usb_resume, | ||
589 | }; | ||
590 | |||
591 | static int __init alchemy_usb_init(void) | ||
592 | { | ||
593 | switch (alchemy_get_cputype()) { | ||
594 | case ALCHEMY_CPU_AU1000: | ||
595 | case ALCHEMY_CPU_AU1500: | ||
596 | case ALCHEMY_CPU_AU1100: | ||
597 | au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | ||
598 | break; | ||
599 | case ALCHEMY_CPU_AU1550: | ||
600 | au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | ||
601 | break; | ||
602 | case ALCHEMY_CPU_AU1200: | ||
603 | au1200_usb_init(); | ||
604 | break; | ||
605 | case ALCHEMY_CPU_AU1300: | ||
606 | au1300_usb_init(); | ||
607 | break; | ||
608 | } | ||
609 | |||
610 | register_syscore_ops(&alchemy_usb_pm_ops); | ||
611 | |||
612 | return 0; | ||
613 | } | ||
614 | arch_initcall(alchemy_usb_init); | ||
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index 072bb9be2304..bd2bc108e1b5 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c | |||
@@ -50,13 +50,11 @@ static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); | |||
50 | 50 | ||
51 | static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { | 51 | static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { |
52 | .has_synopsys_hc_bug = 1, | 52 | .has_synopsys_hc_bug = 1, |
53 | .port_power_off = 1, | ||
54 | }; | 53 | }; |
55 | 54 | ||
56 | static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { | 55 | static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { |
57 | .caps_offset = 0x100, | 56 | .caps_offset = 0x100, |
58 | .has_tt = 1, | 57 | .has_tt = 1, |
59 | .port_power_off = 1, | ||
60 | }; | 58 | }; |
61 | 59 | ||
62 | static struct platform_device ath79_ehci_device = { | 60 | static struct platform_device ath79_ehci_device = { |
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index d43ceff5be47..48a4c70b3842 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
@@ -43,8 +43,8 @@ static void early_nvram_init(void) | |||
43 | #ifdef CONFIG_BCM47XX_SSB | 43 | #ifdef CONFIG_BCM47XX_SSB |
44 | case BCM47XX_BUS_TYPE_SSB: | 44 | case BCM47XX_BUS_TYPE_SSB: |
45 | mcore_ssb = &bcm47xx_bus.ssb.mipscore; | 45 | mcore_ssb = &bcm47xx_bus.ssb.mipscore; |
46 | base = mcore_ssb->flash_window; | 46 | base = mcore_ssb->pflash.window; |
47 | lim = mcore_ssb->flash_window_size; | 47 | lim = mcore_ssb->pflash.window_size; |
48 | break; | 48 | break; |
49 | #endif | 49 | #endif |
50 | #ifdef CONFIG_BCM47XX_BCMA | 50 | #ifdef CONFIG_BCM47XX_BCMA |
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c index e9f9ec8d443b..e80d585731aa 100644 --- a/arch/mips/bcm47xx/wgt634u.c +++ b/arch/mips/bcm47xx/wgt634u.c | |||
@@ -156,10 +156,10 @@ static int __init wgt634u_init(void) | |||
156 | SSB_CHIPCO_IRQ_GPIO); | 156 | SSB_CHIPCO_IRQ_GPIO); |
157 | } | 157 | } |
158 | 158 | ||
159 | wgt634u_flash_data.width = mcore->flash_buswidth; | 159 | wgt634u_flash_data.width = mcore->pflash.buswidth; |
160 | wgt634u_flash_resource.start = mcore->flash_window; | 160 | wgt634u_flash_resource.start = mcore->pflash.window; |
161 | wgt634u_flash_resource.end = mcore->flash_window | 161 | wgt634u_flash_resource.end = mcore->pflash.window |
162 | + mcore->flash_window_size | 162 | + mcore->pflash.window_size |
163 | - 1; | 163 | - 1; |
164 | return platform_add_devices(wgt634u_devices, | 164 | return platform_add_devices(wgt634u_devices, |
165 | ARRAY_SIZE(wgt634u_devices)); | 165 | ARRAY_SIZE(wgt634u_devices)); |
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile index bc96e2908f14..6e927cf20df2 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile | |||
@@ -24,9 +24,6 @@ DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES)) | |||
24 | 24 | ||
25 | obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES)) | 25 | obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES)) |
26 | 26 | ||
27 | $(obj)/%.dtb: $(src)/%.dts FORCE | ||
28 | $(call if_changed_dep,dtc) | ||
29 | |||
30 | # Let's keep the .dtb files around in case we want to look at them. | 27 | # Let's keep the .dtb files around in case we want to look at them. |
31 | .SECONDARY: $(addprefix $(obj)/, $(DTB_FILES)) | 28 | .SECONDARY: $(addprefix $(obj)/, $(DTB_FILES)) |
32 | 29 | ||
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index d38246e33ddb..9f883bf76953 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * measurement, and debugging facilities. | 30 | * measurement, and debugging facilities. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/irqflags.h> | ||
33 | #include <asm/octeon/cvmx.h> | 34 | #include <asm/octeon/cvmx.h> |
34 | #include <asm/octeon/cvmx-l2c.h> | 35 | #include <asm/octeon/cvmx-l2c.h> |
35 | #include <asm/octeon/cvmx-spinlock.h> | 36 | #include <asm/octeon/cvmx-spinlock.h> |
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index b6fde2bb51b6..4ca8e5c99225 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig | |||
@@ -473,7 +473,7 @@ CONFIG_USB_GADGET_NET2280=y | |||
473 | CONFIG_USB_ZERO=m | 473 | CONFIG_USB_ZERO=m |
474 | CONFIG_USB_ETH=m | 474 | CONFIG_USB_ETH=m |
475 | CONFIG_USB_GADGETFS=m | 475 | CONFIG_USB_GADGETFS=m |
476 | CONFIG_USB_FILE_STORAGE=m | 476 | CONFIG_USB_MASS_STORAGE=m |
477 | CONFIG_USB_G_SERIAL=m | 477 | CONFIG_USB_G_SERIAL=m |
478 | CONFIG_USB_MIDI_GADGET=m | 478 | CONFIG_USB_MIDI_GADGET=m |
479 | CONFIG_LEDS_CLASS=y | 479 | CONFIG_LEDS_CLASS=y |
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 17a36c125172..face9d26e6d5 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig | |||
@@ -233,6 +233,7 @@ CONFIG_USB_EHCI_HCD=y | |||
233 | CONFIG_USB_EHCI_ROOT_HUB_TT=y | 233 | CONFIG_USB_EHCI_ROOT_HUB_TT=y |
234 | CONFIG_USB_EHCI_TT_NEWSCHED=y | 234 | CONFIG_USB_EHCI_TT_NEWSCHED=y |
235 | CONFIG_USB_OHCI_HCD=y | 235 | CONFIG_USB_OHCI_HCD=y |
236 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
236 | CONFIG_USB_UHCI_HCD=y | 237 | CONFIG_USB_UHCI_HCD=y |
237 | CONFIG_USB_STORAGE=y | 238 | CONFIG_USB_STORAGE=y |
238 | CONFIG_NEW_LEDS=y | 239 | CONFIG_NEW_LEDS=y |
diff --git a/arch/mips/configs/db1235_defconfig b/arch/mips/configs/db1235_defconfig index c48998ffd198..14752dde7540 100644 --- a/arch/mips/configs/db1235_defconfig +++ b/arch/mips/configs/db1235_defconfig | |||
@@ -346,8 +346,10 @@ CONFIG_USB=y | |||
346 | CONFIG_USB_DYNAMIC_MINORS=y | 346 | CONFIG_USB_DYNAMIC_MINORS=y |
347 | CONFIG_USB_SUSPEND=y | 347 | CONFIG_USB_SUSPEND=y |
348 | CONFIG_USB_EHCI_HCD=y | 348 | CONFIG_USB_EHCI_HCD=y |
349 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
349 | CONFIG_USB_EHCI_ROOT_HUB_TT=y | 350 | CONFIG_USB_EHCI_ROOT_HUB_TT=y |
350 | CONFIG_USB_OHCI_HCD=y | 351 | CONFIG_USB_OHCI_HCD=y |
352 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
351 | CONFIG_USB_STORAGE=y | 353 | CONFIG_USB_STORAGE=y |
352 | CONFIG_MMC=y | 354 | CONFIG_MMC=y |
353 | CONFIG_MMC_CLKGATE=y | 355 | CONFIG_MMC_CLKGATE=y |
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig index 48a40aefaf58..fb64589015fc 100644 --- a/arch/mips/configs/gpr_defconfig +++ b/arch/mips/configs/gpr_defconfig | |||
@@ -291,6 +291,7 @@ CONFIG_USB_MON=y | |||
291 | CONFIG_USB_EHCI_HCD=y | 291 | CONFIG_USB_EHCI_HCD=y |
292 | CONFIG_USB_EHCI_ROOT_HUB_TT=y | 292 | CONFIG_USB_EHCI_ROOT_HUB_TT=y |
293 | CONFIG_USB_OHCI_HCD=y | 293 | CONFIG_USB_OHCI_HCD=y |
294 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
294 | CONFIG_USB_STORAGE=m | 295 | CONFIG_USB_STORAGE=m |
295 | CONFIG_USB_LIBUSUAL=y | 296 | CONFIG_USB_LIBUSUAL=y |
296 | CONFIG_USB_SERIAL=y | 297 | CONFIG_USB_SERIAL=y |
diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig index 80cff8bea8e8..7eb75543ca1a 100644 --- a/arch/mips/configs/ls1b_defconfig +++ b/arch/mips/configs/ls1b_defconfig | |||
@@ -76,6 +76,7 @@ CONFIG_HID_GENERIC=m | |||
76 | CONFIG_USB=y | 76 | CONFIG_USB=y |
77 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | 77 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y |
78 | CONFIG_USB_EHCI_HCD=y | 78 | CONFIG_USB_EHCI_HCD=y |
79 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
79 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | 80 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set |
80 | CONFIG_USB_STORAGE=m | 81 | CONFIG_USB_STORAGE=m |
81 | CONFIG_USB_SERIAL=m | 82 | CONFIG_USB_SERIAL=m |
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 46c61edcdf7b..9fa8f16068d8 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig | |||
@@ -581,6 +581,7 @@ CONFIG_USB_MON=m | |||
581 | CONFIG_USB_EHCI_HCD=m | 581 | CONFIG_USB_EHCI_HCD=m |
582 | CONFIG_USB_EHCI_ROOT_HUB_TT=y | 582 | CONFIG_USB_EHCI_ROOT_HUB_TT=y |
583 | CONFIG_USB_OHCI_HCD=m | 583 | CONFIG_USB_OHCI_HCD=m |
584 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
584 | CONFIG_USB_UHCI_HCD=m | 585 | CONFIG_USB_UHCI_HCD=m |
585 | CONFIG_USB_U132_HCD=m | 586 | CONFIG_USB_U132_HCD=m |
586 | CONFIG_USB_SL811_HCD=m | 587 | CONFIG_USB_SL811_HCD=m |
@@ -661,7 +662,7 @@ CONFIG_USB_GADGET_NET2280=y | |||
661 | CONFIG_USB_ZERO=m | 662 | CONFIG_USB_ZERO=m |
662 | CONFIG_USB_ETH=m | 663 | CONFIG_USB_ETH=m |
663 | CONFIG_USB_GADGETFS=m | 664 | CONFIG_USB_GADGETFS=m |
664 | CONFIG_USB_FILE_STORAGE=m | 665 | CONFIG_USB_MASS_STORAGE=m |
665 | CONFIG_USB_G_SERIAL=m | 666 | CONFIG_USB_G_SERIAL=m |
666 | CONFIG_USB_MIDI_GADGET=m | 667 | CONFIG_USB_MIDI_GADGET=m |
667 | CONFIG_MMC=m | 668 | CONFIG_MMC=m |
diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c index 7cf80ca2c1d2..f9f5307434c2 100644 --- a/arch/mips/fw/arc/misc.c +++ b/arch/mips/fw/arc/misc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/irqflags.h> | ||
14 | 15 | ||
15 | #include <asm/bcache.h> | 16 | #include <asm/bcache.h> |
16 | 17 | ||
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 533053d12ced..9b54b7a403d4 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild | |||
@@ -1 +1,2 @@ | |||
1 | # MIPS headers | 1 | # MIPS headers |
2 | generic-y += trace_clock.h | ||
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 82ad35ce2b45..46ac73abd5ee 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
17 | #include <linux/irqflags.h> | ||
18 | #include <linux/types.h> | 17 | #include <linux/types.h> |
19 | #include <asm/barrier.h> | 18 | #include <asm/barrier.h> |
20 | #include <asm/byteorder.h> /* sigh ... */ | 19 | #include <asm/byteorder.h> /* sigh ... */ |
@@ -44,6 +43,24 @@ | |||
44 | #define smp_mb__before_clear_bit() smp_mb__before_llsc() | 43 | #define smp_mb__before_clear_bit() smp_mb__before_llsc() |
45 | #define smp_mb__after_clear_bit() smp_llsc_mb() | 44 | #define smp_mb__after_clear_bit() smp_llsc_mb() |
46 | 45 | ||
46 | |||
47 | /* | ||
48 | * These are the "slower" versions of the functions and are in bitops.c. | ||
49 | * These functions call raw_local_irq_{save,restore}(). | ||
50 | */ | ||
51 | void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); | ||
52 | void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); | ||
53 | void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); | ||
54 | int __mips_test_and_set_bit(unsigned long nr, | ||
55 | volatile unsigned long *addr); | ||
56 | int __mips_test_and_set_bit_lock(unsigned long nr, | ||
57 | volatile unsigned long *addr); | ||
58 | int __mips_test_and_clear_bit(unsigned long nr, | ||
59 | volatile unsigned long *addr); | ||
60 | int __mips_test_and_change_bit(unsigned long nr, | ||
61 | volatile unsigned long *addr); | ||
62 | |||
63 | |||
47 | /* | 64 | /* |
48 | * set_bit - Atomically set a bit in memory | 65 | * set_bit - Atomically set a bit in memory |
49 | * @nr: the bit to set | 66 | * @nr: the bit to set |
@@ -57,7 +74,7 @@ | |||
57 | static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | 74 | static inline void set_bit(unsigned long nr, volatile unsigned long *addr) |
58 | { | 75 | { |
59 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 76 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
60 | unsigned short bit = nr & SZLONG_MASK; | 77 | int bit = nr & SZLONG_MASK; |
61 | unsigned long temp; | 78 | unsigned long temp; |
62 | 79 | ||
63 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 80 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
@@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
92 | : "=&r" (temp), "+m" (*m) | 109 | : "=&r" (temp), "+m" (*m) |
93 | : "ir" (1UL << bit)); | 110 | : "ir" (1UL << bit)); |
94 | } while (unlikely(!temp)); | 111 | } while (unlikely(!temp)); |
95 | } else { | 112 | } else |
96 | volatile unsigned long *a = addr; | 113 | __mips_set_bit(nr, addr); |
97 | unsigned long mask; | ||
98 | unsigned long flags; | ||
99 | |||
100 | a += nr >> SZLONG_LOG; | ||
101 | mask = 1UL << bit; | ||
102 | raw_local_irq_save(flags); | ||
103 | *a |= mask; | ||
104 | raw_local_irq_restore(flags); | ||
105 | } | ||
106 | } | 114 | } |
107 | 115 | ||
108 | /* | 116 | /* |
@@ -118,7 +126,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
118 | static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | 126 | static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) |
119 | { | 127 | { |
120 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 128 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
121 | unsigned short bit = nr & SZLONG_MASK; | 129 | int bit = nr & SZLONG_MASK; |
122 | unsigned long temp; | 130 | unsigned long temp; |
123 | 131 | ||
124 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 132 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
@@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
153 | : "=&r" (temp), "+m" (*m) | 161 | : "=&r" (temp), "+m" (*m) |
154 | : "ir" (~(1UL << bit))); | 162 | : "ir" (~(1UL << bit))); |
155 | } while (unlikely(!temp)); | 163 | } while (unlikely(!temp)); |
156 | } else { | 164 | } else |
157 | volatile unsigned long *a = addr; | 165 | __mips_clear_bit(nr, addr); |
158 | unsigned long mask; | ||
159 | unsigned long flags; | ||
160 | |||
161 | a += nr >> SZLONG_LOG; | ||
162 | mask = 1UL << bit; | ||
163 | raw_local_irq_save(flags); | ||
164 | *a &= ~mask; | ||
165 | raw_local_irq_restore(flags); | ||
166 | } | ||
167 | } | 166 | } |
168 | 167 | ||
169 | /* | 168 | /* |
@@ -191,7 +190,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad | |||
191 | */ | 190 | */ |
192 | static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | 191 | static inline void change_bit(unsigned long nr, volatile unsigned long *addr) |
193 | { | 192 | { |
194 | unsigned short bit = nr & SZLONG_MASK; | 193 | int bit = nr & SZLONG_MASK; |
195 | 194 | ||
196 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 195 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
197 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 196 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
@@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
220 | : "=&r" (temp), "+m" (*m) | 219 | : "=&r" (temp), "+m" (*m) |
221 | : "ir" (1UL << bit)); | 220 | : "ir" (1UL << bit)); |
222 | } while (unlikely(!temp)); | 221 | } while (unlikely(!temp)); |
223 | } else { | 222 | } else |
224 | volatile unsigned long *a = addr; | 223 | __mips_change_bit(nr, addr); |
225 | unsigned long mask; | ||
226 | unsigned long flags; | ||
227 | |||
228 | a += nr >> SZLONG_LOG; | ||
229 | mask = 1UL << bit; | ||
230 | raw_local_irq_save(flags); | ||
231 | *a ^= mask; | ||
232 | raw_local_irq_restore(flags); | ||
233 | } | ||
234 | } | 224 | } |
235 | 225 | ||
236 | /* | 226 | /* |
@@ -244,7 +234,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
244 | static inline int test_and_set_bit(unsigned long nr, | 234 | static inline int test_and_set_bit(unsigned long nr, |
245 | volatile unsigned long *addr) | 235 | volatile unsigned long *addr) |
246 | { | 236 | { |
247 | unsigned short bit = nr & SZLONG_MASK; | 237 | int bit = nr & SZLONG_MASK; |
248 | unsigned long res; | 238 | unsigned long res; |
249 | 239 | ||
250 | smp_mb__before_llsc(); | 240 | smp_mb__before_llsc(); |
@@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, | |||
281 | } while (unlikely(!res)); | 271 | } while (unlikely(!res)); |
282 | 272 | ||
283 | res = temp & (1UL << bit); | 273 | res = temp & (1UL << bit); |
284 | } else { | 274 | } else |
285 | volatile unsigned long *a = addr; | 275 | res = __mips_test_and_set_bit(nr, addr); |
286 | unsigned long mask; | ||
287 | unsigned long flags; | ||
288 | |||
289 | a += nr >> SZLONG_LOG; | ||
290 | mask = 1UL << bit; | ||
291 | raw_local_irq_save(flags); | ||
292 | res = (mask & *a); | ||
293 | *a |= mask; | ||
294 | raw_local_irq_restore(flags); | ||
295 | } | ||
296 | 276 | ||
297 | smp_llsc_mb(); | 277 | smp_llsc_mb(); |
298 | 278 | ||
@@ -310,7 +290,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
310 | static inline int test_and_set_bit_lock(unsigned long nr, | 290 | static inline int test_and_set_bit_lock(unsigned long nr, |
311 | volatile unsigned long *addr) | 291 | volatile unsigned long *addr) |
312 | { | 292 | { |
313 | unsigned short bit = nr & SZLONG_MASK; | 293 | int bit = nr & SZLONG_MASK; |
314 | unsigned long res; | 294 | unsigned long res; |
315 | 295 | ||
316 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 296 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
@@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
345 | } while (unlikely(!res)); | 325 | } while (unlikely(!res)); |
346 | 326 | ||
347 | res = temp & (1UL << bit); | 327 | res = temp & (1UL << bit); |
348 | } else { | 328 | } else |
349 | volatile unsigned long *a = addr; | 329 | res = __mips_test_and_set_bit_lock(nr, addr); |
350 | unsigned long mask; | ||
351 | unsigned long flags; | ||
352 | |||
353 | a += nr >> SZLONG_LOG; | ||
354 | mask = 1UL << bit; | ||
355 | raw_local_irq_save(flags); | ||
356 | res = (mask & *a); | ||
357 | *a |= mask; | ||
358 | raw_local_irq_restore(flags); | ||
359 | } | ||
360 | 330 | ||
361 | smp_llsc_mb(); | 331 | smp_llsc_mb(); |
362 | 332 | ||
@@ -373,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
373 | static inline int test_and_clear_bit(unsigned long nr, | 343 | static inline int test_and_clear_bit(unsigned long nr, |
374 | volatile unsigned long *addr) | 344 | volatile unsigned long *addr) |
375 | { | 345 | { |
376 | unsigned short bit = nr & SZLONG_MASK; | 346 | int bit = nr & SZLONG_MASK; |
377 | unsigned long res; | 347 | unsigned long res; |
378 | 348 | ||
379 | smp_mb__before_llsc(); | 349 | smp_mb__before_llsc(); |
@@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
428 | } while (unlikely(!res)); | 398 | } while (unlikely(!res)); |
429 | 399 | ||
430 | res = temp & (1UL << bit); | 400 | res = temp & (1UL << bit); |
431 | } else { | 401 | } else |
432 | volatile unsigned long *a = addr; | 402 | res = __mips_test_and_clear_bit(nr, addr); |
433 | unsigned long mask; | ||
434 | unsigned long flags; | ||
435 | |||
436 | a += nr >> SZLONG_LOG; | ||
437 | mask = 1UL << bit; | ||
438 | raw_local_irq_save(flags); | ||
439 | res = (mask & *a); | ||
440 | *a &= ~mask; | ||
441 | raw_local_irq_restore(flags); | ||
442 | } | ||
443 | 403 | ||
444 | smp_llsc_mb(); | 404 | smp_llsc_mb(); |
445 | 405 | ||
@@ -457,7 +417,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
457 | static inline int test_and_change_bit(unsigned long nr, | 417 | static inline int test_and_change_bit(unsigned long nr, |
458 | volatile unsigned long *addr) | 418 | volatile unsigned long *addr) |
459 | { | 419 | { |
460 | unsigned short bit = nr & SZLONG_MASK; | 420 | int bit = nr & SZLONG_MASK; |
461 | unsigned long res; | 421 | unsigned long res; |
462 | 422 | ||
463 | smp_mb__before_llsc(); | 423 | smp_mb__before_llsc(); |
@@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, | |||
494 | } while (unlikely(!res)); | 454 | } while (unlikely(!res)); |
495 | 455 | ||
496 | res = temp & (1UL << bit); | 456 | res = temp & (1UL << bit); |
497 | } else { | 457 | } else |
498 | volatile unsigned long *a = addr; | 458 | res = __mips_test_and_change_bit(nr, addr); |
499 | unsigned long mask; | ||
500 | unsigned long flags; | ||
501 | |||
502 | a += nr >> SZLONG_LOG; | ||
503 | mask = 1UL << bit; | ||
504 | raw_local_irq_save(flags); | ||
505 | res = (mask & *a); | ||
506 | *a ^= mask; | ||
507 | raw_local_irq_restore(flags); | ||
508 | } | ||
509 | 459 | ||
510 | smp_llsc_mb(); | 460 | smp_llsc_mb(); |
511 | 461 | ||
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 58277e0e9cd4..3c5d1464b7bd 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h | |||
@@ -290,7 +290,7 @@ struct compat_shmid64_ds { | |||
290 | 290 | ||
291 | static inline int is_compat_task(void) | 291 | static inline int is_compat_task(void) |
292 | { | 292 | { |
293 | return test_thread_flag(TIF_32BIT); | 293 | return test_thread_flag(TIF_32BIT_ADDR); |
294 | } | 294 | } |
295 | 295 | ||
296 | #endif /* _ASM_COMPAT_H */ | 296 | #endif /* _ASM_COMPAT_H */ |
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index bd94946a18f3..ef99db994c2f 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h | |||
@@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, | |||
95 | pte_t *ptep, pte_t pte, | 95 | pte_t *ptep, pte_t pte, |
96 | int dirty) | 96 | int dirty) |
97 | { | 97 | { |
98 | return ptep_set_access_flags(vma, addr, ptep, pte, dirty); | 98 | int changed = !pte_same(*ptep, pte); |
99 | |||
100 | if (changed) { | ||
101 | set_pte_at(vma->vm_mm, addr, ptep, pte); | ||
102 | /* | ||
103 | * There could be some standard sized pages in there, | ||
104 | * get them all. | ||
105 | */ | ||
106 | flush_tlb_range(vma, addr, addr + HPAGE_SIZE); | ||
107 | } | ||
108 | return changed; | ||
99 | } | 109 | } |
100 | 110 | ||
101 | static inline pte_t huge_ptep_get(pte_t *ptep) | 111 | static inline pte_t huge_ptep_get(pte_t *ptep) |
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 29d9c23c20c7..ff2e0345e013 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/irqflags.h> | ||
18 | 19 | ||
19 | #include <asm/addrspace.h> | 20 | #include <asm/addrspace.h> |
20 | #include <asm/bug.h> | 21 | #include <asm/bug.h> |
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 309cbcd6909c..9f3384c789d7 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h | |||
@@ -16,83 +16,13 @@ | |||
16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
17 | #include <asm/hazards.h> | 17 | #include <asm/hazards.h> |
18 | 18 | ||
19 | __asm__( | 19 | #if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) |
20 | " .macro arch_local_irq_enable \n" | ||
21 | " .set push \n" | ||
22 | " .set reorder \n" | ||
23 | " .set noat \n" | ||
24 | #ifdef CONFIG_MIPS_MT_SMTC | ||
25 | " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | ||
26 | " ori $1, 0x400 \n" | ||
27 | " xori $1, 0x400 \n" | ||
28 | " mtc0 $1, $2, 1 \n" | ||
29 | #elif defined(CONFIG_CPU_MIPSR2) | ||
30 | " ei \n" | ||
31 | #else | ||
32 | " mfc0 $1,$12 \n" | ||
33 | " ori $1,0x1f \n" | ||
34 | " xori $1,0x1e \n" | ||
35 | " mtc0 $1,$12 \n" | ||
36 | #endif | ||
37 | " irq_enable_hazard \n" | ||
38 | " .set pop \n" | ||
39 | " .endm"); | ||
40 | 20 | ||
41 | extern void smtc_ipi_replay(void); | ||
42 | |||
43 | static inline void arch_local_irq_enable(void) | ||
44 | { | ||
45 | #ifdef CONFIG_MIPS_MT_SMTC | ||
46 | /* | ||
47 | * SMTC kernel needs to do a software replay of queued | ||
48 | * IPIs, at the cost of call overhead on each local_irq_enable() | ||
49 | */ | ||
50 | smtc_ipi_replay(); | ||
51 | #endif | ||
52 | __asm__ __volatile__( | ||
53 | "arch_local_irq_enable" | ||
54 | : /* no outputs */ | ||
55 | : /* no inputs */ | ||
56 | : "memory"); | ||
57 | } | ||
58 | |||
59 | |||
60 | /* | ||
61 | * For cli() we have to insert nops to make sure that the new value | ||
62 | * has actually arrived in the status register before the end of this | ||
63 | * macro. | ||
64 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | ||
65 | * no nops at all. | ||
66 | */ | ||
67 | /* | ||
68 | * For TX49, operating only IE bit is not enough. | ||
69 | * | ||
70 | * If mfc0 $12 follows store and the mfc0 is last instruction of a | ||
71 | * page and fetching the next instruction causes TLB miss, the result | ||
72 | * of the mfc0 might wrongly contain EXL bit. | ||
73 | * | ||
74 | * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | ||
75 | * | ||
76 | * Workaround: mask EXL bit of the result or place a nop before mfc0. | ||
77 | */ | ||
78 | __asm__( | 21 | __asm__( |
79 | " .macro arch_local_irq_disable\n" | 22 | " .macro arch_local_irq_disable\n" |
80 | " .set push \n" | 23 | " .set push \n" |
81 | " .set noat \n" | 24 | " .set noat \n" |
82 | #ifdef CONFIG_MIPS_MT_SMTC | ||
83 | " mfc0 $1, $2, 1 \n" | ||
84 | " ori $1, 0x400 \n" | ||
85 | " .set noreorder \n" | ||
86 | " mtc0 $1, $2, 1 \n" | ||
87 | #elif defined(CONFIG_CPU_MIPSR2) | ||
88 | " di \n" | 25 | " di \n" |
89 | #else | ||
90 | " mfc0 $1,$12 \n" | ||
91 | " ori $1,0x1f \n" | ||
92 | " xori $1,0x1f \n" | ||
93 | " .set noreorder \n" | ||
94 | " mtc0 $1,$12 \n" | ||
95 | #endif | ||
96 | " irq_disable_hazard \n" | 26 | " irq_disable_hazard \n" |
97 | " .set pop \n" | 27 | " .set pop \n" |
98 | " .endm \n"); | 28 | " .endm \n"); |
@@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) | |||
106 | : "memory"); | 36 | : "memory"); |
107 | } | 37 | } |
108 | 38 | ||
109 | __asm__( | ||
110 | " .macro arch_local_save_flags flags \n" | ||
111 | " .set push \n" | ||
112 | " .set reorder \n" | ||
113 | #ifdef CONFIG_MIPS_MT_SMTC | ||
114 | " mfc0 \\flags, $2, 1 \n" | ||
115 | #else | ||
116 | " mfc0 \\flags, $12 \n" | ||
117 | #endif | ||
118 | " .set pop \n" | ||
119 | " .endm \n"); | ||
120 | |||
121 | static inline unsigned long arch_local_save_flags(void) | ||
122 | { | ||
123 | unsigned long flags; | ||
124 | asm volatile("arch_local_save_flags %0" : "=r" (flags)); | ||
125 | return flags; | ||
126 | } | ||
127 | 39 | ||
128 | __asm__( | 40 | __asm__( |
129 | " .macro arch_local_irq_save result \n" | 41 | " .macro arch_local_irq_save result \n" |
130 | " .set push \n" | 42 | " .set push \n" |
131 | " .set reorder \n" | 43 | " .set reorder \n" |
132 | " .set noat \n" | 44 | " .set noat \n" |
133 | #ifdef CONFIG_MIPS_MT_SMTC | ||
134 | " mfc0 \\result, $2, 1 \n" | ||
135 | " ori $1, \\result, 0x400 \n" | ||
136 | " .set noreorder \n" | ||
137 | " mtc0 $1, $2, 1 \n" | ||
138 | " andi \\result, \\result, 0x400 \n" | ||
139 | #elif defined(CONFIG_CPU_MIPSR2) | ||
140 | " di \\result \n" | 45 | " di \\result \n" |
141 | " andi \\result, 1 \n" | 46 | " andi \\result, 1 \n" |
142 | #else | ||
143 | " mfc0 \\result, $12 \n" | ||
144 | " ori $1, \\result, 0x1f \n" | ||
145 | " xori $1, 0x1f \n" | ||
146 | " .set noreorder \n" | ||
147 | " mtc0 $1, $12 \n" | ||
148 | #endif | ||
149 | " irq_disable_hazard \n" | 47 | " irq_disable_hazard \n" |
150 | " .set pop \n" | 48 | " .set pop \n" |
151 | " .endm \n"); | 49 | " .endm \n"); |
@@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) | |||
160 | return flags; | 58 | return flags; |
161 | } | 59 | } |
162 | 60 | ||
61 | |||
163 | __asm__( | 62 | __asm__( |
164 | " .macro arch_local_irq_restore flags \n" | 63 | " .macro arch_local_irq_restore flags \n" |
165 | " .set push \n" | 64 | " .set push \n" |
166 | " .set noreorder \n" | 65 | " .set noreorder \n" |
167 | " .set noat \n" | 66 | " .set noat \n" |
168 | #ifdef CONFIG_MIPS_MT_SMTC | 67 | #if defined(CONFIG_IRQ_CPU) |
169 | "mfc0 $1, $2, 1 \n" | ||
170 | "andi \\flags, 0x400 \n" | ||
171 | "ori $1, 0x400 \n" | ||
172 | "xori $1, 0x400 \n" | ||
173 | "or \\flags, $1 \n" | ||
174 | "mtc0 \\flags, $2, 1 \n" | ||
175 | #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
176 | /* | 68 | /* |
177 | * Slow, but doesn't suffer from a relatively unlikely race | 69 | * Slow, but doesn't suffer from a relatively unlikely race |
178 | * condition we're having since days 1. | 70 | * condition we're having since days 1. |
179 | */ | 71 | */ |
180 | " beqz \\flags, 1f \n" | 72 | " beqz \\flags, 1f \n" |
181 | " di \n" | 73 | " di \n" |
182 | " ei \n" | 74 | " ei \n" |
183 | "1: \n" | 75 | "1: \n" |
184 | #elif defined(CONFIG_CPU_MIPSR2) | 76 | #else |
185 | /* | 77 | /* |
186 | * Fast, dangerous. Life is fun, life is good. | 78 | * Fast, dangerous. Life is fun, life is good. |
187 | */ | 79 | */ |
188 | " mfc0 $1, $12 \n" | 80 | " mfc0 $1, $12 \n" |
189 | " ins $1, \\flags, 0, 1 \n" | 81 | " ins $1, \\flags, 0, 1 \n" |
190 | " mtc0 $1, $12 \n" | 82 | " mtc0 $1, $12 \n" |
191 | #else | ||
192 | " mfc0 $1, $12 \n" | ||
193 | " andi \\flags, 1 \n" | ||
194 | " ori $1, 0x1f \n" | ||
195 | " xori $1, 0x1f \n" | ||
196 | " or \\flags, $1 \n" | ||
197 | " mtc0 \\flags, $12 \n" | ||
198 | #endif | 83 | #endif |
199 | " irq_disable_hazard \n" | 84 | " irq_disable_hazard \n" |
200 | " .set pop \n" | 85 | " .set pop \n" |
201 | " .endm \n"); | 86 | " .endm \n"); |
202 | 87 | ||
203 | |||
204 | static inline void arch_local_irq_restore(unsigned long flags) | 88 | static inline void arch_local_irq_restore(unsigned long flags) |
205 | { | 89 | { |
206 | unsigned long __tmp1; | 90 | unsigned long __tmp1; |
207 | 91 | ||
208 | #ifdef CONFIG_MIPS_MT_SMTC | ||
209 | /* | ||
210 | * SMTC kernel needs to do a software replay of queued | ||
211 | * IPIs, at the cost of branch and call overhead on each | ||
212 | * local_irq_restore() | ||
213 | */ | ||
214 | if (unlikely(!(flags & 0x0400))) | ||
215 | smtc_ipi_replay(); | ||
216 | #endif | ||
217 | |||
218 | __asm__ __volatile__( | 92 | __asm__ __volatile__( |
219 | "arch_local_irq_restore\t%0" | 93 | "arch_local_irq_restore\t%0" |
220 | : "=r" (__tmp1) | 94 | : "=r" (__tmp1) |
@@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) | |||
232 | : "0" (flags) | 106 | : "0" (flags) |
233 | : "memory"); | 107 | : "memory"); |
234 | } | 108 | } |
109 | #else | ||
110 | /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | ||
111 | void arch_local_irq_disable(void); | ||
112 | unsigned long arch_local_irq_save(void); | ||
113 | void arch_local_irq_restore(unsigned long flags); | ||
114 | void __arch_local_irq_restore(unsigned long flags); | ||
115 | #endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ | ||
116 | |||
117 | |||
118 | __asm__( | ||
119 | " .macro arch_local_irq_enable \n" | ||
120 | " .set push \n" | ||
121 | " .set reorder \n" | ||
122 | " .set noat \n" | ||
123 | #ifdef CONFIG_MIPS_MT_SMTC | ||
124 | " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | ||
125 | " ori $1, 0x400 \n" | ||
126 | " xori $1, 0x400 \n" | ||
127 | " mtc0 $1, $2, 1 \n" | ||
128 | #elif defined(CONFIG_CPU_MIPSR2) | ||
129 | " ei \n" | ||
130 | #else | ||
131 | " mfc0 $1,$12 \n" | ||
132 | " ori $1,0x1f \n" | ||
133 | " xori $1,0x1e \n" | ||
134 | " mtc0 $1,$12 \n" | ||
135 | #endif | ||
136 | " irq_enable_hazard \n" | ||
137 | " .set pop \n" | ||
138 | " .endm"); | ||
139 | |||
140 | extern void smtc_ipi_replay(void); | ||
141 | |||
142 | static inline void arch_local_irq_enable(void) | ||
143 | { | ||
144 | #ifdef CONFIG_MIPS_MT_SMTC | ||
145 | /* | ||
146 | * SMTC kernel needs to do a software replay of queued | ||
147 | * IPIs, at the cost of call overhead on each local_irq_enable() | ||
148 | */ | ||
149 | smtc_ipi_replay(); | ||
150 | #endif | ||
151 | __asm__ __volatile__( | ||
152 | "arch_local_irq_enable" | ||
153 | : /* no outputs */ | ||
154 | : /* no inputs */ | ||
155 | : "memory"); | ||
156 | } | ||
157 | |||
158 | |||
159 | __asm__( | ||
160 | " .macro arch_local_save_flags flags \n" | ||
161 | " .set push \n" | ||
162 | " .set reorder \n" | ||
163 | #ifdef CONFIG_MIPS_MT_SMTC | ||
164 | " mfc0 \\flags, $2, 1 \n" | ||
165 | #else | ||
166 | " mfc0 \\flags, $12 \n" | ||
167 | #endif | ||
168 | " .set pop \n" | ||
169 | " .endm \n"); | ||
170 | |||
171 | static inline unsigned long arch_local_save_flags(void) | ||
172 | { | ||
173 | unsigned long flags; | ||
174 | asm volatile("arch_local_save_flags %0" : "=r" (flags)); | ||
175 | return flags; | ||
176 | } | ||
177 | |||
235 | 178 | ||
236 | static inline int arch_irqs_disabled_flags(unsigned long flags) | 179 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
237 | { | 180 | { |
@@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) | |||
245 | #endif | 188 | #endif |
246 | } | 189 | } |
247 | 190 | ||
248 | #endif | 191 | #endif /* #ifndef __ASSEMBLY__ */ |
249 | 192 | ||
250 | /* | 193 | /* |
251 | * Do the CPU's IRQ-state tracing from assembly code. | 194 | * Do the CPU's IRQ-state tracing from assembly code. |
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 5e33fabe354d..d28c41e0887c 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -310,8 +310,6 @@ struct task_struct; | |||
310 | /* Free all resources held by a thread. */ | 310 | /* Free all resources held by a thread. */ |
311 | #define release_thread(thread) do { } while(0) | 311 | #define release_thread(thread) do { } while(0) |
312 | 312 | ||
313 | extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
314 | |||
315 | extern unsigned long thread_saved_pc(struct task_struct *tsk); | 313 | extern unsigned long thread_saved_pc(struct task_struct *tsk); |
316 | 314 | ||
317 | /* | 315 | /* |
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index 4f5da948a777..cec5e125f7e4 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h | |||
@@ -61,4 +61,10 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs) | |||
61 | die(str, regs); | 61 | die(str, regs); |
62 | } | 62 | } |
63 | 63 | ||
64 | #define current_pt_regs() \ | ||
65 | ({ \ | ||
66 | unsigned long sp = (unsigned long)__builtin_frame_address(0); \ | ||
67 | (struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1; \ | ||
68 | }) | ||
69 | |||
64 | #endif /* _ASM_PTRACE_H */ | 70 | #endif /* _ASM_PTRACE_H */ |
diff --git a/arch/mips/include/asm/signal.h b/arch/mips/include/asm/signal.h index 880240dff8b7..cf4a08062d1d 100644 --- a/arch/mips/include/asm/signal.h +++ b/arch/mips/include/asm/signal.h | |||
@@ -21,6 +21,4 @@ | |||
21 | #include <asm/sigcontext.h> | 21 | #include <asm/sigcontext.h> |
22 | #include <asm/siginfo.h> | 22 | #include <asm/siginfo.h> |
23 | 23 | ||
24 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
25 | |||
26 | #endif /* _ASM_SIGNAL_H */ | 24 | #endif /* _ASM_SIGNAL_H */ |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 8debe9e91754..18806a52061c 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
112 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ | 112 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ |
113 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ | 113 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
114 | 114 | ||
115 | #ifdef CONFIG_MIPS32_O32 | ||
116 | #define TIF_32BIT TIF_32BIT_REGS | ||
117 | #elif defined(CONFIG_MIPS32_N32) | ||
118 | #define TIF_32BIT _TIF_32BIT_ADDR | ||
119 | #endif /* CONFIG_MIPS32_O32 */ | ||
120 | |||
121 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 115 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
122 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 116 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
123 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 117 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 9e47cc11aa26..b306e2081cad 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 | 20 | #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 |
21 | #define __ARCH_WANT_OLD_READDIR | 21 | #define __ARCH_WANT_OLD_READDIR |
22 | #define __ARCH_WANT_SYS_ALARM | 22 | #define __ARCH_WANT_SYS_ALARM |
23 | #define __ARCH_WANT_SYS_EXECVE | ||
23 | #define __ARCH_WANT_SYS_GETHOSTNAME | 24 | #define __ARCH_WANT_SYS_GETHOSTNAME |
24 | #define __ARCH_WANT_SYS_IPC | 25 | #define __ARCH_WANT_SYS_IPC |
25 | #define __ARCH_WANT_SYS_PAUSE | 26 | #define __ARCH_WANT_SYS_PAUSE |
diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h index 92403c3d6007..addd56b60694 100644 --- a/arch/mips/include/uapi/asm/ioctls.h +++ b/arch/mips/include/uapi/asm/ioctls.h | |||
@@ -86,6 +86,9 @@ | |||
86 | #define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ | 86 | #define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ |
87 | #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ | 87 | #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ |
88 | #define TIOCVHANGUP 0x5437 | 88 | #define TIOCVHANGUP 0x5437 |
89 | #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ | ||
90 | #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ | ||
91 | #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ | ||
89 | 92 | ||
90 | /* I hope the range from 0x5480 on is free ... */ | 93 | /* I hope the range from 0x5480 on is free ... */ |
91 | #define TIOCSCTTY 0x5480 /* become controlling tty */ | 94 | #define TIOCSCTTY 0x5480 /* become controlling tty */ |
diff --git a/arch/mips/include/uapi/asm/mman.h b/arch/mips/include/uapi/asm/mman.h index 46d3da0d4b92..9a936ac9a942 100644 --- a/arch/mips/include/uapi/asm/mman.h +++ b/arch/mips/include/uapi/asm/mman.h | |||
@@ -87,4 +87,15 @@ | |||
87 | /* compatibility flags */ | 87 | /* compatibility flags */ |
88 | #define MAP_FILE 0 | 88 | #define MAP_FILE 0 |
89 | 89 | ||
90 | /* | ||
91 | * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. | ||
92 | * This gives us 6 bits, which is enough until someone invents 128 bit address | ||
93 | * spaces. | ||
94 | * | ||
95 | * Assume these are all power of twos. | ||
96 | * When 0 use the default page size. | ||
97 | */ | ||
98 | #define MAP_HUGE_SHIFT 26 | ||
99 | #define MAP_HUGE_MASK 0x3f | ||
100 | |||
90 | #endif /* _ASM_MMAN_H */ | 101 | #endif /* _ASM_MMAN_H */ |
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index c5ed59549cb8..17307ab90474 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h | |||
@@ -63,6 +63,7 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ | |||
63 | /* Socket filtering */ | 63 | /* Socket filtering */ |
64 | #define SO_ATTACH_FILTER 26 | 64 | #define SO_ATTACH_FILTER 26 |
65 | #define SO_DETACH_FILTER 27 | 65 | #define SO_DETACH_FILTER 27 |
66 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
66 | 67 | ||
67 | #define SO_PEERNAME 28 | 68 | #define SO_PEERNAME 28 |
68 | #define SO_TIMESTAMP 29 | 69 | #define SO_TIMESTAMP 29 |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b1fb7af3c350..cce3782c96c9 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
510 | c->cputype = CPU_R3000A; | 510 | c->cputype = CPU_R3000A; |
511 | __cpu_name[cpu] = "R3000A"; | 511 | __cpu_name[cpu] = "R3000A"; |
512 | } | 512 | } |
513 | break; | ||
514 | } else { | 513 | } else { |
515 | c->cputype = CPU_R3000; | 514 | c->cputype = CPU_R3000; |
516 | __cpu_name[cpu] = "R3000"; | 515 | __cpu_name[cpu] = "R3000"; |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index a6c133212003..e5786858cdb6 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
@@ -36,6 +36,11 @@ FEXPORT(ret_from_exception) | |||
36 | FEXPORT(ret_from_irq) | 36 | FEXPORT(ret_from_irq) |
37 | LONG_S s0, TI_REGS($28) | 37 | LONG_S s0, TI_REGS($28) |
38 | FEXPORT(__ret_from_irq) | 38 | FEXPORT(__ret_from_irq) |
39 | /* | ||
40 | * We can be coming here from a syscall done in the kernel space, | ||
41 | * e.g. a failed kernel_execve(). | ||
42 | */ | ||
43 | resume_userspace_check: | ||
39 | LONG_L t0, PT_STATUS(sp) # returning to kernel mode? | 44 | LONG_L t0, PT_STATUS(sp) # returning to kernel mode? |
40 | andi t0, t0, KU_USER | 45 | andi t0, t0, KU_USER |
41 | beqz t0, resume_kernel | 46 | beqz t0, resume_kernel |
@@ -65,6 +70,12 @@ need_resched: | |||
65 | b need_resched | 70 | b need_resched |
66 | #endif | 71 | #endif |
67 | 72 | ||
73 | FEXPORT(ret_from_kernel_thread) | ||
74 | jal schedule_tail # a0 = struct task_struct *prev | ||
75 | move a0, s1 | ||
76 | jal s0 | ||
77 | j syscall_exit | ||
78 | |||
68 | FEXPORT(ret_from_fork) | 79 | FEXPORT(ret_from_fork) |
69 | jal schedule_tail # a0 = struct task_struct *prev | 80 | jal schedule_tail # a0 = struct task_struct *prev |
70 | 81 | ||
@@ -162,7 +173,7 @@ work_notifysig: # deal with pending signals and | |||
162 | move a0, sp | 173 | move a0, sp |
163 | li a1, 0 | 174 | li a1, 0 |
164 | jal do_notify_resume # a2 already loaded | 175 | jal do_notify_resume # a2 already loaded |
165 | j resume_userspace | 176 | j resume_userspace_check |
166 | 177 | ||
167 | FEXPORT(syscall_exit_partial) | 178 | FEXPORT(syscall_exit_partial) |
168 | local_irq_disable # make sure need_resched doesn't | 179 | local_irq_disable # make sure need_resched doesn't |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 3a21acedf882..7adab86c632c 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2000 Silicon Graphics, Inc. | 4 | * Copyright (C) 2000 Silicon Graphics, Inc. |
5 | * Written by Ulf Carlsson (ulfc@engr.sgi.com) | 5 | * Written by Ulf Carlsson (ulfc@engr.sgi.com) |
6 | * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com) | ||
7 | */ | 6 | */ |
8 | #include <linux/compiler.h> | 7 | #include <linux/compiler.h> |
9 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
@@ -77,26 +76,6 @@ out: | |||
77 | return error; | 76 | return error; |
78 | } | 77 | } |
79 | 78 | ||
80 | /* | ||
81 | * sys_execve() executes a new program. | ||
82 | */ | ||
83 | asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs) | ||
84 | { | ||
85 | int error; | ||
86 | struct filename *filename; | ||
87 | |||
88 | filename = getname(compat_ptr(regs.regs[4])); | ||
89 | error = PTR_ERR(filename); | ||
90 | if (IS_ERR(filename)) | ||
91 | goto out; | ||
92 | error = compat_do_execve(filename->name, compat_ptr(regs.regs[5]), | ||
93 | compat_ptr(regs.regs[6]), ®s); | ||
94 | putname(filename); | ||
95 | |||
96 | out: | ||
97 | return error; | ||
98 | } | ||
99 | |||
100 | #define RLIM_INFINITY32 0x7fffffff | 79 | #define RLIM_INFINITY32 0x7fffffff |
101 | #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) | 80 | #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) |
102 | 81 | ||
@@ -333,7 +312,7 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) | |||
333 | /* Use __dummy4 instead of getting it off the stack, so that | 312 | /* Use __dummy4 instead of getting it off the stack, so that |
334 | syscall() works. */ | 313 | syscall() works. */ |
335 | child_tidptr = (int __user *) __dummy4; | 314 | child_tidptr = (int __user *) __dummy4; |
336 | return do_fork(clone_flags, newsp, ®s, 0, | 315 | return do_fork(clone_flags, newsp, 0, |
337 | parent_tidptr, child_tidptr); | 316 | parent_tidptr, child_tidptr); |
338 | } | 317 | } |
339 | 318 | ||
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 3fc1691110dc..2d9304c2b54c 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -32,8 +32,6 @@ EXPORT_SYMBOL(memset); | |||
32 | EXPORT_SYMBOL(memcpy); | 32 | EXPORT_SYMBOL(memcpy); |
33 | EXPORT_SYMBOL(memmove); | 33 | EXPORT_SYMBOL(memmove); |
34 | 34 | ||
35 | EXPORT_SYMBOL(kernel_thread); | ||
36 | |||
37 | /* | 35 | /* |
38 | * Functions that operate on entire pages. Mostly used by memory management. | 36 | * Functions that operate on entire pages. Mostly used by memory management. |
39 | */ | 37 | */ |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index e9a5fd7277f4..38097652d62d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -84,6 +84,7 @@ void __noreturn cpu_idle(void) | |||
84 | } | 84 | } |
85 | 85 | ||
86 | asmlinkage void ret_from_fork(void); | 86 | asmlinkage void ret_from_fork(void); |
87 | asmlinkage void ret_from_kernel_thread(void); | ||
87 | 88 | ||
88 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | 89 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) |
89 | { | 90 | { |
@@ -113,10 +114,10 @@ void flush_thread(void) | |||
113 | } | 114 | } |
114 | 115 | ||
115 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 116 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
116 | unsigned long unused, struct task_struct *p, struct pt_regs *regs) | 117 | unsigned long arg, struct task_struct *p) |
117 | { | 118 | { |
118 | struct thread_info *ti = task_thread_info(p); | 119 | struct thread_info *ti = task_thread_info(p); |
119 | struct pt_regs *childregs; | 120 | struct pt_regs *childregs, *regs = current_pt_regs(); |
120 | unsigned long childksp; | 121 | unsigned long childksp; |
121 | p->set_child_tid = p->clear_child_tid = NULL; | 122 | p->set_child_tid = p->clear_child_tid = NULL; |
122 | 123 | ||
@@ -136,19 +137,30 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
136 | childregs = (struct pt_regs *) childksp - 1; | 137 | childregs = (struct pt_regs *) childksp - 1; |
137 | /* Put the stack after the struct pt_regs. */ | 138 | /* Put the stack after the struct pt_regs. */ |
138 | childksp = (unsigned long) childregs; | 139 | childksp = (unsigned long) childregs; |
140 | p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); | ||
141 | if (unlikely(p->flags & PF_KTHREAD)) { | ||
142 | unsigned long status = p->thread.cp0_status; | ||
143 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
144 | ti->addr_limit = KERNEL_DS; | ||
145 | p->thread.reg16 = usp; /* fn */ | ||
146 | p->thread.reg17 = arg; | ||
147 | p->thread.reg29 = childksp; | ||
148 | p->thread.reg31 = (unsigned long) ret_from_kernel_thread; | ||
149 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
150 | status = (status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) | | ||
151 | ((status & (ST0_KUC | ST0_IEC)) << 2); | ||
152 | #else | ||
153 | status |= ST0_EXL; | ||
154 | #endif | ||
155 | childregs->cp0_status = status; | ||
156 | return 0; | ||
157 | } | ||
139 | *childregs = *regs; | 158 | *childregs = *regs; |
140 | childregs->regs[7] = 0; /* Clear error flag */ | 159 | childregs->regs[7] = 0; /* Clear error flag */ |
141 | |||
142 | childregs->regs[2] = 0; /* Child gets zero as return value */ | 160 | childregs->regs[2] = 0; /* Child gets zero as return value */ |
161 | childregs->regs[29] = usp; | ||
162 | ti->addr_limit = USER_DS; | ||
143 | 163 | ||
144 | if (childregs->cp0_status & ST0_CU0) { | ||
145 | childregs->regs[28] = (unsigned long) ti; | ||
146 | childregs->regs[29] = childksp; | ||
147 | ti->addr_limit = KERNEL_DS; | ||
148 | } else { | ||
149 | childregs->regs[29] = usp; | ||
150 | ti->addr_limit = USER_DS; | ||
151 | } | ||
152 | p->thread.reg29 = (unsigned long) childregs; | 164 | p->thread.reg29 = (unsigned long) childregs; |
153 | p->thread.reg31 = (unsigned long) ret_from_fork; | 165 | p->thread.reg31 = (unsigned long) ret_from_fork; |
154 | 166 | ||
@@ -156,7 +168,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
156 | * New tasks lose permission to use the fpu. This accelerates context | 168 | * New tasks lose permission to use the fpu. This accelerates context |
157 | * switching for most programs since they don't use the fpu. | 169 | * switching for most programs since they don't use the fpu. |
158 | */ | 170 | */ |
159 | p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); | ||
160 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); | 171 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
161 | 172 | ||
162 | #ifdef CONFIG_MIPS_MT_SMTC | 173 | #ifdef CONFIG_MIPS_MT_SMTC |
@@ -222,35 +233,6 @@ int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) | |||
222 | } | 233 | } |
223 | 234 | ||
224 | /* | 235 | /* |
225 | * Create a kernel thread | ||
226 | */ | ||
227 | static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *)) | ||
228 | { | ||
229 | do_exit(fn(arg)); | ||
230 | } | ||
231 | |||
232 | long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
233 | { | ||
234 | struct pt_regs regs; | ||
235 | |||
236 | memset(®s, 0, sizeof(regs)); | ||
237 | |||
238 | regs.regs[4] = (unsigned long) arg; | ||
239 | regs.regs[5] = (unsigned long) fn; | ||
240 | regs.cp0_epc = (unsigned long) kernel_thread_helper; | ||
241 | regs.cp0_status = read_c0_status(); | ||
242 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
243 | regs.cp0_status = (regs.cp0_status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) | | ||
244 | ((regs.cp0_status & (ST0_KUC | ST0_IEC)) << 2); | ||
245 | #else | ||
246 | regs.cp0_status |= ST0_EXL; | ||
247 | #endif | ||
248 | |||
249 | /* Ok, create the new process.. */ | ||
250 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * | 236 | * |
255 | */ | 237 | */ |
256 | struct mips_frame_info { | 238 | struct mips_frame_info { |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f6ba8381ee01..629719143763 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -167,7 +167,7 @@ EXPORT(sysn32_call_table) | |||
167 | PTR sys_getsockopt | 167 | PTR sys_getsockopt |
168 | PTR sys_clone /* 6055 */ | 168 | PTR sys_clone /* 6055 */ |
169 | PTR sys_fork | 169 | PTR sys_fork |
170 | PTR sys32_execve | 170 | PTR compat_sys_execve |
171 | PTR sys_exit | 171 | PTR sys_exit |
172 | PTR compat_sys_wait4 | 172 | PTR compat_sys_wait4 |
173 | PTR sys_kill /* 6060 */ | 173 | PTR sys_kill /* 6060 */ |
@@ -397,14 +397,14 @@ EXPORT(sysn32_call_table) | |||
397 | PTR sys_timerfd_create | 397 | PTR sys_timerfd_create |
398 | PTR compat_sys_timerfd_gettime /* 6285 */ | 398 | PTR compat_sys_timerfd_gettime /* 6285 */ |
399 | PTR compat_sys_timerfd_settime | 399 | PTR compat_sys_timerfd_settime |
400 | PTR sys_signalfd4 | 400 | PTR compat_sys_signalfd4 |
401 | PTR sys_eventfd2 | 401 | PTR sys_eventfd2 |
402 | PTR sys_epoll_create1 | 402 | PTR sys_epoll_create1 |
403 | PTR sys_dup3 /* 6290 */ | 403 | PTR sys_dup3 /* 6290 */ |
404 | PTR sys_pipe2 | 404 | PTR sys_pipe2 |
405 | PTR sys_inotify_init1 | 405 | PTR sys_inotify_init1 |
406 | PTR sys_preadv | 406 | PTR compat_sys_preadv |
407 | PTR sys_pwritev | 407 | PTR compat_sys_pwritev |
408 | PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ | 408 | PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ |
409 | PTR sys_perf_event_open | 409 | PTR sys_perf_event_open |
410 | PTR sys_accept4 | 410 | PTR sys_accept4 |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 53c2d7245764..9601be6afa3d 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -203,7 +203,7 @@ sys_call_table: | |||
203 | PTR sys_creat | 203 | PTR sys_creat |
204 | PTR sys_link | 204 | PTR sys_link |
205 | PTR sys_unlink /* 4010 */ | 205 | PTR sys_unlink /* 4010 */ |
206 | PTR sys32_execve | 206 | PTR compat_sys_execve |
207 | PTR sys_chdir | 207 | PTR sys_chdir |
208 | PTR compat_sys_time | 208 | PTR compat_sys_time |
209 | PTR sys_mknod | 209 | PTR sys_mknod |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a53f8ec37aac..290dc6a1d7a3 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; | |||
79 | void __init add_memory_region(phys_t start, phys_t size, long type) | 79 | void __init add_memory_region(phys_t start, phys_t size, long type) |
80 | { | 80 | { |
81 | int x = boot_mem_map.nr_map; | 81 | int x = boot_mem_map.nr_map; |
82 | struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; | 82 | int i; |
83 | 83 | ||
84 | /* Sanity check */ | 84 | /* Sanity check */ |
85 | if (start + size < start) { | 85 | if (start + size < start) { |
@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Try to merge with previous entry if any. This is far less than | 91 | * Try to merge with existing entry, if any. |
92 | * perfect but is sufficient for most real world cases. | ||
93 | */ | 92 | */ |
94 | if (x && prev->addr + prev->size == start && prev->type == type) { | 93 | for (i = 0; i < boot_mem_map.nr_map; i++) { |
95 | prev->size += size; | 94 | struct boot_mem_map_entry *entry = boot_mem_map.map + i; |
95 | unsigned long top; | ||
96 | |||
97 | if (entry->type != type) | ||
98 | continue; | ||
99 | |||
100 | if (start + size < entry->addr) | ||
101 | continue; /* no overlap */ | ||
102 | |||
103 | if (entry->addr + entry->size < start) | ||
104 | continue; /* no overlap */ | ||
105 | |||
106 | top = max(entry->addr + entry->size, start + size); | ||
107 | entry->addr = min(entry->addr, start); | ||
108 | entry->size = top - entry->addr; | ||
109 | |||
96 | return; | 110 | return; |
97 | } | 111 | } |
98 | 112 | ||
99 | if (x == BOOT_MEM_MAP_MAX) { | 113 | if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { |
100 | pr_err("Ooops! Too many entries in the memory map!\n"); | 114 | pr_err("Ooops! Too many entries in the memory map!\n"); |
101 | return; | 115 | return; |
102 | } | 116 | } |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 2bd561bc05ae..201cb76b4df9 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -92,7 +92,7 @@ save_static_function(sys_fork); | |||
92 | static int __used noinline | 92 | static int __used noinline |
93 | _sys_fork(nabi_no_regargs struct pt_regs regs) | 93 | _sys_fork(nabi_no_regargs struct pt_regs regs) |
94 | { | 94 | { |
95 | return do_fork(SIGCHLD, regs.regs[29], ®s, 0, NULL, NULL); | 95 | return do_fork(SIGCHLD, regs.regs[29], 0, NULL, NULL); |
96 | } | 96 | } |
97 | 97 | ||
98 | save_static_function(sys_clone); | 98 | save_static_function(sys_clone); |
@@ -123,32 +123,10 @@ _sys_clone(nabi_no_regargs struct pt_regs regs) | |||
123 | #else | 123 | #else |
124 | child_tidptr = (int __user *) regs.regs[8]; | 124 | child_tidptr = (int __user *) regs.regs[8]; |
125 | #endif | 125 | #endif |
126 | return do_fork(clone_flags, newsp, ®s, 0, | 126 | return do_fork(clone_flags, newsp, 0, |
127 | parent_tidptr, child_tidptr); | 127 | parent_tidptr, child_tidptr); |
128 | } | 128 | } |
129 | 129 | ||
130 | /* | ||
131 | * sys_execve() executes a new program. | ||
132 | */ | ||
133 | asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) | ||
134 | { | ||
135 | int error; | ||
136 | struct filename *filename; | ||
137 | |||
138 | filename = getname((const char __user *) (long)regs.regs[4]); | ||
139 | error = PTR_ERR(filename); | ||
140 | if (IS_ERR(filename)) | ||
141 | goto out; | ||
142 | error = do_execve(filename->name, | ||
143 | (const char __user *const __user *) (long)regs.regs[5], | ||
144 | (const char __user *const __user *) (long)regs.regs[6], | ||
145 | ®s); | ||
146 | putname(filename); | ||
147 | |||
148 | out: | ||
149 | return error; | ||
150 | } | ||
151 | |||
152 | SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) | 130 | SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) |
153 | { | 131 | { |
154 | struct thread_info *ti = task_thread_info(current); | 132 | struct thread_info *ti = task_thread_info(current); |
@@ -313,34 +291,3 @@ asmlinkage void bad_stack(void) | |||
313 | { | 291 | { |
314 | do_exit(SIGSEGV); | 292 | do_exit(SIGSEGV); |
315 | } | 293 | } |
316 | |||
317 | /* | ||
318 | * Do a system call from kernel instead of calling sys_execve so we | ||
319 | * end up with proper pt_regs. | ||
320 | */ | ||
321 | int kernel_execve(const char *filename, | ||
322 | const char *const argv[], | ||
323 | const char *const envp[]) | ||
324 | { | ||
325 | register unsigned long __a0 asm("$4") = (unsigned long) filename; | ||
326 | register unsigned long __a1 asm("$5") = (unsigned long) argv; | ||
327 | register unsigned long __a2 asm("$6") = (unsigned long) envp; | ||
328 | register unsigned long __a3 asm("$7"); | ||
329 | unsigned long __v0; | ||
330 | |||
331 | __asm__ volatile (" \n" | ||
332 | " .set noreorder \n" | ||
333 | " li $2, %5 # __NR_execve \n" | ||
334 | " syscall \n" | ||
335 | " move %0, $2 \n" | ||
336 | " .set reorder \n" | ||
337 | : "=&r" (__v0), "=r" (__a3) | ||
338 | : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve) | ||
339 | : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", | ||
340 | "memory"); | ||
341 | |||
342 | if (__a3 == 0) | ||
343 | return __v0; | ||
344 | |||
345 | return -__v0; | ||
346 | } | ||
diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile index 674fca45f72d..6fa72dd641b2 100644 --- a/arch/mips/lantiq/dts/Makefile +++ b/arch/mips/lantiq/dts/Makefile | |||
@@ -1,4 +1 @@ | |||
1 | obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o | obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o | |
2 | |||
3 | $(obj)/%.dtb: $(obj)/%.dts | ||
4 | $(call if_changed,dtc) | ||
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index c4a82e841c73..eeddc58802e1 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile | |||
@@ -2,8 +2,9 @@ | |||
2 | # Makefile for MIPS-specific library files.. | 2 | # Makefile for MIPS-specific library files.. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y += csum_partial.o delay.o memcpy.o memset.o \ | 5 | lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ |
6 | strlen_user.o strncpy_user.o strnlen_user.o uncached.o | 6 | mips-atomic.o strlen_user.o strncpy_user.o \ |
7 | strnlen_user.o uncached.o | ||
7 | 8 | ||
8 | obj-y += iomap.o | 9 | obj-y += iomap.o |
9 | obj-$(CONFIG_PCI) += iomap-pci.o | 10 | obj-$(CONFIG_PCI) += iomap-pci.o |
diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c new file mode 100644 index 000000000000..239a9c957b02 --- /dev/null +++ b/arch/mips/lib/bitops.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) | ||
7 | * Copyright (c) 1999, 2000 Silicon Graphics, Inc. | ||
8 | */ | ||
9 | #include <linux/bitops.h> | ||
10 | #include <linux/irqflags.h> | ||
11 | #include <linux/export.h> | ||
12 | |||
13 | |||
14 | /** | ||
15 | * __mips_set_bit - Atomically set a bit in memory. This is called by | ||
16 | * set_bit() if it cannot find a faster solution. | ||
17 | * @nr: the bit to set | ||
18 | * @addr: the address to start counting from | ||
19 | */ | ||
20 | void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) | ||
21 | { | ||
22 | volatile unsigned long *a = addr; | ||
23 | unsigned bit = nr & SZLONG_MASK; | ||
24 | unsigned long mask; | ||
25 | unsigned long flags; | ||
26 | |||
27 | a += nr >> SZLONG_LOG; | ||
28 | mask = 1UL << bit; | ||
29 | raw_local_irq_save(flags); | ||
30 | *a |= mask; | ||
31 | raw_local_irq_restore(flags); | ||
32 | } | ||
33 | EXPORT_SYMBOL(__mips_set_bit); | ||
34 | |||
35 | |||
36 | /** | ||
37 | * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if | ||
38 | * it cannot find a faster solution. | ||
39 | * @nr: Bit to clear | ||
40 | * @addr: Address to start counting from | ||
41 | */ | ||
42 | void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) | ||
43 | { | ||
44 | volatile unsigned long *a = addr; | ||
45 | unsigned bit = nr & SZLONG_MASK; | ||
46 | unsigned long mask; | ||
47 | unsigned long flags; | ||
48 | |||
49 | a += nr >> SZLONG_LOG; | ||
50 | mask = 1UL << bit; | ||
51 | raw_local_irq_save(flags); | ||
52 | *a &= ~mask; | ||
53 | raw_local_irq_restore(flags); | ||
54 | } | ||
55 | EXPORT_SYMBOL(__mips_clear_bit); | ||
56 | |||
57 | |||
58 | /** | ||
59 | * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() | ||
60 | * if it cannot find a faster solution. | ||
61 | * @nr: Bit to change | ||
62 | * @addr: Address to start counting from | ||
63 | */ | ||
64 | void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) | ||
65 | { | ||
66 | volatile unsigned long *a = addr; | ||
67 | unsigned bit = nr & SZLONG_MASK; | ||
68 | unsigned long mask; | ||
69 | unsigned long flags; | ||
70 | |||
71 | a += nr >> SZLONG_LOG; | ||
72 | mask = 1UL << bit; | ||
73 | raw_local_irq_save(flags); | ||
74 | *a ^= mask; | ||
75 | raw_local_irq_restore(flags); | ||
76 | } | ||
77 | EXPORT_SYMBOL(__mips_change_bit); | ||
78 | |||
79 | |||
80 | /** | ||
81 | * __mips_test_and_set_bit - Set a bit and return its old value. This is | ||
82 | * called by test_and_set_bit() if it cannot find a faster solution. | ||
83 | * @nr: Bit to set | ||
84 | * @addr: Address to count from | ||
85 | */ | ||
86 | int __mips_test_and_set_bit(unsigned long nr, | ||
87 | volatile unsigned long *addr) | ||
88 | { | ||
89 | volatile unsigned long *a = addr; | ||
90 | unsigned bit = nr & SZLONG_MASK; | ||
91 | unsigned long mask; | ||
92 | unsigned long flags; | ||
93 | unsigned long res; | ||
94 | |||
95 | a += nr >> SZLONG_LOG; | ||
96 | mask = 1UL << bit; | ||
97 | raw_local_irq_save(flags); | ||
98 | res = (mask & *a); | ||
99 | *a |= mask; | ||
100 | raw_local_irq_restore(flags); | ||
101 | return res; | ||
102 | } | ||
103 | EXPORT_SYMBOL(__mips_test_and_set_bit); | ||
104 | |||
105 | |||
106 | /** | ||
107 | * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is | ||
108 | * called by test_and_set_bit_lock() if it cannot find a faster solution. | ||
109 | * @nr: Bit to set | ||
110 | * @addr: Address to count from | ||
111 | */ | ||
112 | int __mips_test_and_set_bit_lock(unsigned long nr, | ||
113 | volatile unsigned long *addr) | ||
114 | { | ||
115 | volatile unsigned long *a = addr; | ||
116 | unsigned bit = nr & SZLONG_MASK; | ||
117 | unsigned long mask; | ||
118 | unsigned long flags; | ||
119 | unsigned long res; | ||
120 | |||
121 | a += nr >> SZLONG_LOG; | ||
122 | mask = 1UL << bit; | ||
123 | raw_local_irq_save(flags); | ||
124 | res = (mask & *a); | ||
125 | *a |= mask; | ||
126 | raw_local_irq_restore(flags); | ||
127 | return res; | ||
128 | } | ||
129 | EXPORT_SYMBOL(__mips_test_and_set_bit_lock); | ||
130 | |||
131 | |||
132 | /** | ||
133 | * __mips_test_and_clear_bit - Clear a bit and return its old value. This is | ||
134 | * called by test_and_clear_bit() if it cannot find a faster solution. | ||
135 | * @nr: Bit to clear | ||
136 | * @addr: Address to count from | ||
137 | */ | ||
138 | int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) | ||
139 | { | ||
140 | volatile unsigned long *a = addr; | ||
141 | unsigned bit = nr & SZLONG_MASK; | ||
142 | unsigned long mask; | ||
143 | unsigned long flags; | ||
144 | unsigned long res; | ||
145 | |||
146 | a += nr >> SZLONG_LOG; | ||
147 | mask = 1UL << bit; | ||
148 | raw_local_irq_save(flags); | ||
149 | res = (mask & *a); | ||
150 | *a &= ~mask; | ||
151 | raw_local_irq_restore(flags); | ||
152 | return res; | ||
153 | } | ||
154 | EXPORT_SYMBOL(__mips_test_and_clear_bit); | ||
155 | |||
156 | |||
157 | /** | ||
158 | * __mips_test_and_change_bit - Change a bit and return its old value. This is | ||
159 | * called by test_and_change_bit() if it cannot find a faster solution. | ||
160 | * @nr: Bit to change | ||
161 | * @addr: Address to count from | ||
162 | */ | ||
163 | int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) | ||
164 | { | ||
165 | volatile unsigned long *a = addr; | ||
166 | unsigned bit = nr & SZLONG_MASK; | ||
167 | unsigned long mask; | ||
168 | unsigned long flags; | ||
169 | unsigned long res; | ||
170 | |||
171 | a += nr >> SZLONG_LOG; | ||
172 | mask = 1UL << bit; | ||
173 | raw_local_irq_save(flags); | ||
174 | res = (mask & *a); | ||
175 | *a ^= mask; | ||
176 | raw_local_irq_restore(flags); | ||
177 | return res; | ||
178 | } | ||
179 | EXPORT_SYMBOL(__mips_test_and_change_bit); | ||
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c new file mode 100644 index 000000000000..cd160be3ce4d --- /dev/null +++ b/arch/mips/lib/mips-atomic.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle | ||
7 | * Copyright (C) 1996 by Paul M. Antoine | ||
8 | * Copyright (C) 1999 Silicon Graphics | ||
9 | * Copyright (C) 2000 MIPS Technologies, Inc. | ||
10 | */ | ||
11 | #include <asm/irqflags.h> | ||
12 | #include <asm/hazards.h> | ||
13 | #include <linux/compiler.h> | ||
14 | #include <linux/preempt.h> | ||
15 | #include <linux/export.h> | ||
16 | |||
17 | #if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) | ||
18 | |||
19 | /* | ||
20 | * For cli() we have to insert nops to make sure that the new value | ||
21 | * has actually arrived in the status register before the end of this | ||
22 | * macro. | ||
23 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | ||
24 | * no nops at all. | ||
25 | */ | ||
26 | /* | ||
27 | * For TX49, operating only IE bit is not enough. | ||
28 | * | ||
29 | * If mfc0 $12 follows store and the mfc0 is last instruction of a | ||
30 | * page and fetching the next instruction causes TLB miss, the result | ||
31 | * of the mfc0 might wrongly contain EXL bit. | ||
32 | * | ||
33 | * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | ||
34 | * | ||
35 | * Workaround: mask EXL bit of the result or place a nop before mfc0. | ||
36 | */ | ||
37 | __asm__( | ||
38 | " .macro arch_local_irq_disable\n" | ||
39 | " .set push \n" | ||
40 | " .set noat \n" | ||
41 | #ifdef CONFIG_MIPS_MT_SMTC | ||
42 | " mfc0 $1, $2, 1 \n" | ||
43 | " ori $1, 0x400 \n" | ||
44 | " .set noreorder \n" | ||
45 | " mtc0 $1, $2, 1 \n" | ||
46 | #elif defined(CONFIG_CPU_MIPSR2) | ||
47 | /* see irqflags.h for inline function */ | ||
48 | #else | ||
49 | " mfc0 $1,$12 \n" | ||
50 | " ori $1,0x1f \n" | ||
51 | " xori $1,0x1f \n" | ||
52 | " .set noreorder \n" | ||
53 | " mtc0 $1,$12 \n" | ||
54 | #endif | ||
55 | " irq_disable_hazard \n" | ||
56 | " .set pop \n" | ||
57 | " .endm \n"); | ||
58 | |||
59 | notrace void arch_local_irq_disable(void) | ||
60 | { | ||
61 | preempt_disable(); | ||
62 | __asm__ __volatile__( | ||
63 | "arch_local_irq_disable" | ||
64 | : /* no outputs */ | ||
65 | : /* no inputs */ | ||
66 | : "memory"); | ||
67 | preempt_enable(); | ||
68 | } | ||
69 | EXPORT_SYMBOL(arch_local_irq_disable); | ||
70 | |||
71 | |||
72 | __asm__( | ||
73 | " .macro arch_local_irq_save result \n" | ||
74 | " .set push \n" | ||
75 | " .set reorder \n" | ||
76 | " .set noat \n" | ||
77 | #ifdef CONFIG_MIPS_MT_SMTC | ||
78 | " mfc0 \\result, $2, 1 \n" | ||
79 | " ori $1, \\result, 0x400 \n" | ||
80 | " .set noreorder \n" | ||
81 | " mtc0 $1, $2, 1 \n" | ||
82 | " andi \\result, \\result, 0x400 \n" | ||
83 | #elif defined(CONFIG_CPU_MIPSR2) | ||
84 | /* see irqflags.h for inline function */ | ||
85 | #else | ||
86 | " mfc0 \\result, $12 \n" | ||
87 | " ori $1, \\result, 0x1f \n" | ||
88 | " xori $1, 0x1f \n" | ||
89 | " .set noreorder \n" | ||
90 | " mtc0 $1, $12 \n" | ||
91 | #endif | ||
92 | " irq_disable_hazard \n" | ||
93 | " .set pop \n" | ||
94 | " .endm \n"); | ||
95 | |||
96 | notrace unsigned long arch_local_irq_save(void) | ||
97 | { | ||
98 | unsigned long flags; | ||
99 | preempt_disable(); | ||
100 | asm volatile("arch_local_irq_save\t%0" | ||
101 | : "=r" (flags) | ||
102 | : /* no inputs */ | ||
103 | : "memory"); | ||
104 | preempt_enable(); | ||
105 | return flags; | ||
106 | } | ||
107 | EXPORT_SYMBOL(arch_local_irq_save); | ||
108 | |||
109 | |||
110 | __asm__( | ||
111 | " .macro arch_local_irq_restore flags \n" | ||
112 | " .set push \n" | ||
113 | " .set noreorder \n" | ||
114 | " .set noat \n" | ||
115 | #ifdef CONFIG_MIPS_MT_SMTC | ||
116 | "mfc0 $1, $2, 1 \n" | ||
117 | "andi \\flags, 0x400 \n" | ||
118 | "ori $1, 0x400 \n" | ||
119 | "xori $1, 0x400 \n" | ||
120 | "or \\flags, $1 \n" | ||
121 | "mtc0 \\flags, $2, 1 \n" | ||
122 | #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
123 | /* see irqflags.h for inline function */ | ||
124 | #elif defined(CONFIG_CPU_MIPSR2) | ||
125 | /* see irqflags.h for inline function */ | ||
126 | #else | ||
127 | " mfc0 $1, $12 \n" | ||
128 | " andi \\flags, 1 \n" | ||
129 | " ori $1, 0x1f \n" | ||
130 | " xori $1, 0x1f \n" | ||
131 | " or \\flags, $1 \n" | ||
132 | " mtc0 \\flags, $12 \n" | ||
133 | #endif | ||
134 | " irq_disable_hazard \n" | ||
135 | " .set pop \n" | ||
136 | " .endm \n"); | ||
137 | |||
138 | notrace void arch_local_irq_restore(unsigned long flags) | ||
139 | { | ||
140 | unsigned long __tmp1; | ||
141 | |||
142 | #ifdef CONFIG_MIPS_MT_SMTC | ||
143 | /* | ||
144 | * SMTC kernel needs to do a software replay of queued | ||
145 | * IPIs, at the cost of branch and call overhead on each | ||
146 | * local_irq_restore() | ||
147 | */ | ||
148 | if (unlikely(!(flags & 0x0400))) | ||
149 | smtc_ipi_replay(); | ||
150 | #endif | ||
151 | preempt_disable(); | ||
152 | __asm__ __volatile__( | ||
153 | "arch_local_irq_restore\t%0" | ||
154 | : "=r" (__tmp1) | ||
155 | : "0" (flags) | ||
156 | : "memory"); | ||
157 | preempt_enable(); | ||
158 | } | ||
159 | EXPORT_SYMBOL(arch_local_irq_restore); | ||
160 | |||
161 | |||
162 | notrace void __arch_local_irq_restore(unsigned long flags) | ||
163 | { | ||
164 | unsigned long __tmp1; | ||
165 | |||
166 | preempt_disable(); | ||
167 | __asm__ __volatile__( | ||
168 | "arch_local_irq_restore\t%0" | ||
169 | : "=r" (__tmp1) | ||
170 | : "0" (flags) | ||
171 | : "memory"); | ||
172 | preempt_enable(); | ||
173 | } | ||
174 | EXPORT_SYMBOL(__arch_local_irq_restore); | ||
175 | |||
176 | #endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ | ||
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index e92d59c4bd78..0412ad61e290 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/phy.h> | 13 | #include <linux/phy.h> |
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | #include <linux/stmmac.h> | 15 | #include <linux/stmmac.h> |
16 | #include <linux/usb/ehci_pdriver.h> | ||
16 | #include <asm-generic/sizes.h> | 17 | #include <asm-generic/sizes.h> |
17 | 18 | ||
18 | #include <loongson1.h> | 19 | #include <loongson1.h> |
@@ -107,13 +108,17 @@ static struct resource ls1x_ehci_resources[] = { | |||
107 | }, | 108 | }, |
108 | }; | 109 | }; |
109 | 110 | ||
111 | static struct usb_ehci_pdata ls1x_ehci_pdata = { | ||
112 | }; | ||
113 | |||
110 | struct platform_device ls1x_ehci_device = { | 114 | struct platform_device ls1x_ehci_device = { |
111 | .name = "ls1x-ehci", | 115 | .name = "ehci-platform", |
112 | .id = -1, | 116 | .id = -1, |
113 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), | 117 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), |
114 | .resource = ls1x_ehci_resources, | 118 | .resource = ls1x_ehci_resources, |
115 | .dev = { | 119 | .dev = { |
116 | .dma_mask = &ls1x_ehci_dmamask, | 120 | .dma_mask = &ls1x_ehci_dmamask, |
121 | .platform_data = &ls1x_ehci_pdata, | ||
117 | }, | 122 | }, |
118 | }; | 123 | }; |
119 | 124 | ||
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 302d779d5b0d..d9be7540a6be 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c | |||
@@ -45,18 +45,6 @@ static unsigned long mmap_base(unsigned long rnd) | |||
45 | return PAGE_ALIGN(TASK_SIZE - gap - rnd); | 45 | return PAGE_ALIGN(TASK_SIZE - gap - rnd); |
46 | } | 46 | } |
47 | 47 | ||
48 | static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr, | ||
49 | unsigned long pgoff) | ||
50 | { | ||
51 | unsigned long base = addr & ~shm_align_mask; | ||
52 | unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask; | ||
53 | |||
54 | if (base + off <= addr) | ||
55 | return base + off; | ||
56 | |||
57 | return base - off; | ||
58 | } | ||
59 | |||
60 | #define COLOUR_ALIGN(addr, pgoff) \ | 48 | #define COLOUR_ALIGN(addr, pgoff) \ |
61 | ((((addr) + shm_align_mask) & ~shm_align_mask) + \ | 49 | ((((addr) + shm_align_mask) & ~shm_align_mask) + \ |
62 | (((pgoff) << PAGE_SHIFT) & shm_align_mask)) | 50 | (((pgoff) << PAGE_SHIFT) & shm_align_mask)) |
@@ -71,6 +59,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, | |||
71 | struct vm_area_struct *vma; | 59 | struct vm_area_struct *vma; |
72 | unsigned long addr = addr0; | 60 | unsigned long addr = addr0; |
73 | int do_color_align; | 61 | int do_color_align; |
62 | struct vm_unmapped_area_info info; | ||
74 | 63 | ||
75 | if (unlikely(len > TASK_SIZE)) | 64 | if (unlikely(len > TASK_SIZE)) |
76 | return -ENOMEM; | 65 | return -ENOMEM; |
@@ -107,97 +96,31 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, | |||
107 | return addr; | 96 | return addr; |
108 | } | 97 | } |
109 | 98 | ||
110 | if (dir == UP) { | 99 | info.length = len; |
111 | addr = mm->mmap_base; | 100 | info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0; |
112 | if (do_color_align) | 101 | info.align_offset = pgoff << PAGE_SHIFT; |
113 | addr = COLOUR_ALIGN(addr, pgoff); | ||
114 | else | ||
115 | addr = PAGE_ALIGN(addr); | ||
116 | 102 | ||
117 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { | 103 | if (dir == DOWN) { |
118 | /* At this point: (!vma || addr < vma->vm_end). */ | 104 | info.flags = VM_UNMAPPED_AREA_TOPDOWN; |
119 | if (TASK_SIZE - len < addr) | 105 | info.low_limit = PAGE_SIZE; |
120 | return -ENOMEM; | 106 | info.high_limit = mm->mmap_base; |
121 | if (!vma || addr + len <= vma->vm_start) | 107 | addr = vm_unmapped_area(&info); |
122 | return addr; | 108 | |
123 | addr = vma->vm_end; | 109 | if (!(addr & ~PAGE_MASK)) |
124 | if (do_color_align) | 110 | return addr; |
125 | addr = COLOUR_ALIGN(addr, pgoff); | ||
126 | } | ||
127 | } else { | ||
128 | /* check if free_area_cache is useful for us */ | ||
129 | if (len <= mm->cached_hole_size) { | ||
130 | mm->cached_hole_size = 0; | ||
131 | mm->free_area_cache = mm->mmap_base; | ||
132 | } | ||
133 | 111 | ||
134 | /* | ||
135 | * either no address requested, or the mapping can't fit into | ||
136 | * the requested address hole | ||
137 | */ | ||
138 | addr = mm->free_area_cache; | ||
139 | if (do_color_align) { | ||
140 | unsigned long base = | ||
141 | COLOUR_ALIGN_DOWN(addr - len, pgoff); | ||
142 | addr = base + len; | ||
143 | } | ||
144 | |||
145 | /* make sure it can fit in the remaining address space */ | ||
146 | if (likely(addr > len)) { | ||
147 | vma = find_vma(mm, addr - len); | ||
148 | if (!vma || addr <= vma->vm_start) { | ||
149 | /* cache the address as a hint for next time */ | ||
150 | return mm->free_area_cache = addr - len; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | if (unlikely(mm->mmap_base < len)) | ||
155 | goto bottomup; | ||
156 | |||
157 | addr = mm->mmap_base - len; | ||
158 | if (do_color_align) | ||
159 | addr = COLOUR_ALIGN_DOWN(addr, pgoff); | ||
160 | |||
161 | do { | ||
162 | /* | ||
163 | * Lookup failure means no vma is above this address, | ||
164 | * else if new region fits below vma->vm_start, | ||
165 | * return with success: | ||
166 | */ | ||
167 | vma = find_vma(mm, addr); | ||
168 | if (likely(!vma || addr + len <= vma->vm_start)) { | ||
169 | /* cache the address as a hint for next time */ | ||
170 | return mm->free_area_cache = addr; | ||
171 | } | ||
172 | |||
173 | /* remember the largest hole we saw so far */ | ||
174 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
175 | mm->cached_hole_size = vma->vm_start - addr; | ||
176 | |||
177 | /* try just below the current vma->vm_start */ | ||
178 | addr = vma->vm_start - len; | ||
179 | if (do_color_align) | ||
180 | addr = COLOUR_ALIGN_DOWN(addr, pgoff); | ||
181 | } while (likely(len < vma->vm_start)); | ||
182 | |||
183 | bottomup: | ||
184 | /* | 112 | /* |
185 | * A failed mmap() very likely causes application failure, | 113 | * A failed mmap() very likely causes application failure, |
186 | * so fall back to the bottom-up function here. This scenario | 114 | * so fall back to the bottom-up function here. This scenario |
187 | * can happen with large stack limits and large mmap() | 115 | * can happen with large stack limits and large mmap() |
188 | * allocations. | 116 | * allocations. |
189 | */ | 117 | */ |
190 | mm->cached_hole_size = ~0UL; | ||
191 | mm->free_area_cache = TASK_UNMAPPED_BASE; | ||
192 | addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); | ||
193 | /* | ||
194 | * Restore the topdown base: | ||
195 | */ | ||
196 | mm->free_area_cache = mm->mmap_base; | ||
197 | mm->cached_hole_size = ~0UL; | ||
198 | |||
199 | return addr; | ||
200 | } | 118 | } |
119 | |||
120 | info.flags = 0; | ||
121 | info.low_limit = mm->mmap_base; | ||
122 | info.high_limit = TASK_SIZE; | ||
123 | return vm_unmapped_area(&info); | ||
201 | } | 124 | } |
202 | 125 | ||
203 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, | 126 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 4b9b935a070e..88e79ad6f811 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
120 | 120 | ||
121 | if (cpu_context(cpu, mm) != 0) { | 121 | if (cpu_context(cpu, mm) != 0) { |
122 | unsigned long size, flags; | 122 | unsigned long size, flags; |
123 | int huge = is_vm_hugetlb_page(vma); | ||
124 | 123 | ||
125 | ENTER_CRITICAL(flags); | 124 | ENTER_CRITICAL(flags); |
126 | if (huge) { | 125 | start = round_down(start, PAGE_SIZE << 1); |
127 | start = round_down(start, HPAGE_SIZE); | 126 | end = round_up(end, PAGE_SIZE << 1); |
128 | end = round_up(end, HPAGE_SIZE); | 127 | size = (end - start) >> (PAGE_SHIFT + 1); |
129 | size = (end - start) >> HPAGE_SHIFT; | ||
130 | } else { | ||
131 | start = round_down(start, PAGE_SIZE << 1); | ||
132 | end = round_up(end, PAGE_SIZE << 1); | ||
133 | size = (end - start) >> (PAGE_SHIFT + 1); | ||
134 | } | ||
135 | if (size <= current_cpu_data.tlbsize/2) { | 128 | if (size <= current_cpu_data.tlbsize/2) { |
136 | int oldpid = read_c0_entryhi(); | 129 | int oldpid = read_c0_entryhi(); |
137 | int newpid = cpu_asid(cpu, mm); | 130 | int newpid = cpu_asid(cpu, mm); |
@@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
140 | int idx; | 133 | int idx; |
141 | 134 | ||
142 | write_c0_entryhi(start | newpid); | 135 | write_c0_entryhi(start | newpid); |
143 | if (huge) | 136 | start += (PAGE_SIZE << 1); |
144 | start += HPAGE_SIZE; | ||
145 | else | ||
146 | start += (PAGE_SIZE << 1); | ||
147 | mtc0_tlbw_hazard(); | 137 | mtc0_tlbw_hazard(); |
148 | tlb_probe(); | 138 | tlb_probe(); |
149 | tlb_probe_hazard(); | 139 | tlb_probe_hazard(); |
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 80562b81f0f2..74732177851c 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mtd/partitions.h> | 29 | #include <linux/mtd/partitions.h> |
30 | #include <linux/mtd/physmap.h> | 30 | #include <linux/mtd/physmap.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <asm/mips-boards/maltaint.h> | ||
32 | #include <mtd/mtd-abi.h> | 33 | #include <mtd/mtd-abi.h> |
33 | 34 | ||
34 | #define SMC_PORT(base, int) \ | 35 | #define SMC_PORT(base, int) \ |
@@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { | |||
48 | SMC_PORT(0x2F8, 3), | 49 | SMC_PORT(0x2F8, 3), |
49 | { | 50 | { |
50 | .mapbase = 0x1f000900, /* The CBUS UART */ | 51 | .mapbase = 0x1f000900, /* The CBUS UART */ |
51 | .irq = MIPS_CPU_IRQ_BASE + 2, | 52 | .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, |
52 | .uartclk = 3686400, /* Twice the usual clk! */ | 53 | .uartclk = 3686400, /* Twice the usual clk! */ |
53 | .iotype = UPIO_MEM32, | 54 | .iotype = UPIO_MEM32, |
54 | .flags = CBUS_UART_FLAGS, | 55 | .flags = CBUS_UART_FLAGS, |
diff --git a/arch/mips/netlogic/dts/Makefile b/arch/mips/netlogic/dts/Makefile index 67ae3fe296f0..d117d46413aa 100644 --- a/arch/mips/netlogic/dts/Makefile +++ b/arch/mips/netlogic/dts/Makefile | |||
@@ -1,4 +1 @@ | |||
1 | obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o | obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o | |
2 | |||
3 | $(obj)/%.dtb: $(obj)/%.dts | ||
4 | $(call if_changed,dtc) | ||
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c index 71b44d82621d..507230eeb768 100644 --- a/arch/mips/netlogic/xlr/platform.c +++ b/arch/mips/netlogic/xlr/platform.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/serial_8250.h> | 15 | #include <linux/serial_8250.h> |
16 | #include <linux/serial_reg.h> | 16 | #include <linux/serial_reg.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/usb/ehci_pdriver.h> | ||
19 | #include <linux/usb/ohci_pdriver.h> | ||
18 | 20 | ||
19 | #include <asm/netlogic/haldefs.h> | 21 | #include <asm/netlogic/haldefs.h> |
20 | #include <asm/netlogic/xlr/iomap.h> | 22 | #include <asm/netlogic/xlr/iomap.h> |
@@ -123,12 +125,18 @@ static u64 xls_usb_dmamask = ~(u32)0; | |||
123 | }, \ | 125 | }, \ |
124 | } | 126 | } |
125 | 127 | ||
128 | static struct usb_ehci_pdata xls_usb_ehci_pdata = { | ||
129 | .caps_offset = 0, | ||
130 | }; | ||
131 | |||
132 | static struct usb_ohci_pdata xls_usb_ohci_pdata; | ||
133 | |||
126 | static struct platform_device xls_usb_ehci_device = | 134 | static struct platform_device xls_usb_ehci_device = |
127 | USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ); | 135 | USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ); |
128 | static struct platform_device xls_usb_ohci_device_0 = | 136 | static struct platform_device xls_usb_ohci_device_0 = |
129 | USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ); | 137 | USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ); |
130 | static struct platform_device xls_usb_ohci_device_1 = | 138 | static struct platform_device xls_usb_ohci_device_1 = |
131 | USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ); | 139 | USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ); |
132 | 140 | ||
133 | static struct platform_device *xls_platform_devices[] = { | 141 | static struct platform_device *xls_platform_devices[] = { |
134 | &xls_usb_ehci_device, | 142 | &xls_usb_ehci_device, |
@@ -172,14 +180,17 @@ int xls_platform_usb_init(void) | |||
172 | memres = CPHYSADDR((unsigned long)usb_mmio); | 180 | memres = CPHYSADDR((unsigned long)usb_mmio); |
173 | xls_usb_ehci_device.resource[0].start = memres; | 181 | xls_usb_ehci_device.resource[0].start = memres; |
174 | xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1; | 182 | xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1; |
183 | xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata; | ||
175 | 184 | ||
176 | memres += 0x400; | 185 | memres += 0x400; |
177 | xls_usb_ohci_device_0.resource[0].start = memres; | 186 | xls_usb_ohci_device_0.resource[0].start = memres; |
178 | xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1; | 187 | xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1; |
188 | xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata; | ||
179 | 189 | ||
180 | memres += 0x400; | 190 | memres += 0x400; |
181 | xls_usb_ohci_device_1.resource[0].start = memres; | 191 | xls_usb_ohci_device_1.resource[0].start = memres; |
182 | xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1; | 192 | xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1; |
193 | xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata; | ||
183 | 194 | ||
184 | return platform_add_devices(xls_platform_devices, | 195 | return platform_add_devices(xls_platform_devices, |
185 | ARRAY_SIZE(xls_platform_devices)); | 196 | ARRAY_SIZE(xls_platform_devices)); |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 04e35bcde07c..4040416e0603 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -313,10 +313,8 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) | |||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | #ifdef CONFIG_HOTPLUG | ||
317 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); | 316 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); |
318 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | 317 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); |
319 | #endif | ||
320 | 318 | ||
321 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 319 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
322 | enum pci_mmap_state mmap_state, int write_combine) | 320 | enum pci_mmap_state mmap_state, int write_combine) |
diff --git a/arch/mips/pnx8550/common/platform.c b/arch/mips/pnx8550/common/platform.c index 5264cc09a27b..0a8faeaa7b70 100644 --- a/arch/mips/pnx8550/common/platform.c +++ b/arch/mips/pnx8550/common/platform.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/serial.h> | 20 | #include <linux/serial.h> |
21 | #include <linux/serial_pnx8xxx.h> | 21 | #include <linux/serial_pnx8xxx.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/usb/ohci_pdriver.h> | ||
23 | 24 | ||
24 | #include <int.h> | 25 | #include <int.h> |
25 | #include <usb.h> | 26 | #include <usb.h> |
@@ -96,12 +97,40 @@ static u64 ohci_dmamask = DMA_BIT_MASK(32); | |||
96 | 97 | ||
97 | static u64 uart_dmamask = DMA_BIT_MASK(32); | 98 | static u64 uart_dmamask = DMA_BIT_MASK(32); |
98 | 99 | ||
100 | static int pnx8550_usb_ohci_power_on(struct platform_device *pdev) | ||
101 | { | ||
102 | /* | ||
103 | * Set register CLK48CTL to enable and 48MHz | ||
104 | */ | ||
105 | outl(0x00000003, PCI_BASE | 0x0004770c); | ||
106 | |||
107 | /* | ||
108 | * Set register CLK12CTL to enable and 48MHz | ||
109 | */ | ||
110 | outl(0x00000003, PCI_BASE | 0x00047710); | ||
111 | |||
112 | udelay(100); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void pnx8550_usb_ohci_power_off(struct platform_device *pdev) | ||
118 | { | ||
119 | udelay(10); | ||
120 | } | ||
121 | |||
122 | static struct usb_ohci_pdata pnx8550_usb_ohci_pdata = { | ||
123 | .power_on = pnx8550_usb_ohci_power_on, | ||
124 | .power_off = pnx8550_usb_ohci_power_off, | ||
125 | }; | ||
126 | |||
99 | static struct platform_device pnx8550_usb_ohci_device = { | 127 | static struct platform_device pnx8550_usb_ohci_device = { |
100 | .name = "pnx8550-ohci", | 128 | .name = "ohci-platform", |
101 | .id = -1, | 129 | .id = -1, |
102 | .dev = { | 130 | .dev = { |
103 | .dma_mask = &ohci_dmamask, | 131 | .dma_mask = &ohci_dmamask, |
104 | .coherent_dma_mask = DMA_BIT_MASK(32), | 132 | .coherent_dma_mask = DMA_BIT_MASK(32), |
133 | .platform_data = &pnx8550_usb_ohci_pdata, | ||
105 | }, | 134 | }, |
106 | .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources), | 135 | .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources), |
107 | .resource = pnx8550_usb_ohci_resources, | 136 | .resource = pnx8550_usb_ohci_resources, |