Re: [PATCH V13 2/7] soc: qcom: dcc: Add driver support for Data Capture and Compare unit(DCC)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 9/24/2022 1:12 AM, Krzysztof Kozlowski wrote:
On 20/09/2022 05:56, Souradeep Chowdhury wrote:
The DCC is a DMA Engine designed to capture and store data
during system crash or software triggers. The DCC operates
based on user inputs via the debugfs interface. The user gives
addresses as inputs and these addresses are stored in the
(...)

+
+#define DCC_RD_MOD_WR_ADDR              0xC105E
+
+/*DCC debugfs directory*/
+static struct dentry	*dcc_dbg;
+
+enum dcc_descriptor_type {
+	DCC_READ_TYPE,
+	DCC_LOOP_TYPE,
+	DCC_READ_WRITE_TYPE,
+	DCC_WRITE_TYPE
+};
+
+struct dcc_config_entry {
+	u32				base;
+	u32				offset;
+	u32				len;
+	u32				loop_cnt;
+	u32				write_val;
+	u32				mask;
+	bool				apb_bus;
+	enum dcc_descriptor_type	desc_type;
+	struct list_head		list;
+};
+
+/**
+ * struct dcc_drvdata - configuration information related to a dcc device
+ * @base:	      Base Address of the dcc device
+ * @dev:	      The device attached to the driver data
+ * @mutex:	      Lock to protect access and manipulation of dcc_drvdata
+ * @ram_base:         Base address for the SRAM dedicated for the dcc device
+ * @ram_size:         Total size of the SRAM dedicated for the dcc device
+ * @ram_offset:       Offset to the SRAM dedicated for dcc device
+ * @mem_map_ver:      Memory map version of DCC hardware
+ * @ram_cfg:          Used for address limit calculation for dcc
+ * @ram_start:        Starting address of DCC SRAM
+ * @sram_dev:	      Micellaneous device equivalent of dcc SRAM
+ * @cfg_head:	      Points to the head of the linked list of addresses
+ * @dbg_dir:          The dcc debugfs directory under which all the debugfs files are placed
+ * @nr_link_list:     Total number of linkedlists supported by the DCC configuration
+ * @loopoff:          Loop offset bits range for the addresses
All these entres have messed up spacing.
Ack

+ * @enable:           This contains an array of linkedlist enable flags
No, this is not an array of linked lists... It's a pointer to bool. This
is not way to store linked lists.
Ack


+
+static int dcc_probe(struct platform_device *pdev)
+{
+	u32 val;
+	int ret = 0, i, size;
+	struct device *dev = &pdev->dev;
+	struct dcc_drvdata *dcc;
+	struct resource *res;
+
+	dcc = devm_kzalloc(dev, sizeof(*dcc), GFP_KERNEL);
+	if (!dcc)
+		return -ENOMEM;
+
+	dcc->dev = &pdev->dev;
+	platform_set_drvdata(pdev, dcc);
+
+	dcc->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(dcc->base))
+		return PTR_ERR(dcc->base);
+
+	dcc->ram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);
+	if (IS_ERR(dcc->ram_base))
+		return PTR_ERR(dcc->ram_base);
+
+	dcc->ram_size = resource_size(res);
+
+	dcc->ram_offset = (size_t)of_device_get_match_data(&pdev->dev);
+
+	val = dcc_readl(dcc, DCC_HW_INFO);
+
+	if (FIELD_GET(DCC_VER_INFO_MASK, val)) {
+		dcc->mem_map_ver = 3;
+		dcc->nr_link_list = dcc_readl(dcc, DCC_LL_NUM_INFO);
+		if (dcc->nr_link_list == 0)
+			return	-EINVAL;
+	} else if ((val & DCC_VER_MASK2) == DCC_VER_MASK2) {
+		dcc->mem_map_ver = 2;
+		dcc->nr_link_list = dcc_readl(dcc, DCC_LL_NUM_INFO);
+		if (dcc->nr_link_list == 0)
+			return	-EINVAL;
+	} else {
+		dcc->mem_map_ver = 1;
+		dcc->nr_link_list = DCC_MAX_LINK_LIST;
+	}
+
+	/* Either set the fixed loop offset or calculate it
Start with /*
(see coding style)
Ack

+	 * from ram_size.Max consecutive addresses the
+	 * dcc can loop is equivalent to the ram size
+	 */
+	if (val & DCC_LOOP_OFFSET_MASK)
+		dcc->loopoff = DCC_FIX_LOOP_OFFSET;
+	else
+		dcc->loopoff = get_bitmask_order((dcc->ram_size +
+				dcc->ram_offset) / 4 - 1);
+
+	mutex_init(&dcc->mutex);
+	/* Allocate space for all entries at once */
+	size = sizeof(*dcc->enable) + sizeof(*dcc->cfg_head);
This is quite confusing way of handling lists - some parts of drvdata
are list, some are not.

We are using three things for lists here.  A cfg_head which points to the head of the

individual linkedlist of addresses. a nr_linked_list to store the total number of lists

supported by dcc and an array of boolean to store the enabled status of each individual lists

+
+	dcc->enable = devm_kcalloc(dev, dcc->nr_link_list, size, GFP_KERNEL);
+	if (!dcc->enable)
+		return -ENOMEM;
+
+	dcc->cfg_head = (struct list_head *)(dcc->enable + dcc->nr_link_list);
That's unusual way to iterate over list...
Here we are instantiating the head of each individual linked lists in the array that stores the list.

+
+	for (i = 0; i < dcc->nr_link_list; i++)
+		INIT_LIST_HEAD(&dcc->cfg_head[i]);
+
+	ret = dcc_sram_dev_init(dcc);
+	if (ret) {
+		dev_err(dcc->dev, "DCC: sram node not registered.\n");
+		return ret;
+	}
+
+	ret = dcc_create_debug_dir(dcc);
+	if (ret) {
+		dev_err(dcc->dev, "DCC: debugfs files not created.\n");
debugfs failures are not reasons to fail probe. Also no need to print
errors.

The total functionality of this driver is dependent on the debugfs files. That is why

the probe if failed with error message if it is not created. This is done as per Alex's

comment on version 8 of the patch.

+		dcc_sram_dev_exit(dcc);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int dcc_remove(struct platform_device *pdev)
+{
+	struct dcc_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	dcc_delete_debug_dir(drvdata);
+
+	dcc_sram_dev_exit(drvdata);
+
No need for blank lines between each calls.
Ack

+	dcc_config_reset(drvdata);
+
+	return 0;
+}
+
+static const struct of_device_id dcc_match_table[] = {
+	{ .compatible = "qcom,sm8150-dcc", .data = (void *)0x5000 },
+	{ .compatible = "qcom,sc7280-dcc", .data = (void *)0x12000 },
+	{ .compatible = "qcom,sc7180-dcc", .data = (void *)0x6000 },
+	{ .compatible = "qcom,sdm845-dcc", .data = (void *)0x6000 },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, dcc_match_table);
+
+static struct platform_driver dcc_driver = {
+	.probe = dcc_probe,
+	.remove	= dcc_remove,
+	.driver	= {
+		.name = "qcom-dcc",
+		.of_match_table	= dcc_match_table,
+	},
+};
+
+module_platform_driver(dcc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Qualcomm Technologies Inc. DCC driver");
+
Best regards,
Krzysztof




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux