Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8286ae03 authored by James Hogan's avatar James Hogan Committed by Ralf Baechle
Browse files

MIPS: Add CDMM bus support



Add MIPS Common Device Memory Map (CDMM) support in the form of a bus in
the standard Linux device model. Each device attached via CDMM is
discoverable via an 8-bit type identifier and may contain a number of
blocks of memory mapped registers in the CDMM region. IRQs are expected
to be handled separately.

Due to the per-cpu (per-VPE for MT cores) nature of the CDMM devices,
all the driver callbacks take place from workqueues which are run on the
right CPU for the device in question, so that the driver doesn't need to
be as concerned about which CPU it is running on. Callbacks also exist
for when CPUs are taken offline, so that any per-CPU resources used by
the driver can be disabled so they don't get forcefully migrated. CDMM
devices are created as children of the CPU device they are attached to.

Any existing CDMM configuration by the bootloader will be inherited,
however platforms wishing to enable CDMM should implement the weak
mips_cdmm_phys_base() function (see asm/cdmm.h) so that the bus driver
knows where it should put the CDMM region in the physical address space
if the bootloader hasn't already enabled it.

A mips_cdmm_early_probe() function is also provided to allow early boot
or particularly low level code to set up the CDMM region and probe for a
specific device type, for example early console or KGDB IO drivers for
the EJTAG Fast Debug Channel (FDC) CDMM device.

Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/9599/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 9b3274bd
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2014 Imagination Technologies Ltd.
 */
#ifndef __ASM_CDMM_H
#define __ASM_CDMM_H

#include <linux/device.h>
#include <linux/mod_devicetable.h>

/**
 * struct mips_cdmm_device - Represents a single device on a CDMM bus.
 * @dev:	Driver model device object.
 * @cpu:	CPU which can access this device.
 * @res:	MMIO resource.
 * @type:	Device type identifier.
 * @rev:	Device revision number.
 */
struct mips_cdmm_device {
	struct device		dev;
	unsigned int		cpu;
	struct resource		res;
	unsigned int		type;
	unsigned int		rev;
};

/**
 * struct mips_cdmm_driver - Represents a driver for a CDMM device.
 * @drv:	Driver model driver object.
 * @probe	Callback for probing newly discovered devices.
 * @remove:	Callback to remove the device.
 * @shutdown:	Callback on system shutdown.
 * @cpu_down:	Callback when the parent CPU is going down.
 *		Any CPU pinned threads/timers should be disabled.
 * @cpu_up:	Callback when the parent CPU is coming back up again.
 *		CPU pinned threads/timers can be restarted.
 * @id_table:	Table for CDMM IDs to match against.
 */
struct mips_cdmm_driver {
	struct device_driver	drv;
	int			(*probe)(struct mips_cdmm_device *);
	int			(*remove)(struct mips_cdmm_device *);
	void			(*shutdown)(struct mips_cdmm_device *);
	int			(*cpu_down)(struct mips_cdmm_device *);
	int			(*cpu_up)(struct mips_cdmm_device *);
	const struct mips_cdmm_device_id *id_table;
};

/**
 * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
 *
 * Picking a suitable physical address at which to map the CDMM region is
 * platform specific, so this weak function can be defined by platform code to
 * pick a suitable value if none is configured by the bootloader.
 *
 * This address must be 32kB aligned, and the region occupies a maximum of 32kB
 * of physical address space which must not be used for anything else.
 *
 * Returns:	Physical base address for CDMM region, or 0 on failure.
 */
phys_addr_t __weak mips_cdmm_phys_base(void);

extern struct bus_type mips_cdmm_bustype;
void __iomem *mips_cdmm_early_probe(unsigned int dev_type);

#define to_mips_cdmm_device(d)	container_of(d, struct mips_cdmm_device, dev)

#define mips_cdmm_get_drvdata(d)	dev_get_drvdata(&d->dev)
#define mips_cdmm_set_drvdata(d, p)	dev_set_drvdata(&d->dev, p)

int mips_cdmm_driver_register(struct mips_cdmm_driver *);
void mips_cdmm_driver_unregister(struct mips_cdmm_driver *);

/*
 * module_mips_cdmm_driver() - Helper macro for drivers that don't do
 * anything special in module init/exit.  This eliminates a lot of
 * boilerplate.  Each module may only use this macro once, and
 * calling it replaces module_init() and module_exit()
 */
#define module_mips_cdmm_driver(__mips_cdmm_driver) \
	module_driver(__mips_cdmm_driver, mips_cdmm_driver_register, \
			mips_cdmm_driver_unregister)

#endif /* __ASM_CDMM_H */
+13 −0
Original line number Diff line number Diff line
@@ -20,6 +20,19 @@ config IMX_WEIM
	  The WEIM(Wireless External Interface Module) works like a bus.
	  You can attach many different devices on it, such as NOR, onenand.

config MIPS_CDMM
	bool "MIPS Common Device Memory Map (CDMM) Driver"
	depends on CPU_MIPSR2
	help
	  Driver needed for the MIPS Common Device Memory Map bus in MIPS
	  cores. This bus is for per-CPU tightly coupled devices such as the
	  Fast Debug Channel (FDC).

	  For this to work, either your bootloader needs to enable the CDMM
	  region at an unused physical address on the boot CPU, or else your
	  platform code needs to implement mips_cdmm_phys_base() (see
	  asm/cdmm.h).

config MVEBU_MBUS
	bool
	depends on PLAT_ORION
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

obj-$(CONFIG_BRCMSTB_GISB_ARB)	+= brcmstb_gisb.o
obj-$(CONFIG_IMX_WEIM)	+= imx-weim.o
obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
obj-$(CONFIG_OMAP_OCP2SCP)	+= omap-ocp2scp.o

+716 −0

File added.

Preview size limit exceeded, changes collapsed.

+8 −0
Original line number Diff line number Diff line
@@ -546,6 +546,14 @@ struct amba_id {
	void			*data;
};

/**
 * struct mips_cdmm_device_id - identifies devices in MIPS CDMM bus
 * @type:	Device type identifier.
 */
struct mips_cdmm_device_id {
	__u8	type;
};

/*
 * Match x86 CPUs for CPU specific drivers.
 * See documentation of "x86_match_cpu" for details.
Loading