diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-29 06:19:06 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-02-09 10:34:17 -0500 |
commit | f942b0fd6c81416bb8d52bc26a76a58c02d87bc2 (patch) | |
tree | f967454e0cc399bd24392a2da8472d63d3302f38 /arch/arm/mach-sa1100/neponset.c | |
parent | bab50a35ee703955bd708a4a44cd56ed30e601c8 (diff) |
ARM: sa11x0: neponset: move register definitions to neponset.c
Move the board specific neponset register definitions to the board
file, rather than mach/neponset.h. However, as the NCR_0 register
definitions are used by some drivers, leave these behind.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-sa1100/neponset.c')
-rw-r--r-- | arch/arm/mach-sa1100/neponset.c | 114 |
1 files changed, 91 insertions, 23 deletions
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 2a9e1e2223f0..3c0d4b837adb 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c | |||
@@ -27,9 +27,40 @@ | |||
27 | #define NEP_IRQ_SA1111 2 | 27 | #define NEP_IRQ_SA1111 2 |
28 | #define NEP_IRQ_NR 3 | 28 | #define NEP_IRQ_NR 3 |
29 | 29 | ||
30 | #define WHOAMI 0x00 | ||
31 | #define LEDS 0x10 | ||
32 | #define SWPK 0x20 | ||
33 | #define IRR 0x24 | ||
34 | #define KP_Y_IN 0x80 | ||
35 | #define KP_X_OUT 0x90 | ||
36 | #define NCR_0 0xa0 | ||
37 | #define MDM_CTL_0 0xb0 | ||
38 | #define MDM_CTL_1 0xb4 | ||
39 | #define AUD_CTL 0xc0 | ||
40 | |||
41 | #define IRR_ETHERNET (1 << 0) | ||
42 | #define IRR_USAR (1 << 1) | ||
43 | #define IRR_SA1111 (1 << 2) | ||
44 | |||
45 | #define MDM_CTL0_RTS1 (1 << 0) | ||
46 | #define MDM_CTL0_DTR1 (1 << 1) | ||
47 | #define MDM_CTL0_RTS2 (1 << 2) | ||
48 | #define MDM_CTL0_DTR2 (1 << 3) | ||
49 | |||
50 | #define MDM_CTL1_CTS1 (1 << 0) | ||
51 | #define MDM_CTL1_DSR1 (1 << 1) | ||
52 | #define MDM_CTL1_DCD1 (1 << 2) | ||
53 | #define MDM_CTL1_CTS2 (1 << 3) | ||
54 | #define MDM_CTL1_DSR2 (1 << 4) | ||
55 | #define MDM_CTL1_DCD2 (1 << 5) | ||
56 | |||
57 | #define AUD_SEL_1341 (1 << 0) | ||
58 | #define AUD_MUTE_1341 (1 << 1) | ||
59 | |||
30 | extern void sa1110_mb_disable(void); | 60 | extern void sa1110_mb_disable(void); |
31 | 61 | ||
32 | struct neponset_drvdata { | 62 | struct neponset_drvdata { |
63 | void __iomem *base; | ||
33 | struct platform_device *sa1111; | 64 | struct platform_device *sa1111; |
34 | struct platform_device *smc91x; | 65 | struct platform_device *smc91x; |
35 | unsigned irq_base; | 66 | unsigned irq_base; |
@@ -39,19 +70,34 @@ struct neponset_drvdata { | |||
39 | #endif | 70 | #endif |
40 | }; | 71 | }; |
41 | 72 | ||
73 | static void __iomem *nep_base; | ||
74 | |||
42 | void neponset_ncr_frob(unsigned int mask, unsigned int val) | 75 | void neponset_ncr_frob(unsigned int mask, unsigned int val) |
43 | { | 76 | { |
44 | unsigned long flags; | 77 | void __iomem *base = nep_base; |
45 | 78 | ||
46 | local_irq_save(flags); | 79 | if (base) { |
47 | NCR_0 = (NCR_0 & ~mask) | val; | 80 | unsigned long flags; |
48 | local_irq_restore(flags); | 81 | unsigned v; |
82 | |||
83 | local_irq_save(flags); | ||
84 | v = readb_relaxed(base + NCR_0); | ||
85 | writeb_relaxed((v & ~mask) | val, base + NCR_0); | ||
86 | local_irq_restore(flags); | ||
87 | } else { | ||
88 | WARN(1, "nep_base unset\n"); | ||
89 | } | ||
49 | } | 90 | } |
50 | 91 | ||
51 | static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) | 92 | static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) |
52 | { | 93 | { |
53 | u_int mdm_ctl0 = MDM_CTL_0; | 94 | void __iomem *base = nep_base; |
95 | u_int mdm_ctl0; | ||
96 | |||
97 | if (!base) | ||
98 | return; | ||
54 | 99 | ||
100 | mdm_ctl0 = readb_relaxed(base + MDM_CTL_0); | ||
55 | if (port->mapbase == _Ser1UTCR0) { | 101 | if (port->mapbase == _Ser1UTCR0) { |
56 | if (mctrl & TIOCM_RTS) | 102 | if (mctrl & TIOCM_RTS) |
57 | mdm_ctl0 &= ~MDM_CTL0_RTS2; | 103 | mdm_ctl0 &= ~MDM_CTL0_RTS2; |
@@ -74,14 +120,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) | |||
74 | mdm_ctl0 |= MDM_CTL0_DTR1; | 120 | mdm_ctl0 |= MDM_CTL0_DTR1; |
75 | } | 121 | } |
76 | 122 | ||
77 | MDM_CTL_0 = mdm_ctl0; | 123 | writeb_relaxed(mdm_ctl0, base + MDM_CTL_0); |
78 | } | 124 | } |
79 | 125 | ||
80 | static u_int neponset_get_mctrl(struct uart_port *port) | 126 | static u_int neponset_get_mctrl(struct uart_port *port) |
81 | { | 127 | { |
128 | void __iomem *base = nep_base; | ||
82 | u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; | 129 | u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; |
83 | u_int mdm_ctl1 = MDM_CTL_1; | 130 | u_int mdm_ctl1; |
84 | 131 | ||
132 | if (!base) | ||
133 | return ret; | ||
134 | |||
135 | mdm_ctl1 = readb_relaxed(base + MDM_CTL_1); | ||
85 | if (port->mapbase == _Ser1UTCR0) { | 136 | if (port->mapbase == _Ser1UTCR0) { |
86 | if (mdm_ctl1 & MDM_CTL1_DCD2) | 137 | if (mdm_ctl1 & MDM_CTL1_DCD2) |
87 | ret &= ~TIOCM_CD; | 138 | ret &= ~TIOCM_CD; |
@@ -128,7 +179,8 @@ static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
128 | * active IRQ bits high. Note: there is a typo in the | 179 | * active IRQ bits high. Note: there is a typo in the |
129 | * Neponset user's guide for the SA1111 IRR level. | 180 | * Neponset user's guide for the SA1111 IRR level. |
130 | */ | 181 | */ |
131 | irr = IRR ^ (IRR_ETHERNET | IRR_USAR); | 182 | irr = readb_relaxed(d->base + IRR); |
183 | irr ^= IRR_ETHERNET | IRR_USAR; | ||
132 | 184 | ||
133 | if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) | 185 | if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) |
134 | break; | 186 | break; |
@@ -182,7 +234,7 @@ static struct sa1111_platform_data sa1111_info = { | |||
182 | static int __devinit neponset_probe(struct platform_device *dev) | 234 | static int __devinit neponset_probe(struct platform_device *dev) |
183 | { | 235 | { |
184 | struct neponset_drvdata *d; | 236 | struct neponset_drvdata *d; |
185 | struct resource *sa1111_res, *smc91x_res; | 237 | struct resource *nep_res, *sa1111_res, *smc91x_res; |
186 | struct resource sa1111_resources[] = { | 238 | struct resource sa1111_resources[] = { |
187 | DEFINE_RES_MEM(0x40000000, SZ_8K), | 239 | DEFINE_RES_MEM(0x40000000, SZ_8K), |
188 | { .flags = IORESOURCE_IRQ }, | 240 | { .flags = IORESOURCE_IRQ }, |
@@ -213,30 +265,40 @@ static int __devinit neponset_probe(struct platform_device *dev) | |||
213 | }; | 265 | }; |
214 | int ret, irq; | 266 | int ret, irq; |
215 | 267 | ||
268 | if (nep_base) | ||
269 | return -EBUSY; | ||
270 | |||
216 | irq = ret = platform_get_irq(dev, 0); | 271 | irq = ret = platform_get_irq(dev, 0); |
217 | if (ret < 0) | 272 | if (ret < 0) |
218 | goto err_alloc; | 273 | goto err_alloc; |
219 | 274 | ||
275 | nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
220 | smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1); | 276 | smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1); |
221 | sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2); | 277 | sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2); |
222 | if (!smc91x_res || !sa1111_res) { | 278 | if (!nep_res || !smc91x_res || !sa1111_res) { |
223 | ret = -ENXIO; | 279 | ret = -ENXIO; |
224 | goto err_alloc; | 280 | goto err_alloc; |
225 | } | 281 | } |
226 | 282 | ||
227 | if (WHOAMI != 0x11) { | ||
228 | dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n", | ||
229 | WHOAMI); | ||
230 | ret = -ENODEV; | ||
231 | goto err_alloc; | ||
232 | } | ||
233 | |||
234 | d = kzalloc(sizeof(*d), GFP_KERNEL); | 283 | d = kzalloc(sizeof(*d), GFP_KERNEL); |
235 | if (!d) { | 284 | if (!d) { |
236 | ret = -ENOMEM; | 285 | ret = -ENOMEM; |
237 | goto err_alloc; | 286 | goto err_alloc; |
238 | } | 287 | } |
239 | 288 | ||
289 | d->base = ioremap(nep_res->start, SZ_4K); | ||
290 | if (!d->base) { | ||
291 | ret = -ENOMEM; | ||
292 | goto err_ioremap; | ||
293 | } | ||
294 | |||
295 | if (readb_relaxed(d->base + WHOAMI) != 0x11) { | ||
296 | dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n", | ||
297 | readb_relaxed(d->base + WHOAMI)); | ||
298 | ret = -ENODEV; | ||
299 | goto err_id; | ||
300 | } | ||
301 | |||
240 | ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1); | 302 | ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1); |
241 | if (ret <= 0) { | 303 | if (ret <= 0) { |
242 | dev_err(&dev->dev, "unable to allocate %u irqs: %d\n", | 304 | dev_err(&dev->dev, "unable to allocate %u irqs: %d\n", |
@@ -270,6 +332,7 @@ static int __devinit neponset_probe(struct platform_device *dev) | |||
270 | 332 | ||
271 | dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n", | 333 | dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n", |
272 | d->irq_base, d->irq_base + NEP_IRQ_NR - 1); | 334 | d->irq_base, d->irq_base + NEP_IRQ_NR - 1); |
335 | nep_base = d->base; | ||
273 | 336 | ||
274 | sa1100_register_uart_fns(&neponset_port_fns); | 337 | sa1100_register_uart_fns(&neponset_port_fns); |
275 | 338 | ||
@@ -277,7 +340,7 @@ static int __devinit neponset_probe(struct platform_device *dev) | |||
277 | sa1110_mb_disable(); | 340 | sa1110_mb_disable(); |
278 | 341 | ||
279 | /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */ | 342 | /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */ |
280 | NCR_0 = NCR_GP01_OFF; | 343 | writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0); |
281 | 344 | ||
282 | sa1111_resources[0].parent = sa1111_res; | 345 | sa1111_resources[0].parent = sa1111_res; |
283 | sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111; | 346 | sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111; |
@@ -295,6 +358,9 @@ static int __devinit neponset_probe(struct platform_device *dev) | |||
295 | return 0; | 358 | return 0; |
296 | 359 | ||
297 | err_irq_alloc: | 360 | err_irq_alloc: |
361 | err_id: | ||
362 | iounmap(d->base); | ||
363 | err_ioremap: | ||
298 | kfree(d); | 364 | kfree(d); |
299 | err_alloc: | 365 | err_alloc: |
300 | return ret; | 366 | return ret; |
@@ -311,6 +377,8 @@ static int __devexit neponset_remove(struct platform_device *dev) | |||
311 | platform_device_unregister(d->smc91x); | 377 | platform_device_unregister(d->smc91x); |
312 | irq_set_chained_handler(irq, NULL); | 378 | irq_set_chained_handler(irq, NULL); |
313 | irq_free_descs(d->irq_base, NEP_IRQ_NR); | 379 | irq_free_descs(d->irq_base, NEP_IRQ_NR); |
380 | nep_base = NULL; | ||
381 | iounmap(d->base); | ||
314 | kfree(d); | 382 | kfree(d); |
315 | 383 | ||
316 | return 0; | 384 | return 0; |
@@ -321,8 +389,8 @@ static int neponset_suspend(struct device *dev) | |||
321 | { | 389 | { |
322 | struct neponset_drvdata *d = dev_get_drvdata(dev); | 390 | struct neponset_drvdata *d = dev_get_drvdata(dev); |
323 | 391 | ||
324 | d->ncr0 = NCR_0; | 392 | d->ncr0 = readb_relaxed(d->base + NCR_0); |
325 | d->mdm_ctl_0 = MDM_CTL_0; | 393 | d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0); |
326 | 394 | ||
327 | return 0; | 395 | return 0; |
328 | } | 396 | } |
@@ -331,8 +399,8 @@ static int neponset_resume(struct device *dev) | |||
331 | { | 399 | { |
332 | struct neponset_drvdata *d = dev_get_drvdata(dev); | 400 | struct neponset_drvdata *d = dev_get_drvdata(dev); |
333 | 401 | ||
334 | NCR_0 = d->ncr0; | 402 | writeb_relaxed(d->ncr0, d->base + NCR_0); |
335 | MDM_CTL_0 = d->mdm_ctl_0; | 403 | writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0); |
336 | 404 | ||
337 | return 0; | 405 | return 0; |
338 | } | 406 | } |