Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * General Purpose functions for the global management of the
0004  * Communication Processor Module.
0005  * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
0006  *
0007  * In addition to the individual control of the communication
0008  * channels, there are a few functions that globally affect the
0009  * communication processor.
0010  *
0011  * Buffer descriptors must be allocated from the dual ported memory
0012  * space.  The allocator for that is here.  When the communication
0013  * process is reset, we reclaim the memory available.  There is
0014  * currently no deallocator for this memory.
0015  * The amount of space available is platform dependent.  On the
0016  * MBX, the EPPC software loads additional microcode into the
0017  * communication processor, and uses some of the DP ram for this
0018  * purpose.  Current, the first 512 bytes and the last 256 bytes of
0019  * memory are used.  Right now I am conservative and only use the
0020  * memory that can never be used for microcode.  If there are
0021  * applications that require more DP ram, we can expand the boundaries
0022  * but then we have to be careful of any downloaded microcode.
0023  */
0024 #include <linux/errno.h>
0025 #include <linux/sched.h>
0026 #include <linux/kernel.h>
0027 #include <linux/dma-mapping.h>
0028 #include <linux/param.h>
0029 #include <linux/string.h>
0030 #include <linux/mm.h>
0031 #include <linux/interrupt.h>
0032 #include <linux/irq.h>
0033 #include <linux/module.h>
0034 #include <linux/spinlock.h>
0035 #include <linux/slab.h>
0036 #include <linux/of_irq.h>
0037 #include <asm/page.h>
0038 #include <asm/8xx_immap.h>
0039 #include <asm/cpm1.h>
0040 #include <asm/io.h>
0041 #include <asm/rheap.h>
0042 #include <asm/cpm.h>
0043 
0044 #include <asm/fs_pd.h>
0045 
0046 #ifdef CONFIG_8xx_GPIO
0047 #include <linux/of_gpio.h>
0048 #endif
0049 
0050 #define CPM_MAP_SIZE    (0x4000)
0051 
0052 cpm8xx_t __iomem *cpmp;  /* Pointer to comm processor space */
0053 immap_t __iomem *mpc8xx_immr = (void __iomem *)VIRT_IMMR_BASE;
0054 
0055 void __init cpm_reset(void)
0056 {
0057     sysconf8xx_t __iomem *siu_conf;
0058 
0059     cpmp = &mpc8xx_immr->im_cpm;
0060 
0061 #ifndef CONFIG_PPC_EARLY_DEBUG_CPM
0062     /* Perform a reset. */
0063     out_be16(&cpmp->cp_cpcr, CPM_CR_RST | CPM_CR_FLG);
0064 
0065     /* Wait for it. */
0066     while (in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG);
0067 #endif
0068 
0069 #ifdef CONFIG_UCODE_PATCH
0070     cpm_load_patch(cpmp);
0071 #endif
0072 
0073     /*
0074      * Set SDMA Bus Request priority 5.
0075      * On 860T, this also enables FEC priority 6.  I am not sure
0076      * this is what we really want for some applications, but the
0077      * manual recommends it.
0078      * Bit 25, FAM can also be set to use FEC aggressive mode (860T).
0079      */
0080     siu_conf = immr_map(im_siu_conf);
0081     if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */
0082         out_be32(&siu_conf->sc_sdcr, 0x40);
0083     else
0084         out_be32(&siu_conf->sc_sdcr, 1);
0085     immr_unmap(siu_conf);
0086 }
0087 
0088 static DEFINE_SPINLOCK(cmd_lock);
0089 
0090 #define MAX_CR_CMD_LOOPS        10000
0091 
0092 int cpm_command(u32 command, u8 opcode)
0093 {
0094     int i, ret;
0095     unsigned long flags;
0096 
0097     if (command & 0xffffff0f)
0098         return -EINVAL;
0099 
0100     spin_lock_irqsave(&cmd_lock, flags);
0101 
0102     ret = 0;
0103     out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8));
0104     for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
0105         if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
0106             goto out;
0107 
0108     printk(KERN_ERR "%s(): Not able to issue CPM command\n", __func__);
0109     ret = -EIO;
0110 out:
0111     spin_unlock_irqrestore(&cmd_lock, flags);
0112     return ret;
0113 }
0114 EXPORT_SYMBOL(cpm_command);
0115 
0116 /*
0117  * Set a baud rate generator.  This needs lots of work.  There are
0118  * four BRGs, any of which can be wired to any channel.
0119  * The internal baud rate clock is the system clock divided by 16.
0120  * This assumes the baudrate is 16x oversampled by the uart.
0121  */
0122 #define BRG_INT_CLK     (get_brgfreq())
0123 #define BRG_UART_CLK        (BRG_INT_CLK/16)
0124 #define BRG_UART_CLK_DIV16  (BRG_UART_CLK/16)
0125 
0126 void
0127 cpm_setbrg(uint brg, uint rate)
0128 {
0129     u32 __iomem *bp;
0130 
0131     /* This is good enough to get SMCs running..... */
0132     bp = &cpmp->cp_brgc1;
0133     bp += brg;
0134     /*
0135      * The BRG has a 12-bit counter.  For really slow baud rates (or
0136      * really fast processors), we may have to further divide by 16.
0137      */
0138     if (((BRG_UART_CLK / rate) - 1) < 4096)
0139         out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);
0140     else
0141         out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
0142                   CPM_BRG_EN | CPM_BRG_DIV16);
0143 }
0144 EXPORT_SYMBOL(cpm_setbrg);
0145 
0146 struct cpm_ioport16 {
0147     __be16 dir, par, odr_sor, dat, intr;
0148     __be16 res[3];
0149 };
0150 
0151 struct cpm_ioport32b {
0152     __be32 dir, par, odr, dat;
0153 };
0154 
0155 struct cpm_ioport32e {
0156     __be32 dir, par, sor, odr, dat;
0157 };
0158 
0159 static void __init cpm1_set_pin32(int port, int pin, int flags)
0160 {
0161     struct cpm_ioport32e __iomem *iop;
0162     pin = 1 << (31 - pin);
0163 
0164     if (port == CPM_PORTB)
0165         iop = (struct cpm_ioport32e __iomem *)
0166               &mpc8xx_immr->im_cpm.cp_pbdir;
0167     else
0168         iop = (struct cpm_ioport32e __iomem *)
0169               &mpc8xx_immr->im_cpm.cp_pedir;
0170 
0171     if (flags & CPM_PIN_OUTPUT)
0172         setbits32(&iop->dir, pin);
0173     else
0174         clrbits32(&iop->dir, pin);
0175 
0176     if (!(flags & CPM_PIN_GPIO))
0177         setbits32(&iop->par, pin);
0178     else
0179         clrbits32(&iop->par, pin);
0180 
0181     if (port == CPM_PORTB) {
0182         if (flags & CPM_PIN_OPENDRAIN)
0183             setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
0184         else
0185             clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
0186     }
0187 
0188     if (port == CPM_PORTE) {
0189         if (flags & CPM_PIN_SECONDARY)
0190             setbits32(&iop->sor, pin);
0191         else
0192             clrbits32(&iop->sor, pin);
0193 
0194         if (flags & CPM_PIN_OPENDRAIN)
0195             setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
0196         else
0197             clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
0198     }
0199 }
0200 
0201 static void __init cpm1_set_pin16(int port, int pin, int flags)
0202 {
0203     struct cpm_ioport16 __iomem *iop =
0204         (struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport;
0205 
0206     pin = 1 << (15 - pin);
0207 
0208     if (port != 0)
0209         iop += port - 1;
0210 
0211     if (flags & CPM_PIN_OUTPUT)
0212         setbits16(&iop->dir, pin);
0213     else
0214         clrbits16(&iop->dir, pin);
0215 
0216     if (!(flags & CPM_PIN_GPIO))
0217         setbits16(&iop->par, pin);
0218     else
0219         clrbits16(&iop->par, pin);
0220 
0221     if (port == CPM_PORTA) {
0222         if (flags & CPM_PIN_OPENDRAIN)
0223             setbits16(&iop->odr_sor, pin);
0224         else
0225             clrbits16(&iop->odr_sor, pin);
0226     }
0227     if (port == CPM_PORTC) {
0228         if (flags & CPM_PIN_SECONDARY)
0229             setbits16(&iop->odr_sor, pin);
0230         else
0231             clrbits16(&iop->odr_sor, pin);
0232         if (flags & CPM_PIN_FALLEDGE)
0233             setbits16(&iop->intr, pin);
0234         else
0235             clrbits16(&iop->intr, pin);
0236     }
0237 }
0238 
0239 void __init cpm1_set_pin(enum cpm_port port, int pin, int flags)
0240 {
0241     if (port == CPM_PORTB || port == CPM_PORTE)
0242         cpm1_set_pin32(port, pin, flags);
0243     else
0244         cpm1_set_pin16(port, pin, flags);
0245 }
0246 
0247 int __init cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
0248 {
0249     int shift;
0250     int i, bits = 0;
0251     u32 __iomem *reg;
0252     u32 mask = 7;
0253 
0254     u8 clk_map[][3] = {
0255         {CPM_CLK_SCC1, CPM_BRG1, 0},
0256         {CPM_CLK_SCC1, CPM_BRG2, 1},
0257         {CPM_CLK_SCC1, CPM_BRG3, 2},
0258         {CPM_CLK_SCC1, CPM_BRG4, 3},
0259         {CPM_CLK_SCC1, CPM_CLK1, 4},
0260         {CPM_CLK_SCC1, CPM_CLK2, 5},
0261         {CPM_CLK_SCC1, CPM_CLK3, 6},
0262         {CPM_CLK_SCC1, CPM_CLK4, 7},
0263 
0264         {CPM_CLK_SCC2, CPM_BRG1, 0},
0265         {CPM_CLK_SCC2, CPM_BRG2, 1},
0266         {CPM_CLK_SCC2, CPM_BRG3, 2},
0267         {CPM_CLK_SCC2, CPM_BRG4, 3},
0268         {CPM_CLK_SCC2, CPM_CLK1, 4},
0269         {CPM_CLK_SCC2, CPM_CLK2, 5},
0270         {CPM_CLK_SCC2, CPM_CLK3, 6},
0271         {CPM_CLK_SCC2, CPM_CLK4, 7},
0272 
0273         {CPM_CLK_SCC3, CPM_BRG1, 0},
0274         {CPM_CLK_SCC3, CPM_BRG2, 1},
0275         {CPM_CLK_SCC3, CPM_BRG3, 2},
0276         {CPM_CLK_SCC3, CPM_BRG4, 3},
0277         {CPM_CLK_SCC3, CPM_CLK5, 4},
0278         {CPM_CLK_SCC3, CPM_CLK6, 5},
0279         {CPM_CLK_SCC3, CPM_CLK7, 6},
0280         {CPM_CLK_SCC3, CPM_CLK8, 7},
0281 
0282         {CPM_CLK_SCC4, CPM_BRG1, 0},
0283         {CPM_CLK_SCC4, CPM_BRG2, 1},
0284         {CPM_CLK_SCC4, CPM_BRG3, 2},
0285         {CPM_CLK_SCC4, CPM_BRG4, 3},
0286         {CPM_CLK_SCC4, CPM_CLK5, 4},
0287         {CPM_CLK_SCC4, CPM_CLK6, 5},
0288         {CPM_CLK_SCC4, CPM_CLK7, 6},
0289         {CPM_CLK_SCC4, CPM_CLK8, 7},
0290 
0291         {CPM_CLK_SMC1, CPM_BRG1, 0},
0292         {CPM_CLK_SMC1, CPM_BRG2, 1},
0293         {CPM_CLK_SMC1, CPM_BRG3, 2},
0294         {CPM_CLK_SMC1, CPM_BRG4, 3},
0295         {CPM_CLK_SMC1, CPM_CLK1, 4},
0296         {CPM_CLK_SMC1, CPM_CLK2, 5},
0297         {CPM_CLK_SMC1, CPM_CLK3, 6},
0298         {CPM_CLK_SMC1, CPM_CLK4, 7},
0299 
0300         {CPM_CLK_SMC2, CPM_BRG1, 0},
0301         {CPM_CLK_SMC2, CPM_BRG2, 1},
0302         {CPM_CLK_SMC2, CPM_BRG3, 2},
0303         {CPM_CLK_SMC2, CPM_BRG4, 3},
0304         {CPM_CLK_SMC2, CPM_CLK5, 4},
0305         {CPM_CLK_SMC2, CPM_CLK6, 5},
0306         {CPM_CLK_SMC2, CPM_CLK7, 6},
0307         {CPM_CLK_SMC2, CPM_CLK8, 7},
0308     };
0309 
0310     switch (target) {
0311     case CPM_CLK_SCC1:
0312         reg = &mpc8xx_immr->im_cpm.cp_sicr;
0313         shift = 0;
0314         break;
0315 
0316     case CPM_CLK_SCC2:
0317         reg = &mpc8xx_immr->im_cpm.cp_sicr;
0318         shift = 8;
0319         break;
0320 
0321     case CPM_CLK_SCC3:
0322         reg = &mpc8xx_immr->im_cpm.cp_sicr;
0323         shift = 16;
0324         break;
0325 
0326     case CPM_CLK_SCC4:
0327         reg = &mpc8xx_immr->im_cpm.cp_sicr;
0328         shift = 24;
0329         break;
0330 
0331     case CPM_CLK_SMC1:
0332         reg = &mpc8xx_immr->im_cpm.cp_simode;
0333         shift = 12;
0334         break;
0335 
0336     case CPM_CLK_SMC2:
0337         reg = &mpc8xx_immr->im_cpm.cp_simode;
0338         shift = 28;
0339         break;
0340 
0341     default:
0342         printk(KERN_ERR "cpm1_clock_setup: invalid clock target\n");
0343         return -EINVAL;
0344     }
0345 
0346     for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
0347         if (clk_map[i][0] == target && clk_map[i][1] == clock) {
0348             bits = clk_map[i][2];
0349             break;
0350         }
0351     }
0352 
0353     if (i == ARRAY_SIZE(clk_map)) {
0354         printk(KERN_ERR "cpm1_clock_setup: invalid clock combination\n");
0355         return -EINVAL;
0356     }
0357 
0358     bits <<= shift;
0359     mask <<= shift;
0360 
0361     if (reg == &mpc8xx_immr->im_cpm.cp_sicr) {
0362         if (mode == CPM_CLK_RTX) {
0363             bits |= bits << 3;
0364             mask |= mask << 3;
0365         } else if (mode == CPM_CLK_RX) {
0366             bits <<= 3;
0367             mask <<= 3;
0368         }
0369     }
0370 
0371     out_be32(reg, (in_be32(reg) & ~mask) | bits);
0372 
0373     return 0;
0374 }
0375 
0376 /*
0377  * GPIO LIB API implementation
0378  */
0379 #ifdef CONFIG_8xx_GPIO
0380 
0381 struct cpm1_gpio16_chip {
0382     struct of_mm_gpio_chip mm_gc;
0383     spinlock_t lock;
0384 
0385     /* shadowed data register to clear/set bits safely */
0386     u16 cpdata;
0387 
0388     /* IRQ associated with Pins when relevant */
0389     int irq[16];
0390 };
0391 
0392 static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc)
0393 {
0394     struct cpm1_gpio16_chip *cpm1_gc =
0395         container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc);
0396     struct cpm_ioport16 __iomem *iop = mm_gc->regs;
0397 
0398     cpm1_gc->cpdata = in_be16(&iop->dat);
0399 }
0400 
0401 static int cpm1_gpio16_get(struct gpio_chip *gc, unsigned int gpio)
0402 {
0403     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0404     struct cpm_ioport16 __iomem *iop = mm_gc->regs;
0405     u16 pin_mask;
0406 
0407     pin_mask = 1 << (15 - gpio);
0408 
0409     return !!(in_be16(&iop->dat) & pin_mask);
0410 }
0411 
0412 static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask,
0413     int value)
0414 {
0415     struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0416     struct cpm_ioport16 __iomem *iop = mm_gc->regs;
0417 
0418     if (value)
0419         cpm1_gc->cpdata |= pin_mask;
0420     else
0421         cpm1_gc->cpdata &= ~pin_mask;
0422 
0423     out_be16(&iop->dat, cpm1_gc->cpdata);
0424 }
0425 
0426 static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
0427 {
0428     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0429     struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0430     unsigned long flags;
0431     u16 pin_mask = 1 << (15 - gpio);
0432 
0433     spin_lock_irqsave(&cpm1_gc->lock, flags);
0434 
0435     __cpm1_gpio16_set(mm_gc, pin_mask, value);
0436 
0437     spin_unlock_irqrestore(&cpm1_gc->lock, flags);
0438 }
0439 
0440 static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio)
0441 {
0442     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0443     struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0444 
0445     return cpm1_gc->irq[gpio] ? : -ENXIO;
0446 }
0447 
0448 static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
0449 {
0450     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0451     struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0452     struct cpm_ioport16 __iomem *iop = mm_gc->regs;
0453     unsigned long flags;
0454     u16 pin_mask = 1 << (15 - gpio);
0455 
0456     spin_lock_irqsave(&cpm1_gc->lock, flags);
0457 
0458     setbits16(&iop->dir, pin_mask);
0459     __cpm1_gpio16_set(mm_gc, pin_mask, val);
0460 
0461     spin_unlock_irqrestore(&cpm1_gc->lock, flags);
0462 
0463     return 0;
0464 }
0465 
0466 static int cpm1_gpio16_dir_in(struct gpio_chip *gc, unsigned int gpio)
0467 {
0468     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0469     struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0470     struct cpm_ioport16 __iomem *iop = mm_gc->regs;
0471     unsigned long flags;
0472     u16 pin_mask = 1 << (15 - gpio);
0473 
0474     spin_lock_irqsave(&cpm1_gc->lock, flags);
0475 
0476     clrbits16(&iop->dir, pin_mask);
0477 
0478     spin_unlock_irqrestore(&cpm1_gc->lock, flags);
0479 
0480     return 0;
0481 }
0482 
0483 int cpm1_gpiochip_add16(struct device *dev)
0484 {
0485     struct device_node *np = dev->of_node;
0486     struct cpm1_gpio16_chip *cpm1_gc;
0487     struct of_mm_gpio_chip *mm_gc;
0488     struct gpio_chip *gc;
0489     u16 mask;
0490 
0491     cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
0492     if (!cpm1_gc)
0493         return -ENOMEM;
0494 
0495     spin_lock_init(&cpm1_gc->lock);
0496 
0497     if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
0498         int i, j;
0499 
0500         for (i = 0, j = 0; i < 16; i++)
0501             if (mask & (1 << (15 - i)))
0502                 cpm1_gc->irq[i] = irq_of_parse_and_map(np, j++);
0503     }
0504 
0505     mm_gc = &cpm1_gc->mm_gc;
0506     gc = &mm_gc->gc;
0507 
0508     mm_gc->save_regs = cpm1_gpio16_save_regs;
0509     gc->ngpio = 16;
0510     gc->direction_input = cpm1_gpio16_dir_in;
0511     gc->direction_output = cpm1_gpio16_dir_out;
0512     gc->get = cpm1_gpio16_get;
0513     gc->set = cpm1_gpio16_set;
0514     gc->to_irq = cpm1_gpio16_to_irq;
0515     gc->parent = dev;
0516     gc->owner = THIS_MODULE;
0517 
0518     return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
0519 }
0520 
0521 struct cpm1_gpio32_chip {
0522     struct of_mm_gpio_chip mm_gc;
0523     spinlock_t lock;
0524 
0525     /* shadowed data register to clear/set bits safely */
0526     u32 cpdata;
0527 };
0528 
0529 static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
0530 {
0531     struct cpm1_gpio32_chip *cpm1_gc =
0532         container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc);
0533     struct cpm_ioport32b __iomem *iop = mm_gc->regs;
0534 
0535     cpm1_gc->cpdata = in_be32(&iop->dat);
0536 }
0537 
0538 static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
0539 {
0540     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0541     struct cpm_ioport32b __iomem *iop = mm_gc->regs;
0542     u32 pin_mask;
0543 
0544     pin_mask = 1 << (31 - gpio);
0545 
0546     return !!(in_be32(&iop->dat) & pin_mask);
0547 }
0548 
0549 static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
0550     int value)
0551 {
0552     struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0553     struct cpm_ioport32b __iomem *iop = mm_gc->regs;
0554 
0555     if (value)
0556         cpm1_gc->cpdata |= pin_mask;
0557     else
0558         cpm1_gc->cpdata &= ~pin_mask;
0559 
0560     out_be32(&iop->dat, cpm1_gc->cpdata);
0561 }
0562 
0563 static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
0564 {
0565     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0566     struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0567     unsigned long flags;
0568     u32 pin_mask = 1 << (31 - gpio);
0569 
0570     spin_lock_irqsave(&cpm1_gc->lock, flags);
0571 
0572     __cpm1_gpio32_set(mm_gc, pin_mask, value);
0573 
0574     spin_unlock_irqrestore(&cpm1_gc->lock, flags);
0575 }
0576 
0577 static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
0578 {
0579     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0580     struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0581     struct cpm_ioport32b __iomem *iop = mm_gc->regs;
0582     unsigned long flags;
0583     u32 pin_mask = 1 << (31 - gpio);
0584 
0585     spin_lock_irqsave(&cpm1_gc->lock, flags);
0586 
0587     setbits32(&iop->dir, pin_mask);
0588     __cpm1_gpio32_set(mm_gc, pin_mask, val);
0589 
0590     spin_unlock_irqrestore(&cpm1_gc->lock, flags);
0591 
0592     return 0;
0593 }
0594 
0595 static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
0596 {
0597     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0598     struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
0599     struct cpm_ioport32b __iomem *iop = mm_gc->regs;
0600     unsigned long flags;
0601     u32 pin_mask = 1 << (31 - gpio);
0602 
0603     spin_lock_irqsave(&cpm1_gc->lock, flags);
0604 
0605     clrbits32(&iop->dir, pin_mask);
0606 
0607     spin_unlock_irqrestore(&cpm1_gc->lock, flags);
0608 
0609     return 0;
0610 }
0611 
0612 int cpm1_gpiochip_add32(struct device *dev)
0613 {
0614     struct device_node *np = dev->of_node;
0615     struct cpm1_gpio32_chip *cpm1_gc;
0616     struct of_mm_gpio_chip *mm_gc;
0617     struct gpio_chip *gc;
0618 
0619     cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
0620     if (!cpm1_gc)
0621         return -ENOMEM;
0622 
0623     spin_lock_init(&cpm1_gc->lock);
0624 
0625     mm_gc = &cpm1_gc->mm_gc;
0626     gc = &mm_gc->gc;
0627 
0628     mm_gc->save_regs = cpm1_gpio32_save_regs;
0629     gc->ngpio = 32;
0630     gc->direction_input = cpm1_gpio32_dir_in;
0631     gc->direction_output = cpm1_gpio32_dir_out;
0632     gc->get = cpm1_gpio32_get;
0633     gc->set = cpm1_gpio32_set;
0634     gc->parent = dev;
0635     gc->owner = THIS_MODULE;
0636 
0637     return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
0638 }
0639 
0640 #endif /* CONFIG_8xx_GPIO */