.. | .. |
---|
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"); |
---|