GNU Linux-libre 4.19.263-gnu1
[releases.git] / drivers / bus / fsl-mc / fsl-mc-bus.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Freescale Management Complex (MC) bus driver
4  *
5  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
6  * Author: German Rivera <German.Rivera@freescale.com>
7  *
8  */
9
10 #define pr_fmt(fmt) "fsl-mc: " fmt
11
12 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/of_address.h>
15 #include <linux/ioport.h>
16 #include <linux/slab.h>
17 #include <linux/limits.h>
18 #include <linux/bitops.h>
19 #include <linux/msi.h>
20 #include <linux/dma-mapping.h>
21
22 #include "fsl-mc-private.h"
23
24 /**
25  * Default DMA mask for devices on a fsl-mc bus
26  */
27 #define FSL_MC_DEFAULT_DMA_MASK (~0ULL)
28
29 /**
30  * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
31  * @root_mc_bus_dev: fsl-mc device representing the root DPRC
32  * @num_translation_ranges: number of entries in addr_translation_ranges
33  * @translation_ranges: array of bus to system address translation ranges
34  */
35 struct fsl_mc {
36         struct fsl_mc_device *root_mc_bus_dev;
37         u8 num_translation_ranges;
38         struct fsl_mc_addr_translation_range *translation_ranges;
39 };
40
41 /**
42  * struct fsl_mc_addr_translation_range - bus to system address translation
43  * range
44  * @mc_region_type: Type of MC region for the range being translated
45  * @start_mc_offset: Start MC offset of the range being translated
46  * @end_mc_offset: MC offset of the first byte after the range (last MC
47  * offset of the range is end_mc_offset - 1)
48  * @start_phys_addr: system physical address corresponding to start_mc_addr
49  */
50 struct fsl_mc_addr_translation_range {
51         enum dprc_region_type mc_region_type;
52         u64 start_mc_offset;
53         u64 end_mc_offset;
54         phys_addr_t start_phys_addr;
55 };
56
57 /**
58  * struct mc_version
59  * @major: Major version number: incremented on API compatibility changes
60  * @minor: Minor version number: incremented on API additions (that are
61  *              backward compatible); reset when major version is incremented
62  * @revision: Internal revision number: incremented on implementation changes
63  *              and/or bug fixes that have no impact on API
64  */
65 struct mc_version {
66         u32 major;
67         u32 minor;
68         u32 revision;
69 };
70
71 /**
72  * fsl_mc_bus_match - device to driver matching callback
73  * @dev: the fsl-mc device to match against
74  * @drv: the device driver to search for matching fsl-mc object type
75  * structures
76  *
77  * Returns 1 on success, 0 otherwise.
78  */
79 static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
80 {
81         const struct fsl_mc_device_id *id;
82         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
83         struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
84         bool found = false;
85
86         if (!mc_drv->match_id_table)
87                 goto out;
88
89         /*
90          * If the object is not 'plugged' don't match.
91          * Only exception is the root DPRC, which is a special case.
92          */
93         if ((mc_dev->obj_desc.state & FSL_MC_OBJ_STATE_PLUGGED) == 0 &&
94             !fsl_mc_is_root_dprc(&mc_dev->dev))
95                 goto out;
96
97         /*
98          * Traverse the match_id table of the given driver, trying to find
99          * a matching for the given device.
100          */
101         for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) {
102                 if (id->vendor == mc_dev->obj_desc.vendor &&
103                     strcmp(id->obj_type, mc_dev->obj_desc.type) == 0) {
104                         found = true;
105
106                         break;
107                 }
108         }
109
110 out:
111         dev_dbg(dev, "%smatched\n", found ? "" : "not ");
112         return found;
113 }
114
115 /**
116  * fsl_mc_bus_uevent - callback invoked when a device is added
117  */
118 static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
119 {
120         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
121
122         if (add_uevent_var(env, "MODALIAS=fsl-mc:v%08Xd%s",
123                            mc_dev->obj_desc.vendor,
124                            mc_dev->obj_desc.type))
125                 return -ENOMEM;
126
127         return 0;
128 }
129
130 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
131                              char *buf)
132 {
133         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
134
135         return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor,
136                        mc_dev->obj_desc.type);
137 }
138 static DEVICE_ATTR_RO(modalias);
139
140 static struct attribute *fsl_mc_dev_attrs[] = {
141         &dev_attr_modalias.attr,
142         NULL,
143 };
144
145 ATTRIBUTE_GROUPS(fsl_mc_dev);
146
147 struct bus_type fsl_mc_bus_type = {
148         .name = "fsl-mc",
149         .match = fsl_mc_bus_match,
150         .uevent = fsl_mc_bus_uevent,
151         .dev_groups = fsl_mc_dev_groups,
152 };
153 EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
154
155 struct device_type fsl_mc_bus_dprc_type = {
156         .name = "fsl_mc_bus_dprc"
157 };
158
159 struct device_type fsl_mc_bus_dpni_type = {
160         .name = "fsl_mc_bus_dpni"
161 };
162
163 struct device_type fsl_mc_bus_dpio_type = {
164         .name = "fsl_mc_bus_dpio"
165 };
166
167 struct device_type fsl_mc_bus_dpsw_type = {
168         .name = "fsl_mc_bus_dpsw"
169 };
170
171 struct device_type fsl_mc_bus_dpbp_type = {
172         .name = "fsl_mc_bus_dpbp"
173 };
174
175 struct device_type fsl_mc_bus_dpcon_type = {
176         .name = "fsl_mc_bus_dpcon"
177 };
178
179 struct device_type fsl_mc_bus_dpmcp_type = {
180         .name = "fsl_mc_bus_dpmcp"
181 };
182
183 struct device_type fsl_mc_bus_dpmac_type = {
184         .name = "fsl_mc_bus_dpmac"
185 };
186
187 struct device_type fsl_mc_bus_dprtc_type = {
188         .name = "fsl_mc_bus_dprtc"
189 };
190
191 static struct device_type *fsl_mc_get_device_type(const char *type)
192 {
193         static const struct {
194                 struct device_type *dev_type;
195                 const char *type;
196         } dev_types[] = {
197                 { &fsl_mc_bus_dprc_type, "dprc" },
198                 { &fsl_mc_bus_dpni_type, "dpni" },
199                 { &fsl_mc_bus_dpio_type, "dpio" },
200                 { &fsl_mc_bus_dpsw_type, "dpsw" },
201                 { &fsl_mc_bus_dpbp_type, "dpbp" },
202                 { &fsl_mc_bus_dpcon_type, "dpcon" },
203                 { &fsl_mc_bus_dpmcp_type, "dpmcp" },
204                 { &fsl_mc_bus_dpmac_type, "dpmac" },
205                 { &fsl_mc_bus_dprtc_type, "dprtc" },
206                 { NULL, NULL }
207         };
208         int i;
209
210         for (i = 0; dev_types[i].dev_type; i++)
211                 if (!strcmp(dev_types[i].type, type))
212                         return dev_types[i].dev_type;
213
214         return NULL;
215 }
216
217 static int fsl_mc_driver_probe(struct device *dev)
218 {
219         struct fsl_mc_driver *mc_drv;
220         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
221         int error;
222
223         mc_drv = to_fsl_mc_driver(dev->driver);
224
225         error = mc_drv->probe(mc_dev);
226         if (error < 0) {
227                 if (error != -EPROBE_DEFER)
228                         dev_err(dev, "%s failed: %d\n", __func__, error);
229                 return error;
230         }
231
232         return 0;
233 }
234
235 static int fsl_mc_driver_remove(struct device *dev)
236 {
237         struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
238         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
239         int error;
240
241         error = mc_drv->remove(mc_dev);
242         if (error < 0) {
243                 dev_err(dev, "%s failed: %d\n", __func__, error);
244                 return error;
245         }
246
247         return 0;
248 }
249
250 static void fsl_mc_driver_shutdown(struct device *dev)
251 {
252         struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
253         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
254
255         mc_drv->shutdown(mc_dev);
256 }
257
258 /**
259  * __fsl_mc_driver_register - registers a child device driver with the
260  * MC bus
261  *
262  * This function is implicitly invoked from the registration function of
263  * fsl_mc device drivers, which is generated by the
264  * module_fsl_mc_driver() macro.
265  */
266 int __fsl_mc_driver_register(struct fsl_mc_driver *mc_driver,
267                              struct module *owner)
268 {
269         int error;
270
271         mc_driver->driver.owner = owner;
272         mc_driver->driver.bus = &fsl_mc_bus_type;
273
274         if (mc_driver->probe)
275                 mc_driver->driver.probe = fsl_mc_driver_probe;
276
277         if (mc_driver->remove)
278                 mc_driver->driver.remove = fsl_mc_driver_remove;
279
280         if (mc_driver->shutdown)
281                 mc_driver->driver.shutdown = fsl_mc_driver_shutdown;
282
283         error = driver_register(&mc_driver->driver);
284         if (error < 0) {
285                 pr_err("driver_register() failed for %s: %d\n",
286                        mc_driver->driver.name, error);
287                 return error;
288         }
289
290         return 0;
291 }
292 EXPORT_SYMBOL_GPL(__fsl_mc_driver_register);
293
294 /**
295  * fsl_mc_driver_unregister - unregisters a device driver from the
296  * MC bus
297  */
298 void fsl_mc_driver_unregister(struct fsl_mc_driver *mc_driver)
299 {
300         driver_unregister(&mc_driver->driver);
301 }
302 EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister);
303
304 /**
305  * mc_get_version() - Retrieves the Management Complex firmware
306  *                      version information
307  * @mc_io:              Pointer to opaque I/O object
308  * @cmd_flags:          Command flags; one or more of 'MC_CMD_FLAG_'
309  * @mc_ver_info:        Returned version information structure
310  *
311  * Return:      '0' on Success; Error code otherwise.
312  */
313 static int mc_get_version(struct fsl_mc_io *mc_io,
314                           u32 cmd_flags,
315                           struct mc_version *mc_ver_info)
316 {
317         struct fsl_mc_command cmd = { 0 };
318         struct dpmng_rsp_get_version *rsp_params;
319         int err;
320
321         /* prepare command */
322         cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
323                                           cmd_flags,
324                                           0);
325
326         /* send command to mc*/
327         err = mc_send_command(mc_io, &cmd);
328         if (err)
329                 return err;
330
331         /* retrieve response parameters */
332         rsp_params = (struct dpmng_rsp_get_version *)cmd.params;
333         mc_ver_info->revision = le32_to_cpu(rsp_params->revision);
334         mc_ver_info->major = le32_to_cpu(rsp_params->version_major);
335         mc_ver_info->minor = le32_to_cpu(rsp_params->version_minor);
336
337         return 0;
338 }
339
340 /**
341  * fsl_mc_get_root_dprc - function to traverse to the root dprc
342  */
343 static void fsl_mc_get_root_dprc(struct device *dev,
344                                  struct device **root_dprc_dev)
345 {
346         if (!dev) {
347                 *root_dprc_dev = NULL;
348         } else if (!dev_is_fsl_mc(dev)) {
349                 *root_dprc_dev = NULL;
350         } else {
351                 *root_dprc_dev = dev;
352                 while (dev_is_fsl_mc((*root_dprc_dev)->parent))
353                         *root_dprc_dev = (*root_dprc_dev)->parent;
354         }
355 }
356
357 static int get_dprc_attr(struct fsl_mc_io *mc_io,
358                          int container_id, struct dprc_attributes *attr)
359 {
360         u16 dprc_handle;
361         int error;
362
363         error = dprc_open(mc_io, 0, container_id, &dprc_handle);
364         if (error < 0) {
365                 dev_err(mc_io->dev, "dprc_open() failed: %d\n", error);
366                 return error;
367         }
368
369         memset(attr, 0, sizeof(struct dprc_attributes));
370         error = dprc_get_attributes(mc_io, 0, dprc_handle, attr);
371         if (error < 0) {
372                 dev_err(mc_io->dev, "dprc_get_attributes() failed: %d\n",
373                         error);
374                 goto common_cleanup;
375         }
376
377         error = 0;
378
379 common_cleanup:
380         (void)dprc_close(mc_io, 0, dprc_handle);
381         return error;
382 }
383
384 static int get_dprc_icid(struct fsl_mc_io *mc_io,
385                          int container_id, u16 *icid)
386 {
387         struct dprc_attributes attr;
388         int error;
389
390         error = get_dprc_attr(mc_io, container_id, &attr);
391         if (error == 0)
392                 *icid = attr.icid;
393
394         return error;
395 }
396
397 static int translate_mc_addr(struct fsl_mc_device *mc_dev,
398                              enum dprc_region_type mc_region_type,
399                              u64 mc_offset, phys_addr_t *phys_addr)
400 {
401         int i;
402         struct device *root_dprc_dev;
403         struct fsl_mc *mc;
404
405         fsl_mc_get_root_dprc(&mc_dev->dev, &root_dprc_dev);
406         mc = dev_get_drvdata(root_dprc_dev->parent);
407
408         if (mc->num_translation_ranges == 0) {
409                 /*
410                  * Do identity mapping:
411                  */
412                 *phys_addr = mc_offset;
413                 return 0;
414         }
415
416         for (i = 0; i < mc->num_translation_ranges; i++) {
417                 struct fsl_mc_addr_translation_range *range =
418                         &mc->translation_ranges[i];
419
420                 if (mc_region_type == range->mc_region_type &&
421                     mc_offset >= range->start_mc_offset &&
422                     mc_offset < range->end_mc_offset) {
423                         *phys_addr = range->start_phys_addr +
424                                      (mc_offset - range->start_mc_offset);
425                         return 0;
426                 }
427         }
428
429         return -EFAULT;
430 }
431
432 static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
433                                           struct fsl_mc_device *mc_bus_dev)
434 {
435         int i;
436         int error;
437         struct resource *regions;
438         struct fsl_mc_obj_desc *obj_desc = &mc_dev->obj_desc;
439         struct device *parent_dev = mc_dev->dev.parent;
440         enum dprc_region_type mc_region_type;
441
442         if (is_fsl_mc_bus_dprc(mc_dev) ||
443             is_fsl_mc_bus_dpmcp(mc_dev)) {
444                 mc_region_type = DPRC_REGION_TYPE_MC_PORTAL;
445         } else if (is_fsl_mc_bus_dpio(mc_dev)) {
446                 mc_region_type = DPRC_REGION_TYPE_QBMAN_PORTAL;
447         } else {
448                 /*
449                  * This function should not have been called for this MC object
450                  * type, as this object type is not supposed to have MMIO
451                  * regions
452                  */
453                 return -EINVAL;
454         }
455
456         regions = kmalloc_array(obj_desc->region_count,
457                                 sizeof(regions[0]), GFP_KERNEL);
458         if (!regions)
459                 return -ENOMEM;
460
461         for (i = 0; i < obj_desc->region_count; i++) {
462                 struct dprc_region_desc region_desc;
463
464                 error = dprc_get_obj_region(mc_bus_dev->mc_io,
465                                             0,
466                                             mc_bus_dev->mc_handle,
467                                             obj_desc->type,
468                                             obj_desc->id, i, &region_desc);
469                 if (error < 0) {
470                         dev_err(parent_dev,
471                                 "dprc_get_obj_region() failed: %d\n", error);
472                         goto error_cleanup_regions;
473                 }
474
475                 error = translate_mc_addr(mc_dev, mc_region_type,
476                                           region_desc.base_offset,
477                                           &regions[i].start);
478                 if (error < 0) {
479                         dev_err(parent_dev,
480                                 "Invalid MC offset: %#x (for %s.%d\'s region %d)\n",
481                                 region_desc.base_offset,
482                                 obj_desc->type, obj_desc->id, i);
483                         goto error_cleanup_regions;
484                 }
485
486                 regions[i].end = regions[i].start + region_desc.size - 1;
487                 regions[i].name = "fsl-mc object MMIO region";
488                 regions[i].flags = IORESOURCE_IO;
489                 if (region_desc.flags & DPRC_REGION_CACHEABLE)
490                         regions[i].flags |= IORESOURCE_CACHEABLE;
491         }
492
493         mc_dev->regions = regions;
494         return 0;
495
496 error_cleanup_regions:
497         kfree(regions);
498         return error;
499 }
500
501 /**
502  * fsl_mc_is_root_dprc - function to check if a given device is a root dprc
503  */
504 bool fsl_mc_is_root_dprc(struct device *dev)
505 {
506         struct device *root_dprc_dev;
507
508         fsl_mc_get_root_dprc(dev, &root_dprc_dev);
509         if (!root_dprc_dev)
510                 return false;
511         return dev == root_dprc_dev;
512 }
513
514 static void fsl_mc_device_release(struct device *dev)
515 {
516         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
517
518         kfree(mc_dev->regions);
519
520         if (is_fsl_mc_bus_dprc(mc_dev))
521                 kfree(to_fsl_mc_bus(mc_dev));
522         else
523                 kfree(mc_dev);
524 }
525
526 /**
527  * Add a newly discovered fsl-mc device to be visible in Linux
528  */
529 int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
530                       struct fsl_mc_io *mc_io,
531                       struct device *parent_dev,
532                       struct fsl_mc_device **new_mc_dev)
533 {
534         int error;
535         struct fsl_mc_device *mc_dev = NULL;
536         struct fsl_mc_bus *mc_bus = NULL;
537         struct fsl_mc_device *parent_mc_dev;
538
539         if (dev_is_fsl_mc(parent_dev))
540                 parent_mc_dev = to_fsl_mc_device(parent_dev);
541         else
542                 parent_mc_dev = NULL;
543
544         if (strcmp(obj_desc->type, "dprc") == 0) {
545                 /*
546                  * Allocate an MC bus device object:
547                  */
548                 mc_bus = kzalloc(sizeof(*mc_bus), GFP_KERNEL);
549                 if (!mc_bus)
550                         return -ENOMEM;
551
552                 mc_dev = &mc_bus->mc_dev;
553         } else {
554                 /*
555                  * Allocate a regular fsl_mc_device object:
556                  */
557                 mc_dev = kzalloc(sizeof(*mc_dev), GFP_KERNEL);
558                 if (!mc_dev)
559                         return -ENOMEM;
560         }
561
562         mc_dev->obj_desc = *obj_desc;
563         mc_dev->mc_io = mc_io;
564         device_initialize(&mc_dev->dev);
565         mc_dev->dev.parent = parent_dev;
566         mc_dev->dev.bus = &fsl_mc_bus_type;
567         mc_dev->dev.release = fsl_mc_device_release;
568         mc_dev->dev.type = fsl_mc_get_device_type(obj_desc->type);
569         if (!mc_dev->dev.type) {
570                 error = -ENODEV;
571                 dev_err(parent_dev, "unknown device type %s\n", obj_desc->type);
572                 goto error_cleanup_dev;
573         }
574         dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id);
575
576         if (strcmp(obj_desc->type, "dprc") == 0) {
577                 struct fsl_mc_io *mc_io2;
578
579                 mc_dev->flags |= FSL_MC_IS_DPRC;
580
581                 /*
582                  * To get the DPRC's ICID, we need to open the DPRC
583                  * in get_dprc_icid(). For child DPRCs, we do so using the
584                  * parent DPRC's MC portal instead of the child DPRC's MC
585                  * portal, in case the child DPRC is already opened with
586                  * its own portal (e.g., the DPRC used by AIOP).
587                  *
588                  * NOTE: There cannot be more than one active open for a
589                  * given MC object, using the same MC portal.
590                  */
591                 if (parent_mc_dev) {
592                         /*
593                          * device being added is a child DPRC device
594                          */
595                         mc_io2 = parent_mc_dev->mc_io;
596                 } else {
597                         /*
598                          * device being added is the root DPRC device
599                          */
600                         if (!mc_io) {
601                                 error = -EINVAL;
602                                 goto error_cleanup_dev;
603                         }
604
605                         mc_io2 = mc_io;
606                 }
607
608                 error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid);
609                 if (error < 0)
610                         goto error_cleanup_dev;
611         } else {
612                 /*
613                  * A non-DPRC object has to be a child of a DPRC, use the
614                  * parent's ICID and interrupt domain.
615                  */
616                 mc_dev->icid = parent_mc_dev->icid;
617                 mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
618                 mc_dev->dev.dma_mask = &mc_dev->dma_mask;
619                 dev_set_msi_domain(&mc_dev->dev,
620                                    dev_get_msi_domain(&parent_mc_dev->dev));
621         }
622
623         /*
624          * Get MMIO regions for the device from the MC:
625          *
626          * NOTE: the root DPRC is a special case as its MMIO region is
627          * obtained from the device tree
628          */
629         if (parent_mc_dev && obj_desc->region_count != 0) {
630                 error = fsl_mc_device_get_mmio_regions(mc_dev,
631                                                        parent_mc_dev);
632                 if (error < 0)
633                         goto error_cleanup_dev;
634         }
635
636         /* Objects are coherent, unless 'no shareability' flag set. */
637         if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY))
638                 arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true);
639
640         /*
641          * The device-specific probe callback will get invoked by device_add()
642          */
643         error = device_add(&mc_dev->dev);
644         if (error < 0) {
645                 dev_err(parent_dev,
646                         "device_add() failed for device %s: %d\n",
647                         dev_name(&mc_dev->dev), error);
648                 goto error_cleanup_dev;
649         }
650
651         dev_dbg(parent_dev, "added %s\n", dev_name(&mc_dev->dev));
652
653         *new_mc_dev = mc_dev;
654         return 0;
655
656 error_cleanup_dev:
657         kfree(mc_dev->regions);
658         kfree(mc_bus);
659         kfree(mc_dev);
660
661         return error;
662 }
663 EXPORT_SYMBOL_GPL(fsl_mc_device_add);
664
665 /**
666  * fsl_mc_device_remove - Remove an fsl-mc device from being visible to
667  * Linux
668  *
669  * @mc_dev: Pointer to an fsl-mc device
670  */
671 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
672 {
673         /*
674          * The device-specific remove callback will get invoked by device_del()
675          */
676         device_del(&mc_dev->dev);
677         put_device(&mc_dev->dev);
678 }
679 EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
680
681 static int parse_mc_ranges(struct device *dev,
682                            int *paddr_cells,
683                            int *mc_addr_cells,
684                            int *mc_size_cells,
685                            const __be32 **ranges_start)
686 {
687         const __be32 *prop;
688         int range_tuple_cell_count;
689         int ranges_len;
690         int tuple_len;
691         struct device_node *mc_node = dev->of_node;
692
693         *ranges_start = of_get_property(mc_node, "ranges", &ranges_len);
694         if (!(*ranges_start) || !ranges_len) {
695                 dev_warn(dev,
696                          "missing or empty ranges property for device tree node '%s'\n",
697                          mc_node->name);
698                 return 0;
699         }
700
701         *paddr_cells = of_n_addr_cells(mc_node);
702
703         prop = of_get_property(mc_node, "#address-cells", NULL);
704         if (prop)
705                 *mc_addr_cells = be32_to_cpup(prop);
706         else
707                 *mc_addr_cells = *paddr_cells;
708
709         prop = of_get_property(mc_node, "#size-cells", NULL);
710         if (prop)
711                 *mc_size_cells = be32_to_cpup(prop);
712         else
713                 *mc_size_cells = of_n_size_cells(mc_node);
714
715         range_tuple_cell_count = *paddr_cells + *mc_addr_cells +
716                                  *mc_size_cells;
717
718         tuple_len = range_tuple_cell_count * sizeof(__be32);
719         if (ranges_len % tuple_len != 0) {
720                 dev_err(dev, "malformed ranges property '%s'\n", mc_node->name);
721                 return -EINVAL;
722         }
723
724         return ranges_len / tuple_len;
725 }
726
727 static int get_mc_addr_translation_ranges(struct device *dev,
728                                           struct fsl_mc_addr_translation_range
729                                                 **ranges,
730                                           u8 *num_ranges)
731 {
732         int ret;
733         int paddr_cells;
734         int mc_addr_cells;
735         int mc_size_cells;
736         int i;
737         const __be32 *ranges_start;
738         const __be32 *cell;
739
740         ret = parse_mc_ranges(dev,
741                               &paddr_cells,
742                               &mc_addr_cells,
743                               &mc_size_cells,
744                               &ranges_start);
745         if (ret < 0)
746                 return ret;
747
748         *num_ranges = ret;
749         if (!ret) {
750                 /*
751                  * Missing or empty ranges property ("ranges;") for the
752                  * 'fsl,qoriq-mc' node. In this case, identity mapping
753                  * will be used.
754                  */
755                 *ranges = NULL;
756                 return 0;
757         }
758
759         *ranges = devm_kcalloc(dev, *num_ranges,
760                                sizeof(struct fsl_mc_addr_translation_range),
761                                GFP_KERNEL);
762         if (!(*ranges))
763                 return -ENOMEM;
764
765         cell = ranges_start;
766         for (i = 0; i < *num_ranges; ++i) {
767                 struct fsl_mc_addr_translation_range *range = &(*ranges)[i];
768
769                 range->mc_region_type = of_read_number(cell, 1);
770                 range->start_mc_offset = of_read_number(cell + 1,
771                                                         mc_addr_cells - 1);
772                 cell += mc_addr_cells;
773                 range->start_phys_addr = of_read_number(cell, paddr_cells);
774                 cell += paddr_cells;
775                 range->end_mc_offset = range->start_mc_offset +
776                                      of_read_number(cell, mc_size_cells);
777
778                 cell += mc_size_cells;
779         }
780
781         return 0;
782 }
783
784 /**
785  * fsl_mc_bus_probe - callback invoked when the root MC bus is being
786  * added
787  */
788 static int fsl_mc_bus_probe(struct platform_device *pdev)
789 {
790         struct fsl_mc_obj_desc obj_desc;
791         int error;
792         struct fsl_mc *mc;
793         struct fsl_mc_device *mc_bus_dev = NULL;
794         struct fsl_mc_io *mc_io = NULL;
795         int container_id;
796         phys_addr_t mc_portal_phys_addr;
797         u32 mc_portal_size;
798         struct mc_version mc_version;
799         struct resource res;
800
801         mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
802         if (!mc)
803                 return -ENOMEM;
804
805         platform_set_drvdata(pdev, mc);
806
807         /*
808          * Get physical address of MC portal for the root DPRC:
809          */
810         error = of_address_to_resource(pdev->dev.of_node, 0, &res);
811         if (error < 0) {
812                 dev_err(&pdev->dev,
813                         "of_address_to_resource() failed for %pOF\n",
814                         pdev->dev.of_node);
815                 return error;
816         }
817
818         mc_portal_phys_addr = res.start;
819         mc_portal_size = resource_size(&res);
820         error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
821                                  mc_portal_size, NULL,
822                                  FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
823         if (error < 0)
824                 return error;
825
826         error = mc_get_version(mc_io, 0, &mc_version);
827         if (error != 0) {
828                 dev_err(&pdev->dev,
829                         "mc_get_version() failed with error %d\n", error);
830                 goto error_cleanup_mc_io;
831         }
832
833         dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
834                  mc_version.major, mc_version.minor, mc_version.revision);
835
836         error = get_mc_addr_translation_ranges(&pdev->dev,
837                                                &mc->translation_ranges,
838                                                &mc->num_translation_ranges);
839         if (error < 0)
840                 goto error_cleanup_mc_io;
841
842         error = dprc_get_container_id(mc_io, 0, &container_id);
843         if (error < 0) {
844                 dev_err(&pdev->dev,
845                         "dprc_get_container_id() failed: %d\n", error);
846                 goto error_cleanup_mc_io;
847         }
848
849         memset(&obj_desc, 0, sizeof(struct fsl_mc_obj_desc));
850         error = dprc_get_api_version(mc_io, 0,
851                                      &obj_desc.ver_major,
852                                      &obj_desc.ver_minor);
853         if (error < 0)
854                 goto error_cleanup_mc_io;
855
856         obj_desc.vendor = FSL_MC_VENDOR_FREESCALE;
857         strcpy(obj_desc.type, "dprc");
858         obj_desc.id = container_id;
859         obj_desc.irq_count = 1;
860         obj_desc.region_count = 0;
861
862         error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
863         if (error < 0)
864                 goto error_cleanup_mc_io;
865
866         mc->root_mc_bus_dev = mc_bus_dev;
867         return 0;
868
869 error_cleanup_mc_io:
870         fsl_destroy_mc_io(mc_io);
871         return error;
872 }
873
874 /**
875  * fsl_mc_bus_remove - callback invoked when the root MC bus is being
876  * removed
877  */
878 static int fsl_mc_bus_remove(struct platform_device *pdev)
879 {
880         struct fsl_mc *mc = platform_get_drvdata(pdev);
881
882         if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev))
883                 return -EINVAL;
884
885         fsl_mc_device_remove(mc->root_mc_bus_dev);
886
887         fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
888         mc->root_mc_bus_dev->mc_io = NULL;
889
890         return 0;
891 }
892
893 static const struct of_device_id fsl_mc_bus_match_table[] = {
894         {.compatible = "fsl,qoriq-mc",},
895         {},
896 };
897
898 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
899
900 static struct platform_driver fsl_mc_bus_driver = {
901         .driver = {
902                    .name = "fsl_mc_bus",
903                    .pm = NULL,
904                    .of_match_table = fsl_mc_bus_match_table,
905                    },
906         .probe = fsl_mc_bus_probe,
907         .remove = fsl_mc_bus_remove,
908 };
909
910 static int __init fsl_mc_bus_driver_init(void)
911 {
912         int error;
913
914         error = bus_register(&fsl_mc_bus_type);
915         if (error < 0) {
916                 pr_err("bus type registration failed: %d\n", error);
917                 goto error_cleanup_cache;
918         }
919
920         error = platform_driver_register(&fsl_mc_bus_driver);
921         if (error < 0) {
922                 pr_err("platform_driver_register() failed: %d\n", error);
923                 goto error_cleanup_bus;
924         }
925
926         error = dprc_driver_init();
927         if (error < 0)
928                 goto error_cleanup_driver;
929
930         error = fsl_mc_allocator_driver_init();
931         if (error < 0)
932                 goto error_cleanup_dprc_driver;
933
934         return 0;
935
936 error_cleanup_dprc_driver:
937         dprc_driver_exit();
938
939 error_cleanup_driver:
940         platform_driver_unregister(&fsl_mc_bus_driver);
941
942 error_cleanup_bus:
943         bus_unregister(&fsl_mc_bus_type);
944
945 error_cleanup_cache:
946         return error;
947 }
948 postcore_initcall(fsl_mc_bus_driver_init);