• Home
  • Raw
  • Download

Lines Matching +full:mips +full:- +full:cdmm

2  * Bus driver for MIPS Common Device Memory Map (CDMM).
4 * Copyright (C) 2014-2015 Imagination Technologies Ltd.
19 #include <asm/cdmm.h>
51 for (; table->type; ++table) { in mips_cdmm_lookup()
52 ret = (dev->type == table->type); in mips_cdmm_lookup()
65 return mips_cdmm_lookup(cdrv->id_table, cdev) != NULL; in mips_cdmm_match()
73 retval = add_uevent_var(env, "CDMM_CPU=%u", cdev->cpu); in mips_cdmm_uevent()
77 retval = add_uevent_var(env, "CDMM_TYPE=0x%02x", cdev->type); in mips_cdmm_uevent()
81 retval = add_uevent_var(env, "CDMM_REV=%u", cdev->rev); in mips_cdmm_uevent()
85 retval = add_uevent_var(env, "MODALIAS=mipscdmm:t%02X", cdev->type); in mips_cdmm_uevent()
100 CDMM_ATTR(cpu, "%u\n", dev->cpu);
101 CDMM_ATTR(type, "0x%02x\n", dev->type);
102 CDMM_ATTR(revision, "%u\n", dev->rev);
103 CDMM_ATTR(modalias, "mipscdmm:t%02X\n", dev->type);
105 (unsigned long long)dev->res.start,
106 (unsigned long long)dev->res.end,
107 dev->res.flags);
120 .name = "cdmm",
130 * All the CDMM driver callbacks need to be executed on the appropriate CPU from
138 * struct mips_cdmm_work_dev - Data for per-device call work.
139 * @fn: CDMM driver callback function to call for the device.
140 * @dev: CDMM device to pass to @fn.
148 * mips_cdmm_void_work() - Call a void returning CDMM driver callback.
151 * A work_on_cpu() callback function to call an arbitrary CDMM driver callback
157 void (*fn)(struct mips_cdmm_device *) = work->fn; in mips_cdmm_void_work()
159 fn(work->dev); in mips_cdmm_void_work()
164 * mips_cdmm_int_work() - Call an int returning CDMM driver callback.
167 * A work_on_cpu() callback function to call an arbitrary CDMM driver callback
173 int (*fn)(struct mips_cdmm_device *) = work->fn; in mips_cdmm_int_work()
175 return fn(work->dev); in mips_cdmm_int_work()
182 * BUILD_PERCPU_HELPER() - Helper to call a CDMM driver callback on right CPU.
184 * @_name: Name of CDMM driver callback function.
186 * Generates a specific device callback function to call a CDMM driver callback
194 struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(dev->driver); \
196 .fn = cdrv->_name, \
200 _BUILD_RET_##_ret work_on_cpu(cdev->cpu, \
213 * mips_cdmm_driver_register() - Register a CDMM driver. in BUILD_PERCPU_HELPER()
214 * @drv: CDMM driver information. in BUILD_PERCPU_HELPER()
216 * Register a CDMM driver with the CDMM subsystem. The driver will be informed in BUILD_PERCPU_HELPER()
223 drv->drv.bus = &mips_cdmm_bustype; in BUILD_PERCPU_HELPER()
225 if (drv->probe) in BUILD_PERCPU_HELPER()
226 drv->drv.probe = mips_cdmm_probe; in BUILD_PERCPU_HELPER()
227 if (drv->remove) in BUILD_PERCPU_HELPER()
228 drv->drv.remove = mips_cdmm_remove; in BUILD_PERCPU_HELPER()
229 if (drv->shutdown) in BUILD_PERCPU_HELPER()
230 drv->drv.shutdown = mips_cdmm_shutdown; in BUILD_PERCPU_HELPER()
232 return driver_register(&drv->drv); in BUILD_PERCPU_HELPER()
237 * mips_cdmm_driver_unregister() - Unregister a CDMM driver.
238 * @drv: CDMM driver information.
240 * Unregister a CDMM driver from the CDMM subsystem.
244 driver_unregister(&drv->drv); in mips_cdmm_driver_unregister()
249 /* CDMM initialisation and bus discovery */
252 * struct mips_cdmm_bus - Info about CDMM bus.
258 * @offline: Whether the CDMM bus is going offline (or very early
273 static atomic_t mips_cdmm_next_id = ATOMIC_INIT(-1);
276 * mips_cdmm_get_bus() - Get the per-CPU CDMM bus information.
278 * Get information about the per-CPU CDMM bus, if the bus is present.
281 * pre-emption or by running from a pinned kernel thread.
283 * Returns: Pointer to CDMM bus information for the current CPU.
284 * May return ERR_PTR(-errno) in case of error, so check with
294 return ERR_PTR(-ENODEV); in mips_cdmm_get_bus()
297 /* Avoid early use of per-cpu primitives before initialised */ in mips_cdmm_get_bus()
309 bus = ERR_PTR(-ENOMEM); in mips_cdmm_get_bus()
318 * mips_cdmm_cur_base() - Find current physical base address of CDMM region.
320 * Returns: Physical base address of CDMM region according to cdmmbase CP0
321 * register, or 0 if the CDMM region is disabled.
335 * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
337 * Picking a suitable physical address at which to map the CDMM region is
347 * mips_cdmm_setup() - Ensure the CDMM bus is initialised and usable.
352 * pre-emption or by running from a pinned kernel thread.
354 * Returns 0 on success, -errno on failure.
366 if (bus->offline) { in mips_cdmm_setup()
367 /* If CDMM region is still set up, nothing to do */ in mips_cdmm_setup()
368 if (bus->phys == mips_cdmm_cur_base()) in mips_cdmm_setup()
371 * The CDMM region isn't set up as expected, so it needs in mips_cdmm_setup()
374 bus->offline = false; in mips_cdmm_setup()
375 } else if (bus->phys > 1) { in mips_cdmm_setup()
379 /* If the CDMM region is already configured, inherit that setup */ in mips_cdmm_setup()
380 if (!bus->phys) in mips_cdmm_setup()
381 bus->phys = mips_cdmm_cur_base(); in mips_cdmm_setup()
383 if (!bus->phys) in mips_cdmm_setup()
384 bus->phys = mips_cdmm_phys_base(); in mips_cdmm_setup()
386 if (!bus->phys) in mips_cdmm_setup()
387 bus->phys = mips_cdmm_default_base; in mips_cdmm_setup()
389 if (!bus->phys) { in mips_cdmm_setup()
390 bus->phys = 1; in mips_cdmm_setup()
393 * CDMM on the boot CPU, or else you need to implement in mips_cdmm_setup()
394 * mips_cdmm_phys_base() for your platform (see asm/cdmm.h). in mips_cdmm_setup()
396 pr_err("cdmm%u: Failed to choose a physical base\n", in mips_cdmm_setup()
400 if (bus->phys == 1) { in mips_cdmm_setup()
401 ret = -ENOMEM; in mips_cdmm_setup()
405 mips_cdmm_default_base = bus->phys; in mips_cdmm_setup()
407 pr_debug("cdmm%u: Enabling CDMM region at %pa\n", in mips_cdmm_setup()
408 smp_processor_id(), &bus->phys); in mips_cdmm_setup()
410 /* Enable CDMM */ in mips_cdmm_setup()
412 cdmmbase &= (1ul << MIPS_CDMMBASE_ADDR_SHIFT) - 1; in mips_cdmm_setup()
413 cdmmbase |= (bus->phys >> MIPS_CDMMBASE_ADDR_START) in mips_cdmm_setup()
419 bus->regs = (void __iomem *)CKSEG1ADDR(bus->phys); in mips_cdmm_setup()
420 bus->drbs = 1 + ((cdmmbase & MIPS_CDMMBASE_SIZE) >> in mips_cdmm_setup()
422 bus->drbs_reserved = !!(cdmmbase & MIPS_CDMMBASE_CI); in mips_cdmm_setup()
430 * mips_cdmm_early_probe() - Minimally probe for a specific device on CDMM.
431 * @dev_type: CDMM type code to look for.
433 * Minimally configure the in-CPU Common Device Memory Map (CDMM) and look for a
438 * pre-emption or by running from a pinned kernel thread.
443 * May return IOMEM_ERR_PTR(-errno) in case of error, so check with
449 void __iomem *cdmm; in mips_cdmm_early_probe() local
455 return IOMEM_ERR_PTR(-ENODEV); in mips_cdmm_early_probe()
463 drb = bus->drbs_reserved; in mips_cdmm_early_probe()
464 cdmm = bus->regs; in mips_cdmm_early_probe()
467 for (; drb < bus->drbs; drb += size + 1) { in mips_cdmm_early_probe()
468 acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE); in mips_cdmm_early_probe()
471 return cdmm + drb * CDMM_DRB_SIZE; in mips_cdmm_early_probe()
475 return IOMEM_ERR_PTR(-ENODEV); in mips_cdmm_early_probe()
480 * mips_cdmm_release() - Release a removed CDMM device.
483 * Clean up the struct mips_cdmm_device for an unused CDMM device. This is
494 * mips_cdmm_bus_discover() - Discover the devices on the CDMM bus.
495 * @bus: CDMM bus information, must already be set up.
499 void __iomem *cdmm; in mips_cdmm_bus_discover() local
508 drb = bus->drbs_reserved; in mips_cdmm_bus_discover()
509 cdmm = bus->regs; in mips_cdmm_bus_discover()
512 bus->discovered = true; in mips_cdmm_bus_discover()
513 pr_info("cdmm%u discovery (%u blocks)\n", cpu, bus->drbs); in mips_cdmm_bus_discover()
514 for (; drb < bus->drbs; drb += size + 1) { in mips_cdmm_bus_discover()
515 acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE); in mips_cdmm_bus_discover()
523 pr_info("cdmm%u-%u: @%u (%#x..%#x), type 0x%02x, rev %u\n", in mips_cdmm_bus_discover()
525 (drb + size + 1) * CDMM_DRB_SIZE - 1, in mips_cdmm_bus_discover()
532 dev->cpu = cpu; in mips_cdmm_bus_discover()
533 dev->res.start = bus->phys + drb * CDMM_DRB_SIZE; in mips_cdmm_bus_discover()
534 dev->res.end = bus->phys + in mips_cdmm_bus_discover()
535 (drb + size + 1) * CDMM_DRB_SIZE - 1; in mips_cdmm_bus_discover()
536 dev->res.flags = IORESOURCE_MEM; in mips_cdmm_bus_discover()
537 dev->type = type; in mips_cdmm_bus_discover()
538 dev->rev = rev; in mips_cdmm_bus_discover()
539 dev->dev.parent = get_cpu_device(cpu); in mips_cdmm_bus_discover()
540 dev->dev.bus = &mips_cdmm_bustype; in mips_cdmm_bus_discover()
541 dev->dev.id = atomic_inc_return(&mips_cdmm_next_id); in mips_cdmm_bus_discover()
542 dev->dev.release = mips_cdmm_release; in mips_cdmm_bus_discover()
544 dev_set_name(&dev->dev, "cdmm%u-%u", cpu, id); in mips_cdmm_bus_discover()
546 ret = device_register(&dev->dev); in mips_cdmm_bus_discover()
548 put_device(&dev->dev); in mips_cdmm_bus_discover()
558 * All the CDMM driver callbacks need to be executed on the appropriate CPU from
566 * BUILD_PERDEV_HELPER() - Helper to call a CDMM driver callback if CPU matches.
567 * @_name: Name of CDMM driver callback function.
569 * Generates a bus_for_each_dev callback function to call a specific CDMM driver
585 if (cdev->cpu != cpu || !dev->driver) \
588 cdrv = to_mips_cdmm_driver(dev->driver); \
589 if (!cdrv->_name) \
591 return cdrv->_name(cdev); \
599 * mips_cdmm_cpu_down_prep() - Callback for CPUHP DOWN_PREP: in BUILD_PERDEV_HELPER()
600 * Tear down the CDMM bus. in BUILD_PERDEV_HELPER()
603 * This function is executed on the hotplugged CPU and calls the CDMM in BUILD_PERDEV_HELPER()
621 bus->offline = true; in BUILD_PERDEV_HELPER()
627 * mips_cdmm_cpu_online() - Callback for CPUHP ONLINE: Bring up the CDMM bus.
631 * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all
649 bus->offline = false; in mips_cdmm_cpu_online()
651 if (!bus->discovered) in mips_cdmm_cpu_online()
662 * mips_cdmm_init() - Initialise CDMM bus.
664 * Initialise CDMM bus, discover CDMM devices for online CPUs, and arrange for
665 * hotplug notifications so the CDMM drivers can be kept up to date.
677 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "bus/cdmm:online", in mips_cdmm_init()
680 pr_warn("cdmm: Failed to register CPU notifier\n"); in mips_cdmm_init()