Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/sysdev/cpm1.c
10817 views
1
/*
2
* General Purpose functions for the global management of the
3
* Communication Processor Module.
4
* Copyright (c) 1997 Dan error_act ([email protected])
5
*
6
* In addition to the individual control of the communication
7
* channels, there are a few functions that globally affect the
8
* communication processor.
9
*
10
* Buffer descriptors must be allocated from the dual ported memory
11
* space. The allocator for that is here. When the communication
12
* process is reset, we reclaim the memory available. There is
13
* currently no deallocator for this memory.
14
* The amount of space available is platform dependent. On the
15
* MBX, the EPPC software loads additional microcode into the
16
* communication processor, and uses some of the DP ram for this
17
* purpose. Current, the first 512 bytes and the last 256 bytes of
18
* memory are used. Right now I am conservative and only use the
19
* memory that can never be used for microcode. If there are
20
* applications that require more DP ram, we can expand the boundaries
21
* but then we have to be careful of any downloaded microcode.
22
*/
23
#include <linux/errno.h>
24
#include <linux/sched.h>
25
#include <linux/kernel.h>
26
#include <linux/dma-mapping.h>
27
#include <linux/param.h>
28
#include <linux/string.h>
29
#include <linux/mm.h>
30
#include <linux/interrupt.h>
31
#include <linux/irq.h>
32
#include <linux/module.h>
33
#include <linux/spinlock.h>
34
#include <linux/slab.h>
35
#include <asm/page.h>
36
#include <asm/pgtable.h>
37
#include <asm/8xx_immap.h>
38
#include <asm/cpm1.h>
39
#include <asm/io.h>
40
#include <asm/tlbflush.h>
41
#include <asm/rheap.h>
42
#include <asm/prom.h>
43
#include <asm/cpm.h>
44
45
#include <asm/fs_pd.h>
46
47
#ifdef CONFIG_8xx_GPIO
48
#include <linux/of_gpio.h>
49
#endif
50
51
#define CPM_MAP_SIZE (0x4000)
52
53
cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
54
immap_t __iomem *mpc8xx_immr;
55
static cpic8xx_t __iomem *cpic_reg;
56
57
static struct irq_host *cpm_pic_host;
58
59
static void cpm_mask_irq(struct irq_data *d)
60
{
61
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
62
63
clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
64
}
65
66
static void cpm_unmask_irq(struct irq_data *d)
67
{
68
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
69
70
setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
71
}
72
73
static void cpm_end_irq(struct irq_data *d)
74
{
75
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
76
77
out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
78
}
79
80
static struct irq_chip cpm_pic = {
81
.name = "CPM PIC",
82
.irq_mask = cpm_mask_irq,
83
.irq_unmask = cpm_unmask_irq,
84
.irq_eoi = cpm_end_irq,
85
};
86
87
int cpm_get_irq(void)
88
{
89
int cpm_vec;
90
91
/* Get the vector by setting the ACK bit and then reading
92
* the register.
93
*/
94
out_be16(&cpic_reg->cpic_civr, 1);
95
cpm_vec = in_be16(&cpic_reg->cpic_civr);
96
cpm_vec >>= 11;
97
98
return irq_linear_revmap(cpm_pic_host, cpm_vec);
99
}
100
101
static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
102
irq_hw_number_t hw)
103
{
104
pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
105
106
irq_set_status_flags(virq, IRQ_LEVEL);
107
irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
108
return 0;
109
}
110
111
/* The CPM can generate the error interrupt when there is a race condition
112
* between generating and masking interrupts. All we have to do is ACK it
113
* and return. This is a no-op function so we don't need any special
114
* tests in the interrupt handler.
115
*/
116
static irqreturn_t cpm_error_interrupt(int irq, void *dev)
117
{
118
return IRQ_HANDLED;
119
}
120
121
static struct irqaction cpm_error_irqaction = {
122
.handler = cpm_error_interrupt,
123
.name = "error",
124
};
125
126
static struct irq_host_ops cpm_pic_host_ops = {
127
.map = cpm_pic_host_map,
128
};
129
130
unsigned int cpm_pic_init(void)
131
{
132
struct device_node *np = NULL;
133
struct resource res;
134
unsigned int sirq = NO_IRQ, hwirq, eirq;
135
int ret;
136
137
pr_debug("cpm_pic_init\n");
138
139
np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic");
140
if (np == NULL)
141
np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
142
if (np == NULL) {
143
printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n");
144
return sirq;
145
}
146
147
ret = of_address_to_resource(np, 0, &res);
148
if (ret)
149
goto end;
150
151
cpic_reg = ioremap(res.start, res.end - res.start + 1);
152
if (cpic_reg == NULL)
153
goto end;
154
155
sirq = irq_of_parse_and_map(np, 0);
156
if (sirq == NO_IRQ)
157
goto end;
158
159
/* Initialize the CPM interrupt controller. */
160
hwirq = (unsigned int)virq_to_hw(sirq);
161
out_be32(&cpic_reg->cpic_cicr,
162
(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
163
((hwirq/2) << 13) | CICR_HP_MASK);
164
165
out_be32(&cpic_reg->cpic_cimr, 0);
166
167
cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
168
64, &cpm_pic_host_ops, 64);
169
if (cpm_pic_host == NULL) {
170
printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
171
sirq = NO_IRQ;
172
goto end;
173
}
174
175
/* Install our own error handler. */
176
np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
177
if (np == NULL)
178
np = of_find_node_by_type(NULL, "cpm");
179
if (np == NULL) {
180
printk(KERN_ERR "CPM PIC init: can not find cpm node\n");
181
goto end;
182
}
183
184
eirq = irq_of_parse_and_map(np, 0);
185
if (eirq == NO_IRQ)
186
goto end;
187
188
if (setup_irq(eirq, &cpm_error_irqaction))
189
printk(KERN_ERR "Could not allocate CPM error IRQ!");
190
191
setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
192
193
end:
194
of_node_put(np);
195
return sirq;
196
}
197
198
void __init cpm_reset(void)
199
{
200
sysconf8xx_t __iomem *siu_conf;
201
202
mpc8xx_immr = ioremap(get_immrbase(), 0x4000);
203
if (!mpc8xx_immr) {
204
printk(KERN_CRIT "Could not map IMMR\n");
205
return;
206
}
207
208
cpmp = &mpc8xx_immr->im_cpm;
209
210
#ifndef CONFIG_PPC_EARLY_DEBUG_CPM
211
/* Perform a reset.
212
*/
213
out_be16(&cpmp->cp_cpcr, CPM_CR_RST | CPM_CR_FLG);
214
215
/* Wait for it.
216
*/
217
while (in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG);
218
#endif
219
220
#ifdef CONFIG_UCODE_PATCH
221
cpm_load_patch(cpmp);
222
#endif
223
224
/* Set SDMA Bus Request priority 5.
225
* On 860T, this also enables FEC priority 6. I am not sure
226
* this is what we really want for some applications, but the
227
* manual recommends it.
228
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
229
*/
230
siu_conf = immr_map(im_siu_conf);
231
out_be32(&siu_conf->sc_sdcr, 1);
232
immr_unmap(siu_conf);
233
234
cpm_muram_init();
235
}
236
237
static DEFINE_SPINLOCK(cmd_lock);
238
239
#define MAX_CR_CMD_LOOPS 10000
240
241
int cpm_command(u32 command, u8 opcode)
242
{
243
int i, ret;
244
unsigned long flags;
245
246
if (command & 0xffffff0f)
247
return -EINVAL;
248
249
spin_lock_irqsave(&cmd_lock, flags);
250
251
ret = 0;
252
out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8));
253
for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
254
if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
255
goto out;
256
257
printk(KERN_ERR "%s(): Not able to issue CPM command\n", __func__);
258
ret = -EIO;
259
out:
260
spin_unlock_irqrestore(&cmd_lock, flags);
261
return ret;
262
}
263
EXPORT_SYMBOL(cpm_command);
264
265
/* Set a baud rate generator. This needs lots of work. There are
266
* four BRGs, any of which can be wired to any channel.
267
* The internal baud rate clock is the system clock divided by 16.
268
* This assumes the baudrate is 16x oversampled by the uart.
269
*/
270
#define BRG_INT_CLK (get_brgfreq())
271
#define BRG_UART_CLK (BRG_INT_CLK/16)
272
#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16)
273
274
void
275
cpm_setbrg(uint brg, uint rate)
276
{
277
u32 __iomem *bp;
278
279
/* This is good enough to get SMCs running.....
280
*/
281
bp = &cpmp->cp_brgc1;
282
bp += brg;
283
/* The BRG has a 12-bit counter. For really slow baud rates (or
284
* really fast processors), we may have to further divide by 16.
285
*/
286
if (((BRG_UART_CLK / rate) - 1) < 4096)
287
out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);
288
else
289
out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
290
CPM_BRG_EN | CPM_BRG_DIV16);
291
}
292
293
struct cpm_ioport16 {
294
__be16 dir, par, odr_sor, dat, intr;
295
__be16 res[3];
296
};
297
298
struct cpm_ioport32b {
299
__be32 dir, par, odr, dat;
300
};
301
302
struct cpm_ioport32e {
303
__be32 dir, par, sor, odr, dat;
304
};
305
306
static void cpm1_set_pin32(int port, int pin, int flags)
307
{
308
struct cpm_ioport32e __iomem *iop;
309
pin = 1 << (31 - pin);
310
311
if (port == CPM_PORTB)
312
iop = (struct cpm_ioport32e __iomem *)
313
&mpc8xx_immr->im_cpm.cp_pbdir;
314
else
315
iop = (struct cpm_ioport32e __iomem *)
316
&mpc8xx_immr->im_cpm.cp_pedir;
317
318
if (flags & CPM_PIN_OUTPUT)
319
setbits32(&iop->dir, pin);
320
else
321
clrbits32(&iop->dir, pin);
322
323
if (!(flags & CPM_PIN_GPIO))
324
setbits32(&iop->par, pin);
325
else
326
clrbits32(&iop->par, pin);
327
328
if (port == CPM_PORTB) {
329
if (flags & CPM_PIN_OPENDRAIN)
330
setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
331
else
332
clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
333
}
334
335
if (port == CPM_PORTE) {
336
if (flags & CPM_PIN_SECONDARY)
337
setbits32(&iop->sor, pin);
338
else
339
clrbits32(&iop->sor, pin);
340
341
if (flags & CPM_PIN_OPENDRAIN)
342
setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
343
else
344
clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
345
}
346
}
347
348
static void cpm1_set_pin16(int port, int pin, int flags)
349
{
350
struct cpm_ioport16 __iomem *iop =
351
(struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport;
352
353
pin = 1 << (15 - pin);
354
355
if (port != 0)
356
iop += port - 1;
357
358
if (flags & CPM_PIN_OUTPUT)
359
setbits16(&iop->dir, pin);
360
else
361
clrbits16(&iop->dir, pin);
362
363
if (!(flags & CPM_PIN_GPIO))
364
setbits16(&iop->par, pin);
365
else
366
clrbits16(&iop->par, pin);
367
368
if (port == CPM_PORTA) {
369
if (flags & CPM_PIN_OPENDRAIN)
370
setbits16(&iop->odr_sor, pin);
371
else
372
clrbits16(&iop->odr_sor, pin);
373
}
374
if (port == CPM_PORTC) {
375
if (flags & CPM_PIN_SECONDARY)
376
setbits16(&iop->odr_sor, pin);
377
else
378
clrbits16(&iop->odr_sor, pin);
379
}
380
}
381
382
void cpm1_set_pin(enum cpm_port port, int pin, int flags)
383
{
384
if (port == CPM_PORTB || port == CPM_PORTE)
385
cpm1_set_pin32(port, pin, flags);
386
else
387
cpm1_set_pin16(port, pin, flags);
388
}
389
390
int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
391
{
392
int shift;
393
int i, bits = 0;
394
u32 __iomem *reg;
395
u32 mask = 7;
396
397
u8 clk_map[][3] = {
398
{CPM_CLK_SCC1, CPM_BRG1, 0},
399
{CPM_CLK_SCC1, CPM_BRG2, 1},
400
{CPM_CLK_SCC1, CPM_BRG3, 2},
401
{CPM_CLK_SCC1, CPM_BRG4, 3},
402
{CPM_CLK_SCC1, CPM_CLK1, 4},
403
{CPM_CLK_SCC1, CPM_CLK2, 5},
404
{CPM_CLK_SCC1, CPM_CLK3, 6},
405
{CPM_CLK_SCC1, CPM_CLK4, 7},
406
407
{CPM_CLK_SCC2, CPM_BRG1, 0},
408
{CPM_CLK_SCC2, CPM_BRG2, 1},
409
{CPM_CLK_SCC2, CPM_BRG3, 2},
410
{CPM_CLK_SCC2, CPM_BRG4, 3},
411
{CPM_CLK_SCC2, CPM_CLK1, 4},
412
{CPM_CLK_SCC2, CPM_CLK2, 5},
413
{CPM_CLK_SCC2, CPM_CLK3, 6},
414
{CPM_CLK_SCC2, CPM_CLK4, 7},
415
416
{CPM_CLK_SCC3, CPM_BRG1, 0},
417
{CPM_CLK_SCC3, CPM_BRG2, 1},
418
{CPM_CLK_SCC3, CPM_BRG3, 2},
419
{CPM_CLK_SCC3, CPM_BRG4, 3},
420
{CPM_CLK_SCC3, CPM_CLK5, 4},
421
{CPM_CLK_SCC3, CPM_CLK6, 5},
422
{CPM_CLK_SCC3, CPM_CLK7, 6},
423
{CPM_CLK_SCC3, CPM_CLK8, 7},
424
425
{CPM_CLK_SCC4, CPM_BRG1, 0},
426
{CPM_CLK_SCC4, CPM_BRG2, 1},
427
{CPM_CLK_SCC4, CPM_BRG3, 2},
428
{CPM_CLK_SCC4, CPM_BRG4, 3},
429
{CPM_CLK_SCC4, CPM_CLK5, 4},
430
{CPM_CLK_SCC4, CPM_CLK6, 5},
431
{CPM_CLK_SCC4, CPM_CLK7, 6},
432
{CPM_CLK_SCC4, CPM_CLK8, 7},
433
434
{CPM_CLK_SMC1, CPM_BRG1, 0},
435
{CPM_CLK_SMC1, CPM_BRG2, 1},
436
{CPM_CLK_SMC1, CPM_BRG3, 2},
437
{CPM_CLK_SMC1, CPM_BRG4, 3},
438
{CPM_CLK_SMC1, CPM_CLK1, 4},
439
{CPM_CLK_SMC1, CPM_CLK2, 5},
440
{CPM_CLK_SMC1, CPM_CLK3, 6},
441
{CPM_CLK_SMC1, CPM_CLK4, 7},
442
443
{CPM_CLK_SMC2, CPM_BRG1, 0},
444
{CPM_CLK_SMC2, CPM_BRG2, 1},
445
{CPM_CLK_SMC2, CPM_BRG3, 2},
446
{CPM_CLK_SMC2, CPM_BRG4, 3},
447
{CPM_CLK_SMC2, CPM_CLK5, 4},
448
{CPM_CLK_SMC2, CPM_CLK6, 5},
449
{CPM_CLK_SMC2, CPM_CLK7, 6},
450
{CPM_CLK_SMC2, CPM_CLK8, 7},
451
};
452
453
switch (target) {
454
case CPM_CLK_SCC1:
455
reg = &mpc8xx_immr->im_cpm.cp_sicr;
456
shift = 0;
457
break;
458
459
case CPM_CLK_SCC2:
460
reg = &mpc8xx_immr->im_cpm.cp_sicr;
461
shift = 8;
462
break;
463
464
case CPM_CLK_SCC3:
465
reg = &mpc8xx_immr->im_cpm.cp_sicr;
466
shift = 16;
467
break;
468
469
case CPM_CLK_SCC4:
470
reg = &mpc8xx_immr->im_cpm.cp_sicr;
471
shift = 24;
472
break;
473
474
case CPM_CLK_SMC1:
475
reg = &mpc8xx_immr->im_cpm.cp_simode;
476
shift = 12;
477
break;
478
479
case CPM_CLK_SMC2:
480
reg = &mpc8xx_immr->im_cpm.cp_simode;
481
shift = 28;
482
break;
483
484
default:
485
printk(KERN_ERR "cpm1_clock_setup: invalid clock target\n");
486
return -EINVAL;
487
}
488
489
for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
490
if (clk_map[i][0] == target && clk_map[i][1] == clock) {
491
bits = clk_map[i][2];
492
break;
493
}
494
}
495
496
if (i == ARRAY_SIZE(clk_map)) {
497
printk(KERN_ERR "cpm1_clock_setup: invalid clock combination\n");
498
return -EINVAL;
499
}
500
501
bits <<= shift;
502
mask <<= shift;
503
504
if (reg == &mpc8xx_immr->im_cpm.cp_sicr) {
505
if (mode == CPM_CLK_RTX) {
506
bits |= bits << 3;
507
mask |= mask << 3;
508
} else if (mode == CPM_CLK_RX) {
509
bits <<= 3;
510
mask <<= 3;
511
}
512
}
513
514
out_be32(reg, (in_be32(reg) & ~mask) | bits);
515
516
return 0;
517
}
518
519
/*
520
* GPIO LIB API implementation
521
*/
522
#ifdef CONFIG_8xx_GPIO
523
524
struct cpm1_gpio16_chip {
525
struct of_mm_gpio_chip mm_gc;
526
spinlock_t lock;
527
528
/* shadowed data register to clear/set bits safely */
529
u16 cpdata;
530
};
531
532
static inline struct cpm1_gpio16_chip *
533
to_cpm1_gpio16_chip(struct of_mm_gpio_chip *mm_gc)
534
{
535
return container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc);
536
}
537
538
static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc)
539
{
540
struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
541
struct cpm_ioport16 __iomem *iop = mm_gc->regs;
542
543
cpm1_gc->cpdata = in_be16(&iop->dat);
544
}
545
546
static int cpm1_gpio16_get(struct gpio_chip *gc, unsigned int gpio)
547
{
548
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
549
struct cpm_ioport16 __iomem *iop = mm_gc->regs;
550
u16 pin_mask;
551
552
pin_mask = 1 << (15 - gpio);
553
554
return !!(in_be16(&iop->dat) & pin_mask);
555
}
556
557
static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask,
558
int value)
559
{
560
struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
561
struct cpm_ioport16 __iomem *iop = mm_gc->regs;
562
563
if (value)
564
cpm1_gc->cpdata |= pin_mask;
565
else
566
cpm1_gc->cpdata &= ~pin_mask;
567
568
out_be16(&iop->dat, cpm1_gc->cpdata);
569
}
570
571
static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
572
{
573
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
574
struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
575
unsigned long flags;
576
u16 pin_mask = 1 << (15 - gpio);
577
578
spin_lock_irqsave(&cpm1_gc->lock, flags);
579
580
__cpm1_gpio16_set(mm_gc, pin_mask, value);
581
582
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
583
}
584
585
static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
586
{
587
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
588
struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
589
struct cpm_ioport16 __iomem *iop = mm_gc->regs;
590
unsigned long flags;
591
u16 pin_mask = 1 << (15 - gpio);
592
593
spin_lock_irqsave(&cpm1_gc->lock, flags);
594
595
setbits16(&iop->dir, pin_mask);
596
__cpm1_gpio16_set(mm_gc, pin_mask, val);
597
598
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
599
600
return 0;
601
}
602
603
static int cpm1_gpio16_dir_in(struct gpio_chip *gc, unsigned int gpio)
604
{
605
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
606
struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
607
struct cpm_ioport16 __iomem *iop = mm_gc->regs;
608
unsigned long flags;
609
u16 pin_mask = 1 << (15 - gpio);
610
611
spin_lock_irqsave(&cpm1_gc->lock, flags);
612
613
clrbits16(&iop->dir, pin_mask);
614
615
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
616
617
return 0;
618
}
619
620
int cpm1_gpiochip_add16(struct device_node *np)
621
{
622
struct cpm1_gpio16_chip *cpm1_gc;
623
struct of_mm_gpio_chip *mm_gc;
624
struct gpio_chip *gc;
625
626
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
627
if (!cpm1_gc)
628
return -ENOMEM;
629
630
spin_lock_init(&cpm1_gc->lock);
631
632
mm_gc = &cpm1_gc->mm_gc;
633
gc = &mm_gc->gc;
634
635
mm_gc->save_regs = cpm1_gpio16_save_regs;
636
gc->ngpio = 16;
637
gc->direction_input = cpm1_gpio16_dir_in;
638
gc->direction_output = cpm1_gpio16_dir_out;
639
gc->get = cpm1_gpio16_get;
640
gc->set = cpm1_gpio16_set;
641
642
return of_mm_gpiochip_add(np, mm_gc);
643
}
644
645
struct cpm1_gpio32_chip {
646
struct of_mm_gpio_chip mm_gc;
647
spinlock_t lock;
648
649
/* shadowed data register to clear/set bits safely */
650
u32 cpdata;
651
};
652
653
static inline struct cpm1_gpio32_chip *
654
to_cpm1_gpio32_chip(struct of_mm_gpio_chip *mm_gc)
655
{
656
return container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc);
657
}
658
659
static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
660
{
661
struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
662
struct cpm_ioport32b __iomem *iop = mm_gc->regs;
663
664
cpm1_gc->cpdata = in_be32(&iop->dat);
665
}
666
667
static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
668
{
669
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
670
struct cpm_ioport32b __iomem *iop = mm_gc->regs;
671
u32 pin_mask;
672
673
pin_mask = 1 << (31 - gpio);
674
675
return !!(in_be32(&iop->dat) & pin_mask);
676
}
677
678
static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
679
int value)
680
{
681
struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
682
struct cpm_ioport32b __iomem *iop = mm_gc->regs;
683
684
if (value)
685
cpm1_gc->cpdata |= pin_mask;
686
else
687
cpm1_gc->cpdata &= ~pin_mask;
688
689
out_be32(&iop->dat, cpm1_gc->cpdata);
690
}
691
692
static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
693
{
694
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
695
struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
696
unsigned long flags;
697
u32 pin_mask = 1 << (31 - gpio);
698
699
spin_lock_irqsave(&cpm1_gc->lock, flags);
700
701
__cpm1_gpio32_set(mm_gc, pin_mask, value);
702
703
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
704
}
705
706
static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
707
{
708
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
709
struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
710
struct cpm_ioport32b __iomem *iop = mm_gc->regs;
711
unsigned long flags;
712
u32 pin_mask = 1 << (31 - gpio);
713
714
spin_lock_irqsave(&cpm1_gc->lock, flags);
715
716
setbits32(&iop->dir, pin_mask);
717
__cpm1_gpio32_set(mm_gc, pin_mask, val);
718
719
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
720
721
return 0;
722
}
723
724
static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
725
{
726
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
727
struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
728
struct cpm_ioport32b __iomem *iop = mm_gc->regs;
729
unsigned long flags;
730
u32 pin_mask = 1 << (31 - gpio);
731
732
spin_lock_irqsave(&cpm1_gc->lock, flags);
733
734
clrbits32(&iop->dir, pin_mask);
735
736
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
737
738
return 0;
739
}
740
741
int cpm1_gpiochip_add32(struct device_node *np)
742
{
743
struct cpm1_gpio32_chip *cpm1_gc;
744
struct of_mm_gpio_chip *mm_gc;
745
struct gpio_chip *gc;
746
747
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
748
if (!cpm1_gc)
749
return -ENOMEM;
750
751
spin_lock_init(&cpm1_gc->lock);
752
753
mm_gc = &cpm1_gc->mm_gc;
754
gc = &mm_gc->gc;
755
756
mm_gc->save_regs = cpm1_gpio32_save_regs;
757
gc->ngpio = 32;
758
gc->direction_input = cpm1_gpio32_dir_in;
759
gc->direction_output = cpm1_gpio32_dir_out;
760
gc->get = cpm1_gpio32_get;
761
gc->set = cpm1_gpio32_set;
762
763
return of_mm_gpiochip_add(np, mm_gc);
764
}
765
766
static int cpm_init_par_io(void)
767
{
768
struct device_node *np;
769
770
for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-a")
771
cpm1_gpiochip_add16(np);
772
773
for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-b")
774
cpm1_gpiochip_add32(np);
775
776
for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-c")
777
cpm1_gpiochip_add16(np);
778
779
for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-d")
780
cpm1_gpiochip_add16(np);
781
782
/* Port E uses CPM2 layout */
783
for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-e")
784
cpm2_gpiochip_add32(np);
785
return 0;
786
}
787
arch_initcall(cpm_init_par_io);
788
789
#endif /* CONFIG_8xx_GPIO */
790
791