From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/hwtracing/coresight/coresight-stm.c | 173 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 126 insertions(+), 47 deletions(-) diff --git a/kernel/drivers/hwtracing/coresight/coresight-stm.c b/kernel/drivers/hwtracing/coresight/coresight-stm.c index 35d6f97..ed9a47c 100644 --- a/kernel/drivers/hwtracing/coresight/coresight-stm.c +++ b/kernel/drivers/hwtracing/coresight/coresight-stm.c @@ -16,6 +16,7 @@ * (C) 2015-2016 Chunyan Zhang <zhang.chunyan@linaro.org> */ #include <asm/local.h> +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/bitmap.h> #include <linux/clk.h> @@ -107,10 +108,11 @@ unsigned long *guaranteed; }; +DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm"); + /** * struct stm_drvdata - specifics associated to an STM component * @base: memory mapped base address for this component. - * @dev: the device entity associated to this component. * @atclk: optional clock for the core parts of the STM. * @csdev: component vitals needed by the framework. * @spinlock: only one at a time pls. @@ -128,7 +130,6 @@ */ struct stm_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; spinlock_t spinlock; @@ -205,13 +206,13 @@ if (val) return -EBUSY; - pm_runtime_get_sync(drvdata->dev); + pm_runtime_get_sync(csdev->dev.parent); spin_lock(&drvdata->spinlock); stm_enable_hw(drvdata); spin_unlock(&drvdata->spinlock); - dev_dbg(drvdata->dev, "STM tracing enabled\n"); + dev_dbg(&csdev->dev, "STM tracing enabled\n"); return 0; } @@ -257,6 +258,7 @@ struct perf_event *event) { struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct csdev_access *csa = &csdev->access; /* * For as long as the tracer isn't disabled another entity can't @@ -269,12 +271,12 @@ spin_unlock(&drvdata->spinlock); /* Wait until the engine has completely stopped */ - coresight_timeout(drvdata->base, STMTCSR, STMTCSR_BUSY_BIT, 0); + coresight_timeout(csa, STMTCSR, STMTCSR_BUSY_BIT, 0); - pm_runtime_put(drvdata->dev); + pm_runtime_put(csdev->dev.parent); local_set(&drvdata->mode, CS_MODE_DISABLED); - dev_dbg(drvdata->dev, "STM tracing disabled\n"); + dev_dbg(&csdev->dev, "STM tracing disabled\n"); } } @@ -411,6 +413,7 @@ void __iomem *ch_addr; struct stm_drvdata *drvdata = container_of(stm_data, struct stm_drvdata, stm); + unsigned int stm_flags; if (!(drvdata && local_read(&drvdata->mode))) return -EACCES; @@ -420,8 +423,9 @@ ch_addr = stm_channel_addr(drvdata, channel); - flags = (flags == STP_PACKET_TIMESTAMPED) ? STM_FLAG_TIMESTAMPED : 0; - flags |= test_bit(channel, drvdata->chs.guaranteed) ? + stm_flags = (flags & STP_PACKET_TIMESTAMPED) ? + STM_FLAG_TIMESTAMPED : 0; + stm_flags |= test_bit(channel, drvdata->chs.guaranteed) ? STM_FLAG_GUARANTEED : 0; if (size > drvdata->write_bytes) @@ -431,7 +435,7 @@ switch (packet) { case STP_PACKET_FLAG: - ch_addr += stm_channel_off(STM_PKT_TYPE_FLAG, flags); + ch_addr += stm_channel_off(STM_PKT_TYPE_FLAG, stm_flags); /* * The generic STM core sets a size of '0' on flag packets. @@ -443,7 +447,8 @@ break; case STP_PACKET_DATA: - ch_addr += stm_channel_off(STM_PKT_TYPE_DATA, flags); + stm_flags |= (flags & STP_PACKET_MARKED) ? STM_FLAG_MARKED : 0; + ch_addr += stm_channel_off(STM_PKT_TYPE_DATA, stm_flags); stm_send(ch_addr, payload, size, drvdata->write_bytes); break; @@ -685,14 +690,15 @@ NULL, }; -static int stm_get_resource_byname(struct device_node *np, - char *ch_base, struct resource *res) +#ifdef CONFIG_OF +static int of_stm_get_stimulus_area(struct device *dev, struct resource *res) { const char *name = NULL; int index = 0, found = 0; + struct device_node *np = dev->of_node; while (!of_property_read_string_index(np, "reg-names", index, &name)) { - if (strcmp(ch_base, name)) { + if (strcmp("stm-stimulus-base", name)) { index++; continue; } @@ -706,6 +712,68 @@ return -EINVAL; return of_address_to_resource(np, index, res); +} +#else +static inline int of_stm_get_stimulus_area(struct device *dev, + struct resource *res) +{ + return -ENOENT; +} +#endif + +#ifdef CONFIG_ACPI +static int acpi_stm_get_stimulus_area(struct device *dev, struct resource *res) +{ + int rc; + bool found_base = false; + struct resource_entry *rent; + LIST_HEAD(res_list); + + struct acpi_device *adev = ACPI_COMPANION(dev); + + rc = acpi_dev_get_resources(adev, &res_list, NULL, NULL); + if (rc < 0) + return rc; + + /* + * The stimulus base for STM device must be listed as the second memory + * resource, followed by the programming base address as described in + * "Section 2.3 Resources" in ACPI for CoreSightTM 1.0 Platform Design + * document (DEN0067). + */ + rc = -ENOENT; + list_for_each_entry(rent, &res_list, node) { + if (resource_type(rent->res) != IORESOURCE_MEM) + continue; + if (found_base) { + *res = *rent->res; + rc = 0; + break; + } + + found_base = true; + } + + acpi_dev_free_resource_list(&res_list); + return rc; +} +#else +static inline int acpi_stm_get_stimulus_area(struct device *dev, + struct resource *res) +{ + return -ENOENT; +} +#endif + +static int stm_get_stimulus_area(struct device *dev, struct resource *res) +{ + struct fwnode_handle *fwnode = dev_fwnode(dev); + + if (is_of_node(fwnode)) + return of_stm_get_stimulus_area(dev, res); + else if (is_acpi_node(fwnode)) + return acpi_stm_get_stimulus_area(dev, res); + return -ENOENT; } static u32 stm_fundamental_data_size(struct stm_drvdata *drvdata) @@ -763,9 +831,10 @@ bitmap_clear(drvdata->chs.guaranteed, 0, drvdata->numsp); } -static void stm_init_generic_data(struct stm_drvdata *drvdata) +static void stm_init_generic_data(struct stm_drvdata *drvdata, + const char *name) { - drvdata->stm.name = dev_name(drvdata->dev); + drvdata->stm.name = name; /* * MasterIDs are assigned at HW design phase. As such the core is @@ -793,21 +862,17 @@ struct stm_drvdata *drvdata; struct resource *res = &adev->res; struct resource ch_res; - size_t res_size, bitmap_size; + size_t bitmap_size; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node; - if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + desc.name = coresight_alloc_device_name(&stm_devs, dev); + if (!desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk); @@ -820,8 +885,9 @@ if (IS_ERR(base)) return PTR_ERR(base); drvdata->base = base; + desc.access = CSDEV_ACCESS_IOMEM(base); - ret = stm_get_resource_byname(np, "stm-stimulus-base", &ch_res); + ret = stm_get_stimulus_area(dev, &ch_res); if (ret) return ret; drvdata->chs.phys = ch_res.start; @@ -833,15 +899,11 @@ drvdata->write_bytes = stm_fundamental_data_size(drvdata); - if (boot_nr_channel) { + if (boot_nr_channel) drvdata->numsp = boot_nr_channel; - res_size = min((resource_size_t)(boot_nr_channel * - BYTES_PER_CHANNEL), resource_size(res)); - } else { + else drvdata->numsp = stm_num_stimulus_port(drvdata); - res_size = min((resource_size_t)(drvdata->numsp * - BYTES_PER_CHANNEL), resource_size(res)); - } + bitmap_size = BITS_TO_LONGS(drvdata->numsp) * sizeof(long); guaranteed = devm_kzalloc(dev, bitmap_size, GFP_KERNEL); @@ -852,13 +914,21 @@ spin_lock_init(&drvdata->spinlock); stm_init_default_data(drvdata); - stm_init_generic_data(drvdata); + stm_init_generic_data(drvdata, desc.name); if (stm_register_device(dev, &drvdata->stm, THIS_MODULE)) { dev_info(dev, - "stm_register_device failed, probing deffered\n"); + "%s : stm_register_device failed, probing deferred\n", + desc.name); return -EPROBE_DEFER; } + + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto stm_unregister; + } + adev->dev.platform_data = pdata; desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE; @@ -874,12 +944,22 @@ pm_runtime_put(&adev->dev); - dev_info(dev, "%s initialized\n", (char *)id->data); + dev_info(&drvdata->csdev->dev, "%s initialized\n", + (char *)coresight_get_uci_data(id)); return 0; stm_unregister: stm_unregister_device(&drvdata->stm); return ret; +} + +static void stm_remove(struct amba_device *adev) +{ + struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev); + + coresight_unregister(drvdata->csdev); + + stm_unregister_device(&drvdata->stm); } #ifdef CONFIG_PM @@ -909,18 +989,12 @@ }; static const struct amba_id stm_ids[] = { - { - .id = 0x000bb962, - .mask = 0x000fffff, - .data = "STM32", - }, - { - .id = 0x000bb963, - .mask = 0x000fffff, - .data = "STM500", - }, + CS_AMBA_ID_DATA(0x000bb962, "STM32"), + CS_AMBA_ID_DATA(0x000bb963, "STM500"), { 0, 0}, }; + +MODULE_DEVICE_TABLE(amba, stm_ids); static struct amba_driver stm_driver = { .drv = { @@ -930,7 +1004,12 @@ .suppress_bind_attrs = true, }, .probe = stm_probe, + .remove = stm_remove, .id_table = stm_ids, }; -builtin_amba_driver(stm_driver); +module_amba_driver(stm_driver); + +MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); +MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver"); +MODULE_LICENSE("GPL v2"); -- Gitblit v1.6.2