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