Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <linux/device.h>
0004 #include <linux/err.h>
0005 #include <linux/errno.h>
0006 #include <linux/fs.h>
0007 #include <linux/fsi-sbefifo.h>
0008 #include <linux/gfp.h>
0009 #include <linux/idr.h>
0010 #include <linux/kernel.h>
0011 #include <linux/list.h>
0012 #include <linux/miscdevice.h>
0013 #include <linux/mm.h>
0014 #include <linux/module.h>
0015 #include <linux/mutex.h>
0016 #include <linux/fsi-occ.h>
0017 #include <linux/of.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/sched.h>
0021 #include <linux/slab.h>
0022 #include <linux/uaccess.h>
0023 #include <asm/unaligned.h>
0024 
0025 #define OCC_SRAM_BYTES      4096
0026 #define OCC_CMD_DATA_BYTES  4090
0027 #define OCC_RESP_DATA_BYTES 4089
0028 
0029 #define OCC_P9_SRAM_CMD_ADDR    0xFFFBE000
0030 #define OCC_P9_SRAM_RSP_ADDR    0xFFFBF000
0031 
0032 #define OCC_P10_SRAM_CMD_ADDR   0xFFFFD000
0033 #define OCC_P10_SRAM_RSP_ADDR   0xFFFFE000
0034 
0035 #define OCC_P10_SRAM_MODE   0x58    /* Normal mode, OCB channel 2 */
0036 
0037 #define OCC_TIMEOUT_MS      1000
0038 #define OCC_CMD_IN_PRG_WAIT_MS  50
0039 
0040 enum versions { occ_p9, occ_p10 };
0041 
0042 struct occ {
0043     struct device *dev;
0044     struct device *sbefifo;
0045     char name[32];
0046     int idx;
0047     u8 sequence_number;
0048     void *buffer;
0049     void *client_buffer;
0050     size_t client_buffer_size;
0051     size_t client_response_size;
0052     enum versions version;
0053     struct miscdevice mdev;
0054     struct mutex occ_lock;
0055 };
0056 
0057 #define to_occ(x)   container_of((x), struct occ, mdev)
0058 
0059 struct occ_response {
0060     u8 seq_no;
0061     u8 cmd_type;
0062     u8 return_status;
0063     __be16 data_length;
0064     u8 data[OCC_RESP_DATA_BYTES + 2];   /* two bytes checksum */
0065 } __packed;
0066 
0067 struct occ_client {
0068     struct occ *occ;
0069     struct mutex lock;
0070     size_t data_size;
0071     size_t read_offset;
0072     u8 *buffer;
0073 };
0074 
0075 #define to_client(x)    container_of((x), struct occ_client, xfr)
0076 
0077 static DEFINE_IDA(occ_ida);
0078 
0079 static int occ_open(struct inode *inode, struct file *file)
0080 {
0081     struct occ_client *client = kzalloc(sizeof(*client), GFP_KERNEL);
0082     struct miscdevice *mdev = file->private_data;
0083     struct occ *occ = to_occ(mdev);
0084 
0085     if (!client)
0086         return -ENOMEM;
0087 
0088     client->buffer = (u8 *)__get_free_page(GFP_KERNEL);
0089     if (!client->buffer) {
0090         kfree(client);
0091         return -ENOMEM;
0092     }
0093 
0094     client->occ = occ;
0095     mutex_init(&client->lock);
0096     file->private_data = client;
0097 
0098     /* We allocate a 1-page buffer, make sure it all fits */
0099     BUILD_BUG_ON((OCC_CMD_DATA_BYTES + 3) > PAGE_SIZE);
0100     BUILD_BUG_ON((OCC_RESP_DATA_BYTES + 7) > PAGE_SIZE);
0101 
0102     return 0;
0103 }
0104 
0105 static ssize_t occ_read(struct file *file, char __user *buf, size_t len,
0106             loff_t *offset)
0107 {
0108     struct occ_client *client = file->private_data;
0109     ssize_t rc = 0;
0110 
0111     if (!client)
0112         return -ENODEV;
0113 
0114     if (len > OCC_SRAM_BYTES)
0115         return -EINVAL;
0116 
0117     mutex_lock(&client->lock);
0118 
0119     /* This should not be possible ... */
0120     if (WARN_ON_ONCE(client->read_offset > client->data_size)) {
0121         rc = -EIO;
0122         goto done;
0123     }
0124 
0125     /* Grab how much data we have to read */
0126     rc = min(len, client->data_size - client->read_offset);
0127     if (copy_to_user(buf, client->buffer + client->read_offset, rc))
0128         rc = -EFAULT;
0129     else
0130         client->read_offset += rc;
0131 
0132  done:
0133     mutex_unlock(&client->lock);
0134 
0135     return rc;
0136 }
0137 
0138 static ssize_t occ_write(struct file *file, const char __user *buf,
0139              size_t len, loff_t *offset)
0140 {
0141     struct occ_client *client = file->private_data;
0142     size_t rlen, data_length;
0143     ssize_t rc;
0144     u8 *cmd;
0145 
0146     if (!client)
0147         return -ENODEV;
0148 
0149     if (len > (OCC_CMD_DATA_BYTES + 3) || len < 3)
0150         return -EINVAL;
0151 
0152     mutex_lock(&client->lock);
0153 
0154     /* Construct the command */
0155     cmd = client->buffer;
0156 
0157     /*
0158      * Copy the user command (assume user data follows the occ command
0159      * format)
0160      * byte 0: command type
0161      * bytes 1-2: data length (msb first)
0162      * bytes 3-n: data
0163      */
0164     if (copy_from_user(&cmd[1], buf, len)) {
0165         rc = -EFAULT;
0166         goto done;
0167     }
0168 
0169     /* Extract data length */
0170     data_length = (cmd[2] << 8) + cmd[3];
0171     if (data_length > OCC_CMD_DATA_BYTES) {
0172         rc = -EINVAL;
0173         goto done;
0174     }
0175 
0176     /* Submit command; 4 bytes before the data and 2 bytes after */
0177     rlen = PAGE_SIZE;
0178     rc = fsi_occ_submit(client->occ->dev, cmd, data_length + 6, cmd,
0179                 &rlen);
0180     if (rc)
0181         goto done;
0182 
0183     /* Set read tracking data */
0184     client->data_size = rlen;
0185     client->read_offset = 0;
0186 
0187     /* Done */
0188     rc = len;
0189 
0190  done:
0191     mutex_unlock(&client->lock);
0192 
0193     return rc;
0194 }
0195 
0196 static int occ_release(struct inode *inode, struct file *file)
0197 {
0198     struct occ_client *client = file->private_data;
0199 
0200     free_page((unsigned long)client->buffer);
0201     kfree(client);
0202 
0203     return 0;
0204 }
0205 
0206 static const struct file_operations occ_fops = {
0207     .owner = THIS_MODULE,
0208     .open = occ_open,
0209     .read = occ_read,
0210     .write = occ_write,
0211     .release = occ_release,
0212 };
0213 
0214 static void occ_save_ffdc(struct occ *occ, __be32 *resp, size_t parsed_len,
0215               size_t resp_len)
0216 {
0217     if (resp_len > parsed_len) {
0218         size_t dh = resp_len - parsed_len;
0219         size_t ffdc_len = (dh - 1) * 4; /* SBE words are four bytes */
0220         __be32 *ffdc = &resp[parsed_len];
0221 
0222         if (ffdc_len > occ->client_buffer_size)
0223             ffdc_len = occ->client_buffer_size;
0224 
0225         memcpy(occ->client_buffer, ffdc, ffdc_len);
0226         occ->client_response_size = ffdc_len;
0227     }
0228 }
0229 
0230 static int occ_verify_checksum(struct occ *occ, struct occ_response *resp,
0231                    u16 data_length)
0232 {
0233     /* Fetch the two bytes after the data for the checksum. */
0234     u16 checksum_resp = get_unaligned_be16(&resp->data[data_length]);
0235     u16 checksum;
0236     u16 i;
0237 
0238     checksum = resp->seq_no;
0239     checksum += resp->cmd_type;
0240     checksum += resp->return_status;
0241     checksum += (data_length >> 8) + (data_length & 0xFF);
0242 
0243     for (i = 0; i < data_length; ++i)
0244         checksum += resp->data[i];
0245 
0246     if (checksum != checksum_resp) {
0247         dev_err(occ->dev, "Bad checksum: %04x!=%04x\n", checksum,
0248             checksum_resp);
0249         return -EBADMSG;
0250     }
0251 
0252     return 0;
0253 }
0254 
0255 static int occ_getsram(struct occ *occ, u32 offset, void *data, ssize_t len)
0256 {
0257     u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */
0258     size_t cmd_len, parsed_len, resp_data_len;
0259     size_t resp_len = OCC_MAX_RESP_WORDS;
0260     __be32 *resp = occ->buffer;
0261     __be32 cmd[6];
0262     int idx = 0, rc;
0263 
0264     /*
0265      * Magic sequence to do SBE getsram command. SBE will fetch data from
0266      * specified SRAM address.
0267      */
0268     switch (occ->version) {
0269     default:
0270     case occ_p9:
0271         cmd_len = 5;
0272         cmd[2] = cpu_to_be32(1);    /* Normal mode */
0273         cmd[3] = cpu_to_be32(OCC_P9_SRAM_RSP_ADDR + offset);
0274         break;
0275     case occ_p10:
0276         idx = 1;
0277         cmd_len = 6;
0278         cmd[2] = cpu_to_be32(OCC_P10_SRAM_MODE);
0279         cmd[3] = 0;
0280         cmd[4] = cpu_to_be32(OCC_P10_SRAM_RSP_ADDR + offset);
0281         break;
0282     }
0283 
0284     cmd[0] = cpu_to_be32(cmd_len);
0285     cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_OCC_SRAM);
0286     cmd[4 + idx] = cpu_to_be32(data_len);
0287 
0288     rc = sbefifo_submit(occ->sbefifo, cmd, cmd_len, resp, &resp_len);
0289     if (rc)
0290         return rc;
0291 
0292     rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_GET_OCC_SRAM,
0293                   resp, resp_len, &parsed_len);
0294     if (rc > 0) {
0295         dev_err(occ->dev, "SRAM read returned failure status: %08x\n",
0296             rc);
0297         occ_save_ffdc(occ, resp, parsed_len, resp_len);
0298         return -ECOMM;
0299     } else if (rc) {
0300         return rc;
0301     }
0302 
0303     resp_data_len = be32_to_cpu(resp[parsed_len - 1]);
0304     if (resp_data_len != data_len) {
0305         dev_err(occ->dev, "SRAM read expected %d bytes got %zd\n",
0306             data_len, resp_data_len);
0307         rc = -EBADMSG;
0308     } else {
0309         memcpy(data, resp, len);
0310     }
0311 
0312     return rc;
0313 }
0314 
0315 static int occ_putsram(struct occ *occ, const void *data, ssize_t len,
0316                u8 seq_no, u16 checksum)
0317 {
0318     u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */
0319     size_t cmd_len, parsed_len, resp_data_len;
0320     size_t resp_len = OCC_MAX_RESP_WORDS;
0321     __be32 *buf = occ->buffer;
0322     u8 *byte_buf;
0323     int idx = 0, rc;
0324 
0325     cmd_len = (occ->version == occ_p10) ? 6 : 5;
0326     cmd_len += data_len >> 2;
0327 
0328     /*
0329      * Magic sequence to do SBE putsram command. SBE will transfer
0330      * data to specified SRAM address.
0331      */
0332     buf[0] = cpu_to_be32(cmd_len);
0333     buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM);
0334 
0335     switch (occ->version) {
0336     default:
0337     case occ_p9:
0338         buf[2] = cpu_to_be32(1);    /* Normal mode */
0339         buf[3] = cpu_to_be32(OCC_P9_SRAM_CMD_ADDR);
0340         break;
0341     case occ_p10:
0342         idx = 1;
0343         buf[2] = cpu_to_be32(OCC_P10_SRAM_MODE);
0344         buf[3] = 0;
0345         buf[4] = cpu_to_be32(OCC_P10_SRAM_CMD_ADDR);
0346         break;
0347     }
0348 
0349     buf[4 + idx] = cpu_to_be32(data_len);
0350     memcpy(&buf[5 + idx], data, len);
0351 
0352     byte_buf = (u8 *)&buf[5 + idx];
0353     /*
0354      * Overwrite the first byte with our sequence number and the last two
0355      * bytes with the checksum.
0356      */
0357     byte_buf[0] = seq_no;
0358     byte_buf[len - 2] = checksum >> 8;
0359     byte_buf[len - 1] = checksum & 0xff;
0360 
0361     rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len);
0362     if (rc)
0363         return rc;
0364 
0365     rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM,
0366                   buf, resp_len, &parsed_len);
0367     if (rc > 0) {
0368         dev_err(occ->dev, "SRAM write returned failure status: %08x\n",
0369             rc);
0370         occ_save_ffdc(occ, buf, parsed_len, resp_len);
0371         return -ECOMM;
0372     } else if (rc) {
0373         return rc;
0374     }
0375 
0376     if (parsed_len != 1) {
0377         dev_err(occ->dev, "SRAM write response length invalid: %zd\n",
0378             parsed_len);
0379         rc = -EBADMSG;
0380     } else {
0381         resp_data_len = be32_to_cpu(buf[0]);
0382         if (resp_data_len != data_len) {
0383             dev_err(occ->dev,
0384                 "SRAM write expected %d bytes got %zd\n",
0385                 data_len, resp_data_len);
0386             rc = -EBADMSG;
0387         }
0388     }
0389 
0390     return rc;
0391 }
0392 
0393 static int occ_trigger_attn(struct occ *occ)
0394 {
0395     __be32 *buf = occ->buffer;
0396     size_t cmd_len, parsed_len, resp_data_len;
0397     size_t resp_len = OCC_MAX_RESP_WORDS;
0398     int idx = 0, rc;
0399 
0400     switch (occ->version) {
0401     default:
0402     case occ_p9:
0403         cmd_len = 7;
0404         buf[2] = cpu_to_be32(3); /* Circular mode */
0405         buf[3] = 0;
0406         break;
0407     case occ_p10:
0408         idx = 1;
0409         cmd_len = 8;
0410         buf[2] = cpu_to_be32(0xd0); /* Circular mode, OCB Channel 1 */
0411         buf[3] = 0;
0412         buf[4] = 0;
0413         break;
0414     }
0415 
0416     buf[0] = cpu_to_be32(cmd_len);      /* Chip-op length in words */
0417     buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM);
0418     buf[4 + idx] = cpu_to_be32(8);      /* Data length in bytes */
0419     buf[5 + idx] = cpu_to_be32(0x20010000); /* Trigger OCC attention */
0420     buf[6 + idx] = 0;
0421 
0422     rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len);
0423     if (rc)
0424         return rc;
0425 
0426     rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM,
0427                   buf, resp_len, &parsed_len);
0428     if (rc > 0) {
0429         dev_err(occ->dev, "SRAM attn returned failure status: %08x\n",
0430             rc);
0431         occ_save_ffdc(occ, buf, parsed_len, resp_len);
0432         return -ECOMM;
0433     } else if (rc) {
0434         return rc;
0435     }
0436 
0437     if (parsed_len != 1) {
0438         dev_err(occ->dev, "SRAM attn response length invalid: %zd\n",
0439             parsed_len);
0440         rc = -EBADMSG;
0441     } else {
0442         resp_data_len = be32_to_cpu(buf[0]);
0443         if (resp_data_len != 8) {
0444             dev_err(occ->dev,
0445                 "SRAM attn expected 8 bytes got %zd\n",
0446                 resp_data_len);
0447             rc = -EBADMSG;
0448         }
0449     }
0450 
0451     return rc;
0452 }
0453 
0454 static bool fsi_occ_response_not_ready(struct occ_response *resp, u8 seq_no,
0455                        u8 cmd_type)
0456 {
0457     return resp->return_status == OCC_RESP_CMD_IN_PRG ||
0458         resp->return_status == OCC_RESP_CRIT_INIT ||
0459         resp->seq_no != seq_no || resp->cmd_type != cmd_type;
0460 }
0461 
0462 int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
0463            void *response, size_t *resp_len)
0464 {
0465     const unsigned long timeout = msecs_to_jiffies(OCC_TIMEOUT_MS);
0466     const unsigned long wait_time =
0467         msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS);
0468     struct occ *occ = dev_get_drvdata(dev);
0469     struct occ_response *resp = response;
0470     size_t user_resp_len = *resp_len;
0471     u8 seq_no;
0472     u8 cmd_type;
0473     u16 checksum = 0;
0474     u16 resp_data_length;
0475     const u8 *byte_request = (const u8 *)request;
0476     unsigned long end;
0477     int rc;
0478     size_t i;
0479 
0480     *resp_len = 0;
0481 
0482     if (!occ)
0483         return -ENODEV;
0484 
0485     if (user_resp_len < 7) {
0486         dev_dbg(dev, "Bad resplen %zd\n", user_resp_len);
0487         return -EINVAL;
0488     }
0489 
0490     cmd_type = byte_request[1];
0491 
0492     /* Checksum the request, ignoring first byte (sequence number). */
0493     for (i = 1; i < req_len - 2; ++i)
0494         checksum += byte_request[i];
0495 
0496     mutex_lock(&occ->occ_lock);
0497 
0498     occ->client_buffer = response;
0499     occ->client_buffer_size = user_resp_len;
0500     occ->client_response_size = 0;
0501 
0502     /*
0503      * Get a sequence number and update the counter. Avoid a sequence
0504      * number of 0 which would pass the response check below even if the
0505      * OCC response is uninitialized. Any sequence number the user is
0506      * trying to send is overwritten since this function is the only common
0507      * interface to the OCC and therefore the only place we can guarantee
0508      * unique sequence numbers.
0509      */
0510     seq_no = occ->sequence_number++;
0511     if (!occ->sequence_number)
0512         occ->sequence_number = 1;
0513     checksum += seq_no;
0514 
0515     rc = occ_putsram(occ, request, req_len, seq_no, checksum);
0516     if (rc)
0517         goto done;
0518 
0519     rc = occ_trigger_attn(occ);
0520     if (rc)
0521         goto done;
0522 
0523     end = jiffies + timeout;
0524     while (true) {
0525         /* Read occ response header */
0526         rc = occ_getsram(occ, 0, resp, 8);
0527         if (rc)
0528             goto done;
0529 
0530         if (fsi_occ_response_not_ready(resp, seq_no, cmd_type)) {
0531             if (time_after(jiffies, end)) {
0532                 dev_err(occ->dev,
0533                     "resp timeout status=%02x seq=%d cmd=%d, our seq=%d cmd=%d\n",
0534                     resp->return_status, resp->seq_no,
0535                     resp->cmd_type, seq_no, cmd_type);
0536                 rc = -ETIMEDOUT;
0537                 goto done;
0538             }
0539 
0540             set_current_state(TASK_UNINTERRUPTIBLE);
0541             schedule_timeout(wait_time);
0542         } else {
0543             /* Extract size of response data */
0544             resp_data_length =
0545                 get_unaligned_be16(&resp->data_length);
0546 
0547             /*
0548              * Message size is data length + 5 bytes header + 2
0549              * bytes checksum
0550              */
0551             if ((resp_data_length + 7) > user_resp_len) {
0552                 rc = -EMSGSIZE;
0553                 goto done;
0554             }
0555 
0556             /*
0557              * Get the entire response including the header again,
0558              * in case it changed
0559              */
0560             if (resp_data_length > 1) {
0561                 rc = occ_getsram(occ, 0, resp,
0562                          resp_data_length + 7);
0563                 if (rc)
0564                     goto done;
0565 
0566                 if (!fsi_occ_response_not_ready(resp, seq_no,
0567                                 cmd_type))
0568                     break;
0569             } else {
0570                 break;
0571             }
0572         }
0573     }
0574 
0575     dev_dbg(dev, "resp_status=%02x resp_data_len=%d\n",
0576         resp->return_status, resp_data_length);
0577 
0578     occ->client_response_size = resp_data_length + 7;
0579     rc = occ_verify_checksum(occ, resp, resp_data_length);
0580 
0581  done:
0582     *resp_len = occ->client_response_size;
0583     mutex_unlock(&occ->occ_lock);
0584 
0585     return rc;
0586 }
0587 EXPORT_SYMBOL_GPL(fsi_occ_submit);
0588 
0589 static int occ_unregister_child(struct device *dev, void *data)
0590 {
0591     struct platform_device *hwmon_dev = to_platform_device(dev);
0592 
0593     platform_device_unregister(hwmon_dev);
0594 
0595     return 0;
0596 }
0597 
0598 static int occ_probe(struct platform_device *pdev)
0599 {
0600     int rc;
0601     u32 reg;
0602     struct occ *occ;
0603     struct platform_device *hwmon_dev;
0604     struct device *dev = &pdev->dev;
0605     struct platform_device_info hwmon_dev_info = {
0606         .parent = dev,
0607         .name = "occ-hwmon",
0608     };
0609 
0610     occ = devm_kzalloc(dev, sizeof(*occ), GFP_KERNEL);
0611     if (!occ)
0612         return -ENOMEM;
0613 
0614     /* SBE words are always four bytes */
0615     occ->buffer = kvmalloc(OCC_MAX_RESP_WORDS * 4, GFP_KERNEL);
0616     if (!occ->buffer)
0617         return -ENOMEM;
0618 
0619     occ->version = (uintptr_t)of_device_get_match_data(dev);
0620     occ->dev = dev;
0621     occ->sbefifo = dev->parent;
0622     /*
0623      * Quickly derive a pseudo-random number from jiffies so that
0624      * re-probing the driver doesn't accidentally overlap sequence numbers.
0625      */
0626     occ->sequence_number = (u8)((jiffies % 0xff) + 1);
0627     mutex_init(&occ->occ_lock);
0628 
0629     if (dev->of_node) {
0630         rc = of_property_read_u32(dev->of_node, "reg", &reg);
0631         if (!rc) {
0632             /* make sure we don't have a duplicate from dts */
0633             occ->idx = ida_simple_get(&occ_ida, reg, reg + 1,
0634                           GFP_KERNEL);
0635             if (occ->idx < 0)
0636                 occ->idx = ida_simple_get(&occ_ida, 1, INT_MAX,
0637                               GFP_KERNEL);
0638         } else {
0639             occ->idx = ida_simple_get(&occ_ida, 1, INT_MAX,
0640                           GFP_KERNEL);
0641         }
0642     } else {
0643         occ->idx = ida_simple_get(&occ_ida, 1, INT_MAX, GFP_KERNEL);
0644     }
0645 
0646     platform_set_drvdata(pdev, occ);
0647 
0648     snprintf(occ->name, sizeof(occ->name), "occ%d", occ->idx);
0649     occ->mdev.fops = &occ_fops;
0650     occ->mdev.minor = MISC_DYNAMIC_MINOR;
0651     occ->mdev.name = occ->name;
0652     occ->mdev.parent = dev;
0653 
0654     rc = misc_register(&occ->mdev);
0655     if (rc) {
0656         dev_err(dev, "failed to register miscdevice: %d\n", rc);
0657         ida_simple_remove(&occ_ida, occ->idx);
0658         kvfree(occ->buffer);
0659         return rc;
0660     }
0661 
0662     hwmon_dev_info.id = occ->idx;
0663     hwmon_dev = platform_device_register_full(&hwmon_dev_info);
0664     if (IS_ERR(hwmon_dev))
0665         dev_warn(dev, "failed to create hwmon device\n");
0666 
0667     return 0;
0668 }
0669 
0670 static int occ_remove(struct platform_device *pdev)
0671 {
0672     struct occ *occ = platform_get_drvdata(pdev);
0673 
0674     kvfree(occ->buffer);
0675 
0676     misc_deregister(&occ->mdev);
0677 
0678     device_for_each_child(&pdev->dev, NULL, occ_unregister_child);
0679 
0680     ida_simple_remove(&occ_ida, occ->idx);
0681 
0682     return 0;
0683 }
0684 
0685 static const struct of_device_id occ_match[] = {
0686     {
0687         .compatible = "ibm,p9-occ",
0688         .data = (void *)occ_p9
0689     },
0690     {
0691         .compatible = "ibm,p10-occ",
0692         .data = (void *)occ_p10
0693     },
0694     { },
0695 };
0696 MODULE_DEVICE_TABLE(of, occ_match);
0697 
0698 static struct platform_driver occ_driver = {
0699     .driver = {
0700         .name = "occ",
0701         .of_match_table = occ_match,
0702     },
0703     .probe  = occ_probe,
0704     .remove = occ_remove,
0705 };
0706 
0707 static int occ_init(void)
0708 {
0709     return platform_driver_register(&occ_driver);
0710 }
0711 
0712 static void occ_exit(void)
0713 {
0714     platform_driver_unregister(&occ_driver);
0715 
0716     ida_destroy(&occ_ida);
0717 }
0718 
0719 module_init(occ_init);
0720 module_exit(occ_exit);
0721 
0722 MODULE_AUTHOR("Eddie James <eajames@linux.ibm.com>");
0723 MODULE_DESCRIPTION("BMC P9 OCC driver");
0724 MODULE_LICENSE("GPL");