Lines Matching +full:sdfec +full:- +full:code

1 // SPDX-License-Identifier: GPL-2.0
3 * Xilinx SDFEC
32 /* Xilinx SDFEC Register Map */
65 /* Write Only - Interrupt Enable Register */
67 /* Write Only - Interrupt Disable Register */
69 /* Read Only - Interrupt Mask Register */
101 /* Write Only - ECC Interrupt Enable Register */
103 /* Write Only - ECC Interrupt Disable Register */
105 /* Read Only - ECC Interrupt Mask Register */
111 /* Turbo Code Register */
169 * struct xsdfec_clks - For managing SD-FEC clocks
171 * @axi_clk: AXI4-Lite memory-mapped clock
172 * @din_words_clk: DIN Words AXI4-Stream Slave clock
173 * @din_clk: DIN AXI4-Stream Slave clock
174 * @dout_clk: DOUT Words AXI4-Stream Slave clock
175 * @dout_words_clk: DOUT AXI4-Stream Slave clock
176 * @ctrl_clk: Control AXI4-Stream Slave clock
177 * @status_clk: Status AXI4-Stream Slave clock
191 * struct xsdfec_dev - Driver data for SDFEC
193 * @clks: Clocks managed by the SDFEC driver
195 * @config: Configuration of the SDFEC device
200 * @state: State of the SDFEC device
211 * This structure contains necessary state for SDFEC driver to operate
238 dev_dbg(xsdfec->dev, "Writing 0x%x to offset 0x%x", value, addr); in xsdfec_regwrite()
239 iowrite32(value, xsdfec->regs + addr); in xsdfec_regwrite()
246 rval = ioread32(xsdfec->regs + addr); in xsdfec_regread()
247 dev_dbg(xsdfec->dev, "Read value = 0x%x from offset 0x%x", rval, addr); in xsdfec_regread()
269 xsdfec->config.order = reg_value; in update_config_from_hw()
273 &xsdfec->config.bypass); in update_config_from_hw()
277 &xsdfec->config.code_wr_protect); in update_config_from_hw()
280 xsdfec->config.irq.enable_isr = (reg_value & XSDFEC_ISR_MASK) > 0; in update_config_from_hw()
283 xsdfec->config.irq.enable_ecc_isr = in update_config_from_hw()
289 xsdfec->state = XSDFEC_STARTED; in update_config_from_hw()
291 xsdfec->state = XSDFEC_STOPPED; in update_config_from_hw()
300 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_get_status()
301 status.state = xsdfec->state; in xsdfec_get_status()
302 xsdfec->state_updated = false; in xsdfec_get_status()
303 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_get_status()
309 err = -EFAULT; in xsdfec_get_status()
318 err = copy_to_user(arg, &xsdfec->config, sizeof(xsdfec->config)); in xsdfec_get_config()
320 err = -EFAULT; in xsdfec_get_config()
334 dev_dbg(xsdfec->dev, in xsdfec_isr_enable()
335 "SDFEC enabling irq with IER failed"); in xsdfec_isr_enable()
336 return -EIO; in xsdfec_isr_enable()
343 dev_dbg(xsdfec->dev, in xsdfec_isr_enable()
344 "SDFEC disabling irq with IDR failed"); in xsdfec_isr_enable()
345 return -EIO; in xsdfec_isr_enable()
361 dev_dbg(xsdfec->dev, in xsdfec_ecc_isr_enable()
362 "SDFEC enabling ECC irq with ECC IER failed"); in xsdfec_ecc_isr_enable()
363 return -EIO; in xsdfec_ecc_isr_enable()
374 dev_dbg(xsdfec->dev, in xsdfec_ecc_isr_enable()
375 "SDFEC disable ECC irq with ECC IDR failed"); in xsdfec_ecc_isr_enable()
376 return -EIO; in xsdfec_ecc_isr_enable()
391 return -EFAULT; in xsdfec_set_irq()
396 xsdfec->config.irq.enable_isr = irq.enable_isr; in xsdfec_set_irq()
401 xsdfec->config.irq.enable_ecc_isr = irq.enable_ecc_isr; in xsdfec_set_irq()
404 err = -EIO; in xsdfec_set_irq()
417 return -EFAULT; in xsdfec_set_turbo()
420 return -EINVAL; in xsdfec_set_turbo()
423 return -EINVAL; in xsdfec_set_turbo()
426 if (xsdfec->config.code == XSDFEC_LDPC_CODE) in xsdfec_set_turbo()
427 return -EIO; in xsdfec_set_turbo()
442 if (xsdfec->config.code == XSDFEC_LDPC_CODE) in xsdfec_get_turbo()
443 return -EIO; in xsdfec_get_turbo()
454 err = -EFAULT; in xsdfec_get_turbo()
466 dev_dbg(xsdfec->dev, "N value is not in range"); in xsdfec_reg0_write()
467 return -EINVAL; in xsdfec_reg0_write()
473 dev_dbg(xsdfec->dev, "K value is not in range"); in xsdfec_reg0_write()
474 return -EINVAL; in xsdfec_reg0_write()
481 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg0 space 0x%x", in xsdfec_reg0_write()
484 return -EINVAL; in xsdfec_reg0_write()
499 dev_dbg(xsdfec->dev, "Psize is not in range"); in xsdfec_reg1_write()
500 return -EINVAL; in xsdfec_reg1_write()
504 dev_dbg(xsdfec->dev, "No-packing bit register invalid"); in xsdfec_reg1_write()
509 dev_dbg(xsdfec->dev, "NM is beyond 10 bits"); in xsdfec_reg1_write()
515 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg1 space 0x%x", in xsdfec_reg1_write()
518 return -EINVAL; in xsdfec_reg1_write()
535 dev_dbg(xsdfec->dev, "Nlayers is not in range"); in xsdfec_reg2_write()
536 return -EINVAL; in xsdfec_reg2_write()
540 dev_dbg(xsdfec->dev, "NMQC exceeds 11 bits"); in xsdfec_reg2_write()
544 dev_dbg(xsdfec->dev, "Norm type is invalid"); in xsdfec_reg2_write()
548 dev_dbg(xsdfec->dev, "Special QC in invalid"); in xsdfec_reg2_write()
553 dev_dbg(xsdfec->dev, "No final parity check invalid"); in xsdfec_reg2_write()
559 dev_dbg(xsdfec->dev, "Max Schedule exceeds 2 bits"); in xsdfec_reg2_write()
568 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg2 space 0x%x", in xsdfec_reg2_write()
571 return -EINVAL; in xsdfec_reg2_write()
589 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg3 space 0x%x", in xsdfec_reg3_write()
592 return -EINVAL; in xsdfec_reg3_write()
618 dev_dbg(xsdfec->dev, "Write exceeds SC table length"); in xsdfec_table_write()
619 return -EINVAL; in xsdfec_table_write()
627 return -EINVAL; in xsdfec_table_write()
636 return -EINVAL; in xsdfec_table_write()
664 if (xsdfec->config.code == XSDFEC_TURBO_CODE) { in xsdfec_add_ldpc()
665 ret = -EIO; in xsdfec_add_ldpc()
670 if (xsdfec->state == XSDFEC_STARTED) { in xsdfec_add_ldpc()
671 ret = -EIO; in xsdfec_add_ldpc()
675 if (xsdfec->config.code_wr_protect) { in xsdfec_add_ldpc()
676 ret = -EIO; in xsdfec_add_ldpc()
681 ret = xsdfec_reg0_write(xsdfec, ldpc->n, ldpc->k, ldpc->psize, in xsdfec_add_ldpc()
682 ldpc->code_id); in xsdfec_add_ldpc()
687 ret = xsdfec_reg1_write(xsdfec, ldpc->psize, ldpc->no_packing, ldpc->nm, in xsdfec_add_ldpc()
688 ldpc->code_id); in xsdfec_add_ldpc()
693 ret = xsdfec_reg2_write(xsdfec, ldpc->nlayers, ldpc->nmqc, in xsdfec_add_ldpc()
694 ldpc->norm_type, ldpc->special_qc, in xsdfec_add_ldpc()
695 ldpc->no_final_parity, ldpc->max_schedule, in xsdfec_add_ldpc()
696 ldpc->code_id); in xsdfec_add_ldpc()
701 ret = xsdfec_reg3_write(xsdfec, ldpc->sc_off, ldpc->la_off, in xsdfec_add_ldpc()
702 ldpc->qc_off, ldpc->code_id); in xsdfec_add_ldpc()
707 n = ldpc->nlayers / 4; in xsdfec_add_ldpc()
708 if (ldpc->nlayers % 4) in xsdfec_add_ldpc()
711 ret = xsdfec_table_write(xsdfec, ldpc->sc_off, ldpc->sc_table, n, in xsdfec_add_ldpc()
717 ret = xsdfec_table_write(xsdfec, 4 * ldpc->la_off, ldpc->la_table, in xsdfec_add_ldpc()
718 ldpc->nlayers, XSDFEC_LDPC_LA_TABLE_ADDR_BASE, in xsdfec_add_ldpc()
723 ret = xsdfec_table_write(xsdfec, 4 * ldpc->qc_off, ldpc->qc_table, in xsdfec_add_ldpc()
724 ldpc->nqc, XSDFEC_LDPC_QC_TABLE_ADDR_BASE, in xsdfec_add_ldpc()
739 return -EFAULT; in xsdfec_set_order()
744 return -EINVAL; in xsdfec_set_order()
747 if (xsdfec->state == XSDFEC_STARTED) in xsdfec_set_order()
748 return -EIO; in xsdfec_set_order()
752 xsdfec->config.order = order; in xsdfec_set_order()
764 return -EFAULT; in xsdfec_set_bypass()
767 if (xsdfec->state == XSDFEC_STARTED) in xsdfec_set_bypass()
768 return -EIO; in xsdfec_set_bypass()
775 xsdfec->config.bypass = bypass; in xsdfec_set_bypass()
791 return -EFAULT; in xsdfec_is_active()
837 struct xsdfec_config *config = &xsdfec->config; in xsdfec_cfg_axi_streams()
841 xsdfec_translate_axis_words_cfg_val(config->dout_word_include); in xsdfec_cfg_axi_streams()
843 xsdfec_translate_axis_width_cfg_val(config->dout_width); in xsdfec_cfg_axi_streams()
845 xsdfec_translate_axis_words_cfg_val(config->din_word_include); in xsdfec_cfg_axi_streams()
847 xsdfec_translate_axis_width_cfg_val(config->din_width); in xsdfec_cfg_axi_streams()
865 if (regread != xsdfec->config.code) { in xsdfec_start()
866 dev_dbg(xsdfec->dev, in xsdfec_start()
867 "%s SDFEC HW code does not match driver code, reg %d, code %d", in xsdfec_start()
868 __func__, regread, xsdfec->config.code); in xsdfec_start()
869 return -EINVAL; in xsdfec_start()
876 xsdfec->state = XSDFEC_STARTED; in xsdfec_start()
884 if (xsdfec->state != XSDFEC_STARTED) in xsdfec_stop()
885 dev_dbg(xsdfec->dev, "Device not started correctly"); in xsdfec_stop()
891 xsdfec->state = XSDFEC_STOPPED; in xsdfec_stop()
897 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_clear_stats()
898 xsdfec->isr_err_count = 0; in xsdfec_clear_stats()
899 xsdfec->uecc_count = 0; in xsdfec_clear_stats()
900 xsdfec->cecc_count = 0; in xsdfec_clear_stats()
901 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_clear_stats()
911 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_get_stats()
912 user_stats.isr_err_count = xsdfec->isr_err_count; in xsdfec_get_stats()
913 user_stats.cecc_count = xsdfec->cecc_count; in xsdfec_get_stats()
914 user_stats.uecc_count = xsdfec->uecc_count; in xsdfec_get_stats()
915 xsdfec->stats_updated = false; in xsdfec_get_stats()
916 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_get_stats()
920 err = -EFAULT; in xsdfec_get_stats()
928 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code); in xsdfec_set_default_config()
942 xsdfec = container_of(fptr->private_data, struct xsdfec_dev, miscdev); in xsdfec_dev_ioctl()
945 if (xsdfec->state == XSDFEC_NEEDS_RESET && in xsdfec_dev_ioctl()
948 return -EPERM; in xsdfec_dev_ioctl()
995 rval = -ENOTTY; in xsdfec_dev_ioctl()
1006 xsdfec = container_of(file->private_data, struct xsdfec_dev, miscdev); in xsdfec_poll()
1008 poll_wait(file, &xsdfec->waitq, wait); in xsdfec_poll()
1011 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_poll()
1012 if (xsdfec->state_updated) in xsdfec_poll()
1015 if (xsdfec->stats_updated) in xsdfec_poll()
1017 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_poll()
1031 struct device *dev = xsdfec->dev; in xsdfec_parse_of()
1032 struct device_node *node = dev->of_node; in xsdfec_parse_of()
1040 rval = of_property_read_string(node, "xlnx,sdfec-code", &fec_code); in xsdfec_parse_of()
1045 xsdfec->config.code = XSDFEC_LDPC_CODE; in xsdfec_parse_of()
1047 xsdfec->config.code = XSDFEC_TURBO_CODE; in xsdfec_parse_of()
1049 return -EINVAL; in xsdfec_parse_of()
1051 rval = of_property_read_u32(node, "xlnx,sdfec-din-words", in xsdfec_parse_of()
1057 xsdfec->config.din_word_include = din_word_include; in xsdfec_parse_of()
1059 return -EINVAL; in xsdfec_parse_of()
1061 rval = of_property_read_u32(node, "xlnx,sdfec-din-width", &din_width); in xsdfec_parse_of()
1070 xsdfec->config.din_width = din_width; in xsdfec_parse_of()
1073 return -EINVAL; in xsdfec_parse_of()
1076 rval = of_property_read_u32(node, "xlnx,sdfec-dout-words", in xsdfec_parse_of()
1082 xsdfec->config.dout_word_include = dout_word_include; in xsdfec_parse_of()
1084 return -EINVAL; in xsdfec_parse_of()
1086 rval = of_property_read_u32(node, "xlnx,sdfec-dout-width", &dout_width); in xsdfec_parse_of()
1095 xsdfec->config.dout_width = dout_width; in xsdfec_parse_of()
1098 return -EINVAL; in xsdfec_parse_of()
1101 /* Write LDPC to CODE Register */ in xsdfec_parse_of()
1102 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code); in xsdfec_parse_of()
1121 WARN_ON(xsdfec->irq != irq); in xsdfec_irq_thread()
1134 /* Count uncorrectable 2-bit errors */ in xsdfec_irq_thread()
1138 /* Number of correctable 1-bit ECC error */ in xsdfec_irq_thread()
1139 cecc_count = aecc_count - 2 * uecc_count; in xsdfec_irq_thread()
1142 dev_dbg(xsdfec->dev, "tmp=%x, uecc=%x, aecc=%x, cecc=%x, isr=%x", tmp, in xsdfec_irq_thread()
1144 dev_dbg(xsdfec->dev, "uecc=%x, cecc=%x, isr=%x", xsdfec->uecc_count, in xsdfec_irq_thread()
1145 xsdfec->cecc_count, xsdfec->isr_err_count); in xsdfec_irq_thread()
1147 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_irq_thread()
1148 /* Add new errors to a 2-bits counter */ in xsdfec_irq_thread()
1150 xsdfec->uecc_count += uecc_count; in xsdfec_irq_thread()
1151 /* Add new errors to a 1-bits counter */ in xsdfec_irq_thread()
1153 xsdfec->cecc_count += cecc_count; in xsdfec_irq_thread()
1156 xsdfec->isr_err_count += isr_err_count; in xsdfec_irq_thread()
1161 xsdfec->state = XSDFEC_NEEDS_RESET; in xsdfec_irq_thread()
1163 xsdfec->state = XSDFEC_PL_RECONFIGURE; in xsdfec_irq_thread()
1164 xsdfec->stats_updated = true; in xsdfec_irq_thread()
1165 xsdfec->state_updated = true; in xsdfec_irq_thread()
1169 xsdfec->stats_updated = true; in xsdfec_irq_thread()
1172 xsdfec->state = XSDFEC_NEEDS_RESET; in xsdfec_irq_thread()
1173 xsdfec->stats_updated = true; in xsdfec_irq_thread()
1174 xsdfec->state_updated = true; in xsdfec_irq_thread()
1177 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); in xsdfec_irq_thread()
1178 dev_dbg(xsdfec->dev, "state=%x, stats=%x", xsdfec->state_updated, in xsdfec_irq_thread()
1179 xsdfec->stats_updated); in xsdfec_irq_thread()
1182 if (xsdfec->state_updated || xsdfec->stats_updated) in xsdfec_irq_thread()
1183 wake_up_interruptible(&xsdfec->waitq); in xsdfec_irq_thread()
1199 clks->core_clk = devm_clk_get(&pdev->dev, "core_clk"); in xsdfec_clk_init()
1200 if (IS_ERR(clks->core_clk)) { in xsdfec_clk_init()
1201 dev_err(&pdev->dev, "failed to get core_clk"); in xsdfec_clk_init()
1202 return PTR_ERR(clks->core_clk); in xsdfec_clk_init()
1205 clks->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); in xsdfec_clk_init()
1206 if (IS_ERR(clks->axi_clk)) { in xsdfec_clk_init()
1207 dev_err(&pdev->dev, "failed to get axi_clk"); in xsdfec_clk_init()
1208 return PTR_ERR(clks->axi_clk); in xsdfec_clk_init()
1211 clks->din_words_clk = devm_clk_get(&pdev->dev, "s_axis_din_words_aclk"); in xsdfec_clk_init()
1212 if (IS_ERR(clks->din_words_clk)) { in xsdfec_clk_init()
1213 if (PTR_ERR(clks->din_words_clk) != -ENOENT) { in xsdfec_clk_init()
1214 err = PTR_ERR(clks->din_words_clk); in xsdfec_clk_init()
1217 clks->din_words_clk = NULL; in xsdfec_clk_init()
1220 clks->din_clk = devm_clk_get(&pdev->dev, "s_axis_din_aclk"); in xsdfec_clk_init()
1221 if (IS_ERR(clks->din_clk)) { in xsdfec_clk_init()
1222 if (PTR_ERR(clks->din_clk) != -ENOENT) { in xsdfec_clk_init()
1223 err = PTR_ERR(clks->din_clk); in xsdfec_clk_init()
1226 clks->din_clk = NULL; in xsdfec_clk_init()
1229 clks->dout_clk = devm_clk_get(&pdev->dev, "m_axis_dout_aclk"); in xsdfec_clk_init()
1230 if (IS_ERR(clks->dout_clk)) { in xsdfec_clk_init()
1231 if (PTR_ERR(clks->dout_clk) != -ENOENT) { in xsdfec_clk_init()
1232 err = PTR_ERR(clks->dout_clk); in xsdfec_clk_init()
1235 clks->dout_clk = NULL; in xsdfec_clk_init()
1238 clks->dout_words_clk = in xsdfec_clk_init()
1239 devm_clk_get(&pdev->dev, "s_axis_dout_words_aclk"); in xsdfec_clk_init()
1240 if (IS_ERR(clks->dout_words_clk)) { in xsdfec_clk_init()
1241 if (PTR_ERR(clks->dout_words_clk) != -ENOENT) { in xsdfec_clk_init()
1242 err = PTR_ERR(clks->dout_words_clk); in xsdfec_clk_init()
1245 clks->dout_words_clk = NULL; in xsdfec_clk_init()
1248 clks->ctrl_clk = devm_clk_get(&pdev->dev, "s_axis_ctrl_aclk"); in xsdfec_clk_init()
1249 if (IS_ERR(clks->ctrl_clk)) { in xsdfec_clk_init()
1250 if (PTR_ERR(clks->ctrl_clk) != -ENOENT) { in xsdfec_clk_init()
1251 err = PTR_ERR(clks->ctrl_clk); in xsdfec_clk_init()
1254 clks->ctrl_clk = NULL; in xsdfec_clk_init()
1257 clks->status_clk = devm_clk_get(&pdev->dev, "m_axis_status_aclk"); in xsdfec_clk_init()
1258 if (IS_ERR(clks->status_clk)) { in xsdfec_clk_init()
1259 if (PTR_ERR(clks->status_clk) != -ENOENT) { in xsdfec_clk_init()
1260 err = PTR_ERR(clks->status_clk); in xsdfec_clk_init()
1263 clks->status_clk = NULL; in xsdfec_clk_init()
1266 err = clk_prepare_enable(clks->core_clk); in xsdfec_clk_init()
1268 dev_err(&pdev->dev, "failed to enable core_clk (%d)", err); in xsdfec_clk_init()
1272 err = clk_prepare_enable(clks->axi_clk); in xsdfec_clk_init()
1274 dev_err(&pdev->dev, "failed to enable axi_clk (%d)", err); in xsdfec_clk_init()
1278 err = clk_prepare_enable(clks->din_clk); in xsdfec_clk_init()
1280 dev_err(&pdev->dev, "failed to enable din_clk (%d)", err); in xsdfec_clk_init()
1284 err = clk_prepare_enable(clks->din_words_clk); in xsdfec_clk_init()
1286 dev_err(&pdev->dev, "failed to enable din_words_clk (%d)", err); in xsdfec_clk_init()
1290 err = clk_prepare_enable(clks->dout_clk); in xsdfec_clk_init()
1292 dev_err(&pdev->dev, "failed to enable dout_clk (%d)", err); in xsdfec_clk_init()
1296 err = clk_prepare_enable(clks->dout_words_clk); in xsdfec_clk_init()
1298 dev_err(&pdev->dev, "failed to enable dout_words_clk (%d)", in xsdfec_clk_init()
1303 err = clk_prepare_enable(clks->ctrl_clk); in xsdfec_clk_init()
1305 dev_err(&pdev->dev, "failed to enable ctrl_clk (%d)", err); in xsdfec_clk_init()
1309 err = clk_prepare_enable(clks->status_clk); in xsdfec_clk_init()
1311 dev_err(&pdev->dev, "failed to enable status_clk (%d)\n", err); in xsdfec_clk_init()
1318 clk_disable_unprepare(clks->ctrl_clk); in xsdfec_clk_init()
1320 clk_disable_unprepare(clks->dout_words_clk); in xsdfec_clk_init()
1322 clk_disable_unprepare(clks->dout_clk); in xsdfec_clk_init()
1324 clk_disable_unprepare(clks->din_words_clk); in xsdfec_clk_init()
1326 clk_disable_unprepare(clks->din_clk); in xsdfec_clk_init()
1328 clk_disable_unprepare(clks->axi_clk); in xsdfec_clk_init()
1330 clk_disable_unprepare(clks->core_clk); in xsdfec_clk_init()
1337 clk_disable_unprepare(clks->status_clk); in xsdfec_disable_all_clks()
1338 clk_disable_unprepare(clks->ctrl_clk); in xsdfec_disable_all_clks()
1339 clk_disable_unprepare(clks->dout_words_clk); in xsdfec_disable_all_clks()
1340 clk_disable_unprepare(clks->dout_clk); in xsdfec_disable_all_clks()
1341 clk_disable_unprepare(clks->din_words_clk); in xsdfec_disable_all_clks()
1342 clk_disable_unprepare(clks->din_clk); in xsdfec_disable_all_clks()
1343 clk_disable_unprepare(clks->core_clk); in xsdfec_disable_all_clks()
1344 clk_disable_unprepare(clks->axi_clk); in xsdfec_disable_all_clks()
1354 xsdfec = devm_kzalloc(&pdev->dev, sizeof(*xsdfec), GFP_KERNEL); in xsdfec_probe()
1356 return -ENOMEM; in xsdfec_probe()
1358 xsdfec->dev = &pdev->dev; in xsdfec_probe()
1359 spin_lock_init(&xsdfec->error_data_lock); in xsdfec_probe()
1361 err = xsdfec_clk_init(pdev, &xsdfec->clks); in xsdfec_probe()
1365 dev = xsdfec->dev; in xsdfec_probe()
1366 xsdfec->regs = devm_platform_ioremap_resource(pdev, 0); in xsdfec_probe()
1367 if (IS_ERR(xsdfec->regs)) { in xsdfec_probe()
1368 err = PTR_ERR(xsdfec->regs); in xsdfec_probe()
1372 xsdfec->irq = platform_get_irq(pdev, 0); in xsdfec_probe()
1373 if (xsdfec->irq < 0) { in xsdfec_probe()
1388 init_waitqueue_head(&xsdfec->waitq); in xsdfec_probe()
1390 err = devm_request_threaded_irq(dev, xsdfec->irq, NULL, in xsdfec_probe()
1392 "xilinx-sdfec16", xsdfec); in xsdfec_probe()
1394 dev_err(dev, "unable to request IRQ%d", xsdfec->irq); in xsdfec_probe()
1402 xsdfec->dev_id = err; in xsdfec_probe()
1404 snprintf(xsdfec->dev_name, DEV_NAME_LEN, "xsdfec%d", xsdfec->dev_id); in xsdfec_probe()
1405 xsdfec->miscdev.minor = MISC_DYNAMIC_MINOR; in xsdfec_probe()
1406 xsdfec->miscdev.name = xsdfec->dev_name; in xsdfec_probe()
1407 xsdfec->miscdev.fops = &xsdfec_fops; in xsdfec_probe()
1408 xsdfec->miscdev.parent = dev; in xsdfec_probe()
1409 err = misc_register(&xsdfec->miscdev); in xsdfec_probe()
1417 ida_free(&dev_nrs, xsdfec->dev_id); in xsdfec_probe()
1419 xsdfec_disable_all_clks(&xsdfec->clks); in xsdfec_probe()
1428 misc_deregister(&xsdfec->miscdev); in xsdfec_remove()
1429 ida_free(&dev_nrs, xsdfec->dev_id); in xsdfec_remove()
1430 xsdfec_disable_all_clks(&xsdfec->clks); in xsdfec_remove()
1435 .compatible = "xlnx,sd-fec-1.1",
1443 .name = "xilinx-sdfec",
1453 MODULE_DESCRIPTION("Xilinx SD-FEC16 Driver");