.. | .. |
---|
37 | 37 | int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr, |
---|
38 | 38 | size_t *size) |
---|
39 | 39 | { |
---|
40 | | - int ret; |
---|
41 | 40 | struct device_node *mem_node; |
---|
42 | | - u64 size64; |
---|
| 41 | + struct reserved_mem *rmem; |
---|
| 42 | + struct property *prop; |
---|
| 43 | + int len, err; |
---|
| 44 | + __be32 *res_array; |
---|
43 | 45 | |
---|
44 | | - ret = of_reserved_mem_device_init_by_idx(dev, dev->of_node, idx); |
---|
45 | | - if (ret) { |
---|
46 | | - dev_err(dev, |
---|
47 | | - "of_reserved_mem_device_init_by_idx(%d) failed 0x%x\n", |
---|
48 | | - idx, ret); |
---|
49 | | - return -ENODEV; |
---|
50 | | - } |
---|
51 | | - mem_node = of_parse_phandle(dev->of_node, "memory-region", 0); |
---|
52 | | - if (mem_node) { |
---|
53 | | - ret = of_property_read_u64(mem_node, "size", &size64); |
---|
54 | | - if (ret) { |
---|
55 | | - dev_err(dev, "of_address_to_resource fails 0x%x\n", |
---|
56 | | - ret); |
---|
57 | | - return -ENODEV; |
---|
58 | | - } |
---|
59 | | - *size = size64; |
---|
60 | | - } else { |
---|
| 46 | + mem_node = of_parse_phandle(dev->of_node, "memory-region", idx); |
---|
| 47 | + if (!mem_node) { |
---|
61 | 48 | dev_err(dev, "No memory-region found for index %d\n", idx); |
---|
62 | 49 | return -ENODEV; |
---|
63 | 50 | } |
---|
64 | 51 | |
---|
65 | | - if (!dma_zalloc_coherent(dev, *size, addr, 0)) { |
---|
66 | | - dev_err(dev, "DMA Alloc memory failed\n"); |
---|
| 52 | + rmem = of_reserved_mem_lookup(mem_node); |
---|
| 53 | + if (!rmem) { |
---|
| 54 | + dev_err(dev, "of_reserved_mem_lookup() returned NULL\n"); |
---|
67 | 55 | return -ENODEV; |
---|
68 | 56 | } |
---|
| 57 | + *addr = rmem->base; |
---|
| 58 | + *size = rmem->size; |
---|
69 | 59 | |
---|
70 | 60 | /* |
---|
71 | | - * Disassociate the reserved memory area from the device |
---|
72 | | - * because a device can only have one DMA memory area. This |
---|
73 | | - * should be fine since the memory is allocated and initialized |
---|
74 | | - * and only ever accessed by the QBMan device from now on |
---|
| 61 | + * Check if the reg property exists - if not insert the node |
---|
| 62 | + * so upon kexec() the same memory region address will be preserved. |
---|
| 63 | + * This is needed because QBMan HW does not allow the base address/ |
---|
| 64 | + * size to be modified once set. |
---|
75 | 65 | */ |
---|
76 | | - of_reserved_mem_device_release(dev); |
---|
| 66 | + prop = of_find_property(mem_node, "reg", &len); |
---|
| 67 | + if (!prop) { |
---|
| 68 | + prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL); |
---|
| 69 | + if (!prop) |
---|
| 70 | + return -ENOMEM; |
---|
| 71 | + prop->value = res_array = devm_kzalloc(dev, sizeof(__be32) * 4, |
---|
| 72 | + GFP_KERNEL); |
---|
| 73 | + if (!prop->value) |
---|
| 74 | + return -ENOMEM; |
---|
| 75 | + res_array[0] = cpu_to_be32(upper_32_bits(*addr)); |
---|
| 76 | + res_array[1] = cpu_to_be32(lower_32_bits(*addr)); |
---|
| 77 | + res_array[2] = cpu_to_be32(upper_32_bits(*size)); |
---|
| 78 | + res_array[3] = cpu_to_be32(lower_32_bits(*size)); |
---|
| 79 | + prop->length = sizeof(__be32) * 4; |
---|
| 80 | + prop->name = devm_kstrdup(dev, "reg", GFP_KERNEL); |
---|
| 81 | + if (!prop->name) |
---|
| 82 | + return -ENOMEM; |
---|
| 83 | + err = of_add_property(mem_node, prop); |
---|
| 84 | + if (err) |
---|
| 85 | + return err; |
---|
| 86 | + } |
---|
| 87 | + |
---|
77 | 88 | return 0; |
---|
78 | 89 | } |
---|