0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/acpi.h>
0011 #include <linux/export.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/module.h>
0015 #include <linux/auxiliary_bus.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/soundwire/sdw_intel.h>
0018 #include "cadence_master.h"
0019 #include "intel.h"
0020
0021 static void intel_link_dev_release(struct device *dev)
0022 {
0023 struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
0024 struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev);
0025
0026 kfree(ldev);
0027 }
0028
0029
0030 static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *res,
0031 struct sdw_intel_ctx *ctx,
0032 struct fwnode_handle *fwnode,
0033 const char *name,
0034 int link_id)
0035 {
0036 struct sdw_intel_link_dev *ldev;
0037 struct sdw_intel_link_res *link;
0038 struct auxiliary_device *auxdev;
0039 int ret;
0040
0041 ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
0042 if (!ldev)
0043 return ERR_PTR(-ENOMEM);
0044
0045 auxdev = &ldev->auxdev;
0046 auxdev->name = name;
0047 auxdev->dev.parent = res->parent;
0048 auxdev->dev.fwnode = fwnode;
0049 auxdev->dev.release = intel_link_dev_release;
0050
0051
0052 auxdev->id = link_id;
0053
0054
0055
0056
0057
0058
0059 ctx->ldev[link_id] = ldev;
0060
0061
0062 link = &ldev->link_res;
0063 link->mmio_base = res->mmio_base;
0064 link->registers = res->mmio_base + SDW_LINK_BASE
0065 + (SDW_LINK_SIZE * link_id);
0066 link->shim = res->mmio_base + res->shim_base;
0067 link->alh = res->mmio_base + res->alh_base;
0068
0069 link->ops = res->ops;
0070 link->dev = res->dev;
0071
0072 link->clock_stop_quirks = res->clock_stop_quirks;
0073 link->shim_lock = &ctx->shim_lock;
0074 link->shim_mask = &ctx->shim_mask;
0075 link->link_mask = ctx->link_mask;
0076
0077
0078 ret = auxiliary_device_init(auxdev);
0079 if (ret < 0) {
0080 dev_err(res->parent, "failed to initialize link dev %s link_id %d\n",
0081 name, link_id);
0082 kfree(ldev);
0083 return ERR_PTR(ret);
0084 }
0085
0086 ret = auxiliary_device_add(&ldev->auxdev);
0087 if (ret < 0) {
0088 dev_err(res->parent, "failed to add link dev %s link_id %d\n",
0089 ldev->auxdev.name, link_id);
0090
0091 auxiliary_device_uninit(&ldev->auxdev);
0092 return ERR_PTR(ret);
0093 }
0094
0095 return ldev;
0096 }
0097
0098 static void intel_link_dev_unregister(struct sdw_intel_link_dev *ldev)
0099 {
0100 auxiliary_device_delete(&ldev->auxdev);
0101 auxiliary_device_uninit(&ldev->auxdev);
0102 }
0103
0104 static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
0105 {
0106 struct sdw_intel_link_dev *ldev;
0107 u32 link_mask;
0108 int i;
0109
0110 link_mask = ctx->link_mask;
0111
0112 for (i = 0; i < ctx->count; i++) {
0113 if (!(link_mask & BIT(i)))
0114 continue;
0115
0116 ldev = ctx->ldev[i];
0117
0118 pm_runtime_disable(&ldev->auxdev.dev);
0119 if (!ldev->link_res.clock_stop_quirks)
0120 pm_runtime_put_noidle(ldev->link_res.dev);
0121
0122 intel_link_dev_unregister(ldev);
0123 }
0124
0125 return 0;
0126 }
0127
0128 #define HDA_DSP_REG_ADSPIC2 (0x10)
0129 #define HDA_DSP_REG_ADSPIS2 (0x14)
0130 #define HDA_DSP_REG_ADSPIC2_SNDW BIT(5)
0131
0132
0133
0134
0135
0136
0137 void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable)
0138 {
0139 u32 val;
0140
0141 val = readl(mmio_base + HDA_DSP_REG_ADSPIC2);
0142
0143 if (enable)
0144 val |= HDA_DSP_REG_ADSPIC2_SNDW;
0145 else
0146 val &= ~HDA_DSP_REG_ADSPIC2_SNDW;
0147
0148 writel(val, mmio_base + HDA_DSP_REG_ADSPIC2);
0149 }
0150 EXPORT_SYMBOL_NS(sdw_intel_enable_irq, SOUNDWIRE_INTEL_INIT);
0151
0152 irqreturn_t sdw_intel_thread(int irq, void *dev_id)
0153 {
0154 struct sdw_intel_ctx *ctx = dev_id;
0155 struct sdw_intel_link_res *link;
0156
0157 list_for_each_entry(link, &ctx->link_list, list)
0158 sdw_cdns_irq(irq, link->cdns);
0159
0160 sdw_intel_enable_irq(ctx->mmio_base, true);
0161 return IRQ_HANDLED;
0162 }
0163 EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
0164
0165 static struct sdw_intel_ctx
0166 *sdw_intel_probe_controller(struct sdw_intel_res *res)
0167 {
0168 struct sdw_intel_link_res *link;
0169 struct sdw_intel_link_dev *ldev;
0170 struct sdw_intel_ctx *ctx;
0171 struct acpi_device *adev;
0172 struct sdw_slave *slave;
0173 struct list_head *node;
0174 struct sdw_bus *bus;
0175 u32 link_mask;
0176 int num_slaves = 0;
0177 int count;
0178 int i;
0179
0180 if (!res)
0181 return NULL;
0182
0183 adev = acpi_fetch_acpi_dev(res->handle);
0184 if (!adev)
0185 return NULL;
0186
0187 if (!res->count)
0188 return NULL;
0189
0190 count = res->count;
0191 dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
0192
0193
0194
0195
0196
0197
0198
0199 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
0200 if (!ctx)
0201 return NULL;
0202
0203 ctx->count = count;
0204
0205
0206
0207
0208
0209
0210
0211 ctx->ldev = kcalloc(ctx->count, sizeof(*ctx->ldev), GFP_KERNEL);
0212 if (!ctx->ldev) {
0213 kfree(ctx);
0214 return NULL;
0215 }
0216
0217 ctx->mmio_base = res->mmio_base;
0218 ctx->shim_base = res->shim_base;
0219 ctx->alh_base = res->alh_base;
0220 ctx->link_mask = res->link_mask;
0221 ctx->handle = res->handle;
0222 mutex_init(&ctx->shim_lock);
0223
0224 link_mask = ctx->link_mask;
0225
0226 INIT_LIST_HEAD(&ctx->link_list);
0227
0228 for (i = 0; i < count; i++) {
0229 if (!(link_mask & BIT(i)))
0230 continue;
0231
0232
0233
0234
0235
0236
0237
0238
0239 ldev = intel_link_dev_register(res,
0240 ctx,
0241 acpi_fwnode_handle(adev),
0242 "link",
0243 i);
0244 if (IS_ERR(ldev))
0245 goto err;
0246
0247 link = &ldev->link_res;
0248 link->cdns = auxiliary_get_drvdata(&ldev->auxdev);
0249
0250 if (!link->cdns) {
0251 dev_err(&adev->dev, "failed to get link->cdns\n");
0252
0253
0254
0255
0256 i++;
0257 goto err;
0258 }
0259 list_add_tail(&link->list, &ctx->link_list);
0260 bus = &link->cdns->bus;
0261
0262 list_for_each(node, &bus->slaves)
0263 num_slaves++;
0264 }
0265
0266 ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
0267 if (!ctx->ids)
0268 goto err;
0269
0270 ctx->num_slaves = num_slaves;
0271 i = 0;
0272 list_for_each_entry(link, &ctx->link_list, list) {
0273 bus = &link->cdns->bus;
0274 list_for_each_entry(slave, &bus->slaves, node) {
0275 ctx->ids[i].id = slave->id;
0276 ctx->ids[i].link_id = bus->link_id;
0277 i++;
0278 }
0279 }
0280
0281 return ctx;
0282
0283 err:
0284 while (i--) {
0285 if (!(link_mask & BIT(i)))
0286 continue;
0287 ldev = ctx->ldev[i];
0288 intel_link_dev_unregister(ldev);
0289 }
0290 kfree(ctx->ldev);
0291 kfree(ctx);
0292 return NULL;
0293 }
0294
0295 static int
0296 sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
0297 {
0298 struct acpi_device *adev = acpi_fetch_acpi_dev(ctx->handle);
0299 struct sdw_intel_link_dev *ldev;
0300 u32 caps;
0301 u32 link_mask;
0302 int i;
0303
0304 if (!adev)
0305 return -EINVAL;
0306
0307
0308 caps = ioread32(ctx->mmio_base + ctx->shim_base + SDW_SHIM_LCAP);
0309 caps &= GENMASK(2, 0);
0310
0311
0312 if (caps < ctx->count) {
0313 dev_err(&adev->dev,
0314 "BIOS master count is larger than hardware capabilities\n");
0315 return -EINVAL;
0316 }
0317
0318 if (!ctx->ldev)
0319 return -EINVAL;
0320
0321 link_mask = ctx->link_mask;
0322
0323
0324 for (i = 0; i < ctx->count; i++) {
0325 if (!(link_mask & BIT(i)))
0326 continue;
0327
0328 ldev = ctx->ldev[i];
0329
0330 intel_link_startup(&ldev->auxdev);
0331
0332 if (!ldev->link_res.clock_stop_quirks) {
0333
0334
0335
0336
0337
0338
0339 pm_runtime_get_noresume(ldev->link_res.dev);
0340 }
0341 }
0342
0343 return 0;
0344 }
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 struct sdw_intel_ctx
0357 *sdw_intel_probe(struct sdw_intel_res *res)
0358 {
0359 return sdw_intel_probe_controller(res);
0360 }
0361 EXPORT_SYMBOL_NS(sdw_intel_probe, SOUNDWIRE_INTEL_INIT);
0362
0363
0364
0365
0366
0367
0368
0369
0370 int sdw_intel_startup(struct sdw_intel_ctx *ctx)
0371 {
0372 return sdw_intel_startup_controller(ctx);
0373 }
0374 EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT);
0375
0376
0377
0378
0379
0380
0381 void sdw_intel_exit(struct sdw_intel_ctx *ctx)
0382 {
0383 sdw_intel_cleanup(ctx);
0384 kfree(ctx->ids);
0385 kfree(ctx->ldev);
0386 kfree(ctx);
0387 }
0388 EXPORT_SYMBOL_NS(sdw_intel_exit, SOUNDWIRE_INTEL_INIT);
0389
0390 void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx)
0391 {
0392 struct sdw_intel_link_dev *ldev;
0393 u32 link_mask;
0394 int i;
0395
0396 if (!ctx->ldev)
0397 return;
0398
0399 link_mask = ctx->link_mask;
0400
0401
0402 for (i = 0; i < ctx->count; i++) {
0403 if (!(link_mask & BIT(i)))
0404 continue;
0405
0406 ldev = ctx->ldev[i];
0407
0408 intel_link_process_wakeen_event(&ldev->auxdev);
0409 }
0410 }
0411 EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, SOUNDWIRE_INTEL_INIT);
0412
0413 MODULE_LICENSE("Dual BSD/GPL");
0414 MODULE_DESCRIPTION("Intel Soundwire Init Library");