Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support
0004  *
0005  * Copyright (c) 2008 Marvell Semiconductor
0006  * Copyright (c) 2015 CMC Electronics, Inc.
0007  * Copyright (c) 2017 Savoir-faire Linux, Inc.
0008  */
0009 
0010 #include <linux/bitfield.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/irqdomain.h>
0013 
0014 #include "chip.h"
0015 #include "global1.h"
0016 
0017 /* Offset 0x02: VTU FID Register */
0018 
0019 static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip,
0020                      struct mv88e6xxx_vtu_entry *entry)
0021 {
0022     u16 val;
0023     int err;
0024 
0025     err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val);
0026     if (err)
0027         return err;
0028 
0029     entry->fid = val & MV88E6352_G1_VTU_FID_MASK;
0030     entry->policy = !!(val & MV88E6352_G1_VTU_FID_VID_POLICY);
0031     return 0;
0032 }
0033 
0034 static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip,
0035                       struct mv88e6xxx_vtu_entry *entry)
0036 {
0037     u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK;
0038 
0039     if (entry->policy)
0040         val |= MV88E6352_G1_VTU_FID_VID_POLICY;
0041 
0042     return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_FID, val);
0043 }
0044 
0045 /* Offset 0x03: VTU SID Register */
0046 
0047 static int mv88e6xxx_g1_vtu_sid_read(struct mv88e6xxx_chip *chip, u8 *sid)
0048 {
0049     u16 val;
0050     int err;
0051 
0052     err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID, &val);
0053     if (err)
0054         return err;
0055 
0056     *sid = val & MV88E6352_G1_VTU_SID_MASK;
0057 
0058     return 0;
0059 }
0060 
0061 static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip, u8 sid)
0062 {
0063     u16 val = sid & MV88E6352_G1_VTU_SID_MASK;
0064 
0065     return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_SID, val);
0066 }
0067 
0068 /* Offset 0x05: VTU Operation Register */
0069 
0070 static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
0071 {
0072     int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY);
0073 
0074     return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0);
0075 }
0076 
0077 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
0078 {
0079     int err;
0080 
0081     err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP,
0082                  MV88E6XXX_G1_VTU_OP_BUSY | op);
0083     if (err)
0084         return err;
0085 
0086     return mv88e6xxx_g1_vtu_op_wait(chip);
0087 }
0088 
0089 /* Offset 0x06: VTU VID Register */
0090 
0091 static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip,
0092                      bool *valid, u16 *vid)
0093 {
0094     u16 val;
0095     int err;
0096 
0097     err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val);
0098     if (err)
0099         return err;
0100 
0101     if (vid) {
0102         *vid = val & 0xfff;
0103 
0104         if (val & MV88E6390_G1_VTU_VID_PAGE)
0105             *vid |= 0x1000;
0106     }
0107 
0108     if (valid)
0109         *valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID);
0110 
0111     return 0;
0112 }
0113 
0114 static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip,
0115                       bool valid, u16 vid)
0116 {
0117     u16 val = vid & 0xfff;
0118 
0119     if (vid & 0x1000)
0120         val |= MV88E6390_G1_VTU_VID_PAGE;
0121 
0122     if (valid)
0123         val |= MV88E6XXX_G1_VTU_VID_VALID;
0124 
0125     return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val);
0126 }
0127 
0128 /* Offset 0x07: VTU/STU Data Register 1
0129  * Offset 0x08: VTU/STU Data Register 2
0130  * Offset 0x09: VTU/STU Data Register 3
0131  */
0132 static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
0133                       u16 *regs)
0134 {
0135     int i;
0136 
0137     /* Read all 3 VTU/STU Data registers */
0138     for (i = 0; i < 3; ++i) {
0139         u16 *reg = &regs[i];
0140         int err;
0141 
0142         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
0143         if (err)
0144             return err;
0145     }
0146 
0147     return 0;
0148 }
0149 
0150 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
0151                       u8 *member, u8 *state)
0152 {
0153     u16 regs[3];
0154     int err;
0155     int i;
0156 
0157     err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
0158     if (err)
0159         return err;
0160 
0161     /* Extract MemberTag data */
0162     for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
0163         unsigned int member_offset = (i % 4) * 4;
0164         unsigned int state_offset = member_offset + 2;
0165 
0166         if (member)
0167             member[i] = (regs[i / 4] >> member_offset) & 0x3;
0168 
0169         if (state)
0170             state[i] = (regs[i / 4] >> state_offset) & 0x3;
0171     }
0172 
0173     return 0;
0174 }
0175 
0176 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
0177                        u8 *member, u8 *state)
0178 {
0179     u16 regs[3] = { 0 };
0180     int i;
0181 
0182     /* Insert MemberTag and PortState data */
0183     for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
0184         unsigned int member_offset = (i % 4) * 4;
0185         unsigned int state_offset = member_offset + 2;
0186 
0187         if (member)
0188             regs[i / 4] |= (member[i] & 0x3) << member_offset;
0189 
0190         if (state)
0191             regs[i / 4] |= (state[i] & 0x3) << state_offset;
0192     }
0193 
0194     /* Write all 3 VTU/STU Data registers */
0195     for (i = 0; i < 3; ++i) {
0196         u16 reg = regs[i];
0197         int err;
0198 
0199         err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
0200         if (err)
0201             return err;
0202     }
0203 
0204     return 0;
0205 }
0206 
0207 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
0208 {
0209     u16 regs[2];
0210     int i;
0211 
0212     /* Read the 2 VTU/STU Data registers */
0213     for (i = 0; i < 2; ++i) {
0214         u16 *reg = &regs[i];
0215         int err;
0216 
0217         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
0218         if (err)
0219             return err;
0220     }
0221 
0222     /* Extract data */
0223     for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
0224         unsigned int offset = (i % 8) * 2;
0225 
0226         data[i] = (regs[i / 8] >> offset) & 0x3;
0227     }
0228 
0229     return 0;
0230 }
0231 
0232 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
0233 {
0234     u16 regs[2] = { 0 };
0235     int i;
0236 
0237     /* Insert data */
0238     for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
0239         unsigned int offset = (i % 8) * 2;
0240 
0241         regs[i / 8] |= (data[i] & 0x3) << offset;
0242     }
0243 
0244     /* Write the 2 VTU/STU Data registers */
0245     for (i = 0; i < 2; ++i) {
0246         u16 reg = regs[i];
0247         int err;
0248 
0249         err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
0250         if (err)
0251             return err;
0252     }
0253 
0254     return 0;
0255 }
0256 
0257 /* VLAN Translation Unit Operations */
0258 
0259 int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
0260                  struct mv88e6xxx_vtu_entry *entry)
0261 {
0262     int err;
0263 
0264     err = mv88e6xxx_g1_vtu_op_wait(chip);
0265     if (err)
0266         return err;
0267 
0268     /* To get the next higher active VID, the VTU GetNext operation can be
0269      * started again without setting the VID registers since it already
0270      * contains the last VID.
0271      *
0272      * To save a few hardware accesses and abstract this to the caller,
0273      * write the VID only once, when the entry is given as invalid.
0274      */
0275     if (!entry->valid) {
0276         err = mv88e6xxx_g1_vtu_vid_write(chip, false, entry->vid);
0277         if (err)
0278             return err;
0279     }
0280 
0281     err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
0282     if (err)
0283         return err;
0284 
0285     return mv88e6xxx_g1_vtu_vid_read(chip, &entry->valid, &entry->vid);
0286 }
0287 
0288 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
0289                  struct mv88e6xxx_vtu_entry *entry)
0290 {
0291     u16 val;
0292     int err;
0293 
0294     err = mv88e6xxx_g1_vtu_getnext(chip, entry);
0295     if (err)
0296         return err;
0297 
0298     if (entry->valid) {
0299         err = mv88e6185_g1_vtu_data_read(chip, entry->member, entry->state);
0300         if (err)
0301             return err;
0302 
0303         /* VTU DBNum[3:0] are located in VTU Operation 3:0
0304          * VTU DBNum[7:4] ([5:4] for 6250) are located in VTU Operation 11:8 (9:8)
0305          */
0306         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
0307         if (err)
0308             return err;
0309 
0310         entry->fid = val & 0x000f;
0311         entry->fid |= (val & 0x0f00) >> 4;
0312         entry->fid &= mv88e6xxx_num_databases(chip) - 1;
0313     }
0314 
0315     return 0;
0316 }
0317 
0318 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
0319                  struct mv88e6xxx_vtu_entry *entry)
0320 {
0321     int err;
0322 
0323     /* Fetch VLAN MemberTag data from the VTU */
0324     err = mv88e6xxx_g1_vtu_getnext(chip, entry);
0325     if (err)
0326         return err;
0327 
0328     if (entry->valid) {
0329         err = mv88e6185_g1_vtu_data_read(chip, entry->member, NULL);
0330         if (err)
0331             return err;
0332 
0333         err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
0334         if (err)
0335             return err;
0336 
0337         err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid);
0338         if (err)
0339             return err;
0340     }
0341 
0342     return 0;
0343 }
0344 
0345 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
0346                  struct mv88e6xxx_vtu_entry *entry)
0347 {
0348     int err;
0349 
0350     /* Fetch VLAN MemberTag data from the VTU */
0351     err = mv88e6xxx_g1_vtu_getnext(chip, entry);
0352     if (err)
0353         return err;
0354 
0355     if (entry->valid) {
0356         err = mv88e6390_g1_vtu_data_read(chip, entry->member);
0357         if (err)
0358             return err;
0359 
0360         err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
0361         if (err)
0362             return err;
0363 
0364         err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid);
0365         if (err)
0366             return err;
0367     }
0368 
0369     return 0;
0370 }
0371 
0372 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
0373                    struct mv88e6xxx_vtu_entry *entry)
0374 {
0375     u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
0376     int err;
0377 
0378     err = mv88e6xxx_g1_vtu_op_wait(chip);
0379     if (err)
0380         return err;
0381 
0382     err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid);
0383     if (err)
0384         return err;
0385 
0386     if (entry->valid) {
0387         err = mv88e6185_g1_vtu_data_write(chip, entry->member, entry->state);
0388         if (err)
0389             return err;
0390 
0391         /* VTU DBNum[3:0] are located in VTU Operation 3:0
0392          * VTU DBNum[7:4] are located in VTU Operation 11:8
0393          *
0394          * For the 6250/6220, the latter are really [5:4] and
0395          * 9:8, but in those cases bits 7:6 of entry->fid are
0396          * 0 since they have num_databases = 64.
0397          */
0398         op |= entry->fid & 0x000f;
0399         op |= (entry->fid & 0x00f0) << 4;
0400     }
0401 
0402     return mv88e6xxx_g1_vtu_op(chip, op);
0403 }
0404 
0405 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
0406                    struct mv88e6xxx_vtu_entry *entry)
0407 {
0408     int err;
0409 
0410     err = mv88e6xxx_g1_vtu_op_wait(chip);
0411     if (err)
0412         return err;
0413 
0414     err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid);
0415     if (err)
0416         return err;
0417 
0418     if (entry->valid) {
0419         /* Write MemberTag data */
0420         err = mv88e6185_g1_vtu_data_write(chip, entry->member, NULL);
0421         if (err)
0422             return err;
0423 
0424         err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
0425         if (err)
0426             return err;
0427 
0428         err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
0429         if (err)
0430             return err;
0431     }
0432 
0433     /* Load/Purge VTU entry */
0434     return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
0435 }
0436 
0437 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
0438                    struct mv88e6xxx_vtu_entry *entry)
0439 {
0440     int err;
0441 
0442     err = mv88e6xxx_g1_vtu_op_wait(chip);
0443     if (err)
0444         return err;
0445 
0446     err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid);
0447     if (err)
0448         return err;
0449 
0450     if (entry->valid) {
0451         /* Write MemberTag data */
0452         err = mv88e6390_g1_vtu_data_write(chip, entry->member);
0453         if (err)
0454             return err;
0455 
0456         err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
0457         if (err)
0458             return err;
0459 
0460         err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
0461         if (err)
0462             return err;
0463     }
0464 
0465     /* Load/Purge VTU entry */
0466     return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
0467 }
0468 
0469 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
0470 {
0471     int err;
0472 
0473     err = mv88e6xxx_g1_vtu_op_wait(chip);
0474     if (err)
0475         return err;
0476 
0477     return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
0478 }
0479 
0480 /* Spanning Tree Unit Operations */
0481 
0482 int mv88e6xxx_g1_stu_getnext(struct mv88e6xxx_chip *chip,
0483                  struct mv88e6xxx_stu_entry *entry)
0484 {
0485     int err;
0486 
0487     err = mv88e6xxx_g1_vtu_op_wait(chip);
0488     if (err)
0489         return err;
0490 
0491     /* To get the next higher active SID, the STU GetNext operation can be
0492      * started again without setting the SID registers since it already
0493      * contains the last SID.
0494      *
0495      * To save a few hardware accesses and abstract this to the caller,
0496      * write the SID only once, when the entry is given as invalid.
0497      */
0498     if (!entry->valid) {
0499         err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
0500         if (err)
0501             return err;
0502     }
0503 
0504     err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
0505     if (err)
0506         return err;
0507 
0508     err = mv88e6xxx_g1_vtu_vid_read(chip, &entry->valid, NULL);
0509     if (err)
0510         return err;
0511 
0512     if (entry->valid) {
0513         err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid);
0514         if (err)
0515             return err;
0516     }
0517 
0518     return 0;
0519 }
0520 
0521 int mv88e6352_g1_stu_getnext(struct mv88e6xxx_chip *chip,
0522                  struct mv88e6xxx_stu_entry *entry)
0523 {
0524     int err;
0525 
0526     err = mv88e6xxx_g1_stu_getnext(chip, entry);
0527     if (err)
0528         return err;
0529 
0530     if (!entry->valid)
0531         return 0;
0532 
0533     return mv88e6185_g1_vtu_data_read(chip, NULL, entry->state);
0534 }
0535 
0536 int mv88e6390_g1_stu_getnext(struct mv88e6xxx_chip *chip,
0537                  struct mv88e6xxx_stu_entry *entry)
0538 {
0539     int err;
0540 
0541     err = mv88e6xxx_g1_stu_getnext(chip, entry);
0542     if (err)
0543         return err;
0544 
0545     if (!entry->valid)
0546         return 0;
0547 
0548     return mv88e6390_g1_vtu_data_read(chip, entry->state);
0549 }
0550 
0551 int mv88e6352_g1_stu_loadpurge(struct mv88e6xxx_chip *chip,
0552                    struct mv88e6xxx_stu_entry *entry)
0553 {
0554     int err;
0555 
0556     err = mv88e6xxx_g1_vtu_op_wait(chip);
0557     if (err)
0558         return err;
0559 
0560     err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, 0);
0561     if (err)
0562         return err;
0563 
0564     err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
0565     if (err)
0566         return err;
0567 
0568     if (entry->valid) {
0569         err = mv88e6185_g1_vtu_data_write(chip, NULL, entry->state);
0570         if (err)
0571             return err;
0572     }
0573 
0574     /* Load/Purge STU entry */
0575     return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
0576 }
0577 
0578 int mv88e6390_g1_stu_loadpurge(struct mv88e6xxx_chip *chip,
0579                    struct mv88e6xxx_stu_entry *entry)
0580 {
0581     int err;
0582 
0583     err = mv88e6xxx_g1_vtu_op_wait(chip);
0584     if (err)
0585         return err;
0586 
0587     err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, 0);
0588     if (err)
0589         return err;
0590 
0591     err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid);
0592     if (err)
0593         return err;
0594 
0595     if (entry->valid) {
0596         err = mv88e6390_g1_vtu_data_write(chip, entry->state);
0597         if (err)
0598             return err;
0599     }
0600 
0601     /* Load/Purge STU entry */
0602     return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
0603 }
0604 
0605 /* VTU Violation Management */
0606 
0607 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
0608 {
0609     struct mv88e6xxx_chip *chip = dev_id;
0610     u16 val, vid;
0611     int spid;
0612     int err;
0613 
0614     mv88e6xxx_reg_lock(chip);
0615 
0616     err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
0617     if (err)
0618         goto out;
0619 
0620     err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
0621     if (err)
0622         goto out;
0623 
0624     err = mv88e6xxx_g1_vtu_vid_read(chip, NULL, &vid);
0625     if (err)
0626         goto out;
0627 
0628     spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
0629 
0630     if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
0631         dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
0632                     vid, spid);
0633         chip->ports[spid].vtu_member_violation++;
0634     }
0635 
0636     if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
0637         dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
0638                     vid, spid);
0639         chip->ports[spid].vtu_miss_violation++;
0640     }
0641 
0642     mv88e6xxx_reg_unlock(chip);
0643 
0644     return IRQ_HANDLED;
0645 
0646 out:
0647     mv88e6xxx_reg_unlock(chip);
0648 
0649     dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
0650         err);
0651 
0652     return IRQ_HANDLED;
0653 }
0654 
0655 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
0656 {
0657     int err;
0658 
0659     chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
0660                           MV88E6XXX_G1_STS_IRQ_VTU_PROB);
0661     if (chip->vtu_prob_irq < 0)
0662         return chip->vtu_prob_irq;
0663 
0664     snprintf(chip->vtu_prob_irq_name, sizeof(chip->vtu_prob_irq_name),
0665          "mv88e6xxx-%s-g1-vtu-prob", dev_name(chip->dev));
0666 
0667     err = request_threaded_irq(chip->vtu_prob_irq, NULL,
0668                    mv88e6xxx_g1_vtu_prob_irq_thread_fn,
0669                    IRQF_ONESHOT, chip->vtu_prob_irq_name,
0670                    chip);
0671     if (err)
0672         irq_dispose_mapping(chip->vtu_prob_irq);
0673 
0674     return err;
0675 }
0676 
0677 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
0678 {
0679     free_irq(chip->vtu_prob_irq, chip);
0680     irq_dispose_mapping(chip->vtu_prob_irq);
0681 }