.. | .. |
---|
52 | 52 | "#mbox-cells", idx, NULL); |
---|
53 | 53 | } |
---|
54 | 54 | |
---|
| 55 | +static int mailbox_chan_validate(struct device *cdev) |
---|
| 56 | +{ |
---|
| 57 | + int num_mb, num_sh, ret = 0; |
---|
| 58 | + struct device_node *np = cdev->of_node; |
---|
| 59 | + |
---|
| 60 | + num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); |
---|
| 61 | + num_sh = of_count_phandle_with_args(np, "shmem", NULL); |
---|
| 62 | + /* Bail out if mboxes and shmem descriptors are inconsistent */ |
---|
| 63 | + if (num_mb <= 0 || num_sh > 2 || num_mb != num_sh) { |
---|
| 64 | + dev_warn(cdev, "Invalid channel descriptor for '%s'\n", |
---|
| 65 | + of_node_full_name(np)); |
---|
| 66 | + return -EINVAL; |
---|
| 67 | + } |
---|
| 68 | + |
---|
| 69 | + if (num_sh > 1) { |
---|
| 70 | + struct device_node *np_tx, *np_rx; |
---|
| 71 | + |
---|
| 72 | + np_tx = of_parse_phandle(np, "shmem", 0); |
---|
| 73 | + np_rx = of_parse_phandle(np, "shmem", 1); |
---|
| 74 | + /* SCMI Tx and Rx shared mem areas have to be distinct */ |
---|
| 75 | + if (!np_tx || !np_rx || np_tx == np_rx) { |
---|
| 76 | + dev_warn(cdev, "Invalid shmem descriptor for '%s'\n", |
---|
| 77 | + of_node_full_name(np)); |
---|
| 78 | + ret = -EINVAL; |
---|
| 79 | + } |
---|
| 80 | + |
---|
| 81 | + of_node_put(np_tx); |
---|
| 82 | + of_node_put(np_rx); |
---|
| 83 | + } |
---|
| 84 | + |
---|
| 85 | + return ret; |
---|
| 86 | +} |
---|
| 87 | + |
---|
55 | 88 | static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, |
---|
56 | 89 | bool tx) |
---|
57 | 90 | { |
---|
.. | .. |
---|
64 | 97 | resource_size_t size; |
---|
65 | 98 | struct resource res; |
---|
66 | 99 | |
---|
| 100 | + ret = mailbox_chan_validate(cdev); |
---|
| 101 | + if (ret) |
---|
| 102 | + return ret; |
---|
| 103 | + |
---|
67 | 104 | smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL); |
---|
68 | 105 | if (!smbox) |
---|
69 | 106 | return -ENOMEM; |
---|