From e857ff509b43e07eb30b48f283b40ea7dfbde068 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 11 Mar 2013 13:26:41 +0400 Subject: [PATCH] Add system controller register driver (SYSCON) This patch adds support for system controller register driver (SYSCON). Code taken from Linux Kernel and adapted for using in barebox. Signed-off-by: Alexander Shiyan Signed-off-by: Sascha Hauer --- drivers/mfd/Kconfig | 5 +++ drivers/mfd/Makefile | 1 + drivers/mfd/syscon.c | 92 ++++++++++++++++++++++++++++++++++++++++++++ include/mfd/syscon.h | 26 +++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 drivers/mfd/syscon.c create mode 100644 include/mfd/syscon.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index c506d6782..afb87dbd2 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -24,6 +24,11 @@ config MFD_STMPE depends on I2C bool "STMPE-i2c driver" +config MFD_SYSCON + bool "System Controller Register" + help + Select this option to enable accessing system control registers + config MFD_TWLCORE bool diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 542fb0fb3..1afd52bd3 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_MFD_MC34704) += mc34704.o obj-$(CONFIG_MFD_MC34708) += mc34708.o obj-$(CONFIG_MFD_MC9SDZ60) += mc9sdz60.o obj-$(CONFIG_MFD_STMPE) += stmpe-i2c.o +obj-$(CONFIG_MFD_SYSCON) += syscon.o obj-$(CONFIG_MFD_TWLCORE) += twl-core.o obj-$(CONFIG_MFD_TWL4030) += twl4030.o obj-$(CONFIG_MFD_TWL6030) += twl6030.o diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c new file mode 100644 index 000000000..87d2f7c8f --- /dev/null +++ b/drivers/mfd/syscon.c @@ -0,0 +1,92 @@ +/* System Control Driver + * + * Based on linux driver by: + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Linaro Ltd. + * Author: Dong Aisheng + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include + +struct syscon { + void __iomem *base; +}; + +void __iomem *syscon_base_lookup_by_pdevname(const char *s) +{ + struct syscon *syscon; + struct device_d *dev; + + for_each_device(dev) { + if (!strcmp(dev_name(dev), s)) { + syscon = dev->priv; + return syscon->base; + } + } + + return ERR_PTR(-ENODEV); +} + +static int syscon_probe(struct device_d *dev) +{ + struct syscon *syscon; + struct resource *res; + + syscon = xzalloc(sizeof(struct syscon)); + if (!syscon) + return -ENOMEM; + + res = dev_get_resource(dev, 0); + if (!res) { + free(syscon); + return -ENOENT; + } + + res = request_iomem_region(dev_name(dev), res->start, res->end); + if (!res) { + free(syscon); + return -EBUSY; + } + + syscon->base = (void __iomem *)res->start; + dev->priv = syscon; + + dev_info(dev, "map 0x%x-0x%x registered\n", res->start, res->end); + + return 0; +} + +static struct platform_device_id syscon_ids[] = { + { "syscon", }, + { } +}; + +static struct driver_d syscon_driver = { + .name = "syscon", + .probe = syscon_probe, + .id_table = syscon_ids, +}; + +static int __init syscon_init(void) +{ + return platform_driver_register(&syscon_driver); +} +core_initcall(syscon_init); + +MODULE_AUTHOR("Dong Aisheng "); +MODULE_DESCRIPTION("System Control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/mfd/syscon.h b/include/mfd/syscon.h new file mode 100644 index 000000000..68432b7fe --- /dev/null +++ b/include/mfd/syscon.h @@ -0,0 +1,26 @@ +/* System Control Driver + * + * Based on linux driver by: + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Linaro Ltd. + * Author: Dong Aisheng + * + * 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. + */ + +#ifndef __MFD_SYSCON_H__ +#define __MFD_SYSCON_H__ + +#ifdef CONFIG_MFD_SYSCON +void __iomem *syscon_base_lookup_by_pdevname(const char *); +#else +static inline void __iomem *syscon_base_lookup_by_pdevname(const char *) +{ + return NULL; +} +#endif + +#endif