xref: /OK3568_Linux_fs/kernel/arch/arm/mach-ixp4xx/common.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * arch/arm/mach-ixp4xx/common.c
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Generic code shared across all IXP4XX platforms
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Maintainer: Deepak Saxena <dsaxena@plexity.net>
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Copyright 2002 (c) Intel Corporation
9*4882a593Smuzhiyun  * Copyright 2003-2004 (c) MontaVista, Software, Inc.
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * This file is licensed under  the terms of the GNU General Public
12*4882a593Smuzhiyun  * License version 2. This program is licensed "as is" without any
13*4882a593Smuzhiyun  * warranty of any kind, whether express or implied.
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/mm.h>
18*4882a593Smuzhiyun #include <linux/init.h>
19*4882a593Smuzhiyun #include <linux/serial.h>
20*4882a593Smuzhiyun #include <linux/tty.h>
21*4882a593Smuzhiyun #include <linux/platform_device.h>
22*4882a593Smuzhiyun #include <linux/serial_core.h>
23*4882a593Smuzhiyun #include <linux/interrupt.h>
24*4882a593Smuzhiyun #include <linux/bitops.h>
25*4882a593Smuzhiyun #include <linux/io.h>
26*4882a593Smuzhiyun #include <linux/export.h>
27*4882a593Smuzhiyun #include <linux/cpu.h>
28*4882a593Smuzhiyun #include <linux/pci.h>
29*4882a593Smuzhiyun #include <linux/sched_clock.h>
30*4882a593Smuzhiyun #include <linux/irqchip/irq-ixp4xx.h>
31*4882a593Smuzhiyun #include <linux/platform_data/timer-ixp4xx.h>
32*4882a593Smuzhiyun #include <linux/dma-map-ops.h>
33*4882a593Smuzhiyun #include <mach/udc.h>
34*4882a593Smuzhiyun #include <mach/hardware.h>
35*4882a593Smuzhiyun #include <mach/io.h>
36*4882a593Smuzhiyun #include <linux/uaccess.h>
37*4882a593Smuzhiyun #include <asm/page.h>
38*4882a593Smuzhiyun #include <asm/exception.h>
39*4882a593Smuzhiyun #include <asm/irq.h>
40*4882a593Smuzhiyun #include <asm/system_misc.h>
41*4882a593Smuzhiyun #include <asm/mach/map.h>
42*4882a593Smuzhiyun #include <asm/mach/irq.h>
43*4882a593Smuzhiyun #include <asm/mach/time.h>
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #include "irqs.h"
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define IXP4XX_TIMER_FREQ 66666000
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /*************************************************************************
50*4882a593Smuzhiyun  * IXP4xx chipset I/O mapping
51*4882a593Smuzhiyun  *************************************************************************/
52*4882a593Smuzhiyun static struct map_desc ixp4xx_io_desc[] __initdata = {
53*4882a593Smuzhiyun 	{	/* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
54*4882a593Smuzhiyun 		.virtual	= (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT,
55*4882a593Smuzhiyun 		.pfn		= __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
56*4882a593Smuzhiyun 		.length		= IXP4XX_PERIPHERAL_REGION_SIZE,
57*4882a593Smuzhiyun 		.type		= MT_DEVICE
58*4882a593Smuzhiyun 	}, {	/* Expansion Bus Config Registers */
59*4882a593Smuzhiyun 		.virtual	= (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT,
60*4882a593Smuzhiyun 		.pfn		= __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
61*4882a593Smuzhiyun 		.length		= IXP4XX_EXP_CFG_REGION_SIZE,
62*4882a593Smuzhiyun 		.type		= MT_DEVICE
63*4882a593Smuzhiyun 	}, {	/* PCI Registers */
64*4882a593Smuzhiyun 		.virtual	= (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
65*4882a593Smuzhiyun 		.pfn		= __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
66*4882a593Smuzhiyun 		.length		= IXP4XX_PCI_CFG_REGION_SIZE,
67*4882a593Smuzhiyun 		.type		= MT_DEVICE
68*4882a593Smuzhiyun 	},
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
ixp4xx_map_io(void)71*4882a593Smuzhiyun void __init ixp4xx_map_io(void)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun   	iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
ixp4xx_init_irq(void)76*4882a593Smuzhiyun void __init ixp4xx_init_irq(void)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun 	/*
79*4882a593Smuzhiyun 	 * ixp4xx does not implement the XScale PWRMODE register
80*4882a593Smuzhiyun 	 * so it must not call cpu_do_idle().
81*4882a593Smuzhiyun 	 */
82*4882a593Smuzhiyun 	cpu_idle_poll_ctrl(true);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS,
85*4882a593Smuzhiyun 			(cpu_is_ixp46x() || cpu_is_ixp43x()));
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
ixp4xx_timer_init(void)88*4882a593Smuzhiyun void __init ixp4xx_timer_init(void)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
91*4882a593Smuzhiyun 				  IRQ_IXP4XX_TIMER1,
92*4882a593Smuzhiyun 				  IXP4XX_TIMER_FREQ);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
96*4882a593Smuzhiyun 
ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info * info)97*4882a593Smuzhiyun void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun 	memcpy(&ixp4xx_udc_info, info, sizeof *info);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun static struct resource ixp4xx_udc_resources[] = {
103*4882a593Smuzhiyun 	[0] = {
104*4882a593Smuzhiyun 		.start  = 0xc800b000,
105*4882a593Smuzhiyun 		.end    = 0xc800bfff,
106*4882a593Smuzhiyun 		.flags  = IORESOURCE_MEM,
107*4882a593Smuzhiyun 	},
108*4882a593Smuzhiyun 	[1] = {
109*4882a593Smuzhiyun 		.start  = IRQ_IXP4XX_USB,
110*4882a593Smuzhiyun 		.end    = IRQ_IXP4XX_USB,
111*4882a593Smuzhiyun 		.flags  = IORESOURCE_IRQ,
112*4882a593Smuzhiyun 	},
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun static struct resource ixp4xx_gpio_resource[] = {
116*4882a593Smuzhiyun 	{
117*4882a593Smuzhiyun 		.start = IXP4XX_GPIO_BASE_PHYS,
118*4882a593Smuzhiyun 		.end = IXP4XX_GPIO_BASE_PHYS + 0xfff,
119*4882a593Smuzhiyun 		.flags = IORESOURCE_MEM,
120*4882a593Smuzhiyun 	},
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun static struct platform_device ixp4xx_gpio_device = {
124*4882a593Smuzhiyun 	.name           = "ixp4xx-gpio",
125*4882a593Smuzhiyun 	.id             = -1,
126*4882a593Smuzhiyun 	.dev = {
127*4882a593Smuzhiyun 		.coherent_dma_mask      = DMA_BIT_MASK(32),
128*4882a593Smuzhiyun 	},
129*4882a593Smuzhiyun 	.resource = ixp4xx_gpio_resource,
130*4882a593Smuzhiyun 	.num_resources  = ARRAY_SIZE(ixp4xx_gpio_resource),
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun /*
134*4882a593Smuzhiyun  * USB device controller. The IXP4xx uses the same controller as PXA25X,
135*4882a593Smuzhiyun  * so we just use the same device.
136*4882a593Smuzhiyun  */
137*4882a593Smuzhiyun static struct platform_device ixp4xx_udc_device = {
138*4882a593Smuzhiyun 	.name           = "pxa25x-udc",
139*4882a593Smuzhiyun 	.id             = -1,
140*4882a593Smuzhiyun 	.num_resources  = 2,
141*4882a593Smuzhiyun 	.resource       = ixp4xx_udc_resources,
142*4882a593Smuzhiyun 	.dev            = {
143*4882a593Smuzhiyun 		.platform_data = &ixp4xx_udc_info,
144*4882a593Smuzhiyun 	},
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun static struct resource ixp4xx_npe_resources[] = {
148*4882a593Smuzhiyun 	{
149*4882a593Smuzhiyun 		.start = IXP4XX_NPEA_BASE_PHYS,
150*4882a593Smuzhiyun 		.end = IXP4XX_NPEA_BASE_PHYS + 0xfff,
151*4882a593Smuzhiyun 		.flags = IORESOURCE_MEM,
152*4882a593Smuzhiyun 	},
153*4882a593Smuzhiyun 	{
154*4882a593Smuzhiyun 		.start = IXP4XX_NPEB_BASE_PHYS,
155*4882a593Smuzhiyun 		.end = IXP4XX_NPEB_BASE_PHYS + 0xfff,
156*4882a593Smuzhiyun 		.flags = IORESOURCE_MEM,
157*4882a593Smuzhiyun 	},
158*4882a593Smuzhiyun 	{
159*4882a593Smuzhiyun 		.start = IXP4XX_NPEC_BASE_PHYS,
160*4882a593Smuzhiyun 		.end = IXP4XX_NPEC_BASE_PHYS + 0xfff,
161*4882a593Smuzhiyun 		.flags = IORESOURCE_MEM,
162*4882a593Smuzhiyun 	},
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun static struct platform_device ixp4xx_npe_device = {
167*4882a593Smuzhiyun 	.name           = "ixp4xx-npe",
168*4882a593Smuzhiyun 	.id             = -1,
169*4882a593Smuzhiyun 	.num_resources  = ARRAY_SIZE(ixp4xx_npe_resources),
170*4882a593Smuzhiyun 	.resource       = ixp4xx_npe_resources,
171*4882a593Smuzhiyun };
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun static struct resource ixp4xx_qmgr_resources[] = {
174*4882a593Smuzhiyun 	{
175*4882a593Smuzhiyun 		.start = IXP4XX_QMGR_BASE_PHYS,
176*4882a593Smuzhiyun 		.end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
177*4882a593Smuzhiyun 		.flags = IORESOURCE_MEM,
178*4882a593Smuzhiyun 	},
179*4882a593Smuzhiyun 	{
180*4882a593Smuzhiyun 		.start = IRQ_IXP4XX_QM1,
181*4882a593Smuzhiyun 		.end = IRQ_IXP4XX_QM1,
182*4882a593Smuzhiyun 		.flags = IORESOURCE_IRQ,
183*4882a593Smuzhiyun 	},
184*4882a593Smuzhiyun 	{
185*4882a593Smuzhiyun 		.start = IRQ_IXP4XX_QM2,
186*4882a593Smuzhiyun 		.end = IRQ_IXP4XX_QM2,
187*4882a593Smuzhiyun 		.flags = IORESOURCE_IRQ,
188*4882a593Smuzhiyun 	},
189*4882a593Smuzhiyun };
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun static struct platform_device ixp4xx_qmgr_device = {
192*4882a593Smuzhiyun 	.name           = "ixp4xx-qmgr",
193*4882a593Smuzhiyun 	.id             = -1,
194*4882a593Smuzhiyun 	.num_resources  = ARRAY_SIZE(ixp4xx_qmgr_resources),
195*4882a593Smuzhiyun 	.resource       = ixp4xx_qmgr_resources,
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun static struct platform_device *ixp4xx_devices[] __initdata = {
199*4882a593Smuzhiyun 	&ixp4xx_npe_device,
200*4882a593Smuzhiyun 	&ixp4xx_qmgr_device,
201*4882a593Smuzhiyun 	&ixp4xx_gpio_device,
202*4882a593Smuzhiyun 	&ixp4xx_udc_device,
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun static struct resource ixp46x_i2c_resources[] = {
206*4882a593Smuzhiyun 	[0] = {
207*4882a593Smuzhiyun 		.start 	= 0xc8011000,
208*4882a593Smuzhiyun 		.end	= 0xc801101c,
209*4882a593Smuzhiyun 		.flags	= IORESOURCE_MEM,
210*4882a593Smuzhiyun 	},
211*4882a593Smuzhiyun 	[1] = {
212*4882a593Smuzhiyun 		.start 	= IRQ_IXP4XX_I2C,
213*4882a593Smuzhiyun 		.end	= IRQ_IXP4XX_I2C,
214*4882a593Smuzhiyun 		.flags	= IORESOURCE_IRQ
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun };
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun /*
219*4882a593Smuzhiyun  * I2C controller. The IXP46x uses the same block as the IOP3xx, so
220*4882a593Smuzhiyun  * we just use the same device name.
221*4882a593Smuzhiyun  */
222*4882a593Smuzhiyun static struct platform_device ixp46x_i2c_controller = {
223*4882a593Smuzhiyun 	.name		= "IOP3xx-I2C",
224*4882a593Smuzhiyun 	.id		= 0,
225*4882a593Smuzhiyun 	.num_resources	= 2,
226*4882a593Smuzhiyun 	.resource	= ixp46x_i2c_resources
227*4882a593Smuzhiyun };
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun static struct platform_device *ixp46x_devices[] __initdata = {
230*4882a593Smuzhiyun 	&ixp46x_i2c_controller
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun unsigned long ixp4xx_exp_bus_size;
234*4882a593Smuzhiyun EXPORT_SYMBOL(ixp4xx_exp_bus_size);
235*4882a593Smuzhiyun 
ixp4xx_sys_init(void)236*4882a593Smuzhiyun void __init ixp4xx_sys_init(void)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	ixp4xx_exp_bus_size = SZ_16M;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	if (cpu_is_ixp46x()) {
243*4882a593Smuzhiyun 		int region;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 		platform_add_devices(ixp46x_devices,
246*4882a593Smuzhiyun 				ARRAY_SIZE(ixp46x_devices));
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 		for (region = 0; region < 7; region++) {
249*4882a593Smuzhiyun 			if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
250*4882a593Smuzhiyun 				ixp4xx_exp_bus_size = SZ_32M;
251*4882a593Smuzhiyun 				break;
252*4882a593Smuzhiyun 			}
253*4882a593Smuzhiyun 		}
254*4882a593Smuzhiyun 	}
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	printk("IXP4xx: Using %luMiB expansion bus window size\n",
257*4882a593Smuzhiyun 			ixp4xx_exp_bus_size >> 20);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
261*4882a593Smuzhiyun EXPORT_SYMBOL(ixp4xx_timer_freq);
262*4882a593Smuzhiyun 
ixp4xx_restart(enum reboot_mode mode,const char * cmd)263*4882a593Smuzhiyun void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun 	if (mode == REBOOT_SOFT) {
266*4882a593Smuzhiyun 		/* Jump into ROM at address 0 */
267*4882a593Smuzhiyun 		soft_restart(0);
268*4882a593Smuzhiyun 	} else {
269*4882a593Smuzhiyun 		/* Use on-chip reset capability */
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 		/* set the "key" register to enable access to
272*4882a593Smuzhiyun 		 * "timer" and "enable" registers
273*4882a593Smuzhiyun 		 */
274*4882a593Smuzhiyun 		*IXP4XX_OSWK = IXP4XX_WDT_KEY;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 		/* write 0 to the timer register for an immediate reset */
277*4882a593Smuzhiyun 		*IXP4XX_OSWT = 0;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 		*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
280*4882a593Smuzhiyun 	}
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun #ifdef CONFIG_PCI
ixp4xx_needs_bounce(struct device * dev,dma_addr_t dma_addr,size_t size)284*4882a593Smuzhiyun static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	return (dma_addr + size) > SZ_64M;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
ixp4xx_platform_notify_remove(struct device * dev)289*4882a593Smuzhiyun static int ixp4xx_platform_notify_remove(struct device *dev)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	if (dev_is_pci(dev))
292*4882a593Smuzhiyun 		dmabounce_unregister_dev(dev);
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun #endif
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun /*
299*4882a593Smuzhiyun  * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
300*4882a593Smuzhiyun  */
ixp4xx_platform_notify(struct device * dev)301*4882a593Smuzhiyun static int ixp4xx_platform_notify(struct device *dev)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun 	dev->dma_mask = &dev->coherent_dma_mask;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun #ifdef CONFIG_PCI
306*4882a593Smuzhiyun 	if (dev_is_pci(dev)) {
307*4882a593Smuzhiyun 		dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
308*4882a593Smuzhiyun 		dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
309*4882a593Smuzhiyun 		return 0;
310*4882a593Smuzhiyun 	}
311*4882a593Smuzhiyun #endif
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	dev->coherent_dma_mask = DMA_BIT_MASK(32);
314*4882a593Smuzhiyun 	return 0;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
dma_set_coherent_mask(struct device * dev,u64 mask)317*4882a593Smuzhiyun int dma_set_coherent_mask(struct device *dev, u64 mask)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	if (dev_is_pci(dev))
320*4882a593Smuzhiyun 		mask &= DMA_BIT_MASK(28); /* 64 MB */
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
323*4882a593Smuzhiyun 		dev->coherent_dma_mask = mask;
324*4882a593Smuzhiyun 		return 0;
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	return -EIO;		/* device wanted sub-64MB mask */
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun EXPORT_SYMBOL(dma_set_coherent_mask);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun #ifdef CONFIG_IXP4XX_INDIRECT_PCI
332*4882a593Smuzhiyun /*
333*4882a593Smuzhiyun  * In the case of using indirect PCI, we simply return the actual PCI
334*4882a593Smuzhiyun  * address and our read/write implementation use that to drive the
335*4882a593Smuzhiyun  * access registers. If something outside of PCI is ioremap'd, we
336*4882a593Smuzhiyun  * fallback to the default.
337*4882a593Smuzhiyun  */
338*4882a593Smuzhiyun 
ixp4xx_ioremap_caller(phys_addr_t addr,size_t size,unsigned int mtype,void * caller)339*4882a593Smuzhiyun static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
340*4882a593Smuzhiyun 					   unsigned int mtype, void *caller)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	if (!is_pci_memory(addr))
343*4882a593Smuzhiyun 		return __arm_ioremap_caller(addr, size, mtype, caller);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	return (void __iomem *)addr;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun 
ixp4xx_iounmap(volatile void __iomem * addr)348*4882a593Smuzhiyun static void ixp4xx_iounmap(volatile void __iomem *addr)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun 	if (!is_pci_memory((__force u32)addr))
351*4882a593Smuzhiyun 		__iounmap(addr);
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun #endif
354*4882a593Smuzhiyun 
ixp4xx_init_early(void)355*4882a593Smuzhiyun void __init ixp4xx_init_early(void)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun 	platform_notify = ixp4xx_platform_notify;
358*4882a593Smuzhiyun #ifdef CONFIG_PCI
359*4882a593Smuzhiyun 	platform_notify_remove = ixp4xx_platform_notify_remove;
360*4882a593Smuzhiyun #endif
361*4882a593Smuzhiyun #ifdef CONFIG_IXP4XX_INDIRECT_PCI
362*4882a593Smuzhiyun 	arch_ioremap_caller = ixp4xx_ioremap_caller;
363*4882a593Smuzhiyun 	arch_iounmap = ixp4xx_iounmap;
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun }
366