xref: /openbmc/linux/arch/arm/mach-sa1100/neponset.c (revision d782f33d)
1 /*
2  * linux/arch/arm/mach-sa1100/neponset.c
3  *
4  */
5 #include <linux/kernel.h>
6 #include <linux/init.h>
7 #include <linux/ptrace.h>
8 #include <linux/tty.h>
9 #include <linux/ioport.h>
10 #include <linux/serial_core.h>
11 #include <linux/platform_device.h>
12 #include <linux/slab.h>
13 
14 #include <asm/hardware.h>
15 #include <asm/mach-types.h>
16 #include <asm/irq.h>
17 #include <asm/mach/map.h>
18 #include <asm/mach/irq.h>
19 #include <asm/mach/serial_sa1100.h>
20 #include <asm/arch/assabet.h>
21 #include <asm/arch/neponset.h>
22 #include <asm/hardware/sa1111.h>
23 #include <asm/sizes.h>
24 
25 /*
26  * Install handler for Neponset IRQ.  Note that we have to loop here
27  * since the ETHERNET and USAR IRQs are level based, and we need to
28  * ensure that the IRQ signal is deasserted before returning.  This
29  * is rather unfortunate.
30  */
31 static void
32 neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
33 {
34 	unsigned int irr;
35 
36 	while (1) {
37 		struct irqdesc *d;
38 
39 		/*
40 		 * Acknowledge the parent IRQ.
41 		 */
42 		desc->chip->ack(irq);
43 
44 		/*
45 		 * Read the interrupt reason register.  Let's have all
46 		 * active IRQ bits high.  Note: there is a typo in the
47 		 * Neponset user's guide for the SA1111 IRR level.
48 		 */
49 		irr = IRR ^ (IRR_ETHERNET | IRR_USAR);
50 
51 		if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
52 			break;
53 
54 		/*
55 		 * Since there is no individual mask, we have to
56 		 * mask the parent IRQ.  This is safe, since we'll
57 		 * recheck the register for any pending IRQs.
58 		 */
59 		if (irr & (IRR_ETHERNET | IRR_USAR)) {
60 			desc->chip->mask(irq);
61 
62 			/*
63 			 * Ack the interrupt now to prevent re-entering
64 			 * this neponset handler.  Again, this is safe
65 			 * since we'll check the IRR register prior to
66 			 * leaving.
67 			 */
68 			desc->chip->ack(irq);
69 
70 			if (irr & IRR_ETHERNET) {
71 				d = irq_desc + IRQ_NEPONSET_SMC9196;
72 				desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs);
73 			}
74 
75 			if (irr & IRR_USAR) {
76 				d = irq_desc + IRQ_NEPONSET_USAR;
77 				desc_handle_irq(IRQ_NEPONSET_USAR, d, regs);
78 			}
79 
80 			desc->chip->unmask(irq);
81 		}
82 
83 		if (irr & IRR_SA1111) {
84 			d = irq_desc + IRQ_NEPONSET_SA1111;
85 			desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs);
86 		}
87 	}
88 }
89 
90 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
91 {
92 	u_int mdm_ctl0 = MDM_CTL_0;
93 
94 	if (port->mapbase == _Ser1UTCR0) {
95 		if (mctrl & TIOCM_RTS)
96 			mdm_ctl0 &= ~MDM_CTL0_RTS2;
97 		else
98 			mdm_ctl0 |= MDM_CTL0_RTS2;
99 
100 		if (mctrl & TIOCM_DTR)
101 			mdm_ctl0 &= ~MDM_CTL0_DTR2;
102 		else
103 			mdm_ctl0 |= MDM_CTL0_DTR2;
104 	} else if (port->mapbase == _Ser3UTCR0) {
105 		if (mctrl & TIOCM_RTS)
106 			mdm_ctl0 &= ~MDM_CTL0_RTS1;
107 		else
108 			mdm_ctl0 |= MDM_CTL0_RTS1;
109 
110 		if (mctrl & TIOCM_DTR)
111 			mdm_ctl0 &= ~MDM_CTL0_DTR1;
112 		else
113 			mdm_ctl0 |= MDM_CTL0_DTR1;
114 	}
115 
116 	MDM_CTL_0 = mdm_ctl0;
117 }
118 
119 static u_int neponset_get_mctrl(struct uart_port *port)
120 {
121 	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
122 	u_int mdm_ctl1 = MDM_CTL_1;
123 
124 	if (port->mapbase == _Ser1UTCR0) {
125 		if (mdm_ctl1 & MDM_CTL1_DCD2)
126 			ret &= ~TIOCM_CD;
127 		if (mdm_ctl1 & MDM_CTL1_CTS2)
128 			ret &= ~TIOCM_CTS;
129 		if (mdm_ctl1 & MDM_CTL1_DSR2)
130 			ret &= ~TIOCM_DSR;
131 	} else if (port->mapbase == _Ser3UTCR0) {
132 		if (mdm_ctl1 & MDM_CTL1_DCD1)
133 			ret &= ~TIOCM_CD;
134 		if (mdm_ctl1 & MDM_CTL1_CTS1)
135 			ret &= ~TIOCM_CTS;
136 		if (mdm_ctl1 & MDM_CTL1_DSR1)
137 			ret &= ~TIOCM_DSR;
138 	}
139 
140 	return ret;
141 }
142 
143 static struct sa1100_port_fns neponset_port_fns __initdata = {
144 	.set_mctrl	= neponset_set_mctrl,
145 	.get_mctrl	= neponset_get_mctrl,
146 };
147 
148 static int neponset_probe(struct platform_device *dev)
149 {
150 	sa1100_register_uart_fns(&neponset_port_fns);
151 
152 	/*
153 	 * Install handler for GPIO25.
154 	 */
155 	set_irq_type(IRQ_GPIO25, IRQT_RISING);
156 	set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler);
157 
158 	/*
159 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but
160 	 * unfortunately something on the Neponset activates
161 	 * this IRQ on sleep (ethernet?)
162 	 */
163 #if 0
164 	enable_irq_wake(IRQ_GPIO25);
165 #endif
166 
167 	/*
168 	 * Setup other Neponset IRQs.  SA1111 will be done by the
169 	 * generic SA1111 code.
170 	 */
171 	set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ);
172 	set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
173 	set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ);
174 	set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
175 
176 	/*
177 	 * Disable GPIO 0/1 drivers so the buttons work on the module.
178 	 */
179 	NCR_0 = NCR_GP01_OFF;
180 
181 	return 0;
182 }
183 
184 #ifdef CONFIG_PM
185 
186 /*
187  * LDM power management.
188  */
189 static int neponset_suspend(struct platform_device *dev, pm_message_t state)
190 {
191 	/*
192 	 * Save state.
193 	 */
194 	if (!dev->dev.power.saved_state)
195 		dev->dev.power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
196 	if (!dev->dev.power.saved_state)
197 		return -ENOMEM;
198 
199 	*(unsigned int *)dev->dev.power.saved_state = NCR_0;
200 
201 	return 0;
202 }
203 
204 static int neponset_resume(struct platform_device *dev)
205 {
206 	if (dev->dev.power.saved_state) {
207 		NCR_0 = *(unsigned int *)dev->dev.power.saved_state;
208 		kfree(dev->dev.power.saved_state);
209 		dev->dev.power.saved_state = NULL;
210 	}
211 
212 	return 0;
213 }
214 
215 #else
216 #define neponset_suspend NULL
217 #define neponset_resume  NULL
218 #endif
219 
220 static struct platform_driver neponset_device_driver = {
221 	.probe		= neponset_probe,
222 	.suspend	= neponset_suspend,
223 	.resume		= neponset_resume,
224 	.driver		= {
225 		.name	= "neponset",
226 	},
227 };
228 
229 static struct resource neponset_resources[] = {
230 	[0] = {
231 		.start	= 0x10000000,
232 		.end	= 0x17ffffff,
233 		.flags	= IORESOURCE_MEM,
234 	},
235 };
236 
237 static struct platform_device neponset_device = {
238 	.name		= "neponset",
239 	.id		= 0,
240 	.num_resources	= ARRAY_SIZE(neponset_resources),
241 	.resource	= neponset_resources,
242 };
243 
244 static struct resource sa1111_resources[] = {
245 	[0] = {
246 		.start	= 0x40000000,
247 		.end	= 0x40001fff,
248 		.flags	= IORESOURCE_MEM,
249 	},
250 	[1] = {
251 		.start	= IRQ_NEPONSET_SA1111,
252 		.end	= IRQ_NEPONSET_SA1111,
253 		.flags	= IORESOURCE_IRQ,
254 	},
255 };
256 
257 static u64 sa1111_dmamask = 0xffffffffUL;
258 
259 static struct platform_device sa1111_device = {
260 	.name		= "sa1111",
261 	.id		= 0,
262 	.dev		= {
263 		.dma_mask = &sa1111_dmamask,
264 		.coherent_dma_mask = 0xffffffff,
265 	},
266 	.num_resources	= ARRAY_SIZE(sa1111_resources),
267 	.resource	= sa1111_resources,
268 };
269 
270 static struct resource smc91x_resources[] = {
271 	[0] = {
272 		.name	= "smc91x-regs",
273 		.start	= SA1100_CS3_PHYS,
274 		.end	= SA1100_CS3_PHYS + 0x01ffffff,
275 		.flags	= IORESOURCE_MEM,
276 	},
277 	[1] = {
278 		.start	= IRQ_NEPONSET_SMC9196,
279 		.end	= IRQ_NEPONSET_SMC9196,
280 		.flags	= IORESOURCE_IRQ,
281 	},
282 	[2] = {
283 		.name	= "smc91x-attrib",
284 		.start	= SA1100_CS3_PHYS + 0x02000000,
285 		.end	= SA1100_CS3_PHYS + 0x03ffffff,
286 		.flags	= IORESOURCE_MEM,
287 	},
288 };
289 
290 static struct platform_device smc91x_device = {
291 	.name		= "smc91x",
292 	.id		= 0,
293 	.num_resources	= ARRAY_SIZE(smc91x_resources),
294 	.resource	= smc91x_resources,
295 };
296 
297 static struct platform_device *devices[] __initdata = {
298 	&neponset_device,
299 	&sa1111_device,
300 	&smc91x_device,
301 };
302 
303 static int __init neponset_init(void)
304 {
305 	platform_driver_register(&neponset_device_driver);
306 
307 	/*
308 	 * The Neponset is only present on the Assabet machine type.
309 	 */
310 	if (!machine_is_assabet())
311 		return -ENODEV;
312 
313 	/*
314 	 * Ensure that the memory bus request/grant signals are setup,
315 	 * and the grant is held in its inactive state, whether or not
316 	 * we actually have a Neponset attached.
317 	 */
318 	sa1110_mb_disable();
319 
320 	if (!machine_has_neponset()) {
321 		printk(KERN_DEBUG "Neponset expansion board not present\n");
322 		return -ENODEV;
323 	}
324 
325 	if (WHOAMI != 0x11) {
326 		printk(KERN_WARNING "Neponset board detected, but "
327 			"wrong ID: %02x\n", WHOAMI);
328 		return -ENODEV;
329 	}
330 
331 	return platform_add_devices(devices, ARRAY_SIZE(devices));
332 }
333 
334 subsys_initcall(neponset_init);
335 
336 static struct map_desc neponset_io_desc[] __initdata = {
337 	{	/* System Registers */
338 		.virtual	=  0xf3000000,
339 		.pfn		= __phys_to_pfn(0x10000000),
340 		.length		= SZ_1M,
341 		.type		= MT_DEVICE
342 	}, {	/* SA-1111 */
343 		.virtual	=  0xf4000000,
344 		.pfn		= __phys_to_pfn(0x40000000),
345 		.length		= SZ_1M,
346 		.type		= MT_DEVICE
347 	}
348 };
349 
350 void __init neponset_map_io(void)
351 {
352 	iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
353 }
354