From 603aed8ffd4c9cb633c05a514cfb5e8ca6b0751d Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Mon, 16 Jan 2023 12:08:38 +0200 Subject: mfd: intel-m10-bmc: Split into core and spi specific parts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the common code from intel-m10-bmc driver into intel-m10-bmc-core and move the SPI bus parts into an interface specific file. intel-m10-bmc-core becomes the core MFD functions which can support multiple bus interface like SPI bus. Co-developed-by: Tianfei zhang Signed-off-by: Tianfei zhang Reviewed-by: Russ Weight Acked-by: Guenter Roeck # hwmon Reviewed-by: Xu Yilun Signed-off-by: Ilpo Järvinen Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20230116100845.6153-5-ilpo.jarvinen@linux.intel.com --- drivers/mfd/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/mfd/Makefile') diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 457471478a93..b360b29150b5 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -269,7 +269,9 @@ obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o obj-$(CONFIG_MFD_SMPRO) += smpro-core.o -obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o + +obj-$(CONFIG_MFD_INTEL_M10_BMC_CORE) += intel-m10-bmc-core.o +obj-$(CONFIG_MFD_INTEL_M10_BMC_SPI) += intel-m10-bmc-spi.o obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o -- cgit v1.2.3 From 869b9eddf0b38a22c27a400e2fa849d2ff2aa7e1 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Mon, 16 Jan 2023 12:08:44 +0200 Subject: mfd: intel-m10-bmc: Add PMCI driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the mfd driver for the Platform Management Component Interface (PMCI) based interface of Intel MAX10 BMC controller. PMCI is a software-visible interface, connected to card BMC which provided the basic functionality of read/write BMC register. The access to the register is done indirectly via a hardware controller/bridge that handles read/write/clear commands and acknowledgments for the commands. Previously, intel-m10-bmc provided sysfs under /sys/bus/spi/devices/... which is generalized in this change because not all MAX10 BMC appear under SPI anymore. Co-developed-by: Tianfei zhang Signed-off-by: Tianfei zhang Co-developed-by: Russ Weight Signed-off-by: Russ Weight Co-developed-by: Matthew Gerlach Signed-off-by: Matthew Gerlach Reviewed-by: Xu Yilun Signed-off-by: Ilpo Järvinen Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20230116100845.6153-11-ilpo.jarvinen@linux.intel.com --- .../ABI/testing/sysfs-driver-intel-m10-bmc | 8 +- drivers/mfd/Kconfig | 12 ++ drivers/mfd/Makefile | 1 + drivers/mfd/intel-m10-bmc-pmci.c | 219 +++++++++++++++++++++ include/linux/mfd/intel-m10-bmc.h | 28 +++ 5 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 drivers/mfd/intel-m10-bmc-pmci.c (limited to 'drivers/mfd/Makefile') diff --git a/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc b/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc index 9773925138af..a8ab58035c95 100644 --- a/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc +++ b/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc @@ -1,4 +1,4 @@ -What: /sys/bus/spi/devices/.../bmc_version +What: /sys/bus/.../drivers/intel-m10-bmc/.../bmc_version Date: June 2020 KernelVersion: 5.10 Contact: Xu Yilun @@ -6,7 +6,7 @@ Description: Read only. Returns the hardware build version of Intel MAX10 BMC chip. Format: "0x%x". -What: /sys/bus/spi/devices/.../bmcfw_version +What: /sys/bus/.../drivers/intel-m10-bmc/.../bmcfw_version Date: June 2020 KernelVersion: 5.10 Contact: Xu Yilun @@ -14,7 +14,7 @@ Description: Read only. Returns the firmware version of Intel MAX10 BMC chip. Format: "0x%x". -What: /sys/bus/spi/devices/.../mac_address +What: /sys/bus/.../drivers/intel-m10-bmc/.../mac_address Date: January 2021 KernelVersion: 5.12 Contact: Russ Weight @@ -25,7 +25,7 @@ Description: Read only. Returns the first MAC address in a block space. Format: "%02x:%02x:%02x:%02x:%02x:%02x". -What: /sys/bus/spi/devices/.../mac_count +What: /sys/bus/.../drivers/intel-m10-bmc/.../mac_count Date: January 2021 KernelVersion: 5.12 Contact: Russ Weight diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b6ab85831cde..2632ca2162de 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2243,6 +2243,18 @@ config MFD_INTEL_M10_BMC_SPI additional drivers must be enabled in order to use the functionality of the device. +config MFD_INTEL_M10_BMC_PMCI + tristate "Intel MAX 10 Board Management Controller with PMCI" + depends on FPGA_DFL + select MFD_INTEL_M10_BMC_CORE + select REGMAP + help + Support for the Intel MAX 10 board management controller via PMCI. + + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the functionality + of the device. + config MFD_RSMU_I2C tristate "Renesas Synchronization Management Unit with I2C" depends on I2C && OF diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index b360b29150b5..81c30d7cf5d4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -272,6 +272,7 @@ obj-$(CONFIG_MFD_SMPRO) += smpro-core.o obj-$(CONFIG_MFD_INTEL_M10_BMC_CORE) += intel-m10-bmc-core.o obj-$(CONFIG_MFD_INTEL_M10_BMC_SPI) += intel-m10-bmc-spi.o +obj-$(CONFIG_MFD_INTEL_M10_BMC_PMCI) += intel-m10-bmc-pmci.o obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o diff --git a/drivers/mfd/intel-m10-bmc-pmci.c b/drivers/mfd/intel-m10-bmc-pmci.c new file mode 100644 index 000000000000..975019f644b5 --- /dev/null +++ b/drivers/mfd/intel-m10-bmc-pmci.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MAX10 BMC Platform Management Component Interface (PMCI) based + * interface. + * + * Copyright (C) 2020-2023 Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include + +struct m10bmc_pmci_device { + void __iomem *base; + struct intel_m10bmc m10bmc; +}; + +/* + * Intel FGPA indirect register access via hardware controller/bridge. + */ +#define INDIRECT_CMD_OFF 0 +#define INDIRECT_CMD_CLR 0 +#define INDIRECT_CMD_RD BIT(0) +#define INDIRECT_CMD_WR BIT(1) +#define INDIRECT_CMD_ACK BIT(2) + +#define INDIRECT_ADDR_OFF 0x4 +#define INDIRECT_RD_OFF 0x8 +#define INDIRECT_WR_OFF 0xc + +#define INDIRECT_INT_US 1 +#define INDIRECT_TIMEOUT_US 10000 + +struct indirect_ctx { + void __iomem *base; + struct device *dev; +}; + +static int indirect_clear_cmd(struct indirect_ctx *ctx) +{ + unsigned int cmd; + int ret; + + writel(INDIRECT_CMD_CLR, ctx->base + INDIRECT_CMD_OFF); + + ret = readl_poll_timeout(ctx->base + INDIRECT_CMD_OFF, cmd, + cmd == INDIRECT_CMD_CLR, + INDIRECT_INT_US, INDIRECT_TIMEOUT_US); + if (ret) + dev_err(ctx->dev, "timed out waiting clear cmd (residual cmd=0x%x)\n", cmd); + + return ret; +} + +static int indirect_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct indirect_ctx *ctx = context; + unsigned int cmd, ack, tmpval; + int ret, ret2; + + cmd = readl(ctx->base + INDIRECT_CMD_OFF); + if (cmd != INDIRECT_CMD_CLR) + dev_warn(ctx->dev, "residual cmd 0x%x on read entry\n", cmd); + + writel(reg, ctx->base + INDIRECT_ADDR_OFF); + writel(INDIRECT_CMD_RD, ctx->base + INDIRECT_CMD_OFF); + + ret = readl_poll_timeout(ctx->base + INDIRECT_CMD_OFF, ack, + (ack & INDIRECT_CMD_ACK) == INDIRECT_CMD_ACK, + INDIRECT_INT_US, INDIRECT_TIMEOUT_US); + if (ret) + dev_err(ctx->dev, "read timed out on reg 0x%x ack 0x%x\n", reg, ack); + else + tmpval = readl(ctx->base + INDIRECT_RD_OFF); + + ret2 = indirect_clear_cmd(ctx); + + if (ret) + return ret; + if (ret2) + return ret2; + + *val = tmpval; + return 0; +} + +static int indirect_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct indirect_ctx *ctx = context; + unsigned int cmd, ack; + int ret, ret2; + + cmd = readl(ctx->base + INDIRECT_CMD_OFF); + if (cmd != INDIRECT_CMD_CLR) + dev_warn(ctx->dev, "residual cmd 0x%x on write entry\n", cmd); + + writel(val, ctx->base + INDIRECT_WR_OFF); + writel(reg, ctx->base + INDIRECT_ADDR_OFF); + writel(INDIRECT_CMD_WR, ctx->base + INDIRECT_CMD_OFF); + + ret = readl_poll_timeout(ctx->base + INDIRECT_CMD_OFF, ack, + (ack & INDIRECT_CMD_ACK) == INDIRECT_CMD_ACK, + INDIRECT_INT_US, INDIRECT_TIMEOUT_US); + if (ret) + dev_err(ctx->dev, "write timed out on reg 0x%x ack 0x%x\n", reg, ack); + + ret2 = indirect_clear_cmd(ctx); + + if (ret) + return ret; + return ret2; +} + +static const struct regmap_range m10bmc_pmci_regmap_range[] = { + regmap_reg_range(M10BMC_N6000_SYS_BASE, M10BMC_N6000_SYS_END), +}; + +static const struct regmap_access_table m10bmc_pmci_access_table = { + .yes_ranges = m10bmc_pmci_regmap_range, + .n_yes_ranges = ARRAY_SIZE(m10bmc_pmci_regmap_range), +}; + +static struct regmap_config m10bmc_pmci_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .wr_table = &m10bmc_pmci_access_table, + .rd_table = &m10bmc_pmci_access_table, + .reg_read = &indirect_reg_read, + .reg_write = &indirect_reg_write, + .max_register = M10BMC_N6000_SYS_END, +}; + +static struct mfd_cell m10bmc_pmci_n6000_bmc_subdevs[] = { + { .name = "n6000bmc-hwmon" }, +}; + +static const struct m10bmc_csr_map m10bmc_n6000_csr_map = { + .base = M10BMC_N6000_SYS_BASE, + .build_version = M10BMC_N6000_BUILD_VER, + .fw_version = NIOS2_N6000_FW_VERSION, + .mac_low = M10BMC_N6000_MAC_LOW, + .mac_high = M10BMC_N6000_MAC_HIGH, + .doorbell = M10BMC_N6000_DOORBELL, + .auth_result = M10BMC_N6000_AUTH_RESULT, + .bmc_prog_addr = M10BMC_N6000_BMC_PROG_ADDR, + .bmc_reh_addr = M10BMC_N6000_BMC_REH_ADDR, + .bmc_magic = M10BMC_N6000_BMC_PROG_MAGIC, + .sr_prog_addr = M10BMC_N6000_SR_PROG_ADDR, + .sr_reh_addr = M10BMC_N6000_SR_REH_ADDR, + .sr_magic = M10BMC_N6000_SR_PROG_MAGIC, + .pr_prog_addr = M10BMC_N6000_PR_PROG_ADDR, + .pr_reh_addr = M10BMC_N6000_PR_REH_ADDR, + .pr_magic = M10BMC_N6000_PR_PROG_MAGIC, + .rsu_update_counter = M10BMC_N6000_STAGING_FLASH_COUNT, +}; + +static const struct intel_m10bmc_platform_info m10bmc_pmci_n6000 = { + .cells = m10bmc_pmci_n6000_bmc_subdevs, + .n_cells = ARRAY_SIZE(m10bmc_pmci_n6000_bmc_subdevs), + .csr_map = &m10bmc_n6000_csr_map, +}; + +static int m10bmc_pmci_probe(struct dfl_device *ddev) +{ + struct device *dev = &ddev->dev; + struct m10bmc_pmci_device *pmci; + struct indirect_ctx *ctx; + + pmci = devm_kzalloc(dev, sizeof(*pmci), GFP_KERNEL); + if (!pmci) + return -ENOMEM; + + pmci->m10bmc.dev = dev; + + pmci->base = devm_ioremap_resource(dev, &ddev->mmio_res); + if (IS_ERR(pmci->base)) + return PTR_ERR(pmci->base); + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->base = pmci->base + M10BMC_N6000_INDIRECT_BASE; + ctx->dev = dev; + indirect_clear_cmd(ctx); + pmci->m10bmc.regmap = devm_regmap_init(dev, NULL, ctx, &m10bmc_pmci_regmap_config); + + if (IS_ERR(pmci->m10bmc.regmap)) + return PTR_ERR(pmci->m10bmc.regmap); + + return m10bmc_dev_init(&pmci->m10bmc, &m10bmc_pmci_n6000); +} + +#define FME_FEATURE_ID_M10BMC_PMCI 0x12 + +static const struct dfl_device_id m10bmc_pmci_ids[] = { + { FME_ID, FME_FEATURE_ID_M10BMC_PMCI }, + { } +}; +MODULE_DEVICE_TABLE(dfl, m10bmc_pmci_ids); + +static struct dfl_driver m10bmc_pmci_driver = { + .drv = { + .name = "intel-m10-bmc", + .dev_groups = m10bmc_dev_groups, + }, + .id_table = m10bmc_pmci_ids, + .probe = m10bmc_pmci_probe, +}; + +module_dfl_driver(m10bmc_pmci_driver); + +MODULE_DESCRIPTION("MAX10 BMC PMCI-based interface"); +MODULE_AUTHOR("Intel Corporation"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/intel-m10-bmc.h b/include/linux/mfd/intel-m10-bmc.h index 1f75b33240ad..810534b1bd12 100644 --- a/include/linux/mfd/intel-m10-bmc.h +++ b/include/linux/mfd/intel-m10-bmc.h @@ -120,6 +120,34 @@ /* Address of 4KB inverted bit vector containing staging area FLASH count */ #define M10BMC_N3000_STAGING_FLASH_COUNT 0x17ffb000 +#define M10BMC_N6000_INDIRECT_BASE 0x400 + +#define M10BMC_N6000_SYS_BASE 0x0 +#define M10BMC_N6000_SYS_END 0xfff + +#define M10BMC_N6000_DOORBELL 0x1c0 +#define M10BMC_N6000_AUTH_RESULT 0x1c4 + +#define M10BMC_N6000_BUILD_VER 0x0 +#define NIOS2_N6000_FW_VERSION 0x4 +#define M10BMC_N6000_MAC_LOW 0x20 +#define M10BMC_N6000_MAC_HIGH (M10BMC_N6000_MAC_LOW + 4) + +/* Addresses for security related data in FLASH */ +#define M10BMC_N6000_BMC_REH_ADDR 0x7ffc004 +#define M10BMC_N6000_BMC_PROG_ADDR 0x7ffc000 +#define M10BMC_N6000_BMC_PROG_MAGIC 0x5746 + +#define M10BMC_N6000_SR_REH_ADDR 0x7ffd004 +#define M10BMC_N6000_SR_PROG_ADDR 0x7ffd000 +#define M10BMC_N6000_SR_PROG_MAGIC 0x5253 + +#define M10BMC_N6000_PR_REH_ADDR 0x7ffe004 +#define M10BMC_N6000_PR_PROG_ADDR 0x7ffe000 +#define M10BMC_N6000_PR_PROG_MAGIC 0x5250 + +#define M10BMC_N6000_STAGING_FLASH_COUNT 0x7ff5000 + /** * struct m10bmc_csr_map - Intel MAX 10 BMC CSR register map */ -- cgit v1.2.3 From ca78476e4888f1f1caac26c48ec715e546baf432 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Jan 2023 14:46:13 +0100 Subject: mfd: Remove toshiba tmio drivers Four separate mfd drivers are in the "tmio" family, and all of them were used in now-removed PXA machines (eseries, tosa, and hx4700), so the mfd drivers and all its children can be removed as well. Signed-off-by: Arnd Bergmann Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20230105134622.254560-19-arnd@kernel.org --- drivers/mfd/Kconfig | 38 -- drivers/mfd/Makefile | 4 - drivers/mfd/asic3.c | 1071 ------------------------------------------ drivers/mfd/t7l66xb.c | 427 ----------------- drivers/mfd/tc6387xb.c | 228 --------- drivers/mfd/tc6393xb.c | 907 ----------------------------------- drivers/mfd/tmio_core.c | 70 --- include/linux/mfd/asic3.h | 313 ------------ include/linux/mfd/t7l66xb.h | 29 -- include/linux/mfd/tc6387xb.h | 19 - include/linux/mfd/tc6393xb.h | 53 --- include/linux/mfd/tmio.h | 5 - 12 files changed, 3164 deletions(-) delete mode 100644 drivers/mfd/asic3.c delete mode 100644 drivers/mfd/t7l66xb.c delete mode 100644 drivers/mfd/tc6387xb.c delete mode 100644 drivers/mfd/tc6393xb.c delete mode 100644 drivers/mfd/tmio_core.c delete mode 100644 include/linux/mfd/asic3.h delete mode 100644 include/linux/mfd/t7l66xb.h delete mode 100644 include/linux/mfd/tc6387xb.h delete mode 100644 include/linux/mfd/tc6393xb.h (limited to 'drivers/mfd/Makefile') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d90b4258fc44..d4fc4ca9fdbd 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -301,15 +301,6 @@ config MFD_CS47L92 help Support for Cirrus Logic CS42L92, CS47L92 and CS47L93 Smart Codecs -config MFD_ASIC3 - bool "Compaq ASIC3" - depends on GPIOLIB - depends on ARM || COMPILE_TEST - select MFD_CORE - help - This driver supports the ASIC3 multifunction chip found on many - PDAs (mainly iPAQ and HTC based ones) - config PMIC_DA903X bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" depends on I2C=y @@ -1796,35 +1787,6 @@ config MFD_TC3589X additional drivers must be enabled in order to use the functionality of the device. -config MFD_TMIO - bool - default n - -config MFD_T7L66XB - bool "Toshiba T7L66XB" - depends on ARM && HAVE_CLK - select MFD_CORE - select MFD_TMIO - help - Support for Toshiba Mobile IO Controller T7L66XB - -config MFD_TC6387XB - bool "Toshiba TC6387XB" - depends on ARM && HAVE_CLK - select MFD_CORE - select MFD_TMIO - help - Support for Toshiba Mobile IO Controller TC6387XB - -config MFD_TC6393XB - bool "Toshiba TC6393XB" - depends on ARM && HAVE_CLK - select GPIOLIB - select MFD_CORE - select MFD_TMIO - help - Support for Toshiba Mobile IO Controller TC6393XB - config MFD_TQMX86 tristate "TQ-Systems IO controller TQMX86" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 81c30d7cf5d4..48cf532848c4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o obj-$(CONFIG_MFD_ACT8945A) += act8945a.o obj-$(CONFIG_MFD_SM501) += sm501.o -obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o @@ -30,9 +29,6 @@ obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o obj-$(CONFIG_MFD_SUN6I_PRCM) += sun6i-prcm.o obj-$(CONFIG_MFD_TC3589X) += tc3589x.o -obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o -obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o -obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o obj-$(CONFIG_MFD_TQMX86) += tqmx86.o obj-$(CONFIG_MFD_LOCHNAGAR) += lochnagar-i2c.o diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c deleted file mode 100644 index 4fb7e35eb5ed..000000000000 --- a/drivers/mfd/asic3.c +++ /dev/null @@ -1,1071 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * driver/mfd/asic3.c - * - * Compaq ASIC3 support. - * - * Copyright 2001 Compaq Computer Corporation. - * Copyright 2004-2005 Phil Blundell - * Copyright 2007-2008 OpenedHand Ltd. - * - * Authors: Phil Blundell , - * Samuel Ortiz - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -enum { - ASIC3_CLOCK_SPI, - ASIC3_CLOCK_OWM, - ASIC3_CLOCK_PWM0, - ASIC3_CLOCK_PWM1, - ASIC3_CLOCK_LED0, - ASIC3_CLOCK_LED1, - ASIC3_CLOCK_LED2, - ASIC3_CLOCK_SD_HOST, - ASIC3_CLOCK_SD_BUS, - ASIC3_CLOCK_SMBUS, - ASIC3_CLOCK_EX0, - ASIC3_CLOCK_EX1, -}; - -struct asic3_clk { - int enabled; - unsigned int cdex; - unsigned long rate; -}; - -#define INIT_CDEX(_name, _rate) \ - [ASIC3_CLOCK_##_name] = { \ - .cdex = CLOCK_CDEX_##_name, \ - .rate = _rate, \ - } - -static struct asic3_clk asic3_clk_init[] __initdata = { - INIT_CDEX(SPI, 0), - INIT_CDEX(OWM, 5000000), - INIT_CDEX(PWM0, 0), - INIT_CDEX(PWM1, 0), - INIT_CDEX(LED0, 0), - INIT_CDEX(LED1, 0), - INIT_CDEX(LED2, 0), - INIT_CDEX(SD_HOST, 24576000), - INIT_CDEX(SD_BUS, 12288000), - INIT_CDEX(SMBUS, 0), - INIT_CDEX(EX0, 32768), - INIT_CDEX(EX1, 24576000), -}; - -struct asic3 { - void __iomem *mapping; - unsigned int bus_shift; - unsigned int irq_nr; - unsigned int irq_base; - raw_spinlock_t lock; - u16 irq_bothedge[4]; - struct gpio_chip gpio; - struct device *dev; - void __iomem *tmio_cnf; - - struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)]; -}; - -static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset); - -void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 value) -{ - iowrite16(value, asic->mapping + - (reg >> asic->bus_shift)); -} -EXPORT_SYMBOL_GPL(asic3_write_register); - -u32 asic3_read_register(struct asic3 *asic, unsigned int reg) -{ - return ioread16(asic->mapping + - (reg >> asic->bus_shift)); -} -EXPORT_SYMBOL_GPL(asic3_read_register); - -static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) -{ - unsigned long flags; - u32 val; - - raw_spin_lock_irqsave(&asic->lock, flags); - val = asic3_read_register(asic, reg); - if (set) - val |= bits; - else - val &= ~bits; - asic3_write_register(asic, reg, val); - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -/* IRQs */ -#define MAX_ASIC_ISR_LOOPS 20 -#define ASIC3_GPIO_BASE_INCR \ - (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE) - -static void asic3_irq_flip_edge(struct asic3 *asic, - u32 base, int bit) -{ - u16 edge; - unsigned long flags; - - raw_spin_lock_irqsave(&asic->lock, flags); - edge = asic3_read_register(asic, - base + ASIC3_GPIO_EDGE_TRIGGER); - edge ^= bit; - asic3_write_register(asic, - base + ASIC3_GPIO_EDGE_TRIGGER, edge); - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_irq_demux(struct irq_desc *desc) -{ - struct asic3 *asic = irq_desc_get_handler_data(desc); - struct irq_data *data = irq_desc_get_irq_data(desc); - int iter, i; - unsigned long flags; - - data->chip->irq_ack(data); - - for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { - u32 status; - int bank; - - raw_spin_lock_irqsave(&asic->lock, flags); - status = asic3_read_register(asic, - ASIC3_OFFSET(INTR, P_INT_STAT)); - raw_spin_unlock_irqrestore(&asic->lock, flags); - - /* Check all ten register bits */ - if ((status & 0x3ff) == 0) - break; - - /* Handle GPIO IRQs */ - for (bank = 0; bank < ASIC3_NUM_GPIO_BANKS; bank++) { - if (status & (1 << bank)) { - unsigned long base, istat; - - base = ASIC3_GPIO_A_BASE - + bank * ASIC3_GPIO_BASE_INCR; - raw_spin_lock_irqsave(&asic->lock, flags); - istat = asic3_read_register(asic, - base + - ASIC3_GPIO_INT_STATUS); - /* Clearing IntStatus */ - asic3_write_register(asic, - base + - ASIC3_GPIO_INT_STATUS, 0); - raw_spin_unlock_irqrestore(&asic->lock, flags); - - for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) { - int bit = (1 << i); - unsigned int irqnr; - - if (!(istat & bit)) - continue; - - irqnr = asic->irq_base + - (ASIC3_GPIOS_PER_BANK * bank) - + i; - generic_handle_irq(irqnr); - if (asic->irq_bothedge[bank] & bit) - asic3_irq_flip_edge(asic, base, - bit); - } - } - } - - /* Handle remaining IRQs in the status register */ - for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { - /* They start at bit 4 and go up */ - if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) - generic_handle_irq(asic->irq_base + i); - } - } - - if (iter >= MAX_ASIC_ISR_LOOPS) - dev_err(asic->dev, "interrupt processing overrun\n"); -} - -static inline int asic3_irq_to_bank(struct asic3 *asic, int irq) -{ - int n; - - n = (irq - asic->irq_base) >> 4; - - return (n * (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE)); -} - -static inline int asic3_irq_to_index(struct asic3 *asic, int irq) -{ - return (irq - asic->irq_base) & 0xf; -} - -static void asic3_mask_gpio_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 val, bank, index; - unsigned long flags; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - - raw_spin_lock_irqsave(&asic->lock, flags); - val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); - val |= 1 << index; - asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val); - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_mask_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - int regval; - unsigned long flags; - - raw_spin_lock_irqsave(&asic->lock, flags); - regval = asic3_read_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK); - - regval &= ~(ASIC3_INTMASK_MASK0 << - (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); - - asic3_write_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK, - regval); - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_unmask_gpio_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 val, bank, index; - unsigned long flags; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - - raw_spin_lock_irqsave(&asic->lock, flags); - val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); - val &= ~(1 << index); - asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val); - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_unmask_irq(struct irq_data *data) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - int regval; - unsigned long flags; - - raw_spin_lock_irqsave(&asic->lock, flags); - regval = asic3_read_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK); - - regval |= (ASIC3_INTMASK_MASK0 << - (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); - - asic3_write_register(asic, - ASIC3_INTR_BASE + - ASIC3_INTR_INT_MASK, - regval); - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 bank, index; - u16 trigger, level, edge, bit; - unsigned long flags; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - bit = 1<lock, flags); - level = asic3_read_register(asic, - bank + ASIC3_GPIO_LEVEL_TRIGGER); - edge = asic3_read_register(asic, - bank + ASIC3_GPIO_EDGE_TRIGGER); - trigger = asic3_read_register(asic, - bank + ASIC3_GPIO_TRIGGER_TYPE); - asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] &= ~bit; - - if (type == IRQ_TYPE_EDGE_RISING) { - trigger |= bit; - edge |= bit; - } else if (type == IRQ_TYPE_EDGE_FALLING) { - trigger |= bit; - edge &= ~bit; - } else if (type == IRQ_TYPE_EDGE_BOTH) { - trigger |= bit; - if (asic3_gpio_get(&asic->gpio, data->irq - asic->irq_base)) - edge &= ~bit; - else - edge |= bit; - asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] |= bit; - } else if (type == IRQ_TYPE_LEVEL_LOW) { - trigger &= ~bit; - level &= ~bit; - } else if (type == IRQ_TYPE_LEVEL_HIGH) { - trigger &= ~bit; - level |= bit; - } else { - /* - * if type == IRQ_TYPE_NONE, we should mask interrupts, but - * be careful to not unmask them if mask was also called. - * Probably need internal state for mask. - */ - dev_notice(asic->dev, "irq type not changed\n"); - } - asic3_write_register(asic, bank + ASIC3_GPIO_LEVEL_TRIGGER, - level); - asic3_write_register(asic, bank + ASIC3_GPIO_EDGE_TRIGGER, - edge); - asic3_write_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE, - trigger); - raw_spin_unlock_irqrestore(&asic->lock, flags); - return 0; -} - -static int asic3_gpio_irq_set_wake(struct irq_data *data, unsigned int on) -{ - struct asic3 *asic = irq_data_get_irq_chip_data(data); - u32 bank, index; - u16 bit; - - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); - bit = 1<irq_nr = ret; - - /* turn on clock to IRQ controller */ - clksel |= CLOCK_SEL_CX; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), - clksel); - - irq_base = asic->irq_base; - - for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { - if (irq < asic->irq_base + ASIC3_NUM_GPIOS) - irq_set_chip(irq, &asic3_gpio_irq_chip); - else - irq_set_chip(irq, &asic3_irq_chip); - - irq_set_chip_data(irq, asic); - irq_set_handler(irq, handle_level_irq); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - } - - asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), - ASIC3_INTMASK_GINTMASK); - - irq_set_chained_handler_and_data(asic->irq_nr, asic3_irq_demux, asic); - irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); - - return 0; -} - -static void asic3_irq_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - unsigned int irq, irq_base; - - irq_base = asic->irq_base; - - for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { - irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); - } - irq_set_chained_handler(asic->irq_nr, NULL); -} - -/* GPIOs */ -static int asic3_gpio_direction(struct gpio_chip *chip, - unsigned offset, int out) -{ - u32 mask = ASIC3_GPIO_TO_MASK(offset), out_reg; - unsigned int gpio_base; - unsigned long flags; - struct asic3 *asic; - - asic = gpiochip_get_data(chip); - gpio_base = ASIC3_GPIO_TO_BASE(offset); - - if (gpio_base > ASIC3_GPIO_D_BASE) { - dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", - gpio_base, offset); - return -EINVAL; - } - - raw_spin_lock_irqsave(&asic->lock, flags); - - out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_DIRECTION); - - /* Input is 0, Output is 1 */ - if (out) - out_reg |= mask; - else - out_reg &= ~mask; - - asic3_write_register(asic, gpio_base + ASIC3_GPIO_DIRECTION, out_reg); - - raw_spin_unlock_irqrestore(&asic->lock, flags); - - return 0; - -} - -static int asic3_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - return asic3_gpio_direction(chip, offset, 0); -} - -static int asic3_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - return asic3_gpio_direction(chip, offset, 1); -} - -static int asic3_gpio_get(struct gpio_chip *chip, - unsigned offset) -{ - unsigned int gpio_base; - u32 mask = ASIC3_GPIO_TO_MASK(offset); - struct asic3 *asic; - - asic = gpiochip_get_data(chip); - gpio_base = ASIC3_GPIO_TO_BASE(offset); - - if (gpio_base > ASIC3_GPIO_D_BASE) { - dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", - gpio_base, offset); - return -EINVAL; - } - - return !!(asic3_read_register(asic, - gpio_base + ASIC3_GPIO_STATUS) & mask); -} - -static void asic3_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - u32 mask, out_reg; - unsigned int gpio_base; - unsigned long flags; - struct asic3 *asic; - - asic = gpiochip_get_data(chip); - gpio_base = ASIC3_GPIO_TO_BASE(offset); - - if (gpio_base > ASIC3_GPIO_D_BASE) { - dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n", - gpio_base, offset); - return; - } - - mask = ASIC3_GPIO_TO_MASK(offset); - - raw_spin_lock_irqsave(&asic->lock, flags); - - out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_OUT); - - if (value) - out_reg |= mask; - else - out_reg &= ~mask; - - asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg); - - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct asic3 *asic = gpiochip_get_data(chip); - - return asic->irq_base + offset; -} - -static __init int asic3_gpio_probe(struct platform_device *pdev, - u16 *gpio_config, int num) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - u16 alt_reg[ASIC3_NUM_GPIO_BANKS]; - u16 out_reg[ASIC3_NUM_GPIO_BANKS]; - u16 dir_reg[ASIC3_NUM_GPIO_BANKS]; - int i; - - memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); - memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); - memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS * sizeof(u16)); - - /* Enable all GPIOs */ - asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, MASK), 0xffff); - asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, MASK), 0xffff); - asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, MASK), 0xffff); - asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, MASK), 0xffff); - - for (i = 0; i < num; i++) { - u8 alt, pin, dir, init, bank_num, bit_num; - u16 config = gpio_config[i]; - - pin = ASIC3_CONFIG_GPIO_PIN(config); - alt = ASIC3_CONFIG_GPIO_ALT(config); - dir = ASIC3_CONFIG_GPIO_DIR(config); - init = ASIC3_CONFIG_GPIO_INIT(config); - - bank_num = ASIC3_GPIO_TO_BANK(pin); - bit_num = ASIC3_GPIO_TO_BIT(pin); - - alt_reg[bank_num] |= (alt << bit_num); - out_reg[bank_num] |= (init << bit_num); - dir_reg[bank_num] |= (dir << bit_num); - } - - for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) { - asic3_write_register(asic, - ASIC3_BANK_TO_BASE(i) + - ASIC3_GPIO_DIRECTION, - dir_reg[i]); - asic3_write_register(asic, - ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_OUT, - out_reg[i]); - asic3_write_register(asic, - ASIC3_BANK_TO_BASE(i) + - ASIC3_GPIO_ALT_FUNCTION, - alt_reg[i]); - } - - return gpiochip_add_data(&asic->gpio, asic); -} - -static void asic3_gpio_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - - gpiochip_remove(&asic->gpio); -} - -static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) -{ - unsigned long flags; - u32 cdex; - - raw_spin_lock_irqsave(&asic->lock, flags); - if (clk->enabled++ == 0) { - cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX)); - cdex |= clk->cdex; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex); - } - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk) -{ - unsigned long flags; - u32 cdex; - - WARN_ON(clk->enabled == 0); - - raw_spin_lock_irqsave(&asic->lock, flags); - if (--clk->enabled == 0) { - cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX)); - cdex &= ~clk->cdex; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex); - } - raw_spin_unlock_irqrestore(&asic->lock, flags); -} - -/* MFD cells (SPI, PWM, LED, DS1WM, MMC) */ -static struct ds1wm_driver_data ds1wm_pdata = { - .active_high = 1, - .reset_recover_delay = 1, -}; - -static struct resource ds1wm_resources[] = { - { - .start = ASIC3_OWM_BASE, - .end = ASIC3_OWM_BASE + 0x13, - .flags = IORESOURCE_MEM, - }, - { - .start = ASIC3_IRQ_OWM, - .end = ASIC3_IRQ_OWM, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, - }, -}; - -static int ds1wm_enable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - /* Turn on external clocks and the OWM clock */ - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_OWM]); - usleep_range(1000, 5000); - - /* Reset and enable DS1WM */ - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET), - ASIC3_EXTCF_OWM_RESET, 1); - usleep_range(1000, 5000); - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET), - ASIC3_EXTCF_OWM_RESET, 0); - usleep_range(1000, 5000); - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_OWM_EN, 1); - usleep_range(1000, 5000); - - return 0; -} - -static int ds1wm_disable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_OWM_EN, 0); - - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_OWM]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - - return 0; -} - -static const struct mfd_cell asic3_cell_ds1wm = { - .name = "ds1wm", - .enable = ds1wm_enable, - .disable = ds1wm_disable, - .platform_data = &ds1wm_pdata, - .pdata_size = sizeof(ds1wm_pdata), - .num_resources = ARRAY_SIZE(ds1wm_resources), - .resources = ds1wm_resources, -}; - -static void asic3_mmc_pwr(struct platform_device *pdev, int state) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - tmio_core_mmc_pwr(asic->tmio_cnf, 1 - asic->bus_shift, state); -} - -static void asic3_mmc_clk_div(struct platform_device *pdev, int state) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - tmio_core_mmc_clk_div(asic->tmio_cnf, 1 - asic->bus_shift, state); -} - -static struct tmio_mmc_data asic3_mmc_data = { - .hclk = 24576000, - .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .set_pwr = asic3_mmc_pwr, - .set_clk_div = asic3_mmc_clk_div, -}; - -static struct resource asic3_mmc_resources[] = { - DEFINE_RES_MEM(ASIC3_SD_CTRL_BASE, 0x400), - DEFINE_RES_IRQ(0) -}; - -static int asic3_mmc_enable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - /* Not sure if it must be done bit by bit, but leaving as-is */ - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_LEVCD, 1); - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_LEVWP, 1); - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_SUSPEND, 0); - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_PCLR, 0); - - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - /* CLK32 used for card detection and for interruption detection - * when HCLK is stopped. - */ - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - usleep_range(1000, 5000); - - /* HCLK 24.576 MHz, BCLK 12.288 MHz: */ - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), - CLOCK_SEL_CX | CLOCK_SEL_SD_HCLK_SEL); - - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]); - asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]); - usleep_range(1000, 5000); - - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_SD_MEM_ENABLE, 1); - - /* Enable SD card slot 3.3V power supply */ - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_SDPWR, 1); - - /* ASIC3_SD_CTRL_BASE assumes 32-bit addressing, TMIO is 16-bit */ - tmio_core_mmc_enable(asic->tmio_cnf, 1 - asic->bus_shift, - ASIC3_SD_CTRL_BASE >> 1); - - return 0; -} - -static int asic3_mmc_disable(struct platform_device *pdev) -{ - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - /* Put in suspend mode */ - asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), - ASIC3_SDHWCTRL_SUSPEND, 1); - - /* Disable clocks */ - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]); - asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]); - return 0; -} - -static const struct mfd_cell asic3_cell_mmc = { - .name = "tmio-mmc", - .enable = asic3_mmc_enable, - .disable = asic3_mmc_disable, - .suspend = asic3_mmc_disable, - .resume = asic3_mmc_enable, - .platform_data = &asic3_mmc_data, - .pdata_size = sizeof(asic3_mmc_data), - .num_resources = ARRAY_SIZE(asic3_mmc_resources), - .resources = asic3_mmc_resources, -}; - -static const int clock_ledn[ASIC3_NUM_LEDS] = { - [0] = ASIC3_CLOCK_LED0, - [1] = ASIC3_CLOCK_LED1, - [2] = ASIC3_CLOCK_LED2, -}; - -static int asic3_leds_enable(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - asic3_clk_enable(asic, &asic->clocks[clock_ledn[cell->id]]); - - return 0; -} - -static int asic3_leds_disable(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]); - - return 0; -} - -static int asic3_leds_suspend(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); - - while (asic3_gpio_get(&asic->gpio, ASIC3_GPIO(C, cell->id)) != 0) - usleep_range(1000, 5000); - - asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]); - - return 0; -} - -static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = { - [0] = { - .name = "leds-asic3", - .id = 0, - .enable = asic3_leds_enable, - .disable = asic3_leds_disable, - .suspend = asic3_leds_suspend, - .resume = asic3_leds_enable, - }, - [1] = { - .name = "leds-asic3", - .id = 1, - .enable = asic3_leds_enable, - .disable = asic3_leds_disable, - .suspend = asic3_leds_suspend, - .resume = asic3_leds_enable, - }, - [2] = { - .name = "leds-asic3", - .id = 2, - .enable = asic3_leds_enable, - .disable = asic3_leds_disable, - .suspend = asic3_leds_suspend, - .resume = asic3_leds_enable, - }, -}; - -static int __init asic3_mfd_probe(struct platform_device *pdev, - struct asic3_platform_data *pdata, - struct resource *mem) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - struct resource *mem_sdio; - int irq, ret; - - mem_sdio = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!mem_sdio) - dev_dbg(asic->dev, "no SDIO MEM resource\n"); - - irq = platform_get_irq(pdev, 1); - if (irq < 0) - dev_dbg(asic->dev, "no SDIO IRQ resource\n"); - - /* DS1WM */ - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - ASIC3_EXTCF_OWM_SMB, 0); - - ds1wm_resources[0].start >>= asic->bus_shift; - ds1wm_resources[0].end >>= asic->bus_shift; - - /* MMC */ - if (mem_sdio) { - asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> - asic->bus_shift) + mem_sdio->start, - ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); - if (!asic->tmio_cnf) { - ret = -ENOMEM; - dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); - goto out; - } - } - asic3_mmc_resources[0].start >>= asic->bus_shift; - asic3_mmc_resources[0].end >>= asic->bus_shift; - - if (pdata->clock_rate) { - ds1wm_pdata.clock_rate = pdata->clock_rate; - ret = mfd_add_devices(&pdev->dev, pdev->id, - &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); - if (ret < 0) - goto out_unmap; - } - - if (mem_sdio && (irq >= 0)) { - ret = mfd_add_devices(&pdev->dev, pdev->id, - &asic3_cell_mmc, 1, mem_sdio, irq, NULL); - if (ret < 0) - goto out_unmap; - } - - ret = 0; - if (pdata->leds) { - int i; - - for (i = 0; i < ASIC3_NUM_LEDS; ++i) { - asic3_cell_leds[i].platform_data = &pdata->leds[i]; - asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); - } - ret = mfd_add_devices(&pdev->dev, 0, - asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); - } - return ret; - -out_unmap: - if (asic->tmio_cnf) - iounmap(asic->tmio_cnf); -out: - return ret; -} - -static void asic3_mfd_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - - mfd_remove_devices(&pdev->dev); - iounmap(asic->tmio_cnf); -} - -/* Core */ -static int __init asic3_probe(struct platform_device *pdev) -{ - struct asic3_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct asic3 *asic; - struct resource *mem; - unsigned long clksel; - int ret = 0; - - asic = devm_kzalloc(&pdev->dev, - sizeof(struct asic3), GFP_KERNEL); - if (!asic) - return -ENOMEM; - - raw_spin_lock_init(&asic->lock); - platform_set_drvdata(pdev, asic); - asic->dev = &pdev->dev; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(asic->dev, "no MEM resource\n"); - return -ENOMEM; - } - - asic->mapping = ioremap(mem->start, resource_size(mem)); - if (!asic->mapping) { - dev_err(asic->dev, "Couldn't ioremap\n"); - return -ENOMEM; - } - - asic->irq_base = pdata->irq_base; - - /* calculate bus shift from mem resource */ - asic->bus_shift = 2 - (resource_size(mem) >> 12); - - clksel = 0; - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), clksel); - - ret = asic3_irq_probe(pdev); - if (ret < 0) { - dev_err(asic->dev, "Couldn't probe IRQs\n"); - goto out_unmap; - } - - asic->gpio.label = "asic3"; - asic->gpio.base = pdata->gpio_base; - asic->gpio.ngpio = ASIC3_NUM_GPIOS; - asic->gpio.get = asic3_gpio_get; - asic->gpio.set = asic3_gpio_set; - asic->gpio.direction_input = asic3_gpio_direction_input; - asic->gpio.direction_output = asic3_gpio_direction_output; - asic->gpio.to_irq = asic3_gpio_to_irq; - - ret = asic3_gpio_probe(pdev, - pdata->gpio_config, - pdata->gpio_config_num); - if (ret < 0) { - dev_err(asic->dev, "GPIO probe failed\n"); - goto out_irq; - } - - /* Making a per-device copy is only needed for the - * theoretical case of multiple ASIC3s on one board: - */ - memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init)); - - asic3_mfd_probe(pdev, pdata, mem); - - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - (ASIC3_EXTCF_CF0_BUF_EN|ASIC3_EXTCF_CF0_PWAIT_EN), 1); - - dev_info(asic->dev, "ASIC3 Core driver\n"); - - return 0; - - out_irq: - asic3_irq_remove(pdev); - - out_unmap: - iounmap(asic->mapping); - - return ret; -} - -static int asic3_remove(struct platform_device *pdev) -{ - struct asic3 *asic = platform_get_drvdata(pdev); - - asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), - (ASIC3_EXTCF_CF0_BUF_EN|ASIC3_EXTCF_CF0_PWAIT_EN), 0); - - asic3_mfd_remove(pdev); - - asic3_gpio_remove(pdev); - - asic3_irq_remove(pdev); - - asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0); - - iounmap(asic->mapping); - - return 0; -} - -static void asic3_shutdown(struct platform_device *pdev) -{ -} - -static struct platform_driver asic3_device_driver = { - .driver = { - .name = "asic3", - }, - .remove = asic3_remove, - .shutdown = asic3_shutdown, -}; - -static int __init asic3_init(void) -{ - int retval = 0; - - retval = platform_driver_probe(&asic3_device_driver, asic3_probe); - - return retval; -} - -subsys_initcall(asic3_init); diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c deleted file mode 100644 index 1d9d1d38d068..000000000000 --- a/drivers/mfd/t7l66xb.c +++ /dev/null @@ -1,427 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * Toshiba T7L66XB core mfd support - * - * Copyright (c) 2005, 2007, 2008 Ian Molton - * Copyright (c) 2008 Dmitry Baryshkov - * - * T7L66 features: - * - * Supported in this driver: - * SD/MMC - * SM/NAND flash controller - * - * As yet not supported - * GPIO interface (on NAND pins) - * Serial interface - * TFT 'interface converter' - * PCMCIA interface logic - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - T7L66XB_CELL_NAND, - T7L66XB_CELL_MMC, -}; - -static const struct resource t7l66xb_mmc_resources[] = { - DEFINE_RES_MEM(0x800, 0x200), - DEFINE_RES_IRQ(IRQ_T7L66XB_MMC) -}; - -#define SCR_REVID 0x08 /* b Revision ID */ -#define SCR_IMR 0x42 /* b Interrupt Mask */ -#define SCR_DEV_CTL 0xe0 /* b Device control */ -#define SCR_ISR 0xe1 /* b Interrupt Status */ -#define SCR_GPO_OC 0xf0 /* b GPO output control */ -#define SCR_GPO_OS 0xf1 /* b GPO output enable */ -#define SCR_GPI_S 0xf2 /* w GPI status */ -#define SCR_APDC 0xf8 /* b Active pullup down ctrl */ - -#define SCR_DEV_CTL_USB BIT(0) /* USB enable */ -#define SCR_DEV_CTL_MMC BIT(1) /* MMC enable */ - -/*--------------------------------------------------------------------------*/ - -struct t7l66xb { - void __iomem *scr; - /* Lock to protect registers requiring read/modify/write ops. */ - raw_spinlock_t lock; - - struct resource rscr; - struct clk *clk48m; - struct clk *clk32k; - int irq; - int irq_base; -}; - -/*--------------------------------------------------------------------------*/ - -static int t7l66xb_mmc_enable(struct platform_device *mmc) -{ - struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent); - unsigned long flags; - u8 dev_ctl; - int ret; - - ret = clk_prepare_enable(t7l66xb->clk32k); - if (ret) - return ret; - - raw_spin_lock_irqsave(&t7l66xb->lock, flags); - - dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); - dev_ctl |= SCR_DEV_CTL_MMC; - tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); - - raw_spin_unlock_irqrestore(&t7l66xb->lock, flags); - - tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, - t7l66xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static int t7l66xb_mmc_disable(struct platform_device *mmc) -{ - struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent); - unsigned long flags; - u8 dev_ctl; - - raw_spin_lock_irqsave(&t7l66xb->lock, flags); - - dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); - dev_ctl &= ~SCR_DEV_CTL_MMC; - tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); - - raw_spin_unlock_irqrestore(&t7l66xb->lock, flags); - - clk_disable_unprepare(t7l66xb->clk32k); - - return 0; -} - -static void t7l66xb_mmc_pwr(struct platform_device *mmc, int state) -{ - struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_pwr(t7l66xb->scr + 0x200, 0, state); -} - -static void t7l66xb_mmc_clk_div(struct platform_device *mmc, int state) -{ - struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_clk_div(t7l66xb->scr + 0x200, 0, state); -} - -/*--------------------------------------------------------------------------*/ - -static struct tmio_mmc_data t7166xb_mmc_data = { - .hclk = 24000000, - .set_pwr = t7l66xb_mmc_pwr, - .set_clk_div = t7l66xb_mmc_clk_div, -}; - -static const struct resource t7l66xb_nand_resources[] = { - { - .start = 0xc00, - .end = 0xc07, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0100, - .end = 0x01ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_T7L66XB_NAND, - .end = IRQ_T7L66XB_NAND, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mfd_cell t7l66xb_cells[] = { - [T7L66XB_CELL_MMC] = { - .name = "tmio-mmc", - .enable = t7l66xb_mmc_enable, - .disable = t7l66xb_mmc_disable, - .platform_data = &t7166xb_mmc_data, - .pdata_size = sizeof(t7166xb_mmc_data), - .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), - .resources = t7l66xb_mmc_resources, - }, - [T7L66XB_CELL_NAND] = { - .name = "tmio-nand", - .num_resources = ARRAY_SIZE(t7l66xb_nand_resources), - .resources = t7l66xb_nand_resources, - }, -}; - -/*--------------------------------------------------------------------------*/ - -/* Handle the T7L66XB interrupt mux */ -static void t7l66xb_irq(struct irq_desc *desc) -{ - struct t7l66xb *t7l66xb = irq_desc_get_handler_data(desc); - unsigned int isr; - unsigned int i, irq_base; - - irq_base = t7l66xb->irq_base; - - while ((isr = tmio_ioread8(t7l66xb->scr + SCR_ISR) & - ~tmio_ioread8(t7l66xb->scr + SCR_IMR))) - for (i = 0; i < T7L66XB_NR_IRQS; i++) - if (isr & (1 << i)) - generic_handle_irq(irq_base + i); -} - -static void t7l66xb_irq_mask(struct irq_data *data) -{ - struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - raw_spin_lock_irqsave(&t7l66xb->lock, flags); - imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); - imr |= 1 << (data->irq - t7l66xb->irq_base); - tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); - raw_spin_unlock_irqrestore(&t7l66xb->lock, flags); -} - -static void t7l66xb_irq_unmask(struct irq_data *data) -{ - struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - raw_spin_lock_irqsave(&t7l66xb->lock, flags); - imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); - imr &= ~(1 << (data->irq - t7l66xb->irq_base)); - tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); - raw_spin_unlock_irqrestore(&t7l66xb->lock, flags); -} - -static struct irq_chip t7l66xb_chip = { - .name = "t7l66xb", - .irq_ack = t7l66xb_irq_mask, - .irq_mask = t7l66xb_irq_mask, - .irq_unmask = t7l66xb_irq_unmask, -}; - -/*--------------------------------------------------------------------------*/ - -/* Install the IRQ handler */ -static void t7l66xb_attach_irq(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_base = t7l66xb->irq_base; - - for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &t7l66xb_chip, handle_level_irq); - irq_set_chip_data(irq, t7l66xb); - } - - irq_set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_chained_handler_and_data(t7l66xb->irq, t7l66xb_irq, t7l66xb); -} - -static void t7l66xb_detach_irq(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_base = t7l66xb->irq_base; - - irq_set_chained_handler_and_data(t7l66xb->irq, NULL, NULL); - - for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); - } -} - -/*--------------------------------------------------------------------------*/ - -static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); - - if (pdata && pdata->suspend) - pdata->suspend(dev); - clk_disable_unprepare(t7l66xb->clk48m); - - return 0; -} - -static int t7l66xb_resume(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); - int ret; - - ret = clk_prepare_enable(t7l66xb->clk48m); - if (ret) - return ret; - - if (pdata && pdata->resume) - pdata->resume(dev); - - tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, - t7l66xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -static int t7l66xb_probe(struct platform_device *dev) -{ - struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); - struct t7l66xb *t7l66xb; - struct resource *iomem, *rscr; - int ret; - - if (!pdata) - return -EINVAL; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) - return -EINVAL; - - t7l66xb = kzalloc(sizeof *t7l66xb, GFP_KERNEL); - if (!t7l66xb) - return -ENOMEM; - - raw_spin_lock_init(&t7l66xb->lock); - - platform_set_drvdata(dev, t7l66xb); - - ret = platform_get_irq(dev, 0); - if (ret >= 0) - t7l66xb->irq = ret; - else - goto err_noirq; - - t7l66xb->irq_base = pdata->irq_base; - - t7l66xb->clk32k = clk_get(&dev->dev, "CLK_CK32K"); - if (IS_ERR(t7l66xb->clk32k)) { - ret = PTR_ERR(t7l66xb->clk32k); - goto err_clk32k_get; - } - - t7l66xb->clk48m = clk_get(&dev->dev, "CLK_CK48M"); - if (IS_ERR(t7l66xb->clk48m)) { - ret = PTR_ERR(t7l66xb->clk48m); - goto err_clk48m_get; - } - - rscr = &t7l66xb->rscr; - rscr->name = "t7l66xb-core"; - rscr->start = iomem->start; - rscr->end = iomem->start + 0xff; - rscr->flags = IORESOURCE_MEM; - - ret = request_resource(iomem, rscr); - if (ret) - goto err_request_scr; - - t7l66xb->scr = ioremap(rscr->start, resource_size(rscr)); - if (!t7l66xb->scr) { - ret = -ENOMEM; - goto err_ioremap; - } - - ret = clk_prepare_enable(t7l66xb->clk48m); - if (ret) - goto err_clk_enable; - - if (pdata->enable) - pdata->enable(dev); - - /* Mask all interrupts */ - tmio_iowrite8(0xbf, t7l66xb->scr + SCR_IMR); - - printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n", - dev->name, tmio_ioread8(t7l66xb->scr + SCR_REVID), - (unsigned long)iomem->start, t7l66xb->irq); - - t7l66xb_attach_irq(dev); - - t7l66xb_cells[T7L66XB_CELL_NAND].platform_data = pdata->nand_data; - t7l66xb_cells[T7L66XB_CELL_NAND].pdata_size = sizeof(*pdata->nand_data); - - ret = mfd_add_devices(&dev->dev, dev->id, - t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), - iomem, t7l66xb->irq_base, NULL); - - if (!ret) - return 0; - - t7l66xb_detach_irq(dev); - clk_disable_unprepare(t7l66xb->clk48m); -err_clk_enable: - iounmap(t7l66xb->scr); -err_ioremap: - release_resource(&t7l66xb->rscr); -err_request_scr: - clk_put(t7l66xb->clk48m); -err_clk48m_get: - clk_put(t7l66xb->clk32k); -err_clk32k_get: -err_noirq: - kfree(t7l66xb); - return ret; -} - -static int t7l66xb_remove(struct platform_device *dev) -{ - struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - - clk_disable_unprepare(t7l66xb->clk48m); - clk_put(t7l66xb->clk48m); - clk_disable_unprepare(t7l66xb->clk32k); - clk_put(t7l66xb->clk32k); - t7l66xb_detach_irq(dev); - iounmap(t7l66xb->scr); - release_resource(&t7l66xb->rscr); - mfd_remove_devices(&dev->dev); - kfree(t7l66xb); - - return 0; -} - -static struct platform_driver t7l66xb_platform_driver = { - .driver = { - .name = "t7l66xb", - }, - .suspend = pm_sleep_ptr(t7l66xb_suspend), - .resume = pm_sleep_ptr(t7l66xb_resume), - .probe = t7l66xb_probe, - .remove = t7l66xb_remove, -}; - -/*--------------------------------------------------------------------------*/ - -module_platform_driver(t7l66xb_platform_driver); - -MODULE_DESCRIPTION("Toshiba T7L66XB core driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ian Molton"); -MODULE_ALIAS("platform:t7l66xb"); diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c deleted file mode 100644 index 5392da6ba7b0..000000000000 --- a/drivers/mfd/tc6387xb.c +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Toshiba TC6387XB support - * Copyright (c) 2005 Ian Molton - * - * This file contains TC6387XB base support. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - TC6387XB_CELL_MMC, -}; - -struct tc6387xb { - void __iomem *scr; - struct clk *clk32k; - struct resource rscr; -}; - -static const struct resource tc6387xb_mmc_resources[] = { - { - .start = 0x800, - .end = 0x9ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, -}; - -/*--------------------------------------------------------------------------*/ - -static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev); - - if (pdata && pdata->suspend) - pdata->suspend(dev); - clk_disable_unprepare(tc6387xb->clk32k); - - return 0; -} - -static int tc6387xb_resume(struct platform_device *dev) -{ - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev); - - clk_prepare_enable(tc6387xb->clk32k); - if (pdata && pdata->resume) - pdata->resume(dev); - - tmio_core_mmc_resume(tc6387xb->scr + 0x200, 0, - tc6387xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state) -{ - struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_pwr(tc6387xb->scr + 0x200, 0, state); -} - -static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state) -{ - struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, 0, state); -} - - -static int tc6387xb_mmc_enable(struct platform_device *mmc) -{ - struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent); - - clk_prepare_enable(tc6387xb->clk32k); - - tmio_core_mmc_enable(tc6387xb->scr + 0x200, 0, - tc6387xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static int tc6387xb_mmc_disable(struct platform_device *mmc) -{ - struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent); - - clk_disable_unprepare(tc6387xb->clk32k); - - return 0; -} - -static struct tmio_mmc_data tc6387xb_mmc_data = { - .hclk = 24000000, - .set_pwr = tc6387xb_mmc_pwr, - .set_clk_div = tc6387xb_mmc_clk_div, -}; - -/*--------------------------------------------------------------------------*/ - -static const struct mfd_cell tc6387xb_cells[] = { - [TC6387XB_CELL_MMC] = { - .name = "tmio-mmc", - .enable = tc6387xb_mmc_enable, - .disable = tc6387xb_mmc_disable, - .platform_data = &tc6387xb_mmc_data, - .pdata_size = sizeof(tc6387xb_mmc_data), - .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), - .resources = tc6387xb_mmc_resources, - }, -}; - -static int tc6387xb_probe(struct platform_device *dev) -{ - struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev); - struct resource *iomem, *rscr; - struct clk *clk32k; - struct tc6387xb *tc6387xb; - int irq, ret; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) - return -EINVAL; - - tc6387xb = kzalloc(sizeof(*tc6387xb), GFP_KERNEL); - if (!tc6387xb) - return -ENOMEM; - - ret = platform_get_irq(dev, 0); - if (ret >= 0) - irq = ret; - else - goto err_no_irq; - - clk32k = clk_get(&dev->dev, "CLK_CK32K"); - if (IS_ERR(clk32k)) { - ret = PTR_ERR(clk32k); - goto err_no_clk; - } - - rscr = &tc6387xb->rscr; - rscr->name = "tc6387xb-core"; - rscr->start = iomem->start; - rscr->end = iomem->start + 0xff; - rscr->flags = IORESOURCE_MEM; - - ret = request_resource(iomem, rscr); - if (ret) - goto err_resource; - - tc6387xb->scr = ioremap(rscr->start, resource_size(rscr)); - if (!tc6387xb->scr) { - ret = -ENOMEM; - goto err_ioremap; - } - - tc6387xb->clk32k = clk32k; - platform_set_drvdata(dev, tc6387xb); - - if (pdata && pdata->enable) - pdata->enable(dev); - - dev_info(&dev->dev, "Toshiba tc6387xb initialised\n"); - - ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, - ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL); - - if (!ret) - return 0; - - iounmap(tc6387xb->scr); -err_ioremap: - release_resource(&tc6387xb->rscr); -err_resource: - clk_put(clk32k); -err_no_clk: -err_no_irq: - kfree(tc6387xb); - return ret; -} - -static int tc6387xb_remove(struct platform_device *dev) -{ - struct tc6387xb *tc6387xb = platform_get_drvdata(dev); - - mfd_remove_devices(&dev->dev); - iounmap(tc6387xb->scr); - release_resource(&tc6387xb->rscr); - clk_disable_unprepare(tc6387xb->clk32k); - clk_put(tc6387xb->clk32k); - kfree(tc6387xb); - - return 0; -} - - -static struct platform_driver tc6387xb_platform_driver = { - .driver = { - .name = "tc6387xb", - }, - .probe = tc6387xb_probe, - .remove = tc6387xb_remove, - .suspend = pm_sleep_ptr(tc6387xb_suspend), - .resume = pm_sleep_ptr(tc6387xb_resume), -}; - -module_platform_driver(tc6387xb_platform_driver); - -MODULE_DESCRIPTION("Toshiba TC6387XB core driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ian Molton"); -MODULE_ALIAS("platform:tc6387xb"); - diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c deleted file mode 100644 index 997bb8b5881d..000000000000 --- a/drivers/mfd/tc6393xb.c +++ /dev/null @@ -1,907 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Toshiba TC6393XB SoC support - * - * Copyright(c) 2005-2006 Chris Humbert - * Copyright(c) 2005 Dirk Opfer - * Copyright(c) 2005 Ian Molton - * Copyright(c) 2007 Dmitry Baryshkov - * - * Based on code written by Sharp/Lineo for 2.4 kernels - * Based on locomo.c - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SCR_REVID 0x08 /* b Revision ID */ -#define SCR_ISR 0x50 /* b Interrupt Status */ -#define SCR_IMR 0x52 /* b Interrupt Mask */ -#define SCR_IRR 0x54 /* b Interrupt Routing */ -#define SCR_GPER 0x60 /* w GP Enable */ -#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */ -#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */ -#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */ -#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */ -#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */ -#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */ -#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */ -#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */ -#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */ -#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */ -#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */ -#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */ -#define SCR_CCR 0x98 /* w Clock Control */ -#define SCR_PLL2CR 0x9a /* w PLL2 Control */ -#define SCR_PLL1CR 0x9c /* l PLL1 Control */ -#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */ -#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */ -#define SCR_FER 0xe0 /* b Function Enable */ -#define SCR_MCR 0xe4 /* w Mode Control */ -#define SCR_CONFIG 0xfc /* b Configuration Control */ -#define SCR_DEBUG 0xff /* b Debug */ - -#define SCR_CCR_CK32K BIT(0) -#define SCR_CCR_USBCK BIT(1) -#define SCR_CCR_UNK1 BIT(4) -#define SCR_CCR_MCLK_MASK (7 << 8) -#define SCR_CCR_MCLK_OFF (0 << 8) -#define SCR_CCR_MCLK_12 (1 << 8) -#define SCR_CCR_MCLK_24 (2 << 8) -#define SCR_CCR_MCLK_48 (3 << 8) -#define SCR_CCR_HCLK_MASK (3 << 12) -#define SCR_CCR_HCLK_24 (0 << 12) -#define SCR_CCR_HCLK_48 (1 << 12) - -#define SCR_FER_USBEN BIT(0) /* USB host enable */ -#define SCR_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */ -#define SCR_FER_SLCDEN BIT(2) /* SLCD enable */ - -#define SCR_MCR_RDY_MASK (3 << 0) -#define SCR_MCR_RDY_OPENDRAIN (0 << 0) -#define SCR_MCR_RDY_TRISTATE (1 << 0) -#define SCR_MCR_RDY_PUSHPULL (2 << 0) -#define SCR_MCR_RDY_UNK BIT(2) -#define SCR_MCR_RDY_EN BIT(3) -#define SCR_MCR_INT_MASK (3 << 4) -#define SCR_MCR_INT_OPENDRAIN (0 << 4) -#define SCR_MCR_INT_TRISTATE (1 << 4) -#define SCR_MCR_INT_PUSHPULL (2 << 4) -#define SCR_MCR_INT_UNK BIT(6) -#define SCR_MCR_INT_EN BIT(7) -/* bits 8 - 16 are unknown */ - -#define TC_GPIO_BIT(i) (1 << (i & 0x7)) - -/*--------------------------------------------------------------------------*/ - -struct tc6393xb { - void __iomem *scr; - struct device *dev; - - struct gpio_chip gpio; - struct gpio_desc *vcc_on; - - struct clk *clk; /* 3,6 Mhz */ - - raw_spinlock_t lock; /* protects RMW cycles */ - - struct { - u8 fer; - u16 ccr; - u8 gpi_bcr[3]; - u8 gpo_dsr[3]; - u8 gpo_doecr[3]; - } suspend_state; - - struct resource rscr; - struct resource *iomem; - int irq; - int irq_base; -}; - -enum { - TC6393XB_CELL_NAND, - TC6393XB_CELL_MMC, - TC6393XB_CELL_OHCI, - TC6393XB_CELL_FB, -}; - -/*--------------------------------------------------------------------------*/ - -static int tc6393xb_nand_enable(struct platform_device *nand) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(nand->dev.parent); - unsigned long flags; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - /* SMD buffer on */ - dev_dbg(nand->dev.parent, "SMD buffer on\n"); - tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static const struct resource tc6393xb_nand_resources[] = { - { - .start = 0x1000, - .end = 0x1007, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0100, - .end = 0x01ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_NAND, - .end = IRQ_TC6393_NAND, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct resource tc6393xb_mmc_resources[] = { - { - .start = 0x800, - .end = 0x9ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_MMC, - .end = IRQ_TC6393_MMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct resource tc6393xb_ohci_resources[] = { - { - .start = 0x3000, - .end = 0x31ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0300, - .end = 0x03ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x010000, - .end = 0x017fff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x018000, - .end = 0x01ffff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_OHCI, - .end = IRQ_TC6393_OHCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct resource tc6393xb_fb_resources[] = { - { - .start = 0x5000, - .end = 0x51ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x0500, - .end = 0x05ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x100000, - .end = 0x1fffff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_TC6393_FB, - .end = IRQ_TC6393_FB, - .flags = IORESOURCE_IRQ, - }, -}; - -static int tc6393xb_ohci_enable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - u8 fer; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr |= SCR_CCR_USBCK; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - fer = tmio_ioread8(tc6393xb->scr + SCR_FER); - fer |= SCR_FER_USBEN; - tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_ohci_disable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - u8 fer; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - fer = tmio_ioread8(tc6393xb->scr + SCR_FER); - fer &= ~SCR_FER_USBEN; - tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr &= ~SCR_CCR_USBCK; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_ohci_suspend(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent); - - /* We can't properly store/restore OHCI state, so fail here */ - if (tcpd->resume_restore) - return -EBUSY; - - return tc6393xb_ohci_disable(dev); -} - -static int tc6393xb_fb_enable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr &= ~SCR_CCR_MCLK_MASK; - ccr |= SCR_CCR_MCLK_48; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_fb_disable(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); - unsigned long flags; - u16 ccr; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); - ccr &= ~SCR_CCR_MCLK_MASK; - ccr |= SCR_CCR_MCLK_OFF; - tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent); - u8 fer; - unsigned long flags; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - fer = ioread8(tc6393xb->scr + SCR_FER); - if (on) - fer |= SCR_FER_SLCDEN; - else - fer &= ~SCR_FER_SLCDEN; - iowrite8(fer, tc6393xb->scr + SCR_FER); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} -EXPORT_SYMBOL(tc6393xb_lcd_set_power); - -int tc6393xb_lcd_mode(struct platform_device *fb, - const struct fb_videomode *mode) { - struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent); - unsigned long flags; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0); - iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} -EXPORT_SYMBOL(tc6393xb_lcd_mode); - -static int tc6393xb_mmc_enable(struct platform_device *mmc) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0, - tc6393xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static int tc6393xb_mmc_resume(struct platform_device *mmc) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0, - tc6393xb_mmc_resources[0].start & 0xfffe); - - return 0; -} - -static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state); -} - -static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state) -{ - struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); - - tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state); -} - -static struct tmio_mmc_data tc6393xb_mmc_data = { - .hclk = 24000000, - .set_pwr = tc6393xb_mmc_pwr, - .set_clk_div = tc6393xb_mmc_clk_div, -}; - -static struct mfd_cell tc6393xb_cells[] = { - [TC6393XB_CELL_NAND] = { - .name = "tmio-nand", - .enable = tc6393xb_nand_enable, - .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), - .resources = tc6393xb_nand_resources, - }, - [TC6393XB_CELL_MMC] = { - .name = "tmio-mmc", - .enable = tc6393xb_mmc_enable, - .resume = tc6393xb_mmc_resume, - .platform_data = &tc6393xb_mmc_data, - .pdata_size = sizeof(tc6393xb_mmc_data), - .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), - .resources = tc6393xb_mmc_resources, - }, - [TC6393XB_CELL_OHCI] = { - .name = "tmio-ohci", - .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), - .resources = tc6393xb_ohci_resources, - .enable = tc6393xb_ohci_enable, - .suspend = tc6393xb_ohci_suspend, - .resume = tc6393xb_ohci_enable, - .disable = tc6393xb_ohci_disable, - }, - [TC6393XB_CELL_FB] = { - .name = "tmio-fb", - .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), - .resources = tc6393xb_fb_resources, - .enable = tc6393xb_fb_enable, - .suspend = tc6393xb_fb_disable, - .resume = tc6393xb_fb_enable, - .disable = tc6393xb_fb_disable, - }, -}; - -/*--------------------------------------------------------------------------*/ - -static int tc6393xb_gpio_get(struct gpio_chip *chip, - unsigned offset) -{ - struct tc6393xb *tc6393xb = gpiochip_get_data(chip); - - /* XXX: does dsr also represent inputs? */ - return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) - & TC_GPIO_BIT(offset)); -} - -static void __tc6393xb_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct tc6393xb *tc6393xb = gpiochip_get_data(chip); - u8 dsr; - - dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); - if (value) - dsr |= TC_GPIO_BIT(offset); - else - dsr &= ~TC_GPIO_BIT(offset); - - tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); -} - -static void tc6393xb_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct tc6393xb *tc6393xb = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - __tc6393xb_gpio_set(chip, offset, value); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); -} - -static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - struct tc6393xb *tc6393xb = gpiochip_get_data(chip); - unsigned long flags; - u8 doecr; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - doecr &= ~TC_GPIO_BIT(offset); - tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct tc6393xb *tc6393xb = gpiochip_get_data(chip); - unsigned long flags; - u8 doecr; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - - __tc6393xb_gpio_set(chip, offset, value); - - doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - doecr |= TC_GPIO_BIT(offset); - tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); - - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -} - -/* - * TC6393XB GPIOs as used on TOSA, are the only user of this chip. - * GPIOs 2, 5, 8 and 13 are not connected. - */ -#define TOSA_GPIO_TG_ON 0 -#define TOSA_GPIO_L_MUTE 1 -#define TOSA_GPIO_BL_C20MA 3 -#define TOSA_GPIO_CARD_VCC_ON 4 -#define TOSA_GPIO_CHARGE_OFF 6 -#define TOSA_GPIO_CHARGE_OFF_JC 7 -#define TOSA_GPIO_BAT0_V_ON 9 -#define TOSA_GPIO_BAT1_V_ON 10 -#define TOSA_GPIO_BU_CHRG_ON 11 -#define TOSA_GPIO_BAT_SW_ON 12 -#define TOSA_GPIO_BAT0_TH_ON 14 -#define TOSA_GPIO_BAT1_TH_ON 15 - - -GPIO_LOOKUP_SINGLE(tosa_lcd_gpio_lookup, "spi2.0", "tc6393xb", - TOSA_GPIO_TG_ON, "tg #pwr", GPIO_ACTIVE_HIGH); - -GPIO_LOOKUP_SINGLE(tosa_lcd_bl_gpio_lookup, "i2c-tos-bl", "tc6393xb", - TOSA_GPIO_BL_C20MA, "backlight", GPIO_ACTIVE_HIGH); - -GPIO_LOOKUP_SINGLE(tosa_audio_gpio_lookup, "tosa-audio", "tc6393xb", - TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH); - -static struct gpiod_lookup_table tosa_battery_gpio_lookup = { - .dev_id = "wm97xx-battery", - .table = { - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF, - "main charge off", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC, - "jacket charge off", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON, - "main battery", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON, - "jacket battery", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON, - "backup battery", GPIO_ACTIVE_HIGH), - /* BAT1 and BAT0 thermistors appear to be swapped */ - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON, - "main battery temp", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON, - "jacket battery temp", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON, - "battery switch", GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static struct gpiod_lookup_table *tc6393xb_gpio_lookups[] = { - &tosa_lcd_gpio_lookup, - &tosa_lcd_bl_gpio_lookup, - &tosa_audio_gpio_lookup, - &tosa_battery_gpio_lookup, -}; - -static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb) -{ - struct gpio_chip *gc = &tc6393xb->gpio; - struct device *dev = tc6393xb->dev; - int ret; - - gc->label = "tc6393xb"; - gc->base = -1; /* Dynamic allocation */ - gc->ngpio = 16; - gc->set = tc6393xb_gpio_set; - gc->get = tc6393xb_gpio_get; - gc->direction_input = tc6393xb_gpio_direction_input; - gc->direction_output = tc6393xb_gpio_direction_output; - - ret = devm_gpiochip_add_data(dev, gc, tc6393xb); - if (ret) - return dev_err_probe(dev, ret, "failed to add GPIO chip\n"); - - /* Register descriptor look-ups for consumers */ - gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups)); - - /* Request some of our own GPIOs */ - tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON", - GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); - if (IS_ERR(tc6393xb->vcc_on)) - return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on), - "failed to request VCC ON GPIO\n"); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -static void tc6393xb_irq(struct irq_desc *desc) -{ - struct tc6393xb *tc6393xb = irq_desc_get_handler_data(desc); - unsigned int isr; - unsigned int i, irq_base; - - irq_base = tc6393xb->irq_base; - - while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) & - ~tmio_ioread8(tc6393xb->scr + SCR_IMR))) - for (i = 0; i < TC6393XB_NR_IRQS; i++) { - if (isr & (1 << i)) - generic_handle_irq(irq_base + i); - } -} - -static void tc6393xb_irq_ack(struct irq_data *data) -{ -} - -static void tc6393xb_irq_mask(struct irq_data *data) -{ - struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); - imr |= 1 << (data->irq - tc6393xb->irq_base); - tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); -} - -static void tc6393xb_irq_unmask(struct irq_data *data) -{ - struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); - unsigned long flags; - u8 imr; - - raw_spin_lock_irqsave(&tc6393xb->lock, flags); - imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); - imr &= ~(1 << (data->irq - tc6393xb->irq_base)); - tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); - raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); -} - -static struct irq_chip tc6393xb_chip = { - .name = "tc6393xb", - .irq_ack = tc6393xb_irq_ack, - .irq_mask = tc6393xb_irq_mask, - .irq_unmask = tc6393xb_irq_unmask, -}; - -static void tc6393xb_attach_irq(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_base = tc6393xb->irq_base; - - for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq); - irq_set_chip_data(irq, tc6393xb); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - } - - irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_chained_handler_and_data(tc6393xb->irq, tc6393xb_irq, - tc6393xb); -} - -static void tc6393xb_detach_irq(struct platform_device *dev) -{ - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - unsigned int irq, irq_base; - - irq_set_chained_handler_and_data(tc6393xb->irq, NULL, NULL); - - irq_base = tc6393xb->irq_base; - - for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { - irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); - } -} - -/*--------------------------------------------------------------------------*/ - -static int tc6393xb_probe(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); - struct tc6393xb *tc6393xb; - struct resource *iomem, *rscr; - int ret; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) - return -EINVAL; - - tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); - if (!tc6393xb) { - ret = -ENOMEM; - goto err_kzalloc; - } - tc6393xb->dev = &dev->dev; - - raw_spin_lock_init(&tc6393xb->lock); - - platform_set_drvdata(dev, tc6393xb); - - ret = platform_get_irq(dev, 0); - if (ret >= 0) - tc6393xb->irq = ret; - else - goto err_noirq; - - tc6393xb->iomem = iomem; - tc6393xb->irq_base = tcpd->irq_base; - - tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI"); - if (IS_ERR(tc6393xb->clk)) { - ret = PTR_ERR(tc6393xb->clk); - goto err_clk_get; - } - - rscr = &tc6393xb->rscr; - rscr->name = "tc6393xb-core"; - rscr->start = iomem->start; - rscr->end = iomem->start + 0xff; - rscr->flags = IORESOURCE_MEM; - - ret = request_resource(iomem, rscr); - if (ret) - goto err_request_scr; - - tc6393xb->scr = ioremap(rscr->start, resource_size(rscr)); - if (!tc6393xb->scr) { - ret = -ENOMEM; - goto err_ioremap; - } - - ret = clk_prepare_enable(tc6393xb->clk); - if (ret) - goto err_clk_enable; - - ret = tcpd->enable(dev); - if (ret) - goto err_enable; - - iowrite8(0, tc6393xb->scr + SCR_FER); - iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); - iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48, - tc6393xb->scr + SCR_CCR); - iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | - SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | - BIT(15), tc6393xb->scr + SCR_MCR); - iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); - iowrite8(0, tc6393xb->scr + SCR_IRR); - iowrite8(0xbf, tc6393xb->scr + SCR_IMR); - - printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", - tmio_ioread8(tc6393xb->scr + SCR_REVID), - (unsigned long) iomem->start, tc6393xb->irq); - - ret = tc6393xb_register_gpio(tc6393xb); - if (ret) - goto err_gpio_add; - - tc6393xb_attach_irq(dev); - - tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data; - tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size = - sizeof(*tcpd->nand_data); - tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data; - tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); - - ret = mfd_add_devices(&dev->dev, dev->id, - tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), - iomem, tcpd->irq_base, NULL); - - if (!ret) - return 0; - - tc6393xb_detach_irq(dev); -err_gpio_add: - tcpd->disable(dev); -err_enable: - clk_disable_unprepare(tc6393xb->clk); -err_clk_enable: - iounmap(tc6393xb->scr); -err_ioremap: - release_resource(&tc6393xb->rscr); -err_request_scr: - clk_put(tc6393xb->clk); -err_noirq: -err_clk_get: - kfree(tc6393xb); -err_kzalloc: - return ret; -} - -static int tc6393xb_remove(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - - mfd_remove_devices(&dev->dev); - - tc6393xb_detach_irq(dev); - - tcpd->disable(dev); - clk_disable_unprepare(tc6393xb->clk); - iounmap(tc6393xb->scr); - release_resource(&tc6393xb->rscr); - clk_put(tc6393xb->clk); - kfree(tc6393xb); - - return 0; -} - -static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - int i, ret; - - tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); - tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); - - for (i = 0; i < 3; i++) { - tc6393xb->suspend_state.gpo_dsr[i] = - ioread8(tc6393xb->scr + SCR_GPO_DSR(i)); - tc6393xb->suspend_state.gpo_doecr[i] = - ioread8(tc6393xb->scr + SCR_GPO_DOECR(i)); - tc6393xb->suspend_state.gpi_bcr[i] = - ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); - } - ret = tcpd->suspend(dev); - clk_disable_unprepare(tc6393xb->clk); - - return ret; -} - -static int tc6393xb_resume(struct platform_device *dev) -{ - struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - int ret; - int i; - - ret = clk_prepare_enable(tc6393xb->clk); - if (ret) - return ret; - - ret = tcpd->resume(dev); - if (ret) - return ret; - - if (!tcpd->resume_restore) - return 0; - - iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); - iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); - iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); - iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | - SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | - BIT(15), tc6393xb->scr + SCR_MCR); - iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); - iowrite8(0, tc6393xb->scr + SCR_IRR); - iowrite8(0xbf, tc6393xb->scr + SCR_IMR); - - for (i = 0; i < 3; i++) { - iowrite8(tc6393xb->suspend_state.gpo_dsr[i], - tc6393xb->scr + SCR_GPO_DSR(i)); - iowrite8(tc6393xb->suspend_state.gpo_doecr[i], - tc6393xb->scr + SCR_GPO_DOECR(i)); - iowrite8(tc6393xb->suspend_state.gpi_bcr[i], - tc6393xb->scr + SCR_GPI_BCR(i)); - } - - return 0; -} - -static struct platform_driver tc6393xb_driver = { - .probe = tc6393xb_probe, - .remove = tc6393xb_remove, - .suspend = pm_sleep_ptr(tc6393xb_suspend), - .resume = pm_sleep_ptr(tc6393xb_resume), - - .driver = { - .name = "tc6393xb", - }, -}; - -static int __init tc6393xb_init(void) -{ - return platform_driver_register(&tc6393xb_driver); -} - -static void __exit tc6393xb_exit(void) -{ - platform_driver_unregister(&tc6393xb_driver); -} - -subsys_initcall(tc6393xb_init); -module_exit(tc6393xb_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); -MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); -MODULE_ALIAS("platform:tc6393xb"); - diff --git a/drivers/mfd/tmio_core.c b/drivers/mfd/tmio_core.c deleted file mode 100644 index 7ee873551482..000000000000 --- a/drivers/mfd/tmio_core.c +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright(c) 2009 Ian Molton - */ - -#include -#include - -#define CNF_CMD 0x04 -#define CNF_CTL_BASE 0x10 -#define CNF_INT_PIN 0x3d -#define CNF_STOP_CLK_CTL 0x40 -#define CNF_GCLK_CTL 0x41 -#define CNF_SD_CLK_MODE 0x42 -#define CNF_PIN_STATUS 0x44 -#define CNF_PWR_CTL_1 0x48 -#define CNF_PWR_CTL_2 0x49 -#define CNF_PWR_CTL_3 0x4a -#define CNF_CARD_DETECT_MODE 0x4c -#define CNF_SD_SLOT 0x50 -#define CNF_EXT_GCLK_CTL_1 0xf0 -#define CNF_EXT_GCLK_CTL_2 0xf1 -#define CNF_EXT_GCLK_CTL_3 0xf9 -#define CNF_SD_LED_EN_1 0xfa -#define CNF_SD_LED_EN_2 0xfe - -#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ - -int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base) -{ - /* Enable the MMC/SD Control registers */ - sd_config_write16(cnf, shift, CNF_CMD, SDCREN); - sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe); - - /* Disable SD power during suspend */ - sd_config_write8(cnf, shift, CNF_PWR_CTL_3, 0x01); - - /* The below is required but why? FIXME */ - sd_config_write8(cnf, shift, CNF_STOP_CLK_CTL, 0x1f); - - /* Power down SD bus */ - sd_config_write8(cnf, shift, CNF_PWR_CTL_2, 0x00); - - return 0; -} -EXPORT_SYMBOL(tmio_core_mmc_enable); - -int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base) -{ - - /* Enable the MMC/SD Control registers */ - sd_config_write16(cnf, shift, CNF_CMD, SDCREN); - sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe); - - return 0; -} -EXPORT_SYMBOL(tmio_core_mmc_resume); - -void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state) -{ - sd_config_write8(cnf, shift, CNF_PWR_CTL_2, state ? 0x02 : 0x00); -} -EXPORT_SYMBOL(tmio_core_mmc_pwr); - -void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state) -{ - sd_config_write8(cnf, shift, CNF_SD_CLK_MODE, state ? 1 : 0); -} -EXPORT_SYMBOL(tmio_core_mmc_clk_div); - diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h deleted file mode 100644 index 61e686dbaa74..000000000000 --- a/include/linux/mfd/asic3.h +++ /dev/null @@ -1,313 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * include/linux/mfd/asic3.h - * - * Compaq ASIC3 headers. - * - * Copyright 2001 Compaq Computer Corporation. - * Copyright 2007-2008 OpenedHand Ltd. - */ - -#ifndef __ASIC3_H__ -#define __ASIC3_H__ - -#include - -struct led_classdev; -struct asic3_led { - const char *name; - const char *default_trigger; - struct led_classdev *cdev; -}; - -struct asic3_platform_data { - u16 *gpio_config; - unsigned int gpio_config_num; - - unsigned int irq_base; - - unsigned int gpio_base; - - unsigned int clock_rate; - - struct asic3_led *leds; -}; - -#define ASIC3_NUM_GPIO_BANKS 4 -#define ASIC3_GPIOS_PER_BANK 16 -#define ASIC3_NUM_GPIOS 64 -#define ASIC3_NR_IRQS ASIC3_NUM_GPIOS + 6 - -#define ASIC3_IRQ_LED0 64 -#define ASIC3_IRQ_LED1 65 -#define ASIC3_IRQ_LED2 66 -#define ASIC3_IRQ_SPI 67 -#define ASIC3_IRQ_SMBUS 68 -#define ASIC3_IRQ_OWM 69 - -#define ASIC3_TO_GPIO(gpio) (NR_BUILTIN_GPIO + (gpio)) - -#define ASIC3_GPIO_BANK_A 0 -#define ASIC3_GPIO_BANK_B 1 -#define ASIC3_GPIO_BANK_C 2 -#define ASIC3_GPIO_BANK_D 3 - -#define ASIC3_GPIO(bank, gpio) \ - ((ASIC3_GPIOS_PER_BANK * ASIC3_GPIO_BANK_##bank) + (gpio)) -#define ASIC3_GPIO_bit(gpio) (1 << (gpio & 0xf)) -/* All offsets below are specified with this address bus shift */ -#define ASIC3_DEFAULT_ADDR_SHIFT 2 - -#define ASIC3_OFFSET(base, reg) (ASIC3_##base##_BASE + ASIC3_##base##_##reg) -#define ASIC3_GPIO_OFFSET(base, reg) \ - (ASIC3_GPIO_##base##_BASE + ASIC3_GPIO_##reg) - -#define ASIC3_GPIO_A_BASE 0x0000 -#define ASIC3_GPIO_B_BASE 0x0100 -#define ASIC3_GPIO_C_BASE 0x0200 -#define ASIC3_GPIO_D_BASE 0x0300 - -#define ASIC3_GPIO_TO_BANK(gpio) ((gpio) >> 4) -#define ASIC3_GPIO_TO_BIT(gpio) ((gpio) - \ - (ASIC3_GPIOS_PER_BANK * ((gpio) >> 4))) -#define ASIC3_GPIO_TO_MASK(gpio) (1 << ASIC3_GPIO_TO_BIT(gpio)) -#define ASIC3_GPIO_TO_BASE(gpio) (ASIC3_GPIO_A_BASE + (((gpio) >> 4) * 0x0100)) -#define ASIC3_BANK_TO_BASE(bank) (ASIC3_GPIO_A_BASE + ((bank) * 0x100)) - -#define ASIC3_GPIO_MASK 0x00 /* R/W 0:don't mask */ -#define ASIC3_GPIO_DIRECTION 0x04 /* R/W 0:input */ -#define ASIC3_GPIO_OUT 0x08 /* R/W 0:output low */ -#define ASIC3_GPIO_TRIGGER_TYPE 0x0c /* R/W 0:level */ -#define ASIC3_GPIO_EDGE_TRIGGER 0x10 /* R/W 0:falling */ -#define ASIC3_GPIO_LEVEL_TRIGGER 0x14 /* R/W 0:low level detect */ -#define ASIC3_GPIO_SLEEP_MASK 0x18 /* R/W 0:don't mask in sleep mode */ -#define ASIC3_GPIO_SLEEP_OUT 0x1c /* R/W level 0:low in sleep mode */ -#define ASIC3_GPIO_BAT_FAULT_OUT 0x20 /* R/W level 0:low in batt_fault */ -#define ASIC3_GPIO_INT_STATUS 0x24 /* R/W 0:none, 1:detect */ -#define ASIC3_GPIO_ALT_FUNCTION 0x28 /* R/W 1:LED register control */ -#define ASIC3_GPIO_SLEEP_CONF 0x2c /* - * R/W bit 1: autosleep - * 0: disable gposlpout in normal mode, - * enable gposlpout in sleep mode. - */ -#define ASIC3_GPIO_STATUS 0x30 /* R Pin status */ - -/* - * ASIC3 GPIO config - * - * Bits 0..6 gpio number - * Bits 7..13 Alternate function - * Bit 14 Direction - * Bit 15 Initial value - * - */ -#define ASIC3_CONFIG_GPIO_PIN(config) ((config) & 0x7f) -#define ASIC3_CONFIG_GPIO_ALT(config) (((config) & (0x7f << 7)) >> 7) -#define ASIC3_CONFIG_GPIO_DIR(config) ((config & (1 << 14)) >> 14) -#define ASIC3_CONFIG_GPIO_INIT(config) ((config & (1 << 15)) >> 15) -#define ASIC3_CONFIG_GPIO(gpio, alt, dir, init) (((gpio) & 0x7f) \ - | (((alt) & 0x7f) << 7) | (((dir) & 0x1) << 14) \ - | (((init) & 0x1) << 15)) -#define ASIC3_CONFIG_GPIO_DEFAULT(gpio, dir, init) \ - ASIC3_CONFIG_GPIO((gpio), 0, (dir), (init)) -#define ASIC3_CONFIG_GPIO_DEFAULT_OUT(gpio, init) \ - ASIC3_CONFIG_GPIO((gpio), 0, 1, (init)) - -/* - * Alternate functions - */ -#define ASIC3_GPIOA11_PWM0 ASIC3_CONFIG_GPIO(11, 1, 1, 0) -#define ASIC3_GPIOA12_PWM1 ASIC3_CONFIG_GPIO(12, 1, 1, 0) -#define ASIC3_GPIOA15_CONTROL_CX ASIC3_CONFIG_GPIO(15, 1, 1, 0) -#define ASIC3_GPIOC0_LED0 ASIC3_CONFIG_GPIO(32, 1, 0, 0) -#define ASIC3_GPIOC1_LED1 ASIC3_CONFIG_GPIO(33, 1, 0, 0) -#define ASIC3_GPIOC2_LED2 ASIC3_CONFIG_GPIO(34, 1, 0, 0) -#define ASIC3_GPIOC3_SPI_RXD ASIC3_CONFIG_GPIO(35, 1, 0, 0) -#define ASIC3_GPIOC4_CF_nCD ASIC3_CONFIG_GPIO(36, 1, 0, 0) -#define ASIC3_GPIOC4_SPI_TXD ASIC3_CONFIG_GPIO(36, 1, 1, 0) -#define ASIC3_GPIOC5_SPI_CLK ASIC3_CONFIG_GPIO(37, 1, 1, 0) -#define ASIC3_GPIOC5_nCIOW ASIC3_CONFIG_GPIO(37, 1, 1, 0) -#define ASIC3_GPIOC6_nCIOR ASIC3_CONFIG_GPIO(38, 1, 1, 0) -#define ASIC3_GPIOC7_nPCE_1 ASIC3_CONFIG_GPIO(39, 1, 0, 0) -#define ASIC3_GPIOC8_nPCE_2 ASIC3_CONFIG_GPIO(40, 1, 0, 0) -#define ASIC3_GPIOC9_nPOE ASIC3_CONFIG_GPIO(41, 1, 0, 0) -#define ASIC3_GPIOC10_nPWE ASIC3_CONFIG_GPIO(42, 1, 0, 0) -#define ASIC3_GPIOC11_PSKTSEL ASIC3_CONFIG_GPIO(43, 1, 0, 0) -#define ASIC3_GPIOC12_nPREG ASIC3_CONFIG_GPIO(44, 1, 0, 0) -#define ASIC3_GPIOC13_nPWAIT ASIC3_CONFIG_GPIO(45, 1, 1, 0) -#define ASIC3_GPIOC14_nPIOIS16 ASIC3_CONFIG_GPIO(46, 1, 1, 0) -#define ASIC3_GPIOC15_nPIOR ASIC3_CONFIG_GPIO(47, 1, 0, 0) -#define ASIC3_GPIOD4_CF_nCD ASIC3_CONFIG_GPIO(52, 1, 0, 0) -#define ASIC3_GPIOD11_nCIOIS16 ASIC3_CONFIG_GPIO(59, 1, 0, 0) -#define ASIC3_GPIOD12_nCWAIT ASIC3_CONFIG_GPIO(60, 1, 0, 0) -#define ASIC3_GPIOD15_nPIOW ASIC3_CONFIG_GPIO(63, 1, 0, 0) - - -#define ASIC3_SPI_Base 0x0400 -#define ASIC3_SPI_Control 0x0000 -#define ASIC3_SPI_TxData 0x0004 -#define ASIC3_SPI_RxData 0x0008 -#define ASIC3_SPI_Int 0x000c -#define ASIC3_SPI_Status 0x0010 - -#define SPI_CONTROL_SPR(clk) ((clk) & 0x0f) /* Clock rate */ - -#define ASIC3_PWM_0_Base 0x0500 -#define ASIC3_PWM_1_Base 0x0600 -#define ASIC3_PWM_TimeBase 0x0000 -#define ASIC3_PWM_PeriodTime 0x0004 -#define ASIC3_PWM_DutyTime 0x0008 - -#define PWM_TIMEBASE_VALUE(x) ((x)&0xf) /* Low 4 bits sets time base */ -#define PWM_TIMEBASE_ENABLE (1 << 4) /* Enable clock */ - -#define ASIC3_NUM_LEDS 3 -#define ASIC3_LED_0_Base 0x0700 -#define ASIC3_LED_1_Base 0x0800 -#define ASIC3_LED_2_Base 0x0900 -#define ASIC3_LED_TimeBase 0x0000 /* R/W 7 bits */ -#define ASIC3_LED_PeriodTime 0x0004 /* R/W 12 bits */ -#define ASIC3_LED_DutyTime 0x0008 /* R/W 12 bits */ -#define ASIC3_LED_AutoStopCount 0x000c /* R/W 16 bits */ - -/* LED TimeBase bits - match ASIC2 */ -#define LED_TBS 0x0f /* Low 4 bits sets time base, max = 13 */ - /* Note: max = 5 on hx4700 */ - /* 0: maximum time base */ - /* 1: maximum time base / 2 */ - /* n: maximum time base / 2^n */ - -#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */ -#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop 0:disable, 1:enable */ -#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */ - -#define ASIC3_CLOCK_BASE 0x0A00 -#define ASIC3_CLOCK_CDEX 0x00 -#define ASIC3_CLOCK_SEL 0x04 - -#define CLOCK_CDEX_SOURCE (1 << 0) /* 2 bits */ -#define CLOCK_CDEX_SOURCE0 (1 << 0) -#define CLOCK_CDEX_SOURCE1 (1 << 1) -#define CLOCK_CDEX_SPI (1 << 2) -#define CLOCK_CDEX_OWM (1 << 3) -#define CLOCK_CDEX_PWM0 (1 << 4) -#define CLOCK_CDEX_PWM1 (1 << 5) -#define CLOCK_CDEX_LED0 (1 << 6) -#define CLOCK_CDEX_LED1 (1 << 7) -#define CLOCK_CDEX_LED2 (1 << 8) - -/* Clocks settings: 1 for 24.576 MHz, 0 for 12.288Mhz */ -#define CLOCK_CDEX_SD_HOST (1 << 9) /* R/W: SD host clock source */ -#define CLOCK_CDEX_SD_BUS (1 << 10) /* R/W: SD bus clock source ctrl */ -#define CLOCK_CDEX_SMBUS (1 << 11) -#define CLOCK_CDEX_CONTROL_CX (1 << 12) - -#define CLOCK_CDEX_EX0 (1 << 13) /* R/W: 32.768 kHz crystal */ -#define CLOCK_CDEX_EX1 (1 << 14) /* R/W: 24.576 MHz crystal */ - -#define CLOCK_SEL_SD_HCLK_SEL (1 << 0) /* R/W: SDIO host clock select */ -#define CLOCK_SEL_SD_BCLK_SEL (1 << 1) /* R/W: SDIO bus clock select */ - -/* R/W: INT clock source control (32.768 kHz) */ -#define CLOCK_SEL_CX (1 << 2) - - -#define ASIC3_INTR_BASE 0x0B00 - -#define ASIC3_INTR_INT_MASK 0x00 /* Interrupt mask control */ -#define ASIC3_INTR_P_INT_STAT 0x04 /* Peripheral interrupt status */ -#define ASIC3_INTR_INT_CPS 0x08 /* Interrupt timer clock pre-scale */ -#define ASIC3_INTR_INT_TBS 0x0c /* Interrupt timer set */ - -#define ASIC3_INTMASK_GINTMASK (1 << 0) /* Global INTs mask 1:enable */ -#define ASIC3_INTMASK_GINTEL (1 << 1) /* 1: rising edge, 0: hi level */ -#define ASIC3_INTMASK_MASK0 (1 << 2) -#define ASIC3_INTMASK_MASK1 (1 << 3) -#define ASIC3_INTMASK_MASK2 (1 << 4) -#define ASIC3_INTMASK_MASK3 (1 << 5) -#define ASIC3_INTMASK_MASK4 (1 << 6) -#define ASIC3_INTMASK_MASK5 (1 << 7) - -#define ASIC3_INTR_PERIPHERAL_A (1 << 0) -#define ASIC3_INTR_PERIPHERAL_B (1 << 1) -#define ASIC3_INTR_PERIPHERAL_C (1 << 2) -#define ASIC3_INTR_PERIPHERAL_D (1 << 3) -#define ASIC3_INTR_LED0 (1 << 4) -#define ASIC3_INTR_LED1 (1 << 5) -#define ASIC3_INTR_LED2 (1 << 6) -#define ASIC3_INTR_SPI (1 << 7) -#define ASIC3_INTR_SMBUS (1 << 8) -#define ASIC3_INTR_OWM (1 << 9) - -#define ASIC3_INTR_CPS(x) ((x)&0x0f) /* 4 bits, max 14 */ -#define ASIC3_INTR_CPS_SET (1 << 4) /* Time base enable */ - - -/* Basic control of the SD ASIC */ -#define ASIC3_SDHWCTRL_BASE 0x0E00 -#define ASIC3_SDHWCTRL_SDCONF 0x00 - -#define ASIC3_SDHWCTRL_SUSPEND (1 << 0) /* 1=suspend all SD operations */ -#define ASIC3_SDHWCTRL_CLKSEL (1 << 1) /* 1=SDICK, 0=HCLK */ -#define ASIC3_SDHWCTRL_PCLR (1 << 2) /* All registers of SDIO cleared */ -#define ASIC3_SDHWCTRL_LEVCD (1 << 3) /* SD card detection: 0:low */ - -/* SD card write protection: 0=high */ -#define ASIC3_SDHWCTRL_LEVWP (1 << 4) -#define ASIC3_SDHWCTRL_SDLED (1 << 5) /* SD card LED signal 0=disable */ - -/* SD card power supply ctrl 1=enable */ -#define ASIC3_SDHWCTRL_SDPWR (1 << 6) - -#define ASIC3_EXTCF_BASE 0x1100 - -#define ASIC3_EXTCF_SELECT 0x00 -#define ASIC3_EXTCF_RESET 0x04 - -#define ASIC3_EXTCF_SMOD0 (1 << 0) /* slot number of mode 0 */ -#define ASIC3_EXTCF_SMOD1 (1 << 1) /* slot number of mode 1 */ -#define ASIC3_EXTCF_SMOD2 (1 << 2) /* slot number of mode 2 */ -#define ASIC3_EXTCF_OWM_EN (1 << 4) /* enable onewire module */ -#define ASIC3_EXTCF_OWM_SMB (1 << 5) /* OWM bus selection */ -#define ASIC3_EXTCF_OWM_RESET (1 << 6) /* ?? used by OWM and CF */ -#define ASIC3_EXTCF_CF0_SLEEP_MODE (1 << 7) /* CF0 sleep state */ -#define ASIC3_EXTCF_CF1_SLEEP_MODE (1 << 8) /* CF1 sleep state */ -#define ASIC3_EXTCF_CF0_PWAIT_EN (1 << 10) /* CF0 PWAIT_n control */ -#define ASIC3_EXTCF_CF1_PWAIT_EN (1 << 11) /* CF1 PWAIT_n control */ -#define ASIC3_EXTCF_CF0_BUF_EN (1 << 12) /* CF0 buffer control */ -#define ASIC3_EXTCF_CF1_BUF_EN (1 << 13) /* CF1 buffer control */ -#define ASIC3_EXTCF_SD_MEM_ENABLE (1 << 14) -#define ASIC3_EXTCF_CF_SLEEP (1 << 15) /* CF sleep mode control */ - -/********************************************* - * The Onewire interface (DS1WM) is handled - * by the ds1wm driver. - * - *********************************************/ - -#define ASIC3_OWM_BASE 0xC00 - -/***************************************************************************** - * The SD configuration registers are at a completely different location - * in memory. They are divided into three sets of registers: - * - * SD_CONFIG Core configuration register - * SD_CTRL Control registers for SD operations - * SDIO_CTRL Control registers for SDIO operations - * - *****************************************************************************/ -#define ASIC3_SD_CONFIG_BASE 0x0400 /* Assumes 32 bit addressing */ -#define ASIC3_SD_CONFIG_SIZE 0x0200 /* Assumes 32 bit addressing */ -#define ASIC3_SD_CTRL_BASE 0x1000 -#define ASIC3_SDIO_CTRL_BASE 0x1200 - -#define ASIC3_MAP_SIZE_32BIT 0x2000 -#define ASIC3_MAP_SIZE_16BIT 0x1000 - -/* Functions needed by leds-asic3 */ - -struct asic3; -extern void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 val); -extern u32 asic3_read_register(struct asic3 *asic, unsigned int reg); - -#endif /* __ASIC3_H__ */ diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h deleted file mode 100644 index ae3e7a5c5219..000000000000 --- a/include/linux/mfd/t7l66xb.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * This file contains the definitions for the T7L66XB - * - * (C) Copyright 2005 Ian Molton - */ -#ifndef MFD_T7L66XB_H -#define MFD_T7L66XB_H - -#include -#include - -struct t7l66xb_platform_data { - int (*enable)(struct platform_device *dev); - int (*suspend)(struct platform_device *dev); - int (*resume)(struct platform_device *dev); - - int irq_base; /* The base for subdevice irqs */ - - struct tmio_nand_data *nand_data; -}; - - -#define IRQ_T7L66XB_MMC (1) -#define IRQ_T7L66XB_NAND (3) - -#define T7L66XB_NR_IRQS 8 - -#endif diff --git a/include/linux/mfd/tc6387xb.h b/include/linux/mfd/tc6387xb.h deleted file mode 100644 index aacf1dcc86b9..000000000000 --- a/include/linux/mfd/tc6387xb.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file contains the definitions for the TC6387XB - * - * (C) Copyright 2005 Ian Molton - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - */ -#ifndef MFD_TC6387XB_H -#define MFD_TC6387XB_H - -struct tc6387xb_platform_data { - int (*enable)(struct platform_device *dev); - int (*suspend)(struct platform_device *dev); - int (*resume)(struct platform_device *dev); -}; - -#endif diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h deleted file mode 100644 index d17807f2d0c9..000000000000 --- a/include/linux/mfd/tc6393xb.h +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Toshiba TC6393XB SoC support - * - * Copyright(c) 2005-2006 Chris Humbert - * Copyright(c) 2005 Dirk Opfer - * Copyright(c) 2005 Ian Molton - * Copyright(c) 2007 Dmitry Baryshkov - * - * Based on code written by Sharp/Lineo for 2.4 kernels - * Based on locomo.c - */ - -#ifndef MFD_TC6393XB_H -#define MFD_TC6393XB_H - -#include - -/* Also one should provide the CK3P6MI clock */ -struct tc6393xb_platform_data { - u16 scr_pll2cr; /* PLL2 Control */ - u16 scr_gper; /* GP Enable */ - - int (*enable)(struct platform_device *dev); - void (*disable)(struct platform_device *dev); - int (*suspend)(struct platform_device *dev); - int (*resume)(struct platform_device *dev); - - int irq_base; /* base for subdevice irqs */ - - struct tmio_nand_data *nand_data; - struct tmio_fb_data *fb_data; - - unsigned resume_restore : 1; /* make special actions - to preserve the state - on suspend/resume */ -}; - -extern int tc6393xb_lcd_mode(struct platform_device *fb, - const struct fb_videomode *mode); -extern int tc6393xb_lcd_set_power(struct platform_device *fb, bool on); - -/* - * Relative to irq_base - */ -#define IRQ_TC6393_NAND 0 -#define IRQ_TC6393_MMC 1 -#define IRQ_TC6393_OHCI 2 -#define IRQ_TC6393_FB 4 - -#define TC6393XB_NR_IRQS 8 - -#endif diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index e8bf90281ba0..eace8ea6cda0 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -84,11 +84,6 @@ /* Some controllers have a CBSY bit */ #define TMIO_MMC_HAVE_CBSY BIT(11) -int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base); -int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base); -void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state); -void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state); - struct dma_chan; /* -- cgit v1.2.3