diff options
Diffstat (limited to 'arch/powerpc/platforms/wsp/scom_wsp.c')
| -rw-r--r-- | arch/powerpc/platforms/wsp/scom_wsp.c | 77 | 
1 files changed, 77 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/wsp/scom_wsp.c b/arch/powerpc/platforms/wsp/scom_wsp.c new file mode 100644 index 00000000000..4052e2259f3 --- /dev/null +++ b/arch/powerpc/platforms/wsp/scom_wsp.c @@ -0,0 +1,77 @@ +/* + *  SCOM backend for WSP + * + *  Copyright 2010 Benjamin Herrenschmidt, IBM Corp. + * + *  This program is free software; you can redistribute it and/or + *  modify it under the terms of the GNU General Public License + *  as published by the Free Software Foundation; either version + *  2 of the License, or (at your option) any later version. + */ + +#include <linux/cpumask.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <asm/cputhreads.h> +#include <asm/reg_a2.h> +#include <asm/scom.h> +#include <asm/udbg.h> + +#include "wsp.h" + + +static scom_map_t wsp_scom_map(struct device_node *dev, u64 reg, u64 count) +{ +	struct resource r; +	u64 xscom_addr; + +	if (!of_get_property(dev, "scom-controller", NULL)) { +		pr_err("%s: device %s is not a SCOM controller\n", +			__func__, dev->full_name); +		return SCOM_MAP_INVALID; +	} + +	if (of_address_to_resource(dev, 0, &r)) { +		pr_debug("Failed to find SCOM controller address\n"); +		return 0; +	} + +	/* Transform the SCOM address into an XSCOM offset */ +	xscom_addr = ((reg & 0x7f000000) >> 1) | ((reg & 0xfffff) << 3); + +	return (scom_map_t)ioremap(r.start + xscom_addr, count << 3); +} + +static void wsp_scom_unmap(scom_map_t map) +{ +	iounmap((void *)map); +} + +static u64 wsp_scom_read(scom_map_t map, u32 reg) +{ +	u64 __iomem *addr = (u64 __iomem *)map; + +	return in_be64(addr + reg); +} + +static void wsp_scom_write(scom_map_t map, u32 reg, u64 value) +{ +	u64 __iomem *addr = (u64 __iomem *)map; + +	return out_be64(addr + reg, value); +} + +static const struct scom_controller wsp_scom_controller = { +	.map	= wsp_scom_map, +	.unmap	= wsp_scom_unmap, +	.read	= wsp_scom_read, +	.write	= wsp_scom_write +}; + +void scom_init_wsp(void) +{ +	scom_init(&wsp_scom_controller); +}  |