| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * i2sbus driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net> |
|---|
| 5 | | - * |
|---|
| 6 | | - * GPL v2, can be found in COPYING. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 47 | 46 | /* We use the PCI APIs for now until the generic one gets fixed |
|---|
| 48 | 47 | * enough or until we get some macio-specific versions |
|---|
| 49 | 48 | */ |
|---|
| 50 | | - r->space = dma_zalloc_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, |
|---|
| 51 | | - r->size, &r->bus_addr, GFP_KERNEL); |
|---|
| 49 | + r->space = dma_alloc_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, |
|---|
| 50 | + r->size, &r->bus_addr, GFP_KERNEL); |
|---|
| 52 | 51 | if (!r->space) |
|---|
| 53 | 52 | return -ENOMEM; |
|---|
| 54 | 53 | |
|---|
| .. | .. |
|---|
| 148 | 147 | return rc; |
|---|
| 149 | 148 | } |
|---|
| 150 | 149 | |
|---|
| 150 | +/* Returns 1 if added, 0 for otherwise; don't return a negative value! */ |
|---|
| 151 | 151 | /* FIXME: look at device node refcounting */ |
|---|
| 152 | 152 | static int i2sbus_add_dev(struct macio_dev *macio, |
|---|
| 153 | 153 | struct i2sbus_control *control, |
|---|
| 154 | 154 | struct device_node *np) |
|---|
| 155 | 155 | { |
|---|
| 156 | 156 | struct i2sbus_dev *dev; |
|---|
| 157 | | - struct device_node *child = NULL, *sound = NULL; |
|---|
| 157 | + struct device_node *child, *sound = NULL; |
|---|
| 158 | 158 | struct resource *r; |
|---|
| 159 | 159 | int i, layout = 0, rlen, ok = force; |
|---|
| 160 | | - static const char *rnames[] = { "i2sbus: %s (control)", |
|---|
| 161 | | - "i2sbus: %s (tx)", |
|---|
| 162 | | - "i2sbus: %s (rx)" }; |
|---|
| 163 | | - static irq_handler_t ints[] = { |
|---|
| 160 | + char node_name[6]; |
|---|
| 161 | + static const char *rnames[] = { "i2sbus: %pOFn (control)", |
|---|
| 162 | + "i2sbus: %pOFn (tx)", |
|---|
| 163 | + "i2sbus: %pOFn (rx)" }; |
|---|
| 164 | + static const irq_handler_t ints[] = { |
|---|
| 164 | 165 | i2sbus_bus_intr, |
|---|
| 165 | 166 | i2sbus_tx_intr, |
|---|
| 166 | 167 | i2sbus_rx_intr |
|---|
| 167 | 168 | }; |
|---|
| 168 | 169 | |
|---|
| 169 | | - if (strlen(np->name) != 5) |
|---|
| 170 | + if (snprintf(node_name, sizeof(node_name), "%pOFn", np) != 5) |
|---|
| 170 | 171 | return 0; |
|---|
| 171 | | - if (strncmp(np->name, "i2s-", 4)) |
|---|
| 172 | + if (strncmp(node_name, "i2s-", 4)) |
|---|
| 172 | 173 | return 0; |
|---|
| 173 | 174 | |
|---|
| 174 | 175 | dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 176 | 177 | return 0; |
|---|
| 177 | 178 | |
|---|
| 178 | 179 | i = 0; |
|---|
| 179 | | - while ((child = of_get_next_child(np, child))) { |
|---|
| 180 | | - if (strcmp(child->name, "sound") == 0) { |
|---|
| 180 | + for_each_child_of_node(np, child) { |
|---|
| 181 | + if (of_node_name_eq(child, "sound")) { |
|---|
| 181 | 182 | i++; |
|---|
| 182 | 183 | sound = child; |
|---|
| 183 | 184 | } |
|---|
| .. | .. |
|---|
| 213 | 214 | * either as the second one in that case is just a modem. */ |
|---|
| 214 | 215 | if (!ok) { |
|---|
| 215 | 216 | kfree(dev); |
|---|
| 216 | | - return -ENODEV; |
|---|
| 217 | + return 0; |
|---|
| 217 | 218 | } |
|---|
| 218 | 219 | |
|---|
| 219 | 220 | mutex_init(&dev->lock); |
|---|
| .. | .. |
|---|
| 228 | 229 | dev->sound.pcmid = -1; |
|---|
| 229 | 230 | dev->macio = macio; |
|---|
| 230 | 231 | dev->control = control; |
|---|
| 231 | | - dev->bus_number = np->name[4] - 'a'; |
|---|
| 232 | + dev->bus_number = node_name[4] - 'a'; |
|---|
| 232 | 233 | INIT_LIST_HEAD(&dev->sound.codec_list); |
|---|
| 233 | 234 | |
|---|
| 234 | 235 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { |
|---|
| 235 | 236 | dev->interrupts[i] = -1; |
|---|
| 236 | 237 | snprintf(dev->rnames[i], sizeof(dev->rnames[i]), |
|---|
| 237 | | - rnames[i], np->name); |
|---|
| 238 | + rnames[i], np); |
|---|
| 238 | 239 | } |
|---|
| 239 | 240 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { |
|---|
| 240 | 241 | int irq = irq_of_parse_and_map(np, i); |
|---|
| .. | .. |
|---|
| 302 | 303 | |
|---|
| 303 | 304 | if (soundbus_add_one(&dev->sound)) { |
|---|
| 304 | 305 | printk(KERN_DEBUG "i2sbus: device registration error!\n"); |
|---|
| 306 | + if (dev->sound.ofdev.dev.kobj.state_initialized) { |
|---|
| 307 | + soundbus_dev_put(&dev->sound); |
|---|
| 308 | + return 0; |
|---|
| 309 | + } |
|---|
| 305 | 310 | goto err; |
|---|
| 306 | 311 | } |
|---|
| 307 | 312 | |
|---|
| .. | .. |
|---|
| 379 | 384 | int err, ret = 0; |
|---|
| 380 | 385 | |
|---|
| 381 | 386 | list_for_each_entry(i2sdev, &control->list, item) { |
|---|
| 382 | | - /* Notify Alsa */ |
|---|
| 383 | | - /* Suspend PCM streams */ |
|---|
| 384 | | - snd_pcm_suspend_all(i2sdev->sound.pcm); |
|---|
| 385 | | - |
|---|
| 386 | 387 | /* Notify codecs */ |
|---|
| 387 | 388 | list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { |
|---|
| 388 | 389 | err = 0; |
|---|