Root/
1 | /* |
2 | * LASI Device Driver |
3 | * |
4 | * (c) Copyright 1999 Red Hat Software |
5 | * Portions (c) Copyright 1999 The Puffin Group Inc. |
6 | * Portions (c) Copyright 1999 Hewlett-Packard |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * by Alan Cox <alan@redhat.com> and |
14 | * Alex deVries <alex@onefishtwo.ca> |
15 | */ |
16 | |
17 | #include <linux/errno.h> |
18 | #include <linux/init.h> |
19 | #include <linux/interrupt.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/module.h> |
22 | #include <linux/pm.h> |
23 | #include <linux/types.h> |
24 | |
25 | #include <asm/io.h> |
26 | #include <asm/hardware.h> |
27 | #include <asm/led.h> |
28 | |
29 | #include "gsc.h" |
30 | |
31 | |
32 | #define LASI_VER 0xC008 /* LASI Version */ |
33 | |
34 | #define LASI_IO_CONF 0x7FFFE /* LASI primary configuration register */ |
35 | #define LASI_IO_CONF2 0x7FFFF /* LASI secondary configuration register */ |
36 | |
37 | static void lasi_choose_irq(struct parisc_device *dev, void *ctrl) |
38 | { |
39 | int irq; |
40 | |
41 | switch (dev->id.sversion) { |
42 | case 0x74: irq = 7; break; /* Centronics */ |
43 | case 0x7B: irq = 13; break; /* Audio */ |
44 | case 0x81: irq = 14; break; /* Lasi itself */ |
45 | case 0x82: irq = 9; break; /* SCSI */ |
46 | case 0x83: irq = 20; break; /* Floppy */ |
47 | case 0x84: irq = 26; break; /* PS/2 Keyboard */ |
48 | case 0x87: irq = 18; break; /* ISDN */ |
49 | case 0x8A: irq = 8; break; /* LAN */ |
50 | case 0x8C: irq = 5; break; /* RS232 */ |
51 | case 0x8D: irq = (dev->hw_path == 13) ? 16 : 17; break; |
52 | /* Telephone */ |
53 | default: return; /* unknown */ |
54 | } |
55 | |
56 | gsc_asic_assign_irq(ctrl, irq, &dev->irq); |
57 | } |
58 | |
59 | static void __init |
60 | lasi_init_irq(struct gsc_asic *this_lasi) |
61 | { |
62 | unsigned long lasi_base = this_lasi->hpa; |
63 | |
64 | /* Stop LASI barking for a bit */ |
65 | gsc_writel(0x00000000, lasi_base+OFFSET_IMR); |
66 | |
67 | /* clear pending interrupts */ |
68 | gsc_readl(lasi_base+OFFSET_IRR); |
69 | |
70 | /* We're not really convinced we want to reset the onboard |
71 | * devices. Firmware does it for us... |
72 | */ |
73 | |
74 | /* Resets */ |
75 | /* gsc_writel(0xFFFFFFFF, lasi_base+0x2000);*/ /* Parallel */ |
76 | if(pdc_add_valid(lasi_base+0x4004) == PDC_OK) |
77 | gsc_writel(0xFFFFFFFF, lasi_base+0x4004); /* Audio */ |
78 | /* gsc_writel(0xFFFFFFFF, lasi_base+0x5000);*/ /* Serial */ |
79 | /* gsc_writel(0xFFFFFFFF, lasi_base+0x6000);*/ /* SCSI */ |
80 | gsc_writel(0xFFFFFFFF, lasi_base+0x7000); /* LAN */ |
81 | gsc_writel(0xFFFFFFFF, lasi_base+0x8000); /* Keyboard */ |
82 | gsc_writel(0xFFFFFFFF, lasi_base+0xA000); /* FDC */ |
83 | |
84 | /* Ok we hit it on the head with a hammer, our Dog is now |
85 | ** comatose and muzzled. Devices will now unmask LASI |
86 | ** interrupts as they are registered as irq's in the LASI range. |
87 | */ |
88 | /* XXX: I thought it was `awks that got `it on the `ead with an |
89 | * `ammer. -- willy |
90 | */ |
91 | } |
92 | |
93 | |
94 | /* |
95 | ** lasi_led_init() |
96 | ** |
97 | ** lasi_led_init() initializes the LED controller on the LASI. |
98 | ** |
99 | ** Since Mirage and Electra machines use a different LED |
100 | ** address register, we need to check for these machines |
101 | ** explicitly. |
102 | */ |
103 | |
104 | #ifndef CONFIG_CHASSIS_LCD_LED |
105 | |
106 | #define lasi_led_init(x) /* nothing */ |
107 | |
108 | #else |
109 | |
110 | static void __init lasi_led_init(unsigned long lasi_hpa) |
111 | { |
112 | unsigned long datareg; |
113 | |
114 | switch (CPU_HVERSION) { |
115 | /* Gecko machines have only one single LED, which can be permanently |
116 | turned on by writing a zero into the power control register. */ |
117 | case 0x600: /* Gecko (712/60) */ |
118 | case 0x601: /* Gecko (712/80) */ |
119 | case 0x602: /* Gecko (712/100) */ |
120 | case 0x603: /* Anole 64 (743/64) */ |
121 | case 0x604: /* Anole 100 (743/100) */ |
122 | case 0x605: /* Gecko (712/120) */ |
123 | datareg = lasi_hpa + 0x0000C000; |
124 | gsc_writeb(0, datareg); |
125 | return; /* no need to register the LED interrupt-function */ |
126 | |
127 | /* Mirage and Electra machines need special offsets */ |
128 | case 0x60A: /* Mirage Jr (715/64) */ |
129 | case 0x60B: /* Mirage 100 */ |
130 | case 0x60C: /* Mirage 100+ */ |
131 | case 0x60D: /* Electra 100 */ |
132 | case 0x60E: /* Electra 120 */ |
133 | datareg = lasi_hpa - 0x00020000; |
134 | break; |
135 | |
136 | default: |
137 | datareg = lasi_hpa + 0x0000C000; |
138 | break; |
139 | } |
140 | |
141 | register_led_driver(DISPLAY_MODEL_LASI, LED_CMD_REG_NONE, datareg); |
142 | } |
143 | #endif |
144 | |
145 | /* |
146 | * lasi_power_off |
147 | * |
148 | * Function for lasi to turn off the power. This is accomplished by setting a |
149 | * 1 to PWR_ON_L in the Power Control Register |
150 | * |
151 | */ |
152 | |
153 | static unsigned long lasi_power_off_hpa __read_mostly; |
154 | |
155 | static void lasi_power_off(void) |
156 | { |
157 | unsigned long datareg; |
158 | |
159 | /* calculate addr of the Power Control Register */ |
160 | datareg = lasi_power_off_hpa + 0x0000C000; |
161 | |
162 | /* Power down the machine */ |
163 | gsc_writel(0x02, datareg); |
164 | } |
165 | |
166 | static int __init lasi_init_chip(struct parisc_device *dev) |
167 | { |
168 | extern void (*chassis_power_off)(void); |
169 | struct gsc_asic *lasi; |
170 | struct gsc_irq gsc_irq; |
171 | int ret; |
172 | |
173 | lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); |
174 | if (!lasi) |
175 | return -ENOMEM; |
176 | |
177 | lasi->name = "Lasi"; |
178 | lasi->hpa = dev->hpa.start; |
179 | |
180 | /* Check the 4-bit (yes, only 4) version register */ |
181 | lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf; |
182 | printk(KERN_INFO "%s version %d at 0x%lx found.\n", |
183 | lasi->name, lasi->version, lasi->hpa); |
184 | |
185 | /* initialize the chassis LEDs really early */ |
186 | lasi_led_init(lasi->hpa); |
187 | |
188 | /* Stop LASI barking for a bit */ |
189 | lasi_init_irq(lasi); |
190 | |
191 | /* the IRQ lasi should use */ |
192 | dev->irq = gsc_alloc_irq(&gsc_irq); |
193 | if (dev->irq < 0) { |
194 | printk(KERN_ERR "%s(): cannot get GSC irq\n", |
195 | __func__); |
196 | kfree(lasi); |
197 | return -EBUSY; |
198 | } |
199 | |
200 | lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; |
201 | |
202 | ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi); |
203 | if (ret < 0) { |
204 | kfree(lasi); |
205 | return ret; |
206 | } |
207 | |
208 | /* enable IRQ's for devices below LASI */ |
209 | gsc_writel(lasi->eim, lasi->hpa + OFFSET_IAR); |
210 | |
211 | /* Done init'ing, register this driver */ |
212 | ret = gsc_common_setup(dev, lasi); |
213 | if (ret) { |
214 | kfree(lasi); |
215 | return ret; |
216 | } |
217 | |
218 | gsc_fixup_irqs(dev, lasi, lasi_choose_irq); |
219 | |
220 | /* initialize the power off function */ |
221 | /* FIXME: Record the LASI HPA for the power off function. This should |
222 | * ensure that only the first LASI (the one controlling the power off) |
223 | * should set the HPA here */ |
224 | lasi_power_off_hpa = lasi->hpa; |
225 | chassis_power_off = lasi_power_off; |
226 | |
227 | return ret; |
228 | } |
229 | |
230 | static struct parisc_device_id lasi_tbl[] = { |
231 | { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00081 }, |
232 | { 0, } |
233 | }; |
234 | |
235 | struct parisc_driver lasi_driver = { |
236 | .name = "lasi", |
237 | .id_table = lasi_tbl, |
238 | .probe = lasi_init_chip, |
239 | }; |
240 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9