| .. | .. |
|---|
| 47 | 47 | #define FFCR_FON_MAN BIT(6) |
|---|
| 48 | 48 | #define FFCR_STOP_FI BIT(12) |
|---|
| 49 | 49 | |
|---|
| 50 | +DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu"); |
|---|
| 51 | + |
|---|
| 50 | 52 | /** |
|---|
| 51 | 53 | * @base: memory mapped base address for this component. |
|---|
| 52 | | - * @dev: the device entity associated to this component. |
|---|
| 53 | 54 | * @atclk: optional clock for the core parts of the TPIU. |
|---|
| 54 | 55 | * @csdev: component vitals needed by the framework. |
|---|
| 55 | 56 | */ |
|---|
| 56 | 57 | struct tpiu_drvdata { |
|---|
| 57 | 58 | void __iomem *base; |
|---|
| 58 | | - struct device *dev; |
|---|
| 59 | 59 | struct clk *atclk; |
|---|
| 60 | 60 | struct coresight_device *csdev; |
|---|
| 61 | 61 | }; |
|---|
| 62 | 62 | |
|---|
| 63 | | -static void tpiu_enable_hw(struct tpiu_drvdata *drvdata) |
|---|
| 63 | +static void tpiu_enable_hw(struct csdev_access *csa) |
|---|
| 64 | 64 | { |
|---|
| 65 | | - CS_UNLOCK(drvdata->base); |
|---|
| 65 | + CS_UNLOCK(csa->base); |
|---|
| 66 | 66 | |
|---|
| 67 | 67 | /* TODO: fill this up */ |
|---|
| 68 | 68 | |
|---|
| 69 | | - CS_LOCK(drvdata->base); |
|---|
| 69 | + CS_LOCK(csa->base); |
|---|
| 70 | 70 | } |
|---|
| 71 | 71 | |
|---|
| 72 | 72 | static int tpiu_enable(struct coresight_device *csdev, u32 mode, void *__unused) |
|---|
| 73 | 73 | { |
|---|
| 74 | | - struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); |
|---|
| 75 | | - |
|---|
| 76 | | - tpiu_enable_hw(drvdata); |
|---|
| 74 | + tpiu_enable_hw(&csdev->access); |
|---|
| 77 | 75 | atomic_inc(csdev->refcnt); |
|---|
| 78 | | - dev_dbg(drvdata->dev, "TPIU enabled\n"); |
|---|
| 76 | + dev_dbg(&csdev->dev, "TPIU enabled\n"); |
|---|
| 79 | 77 | return 0; |
|---|
| 80 | 78 | } |
|---|
| 81 | 79 | |
|---|
| 82 | | -static void tpiu_disable_hw(struct tpiu_drvdata *drvdata) |
|---|
| 80 | +static void tpiu_disable_hw(struct csdev_access *csa) |
|---|
| 83 | 81 | { |
|---|
| 84 | | - CS_UNLOCK(drvdata->base); |
|---|
| 82 | + CS_UNLOCK(csa->base); |
|---|
| 85 | 83 | |
|---|
| 86 | 84 | /* Clear formatter and stop on flush */ |
|---|
| 87 | | - writel_relaxed(FFCR_STOP_FI, drvdata->base + TPIU_FFCR); |
|---|
| 85 | + csdev_access_relaxed_write32(csa, FFCR_STOP_FI, TPIU_FFCR); |
|---|
| 88 | 86 | /* Generate manual flush */ |
|---|
| 89 | | - writel_relaxed(FFCR_STOP_FI | FFCR_FON_MAN, drvdata->base + TPIU_FFCR); |
|---|
| 87 | + csdev_access_relaxed_write32(csa, FFCR_STOP_FI | FFCR_FON_MAN, TPIU_FFCR); |
|---|
| 90 | 88 | /* Wait for flush to complete */ |
|---|
| 91 | | - coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN_BIT, 0); |
|---|
| 89 | + coresight_timeout(csa, TPIU_FFCR, FFCR_FON_MAN_BIT, 0); |
|---|
| 92 | 90 | /* Wait for formatter to stop */ |
|---|
| 93 | | - coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED_BIT, 1); |
|---|
| 91 | + coresight_timeout(csa, TPIU_FFSR, FFSR_FT_STOPPED_BIT, 1); |
|---|
| 94 | 92 | |
|---|
| 95 | | - CS_LOCK(drvdata->base); |
|---|
| 93 | + CS_LOCK(csa->base); |
|---|
| 96 | 94 | } |
|---|
| 97 | 95 | |
|---|
| 98 | 96 | static int tpiu_disable(struct coresight_device *csdev) |
|---|
| 99 | 97 | { |
|---|
| 100 | | - struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); |
|---|
| 101 | | - |
|---|
| 102 | 98 | if (atomic_dec_return(csdev->refcnt)) |
|---|
| 103 | 99 | return -EBUSY; |
|---|
| 104 | 100 | |
|---|
| 105 | | - tpiu_disable_hw(drvdata); |
|---|
| 101 | + tpiu_disable_hw(&csdev->access); |
|---|
| 106 | 102 | |
|---|
| 107 | | - dev_dbg(drvdata->dev, "TPIU disabled\n"); |
|---|
| 103 | + dev_dbg(&csdev->dev, "TPIU disabled\n"); |
|---|
| 108 | 104 | return 0; |
|---|
| 109 | 105 | } |
|---|
| 110 | 106 | |
|---|
| .. | .. |
|---|
| 126 | 122 | struct tpiu_drvdata *drvdata; |
|---|
| 127 | 123 | struct resource *res = &adev->res; |
|---|
| 128 | 124 | struct coresight_desc desc = { 0 }; |
|---|
| 129 | | - struct device_node *np = adev->dev.of_node; |
|---|
| 130 | 125 | |
|---|
| 131 | | - if (np) { |
|---|
| 132 | | - pdata = of_get_coresight_platform_data(dev, np); |
|---|
| 133 | | - if (IS_ERR(pdata)) |
|---|
| 134 | | - return PTR_ERR(pdata); |
|---|
| 135 | | - adev->dev.platform_data = pdata; |
|---|
| 136 | | - } |
|---|
| 126 | + desc.name = coresight_alloc_device_name(&tpiu_devs, dev); |
|---|
| 127 | + if (!desc.name) |
|---|
| 128 | + return -ENOMEM; |
|---|
| 137 | 129 | |
|---|
| 138 | 130 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
|---|
| 139 | 131 | if (!drvdata) |
|---|
| 140 | 132 | return -ENOMEM; |
|---|
| 141 | 133 | |
|---|
| 142 | | - drvdata->dev = &adev->dev; |
|---|
| 143 | 134 | drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ |
|---|
| 144 | 135 | if (!IS_ERR(drvdata->atclk)) { |
|---|
| 145 | 136 | ret = clk_prepare_enable(drvdata->atclk); |
|---|
| .. | .. |
|---|
| 154 | 145 | return PTR_ERR(base); |
|---|
| 155 | 146 | |
|---|
| 156 | 147 | drvdata->base = base; |
|---|
| 148 | + desc.access = CSDEV_ACCESS_IOMEM(base); |
|---|
| 157 | 149 | |
|---|
| 158 | 150 | /* Disable tpiu to support older devices */ |
|---|
| 159 | | - tpiu_disable_hw(drvdata); |
|---|
| 151 | + tpiu_disable_hw(&desc.access); |
|---|
| 160 | 152 | |
|---|
| 161 | | - pm_runtime_put(&adev->dev); |
|---|
| 153 | + pdata = coresight_get_platform_data(dev); |
|---|
| 154 | + if (IS_ERR(pdata)) |
|---|
| 155 | + return PTR_ERR(pdata); |
|---|
| 156 | + dev->platform_data = pdata; |
|---|
| 162 | 157 | |
|---|
| 163 | 158 | desc.type = CORESIGHT_DEV_TYPE_SINK; |
|---|
| 164 | 159 | desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PORT; |
|---|
| .. | .. |
|---|
| 167 | 162 | desc.dev = dev; |
|---|
| 168 | 163 | drvdata->csdev = coresight_register(&desc); |
|---|
| 169 | 164 | |
|---|
| 170 | | - return PTR_ERR_OR_ZERO(drvdata->csdev); |
|---|
| 165 | + if (!IS_ERR(drvdata->csdev)) { |
|---|
| 166 | + pm_runtime_put(&adev->dev); |
|---|
| 167 | + return 0; |
|---|
| 168 | + } |
|---|
| 169 | + |
|---|
| 170 | + return PTR_ERR(drvdata->csdev); |
|---|
| 171 | +} |
|---|
| 172 | + |
|---|
| 173 | +static void tpiu_remove(struct amba_device *adev) |
|---|
| 174 | +{ |
|---|
| 175 | + struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev); |
|---|
| 176 | + |
|---|
| 177 | + coresight_unregister(drvdata->csdev); |
|---|
| 171 | 178 | } |
|---|
| 172 | 179 | |
|---|
| 173 | 180 | #ifdef CONFIG_PM |
|---|
| .. | .. |
|---|
| 213 | 220 | { 0, 0}, |
|---|
| 214 | 221 | }; |
|---|
| 215 | 222 | |
|---|
| 223 | +MODULE_DEVICE_TABLE(amba, tpiu_ids); |
|---|
| 224 | + |
|---|
| 216 | 225 | static struct amba_driver tpiu_driver = { |
|---|
| 217 | 226 | .drv = { |
|---|
| 218 | 227 | .name = "coresight-tpiu", |
|---|
| .. | .. |
|---|
| 221 | 230 | .suppress_bind_attrs = true, |
|---|
| 222 | 231 | }, |
|---|
| 223 | 232 | .probe = tpiu_probe, |
|---|
| 233 | + .remove = tpiu_remove, |
|---|
| 224 | 234 | .id_table = tpiu_ids, |
|---|
| 225 | 235 | }; |
|---|
| 226 | | -builtin_amba_driver(tpiu_driver); |
|---|
| 236 | + |
|---|
| 237 | +module_amba_driver(tpiu_driver); |
|---|
| 238 | + |
|---|
| 239 | +MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); |
|---|
| 240 | +MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>"); |
|---|
| 241 | +MODULE_DESCRIPTION("Arm CoreSight TPIU (Trace Port Interface Unit) driver"); |
|---|
| 242 | +MODULE_LICENSE("GPL v2"); |
|---|