diff options
32 files changed, 1640 insertions, 67 deletions
diff --git a/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt b/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt new file mode 100644 index 000000000000..9bb5f57e2066 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt @@ -0,0 +1,136 @@ +* Device tree bindings for Atmel EBI + +The External Bus Interface (EBI) controller is a bus where you can connect +asynchronous (NAND, NOR, SRAM, ....) and synchronous memories (SDR/DDR SDRAMs). +The EBI provides a glue-less interface to asynchronous memories through the SMC +(Static Memory Controller). + +Required properties: + +- compatible: "atmel,at91sam9260-ebi" + "atmel,at91sam9261-ebi" + "atmel,at91sam9263-ebi0" + "atmel,at91sam9263-ebi1" + "atmel,at91sam9rl-ebi" + "atmel,at91sam9g45-ebi" + "atmel,at91sam9x5-ebi" + "atmel,sama5d3-ebi" + +- reg: Contains offset/length value for EBI memory mapping. + This property might contain several entries if the EBI + memory range is not contiguous + +- #address-cells: Must be 2. + The first cell encodes the CS. + The second cell encode the offset into the CS memory + range. + +- #size-cells: Must be set to 1. + +- ranges: Encodes CS to memory region association. + +- clocks: Clock feeding the EBI controller. + See clock-bindings.txt + +Children device nodes are representing device connected to the EBI bus. + +Required device node properties: + +- reg: Contains the chip-select id, the offset and the length + of the memory region requested by the device. + +EBI bus configuration will be defined directly in the device subnode. + +Optional EBI/SMC properties: + +- atmel,smc-bus-width: width of the asynchronous device's data bus + 8, 16 or 32. + Default to 8 when undefined. + +- atmel,smc-byte-access-type "write" or "select" (see Atmel datasheet). + Default to "select" when undefined. + +- atmel,smc-read-mode "nrd" or "ncs". + Default to "ncs" when undefined. + +- atmel,smc-write-mode "nwe" or "ncs". + Default to "ncs" when undefined. + +- atmel,smc-exnw-mode "disabled", "frozen" or "ready". + Default to "disabled" when undefined. + +- atmel,smc-page-mode enable page mode if present. The provided value + defines the page size (supported values: 4, 8, + 16 and 32). + +- atmel,smc-tdf-mode: "normal" or "optimized". When set to + "optimized" the data float time is optimized + depending on the next device being accessed + (next device setup time is subtracted to the + current device data float time). + Default to "normal" when undefined. + +If at least one atmel,smc- property is defined the following SMC timing +properties become mandatory. In the other hand, if none of the atmel,smc- +properties are specified, we assume that the EBI bus configuration will be +handled by the sub-device driver, and none of those properties should be +defined. + +All the timings are expressed in nanoseconds (see Atmel datasheet for a full +description). + +- atmel,smc-ncs-rd-setup-ns +- atmel,smc-nrd-setup-ns +- atmel,smc-ncs-wr-setup-ns +- atmel,smc-nwe-setup-ns +- atmel,smc-ncs-rd-pulse-ns +- atmel,smc-nrd-pulse-ns +- atmel,smc-ncs-wr-pulse-ns +- atmel,smc-nwe-pulse-ns +- atmel,smc-nwe-cycle-ns +- atmel,smc-nrd-cycle-ns +- atmel,smc-tdf-ns + +Example: + + ebi: ebi@10000000 { + compatible = "atmel,sama5d3-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&hsmc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x10000000 + 0x40000000 0x30000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x40000000 0x10000000 + 0x2 0x0 0x50000000 0x10000000 + 0x3 0x0 0x60000000 0x10000000>; + clocks = <&mck>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ebi_addr>; + + nor: flash@0,0 { + compatible = "cfi-flash"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0 0x0 0x1000000>; + bank-width = <2>; + + atmel,smc-read-mode = "nrd"; + atmel,smc-write-mode = "nwe"; + atmel,smc-bus-width = <16>; + atmel,smc-ncs-rd-setup-ns = <0>; + atmel,smc-ncs-wr-setup-ns = <0>; + atmel,smc-nwe-setup-ns = <8>; + atmel,smc-nrd-setup-ns = <16>; + atmel,smc-ncs-rd-pulse-ns = <84>; + atmel,smc-ncs-wr-pulse-ns = <84>; + atmel,smc-nrd-pulse-ns = <76>; + atmel,smc-nwe-pulse-ns = <76>; + atmel,smc-nrd-cycle-ns = <107>; + atmel,smc-nwe-cycle-ns = <84>; + atmel,smc-tdf-ns = <16>; + }; + }; + diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index b74e4d4785ab..0725fb37a973 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -14,6 +14,7 @@ Required properties: - "renesas,r8a7793-sysc" (R-Car M2-N) - "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7795-sysc" (R-Car H3) + - "renesas,r8a7796-sysc" (R-Car M3-W) - reg: Address start and address range for the device. - #power-domain-cells: Must be 1. diff --git a/Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt new file mode 100644 index 000000000000..e746b631793a --- /dev/null +++ b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt @@ -0,0 +1,18 @@ +Amlogic Meson SoC Reset Controller +======================================= + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "amlogic,meson8b-reset" or "amlogic,meson-gxbb-reset" +- reg: should contain the register address base +- #reset-cells: 1, see below + +example: + +reset: reset-controller { + compatible = "amlogic,meson-gxbb-reset"; + reg = <0x0 0x04404 0x0 0x20>; + #reset-cells = <1>; +}; diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index c63eea0c1c8c..f5e522342ee5 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -352,6 +352,10 @@ REGULATOR devm_regulator_put() devm_regulator_register() +RESET + devm_reset_control_get() + devm_reset_controller_register() + SLAVE DMA ENGINE devm_acpi_dma_controller_register() diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index e65aa7d11b20..58b334f5f1d6 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -19,6 +19,7 @@ menuconfig ARCH_EXYNOS select EXYNOS_THERMAL select EXYNOS_PMU select EXYNOS_SROM + select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS select HAVE_ARM_SCU if SMP select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index b91b38204e2a..9ea6c54645ad 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_ARCH_EXYNOS) += exynos.o exynos-smc.o firmware.o obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o obj-$(CONFIG_PM_SLEEP) += suspend.o -obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 81ddb17575a9..133712346911 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -25,6 +25,17 @@ config ATMEL_SDRAMC Starting with the at91sam9g45, this controller supports SDR, DDR and LP-DDR memories. +config ATMEL_EBI + bool "Atmel EBI driver" + default y + depends on ARCH_AT91 && OF + select MFD_SYSCON + help + Driver for Atmel EBI controller. + Used to configure the EBI (external bus interface) when the device- + tree is used. This bus supports NANDs, external ethernet controller, + SRAMs, ATA devices, etc. + config TI_AEMIF tristate "Texas Instruments AEMIF driver" depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index cb0b7a1df11a..b20ae38b5bfb 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_OF) += of_memory.o endif obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o +obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o obj-$(CONFIG_TI_AEMIF) += ti-aemif.o obj-$(CONFIG_TI_EMIF) += emif.o obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c new file mode 100644 index 000000000000..17d9d3f60f20 --- /dev/null +++ b/drivers/memory/atmel-ebi.c @@ -0,0 +1,771 @@ +/* + * EBI driver for Atmel chips + * inspired by the fsl weim bus driver + * + * Copyright (C) 2013 Jean-Jacques Hiblot <[email protected]> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/atmel-matrix.h> +#include <linux/mfd/syscon/atmel-smc.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/regmap.h> + +struct at91sam9_smc_timings { + u32 ncs_rd_setup_ns; + u32 nrd_setup_ns; + u32 ncs_wr_setup_ns; + u32 nwe_setup_ns; + u32 ncs_rd_pulse_ns; + u32 nrd_pulse_ns; + u32 ncs_wr_pulse_ns; + u32 nwe_pulse_ns; + u32 nrd_cycle_ns; + u32 nwe_cycle_ns; + u32 tdf_ns; +}; + +struct at91sam9_smc_generic_fields { + struct regmap_field *setup; + struct regmap_field *pulse; + struct regmap_field *cycle; + struct regmap_field *mode; +}; + +struct at91sam9_ebi_dev_config { + struct at91sam9_smc_timings timings; + u32 mode; +}; + +struct at91_ebi_dev_config { + int cs; + union { + struct at91sam9_ebi_dev_config sam9; + }; +}; + +struct at91_ebi; + +struct at91_ebi_dev { + struct list_head node; + struct at91_ebi *ebi; + u32 mode; + int numcs; + struct at91_ebi_dev_config configs[]; +}; + +struct at91_ebi_caps { + unsigned int available_cs; + const struct reg_field *ebi_csa; + void (*get_config)(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf); + int (*xlate_config)(struct at91_ebi_dev *ebid, + struct device_node *configs_np, + struct at91_ebi_dev_config *conf); + int (*apply_config)(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf); + int (*init)(struct at91_ebi *ebi); +}; + +struct at91_ebi { + struct clk *clk; + struct regmap *smc; + struct regmap *matrix; + + struct regmap_field *ebi_csa; + + struct device *dev; + const struct at91_ebi_caps *caps; + struct list_head devs; + union { + struct at91sam9_smc_generic_fields sam9; + }; +}; + +static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf) +{ + struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9; + unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); + struct at91sam9_ebi_dev_config *config = &conf->sam9; + struct at91sam9_smc_timings *timings = &config->timings; + unsigned int val; + + regmap_fields_read(fields->mode, conf->cs, &val); + config->mode = val & ~AT91_SMC_TDF; + + val = (val & AT91_SMC_TDF) >> 16; + timings->tdf_ns = clk_rate * val; + + regmap_fields_read(fields->setup, conf->cs, &val); + timings->ncs_rd_setup_ns = (val >> 24) & 0x1f; + timings->ncs_rd_setup_ns += ((val >> 29) & 0x1) * 128; + timings->ncs_rd_setup_ns *= clk_rate; + timings->nrd_setup_ns = (val >> 16) & 0x1f; + timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128; + timings->nrd_setup_ns *= clk_rate; + timings->ncs_wr_setup_ns = (val >> 8) & 0x1f; + timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128; + timings->ncs_wr_setup_ns *= clk_rate; + timings->nwe_setup_ns = val & 0x1f; + timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128; + timings->nwe_setup_ns *= clk_rate; + + regmap_fields_read(fields->pulse, conf->cs, &val); + timings->ncs_rd_pulse_ns = (val >> 24) & 0x3f; + timings->ncs_rd_pulse_ns += ((val >> 30) & 0x1) * 256; + timings->ncs_rd_pulse_ns *= clk_rate; + timings->nrd_pulse_ns = (val >> 16) & 0x3f; + timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256; + timings->nrd_pulse_ns *= clk_rate; + timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f; + timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256; + timings->ncs_wr_pulse_ns *= clk_rate; + timings->nwe_pulse_ns = val & 0x3f; + timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256; + timings->nwe_pulse_ns *= clk_rate; + + regmap_fields_read(fields->cycle, conf->cs, &val); + timings->nrd_cycle_ns = (val >> 16) & 0x7f; + timings->nrd_cycle_ns += ((val >> 23) & 0x3) * 256; + timings->nrd_cycle_ns *= clk_rate; + timings->nwe_cycle_ns = val & 0x7f; + timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256; + timings->nwe_cycle_ns *= clk_rate; +} + +static int at91_xlate_timing(struct device_node *np, const char *prop, + u32 *val, bool *required) +{ + if (!of_property_read_u32(np, prop, val)) { + *required = true; + return 0; + } + + if (*required) + return -EINVAL; + + return 0; +} + +static int at91sam9_smc_xslate_timings(struct at91_ebi_dev *ebid, + struct device_node *np, + struct at91sam9_smc_timings *timings, + bool *required) +{ + int ret; + + ret = at91_xlate_timing(np, "atmel,smc-ncs-rd-setup-ns", + &timings->ncs_rd_setup_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-nrd-setup-ns", + &timings->nrd_setup_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-ncs-wr-setup-ns", + &timings->ncs_wr_setup_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-nwe-setup-ns", + &timings->nwe_setup_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-ncs-rd-pulse-ns", + &timings->ncs_rd_pulse_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-nrd-pulse-ns", + &timings->nrd_pulse_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-ncs-wr-pulse-ns", + &timings->ncs_wr_pulse_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-nwe-pulse-ns", + &timings->nwe_pulse_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-nwe-cycle-ns", + &timings->nwe_cycle_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-nrd-cycle-ns", + &timings->nrd_cycle_ns, required); + if (ret) + goto out; + + ret = at91_xlate_timing(np, "atmel,smc-tdf-ns", + &timings->tdf_ns, required); + +out: + if (ret) + dev_err(ebid->ebi->dev, + "missing or invalid timings definition in %s", + np->full_name); + + return ret; +} + +static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, + struct device_node *np, + struct at91_ebi_dev_config *conf) +{ + struct at91sam9_ebi_dev_config *config = &conf->sam9; + bool required = false; + const char *tmp_str; + u32 tmp; + int ret; + + ret = of_property_read_u32(np, "atmel,smc-bus-width", &tmp); + if (!ret) { + switch (tmp) { + case 8: + config->mode |= AT91_SMC_DBW_8; + break; + + case 16: + config->mode |= AT91_SMC_DBW_16; + break; + + case 32: + config->mode |= AT91_SMC_DBW_32; + break; + + default: + return -EINVAL; + } + + required = true; + } + + if (of_property_read_bool(np, "atmel,smc-tdf-optimized")) { + config->mode |= AT91_SMC_TDFMODE_OPTIMIZED; + required = true; + } + + tmp_str = NULL; + of_property_read_string(np, "atmel,smc-byte-access-type", &tmp_str); + if (tmp_str && !strcmp(tmp_str, "write")) { + config->mode |= AT91_SMC_BAT_WRITE; + required = true; + } + + tmp_str = NULL; + of_property_read_string(np, "atmel,smc-read-mode", &tmp_str); + if (tmp_str && !strcmp(tmp_str, "nrd")) { + config->mode |= AT91_SMC_READMODE_NRD; + required = true; + } + + tmp_str = NULL; + of_property_read_string(np, "atmel,smc-write-mode", &tmp_str); + if (tmp_str && !strcmp(tmp_str, "nwe")) { + config->mode |= AT91_SMC_WRITEMODE_NWE; + required = true; + } + + tmp_str = NULL; + of_property_read_string(np, "atmel,smc-exnw-mode", &tmp_str); + if (tmp_str) { + if (!strcmp(tmp_str, "frozen")) + config->mode |= AT91_SMC_EXNWMODE_FROZEN; + else if (!strcmp(tmp_str, "ready")) + config->mode |= AT91_SMC_EXNWMODE_READY; + else if (strcmp(tmp_str, "disabled")) + return -EINVAL; + + required = true; + } + + ret = of_property_read_u32(np, "atmel,smc-page-mode", &tmp); + if (!ret) { + switch (tmp) { + case 4: + config->mode |= AT91_SMC_PS_4; + break; + + case 8: + config->mode |= AT91_SMC_PS_8; + break; + + case 16: + config->mode |= AT91_SMC_PS_16; + break; + + case 32: + config->mode |= AT91_SMC_PS_32; + break; + + default: + return -EINVAL; + } + + config->mode |= AT91_SMC_PMEN; + required = true; + } + + ret = at91sam9_smc_xslate_timings(ebid, np, &config->timings, + &required); + if (ret) + return ret; + + return required; +} + +static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf) +{ + unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); + struct at91sam9_ebi_dev_config *config = &conf->sam9; + struct at91sam9_smc_timings *timings = &config->timings; + struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9; + u32 coded_val; + u32 val; + + coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, + timings->ncs_rd_setup_ns); + val = AT91SAM9_SMC_NCS_NRDSETUP(coded_val); + coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, + timings->nrd_setup_ns); + val |= AT91SAM9_SMC_NRDSETUP(coded_val); + coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, + timings->ncs_wr_setup_ns); + val |= AT91SAM9_SMC_NCS_WRSETUP(coded_val); + coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, + timings->nwe_setup_ns); + val |= AT91SAM9_SMC_NWESETUP(coded_val); + regmap_fields_write(fields->setup, conf->cs, val); + + coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, + timings->ncs_rd_pulse_ns); + val = AT91SAM9_SMC_NCS_NRDPULSE(coded_val); + coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, + timings->nrd_pulse_ns); + val |= AT91SAM9_SMC_NRDPULSE(coded_val); + coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, + timings->ncs_wr_pulse_ns); + val |= AT91SAM9_SMC_NCS_WRPULSE(coded_val); + coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, + timings->nwe_pulse_ns); + val |= AT91SAM9_SMC_NWEPULSE(coded_val); + regmap_fields_write(fields->pulse, conf->cs, val); + + coded_val = at91sam9_smc_cycle_ns_to_cycles(clk_rate, + timings->nrd_cycle_ns); + val = AT91SAM9_SMC_NRDCYCLE(coded_val); + coded_val = at91sam9_smc_cycle_ns_to_cycles(clk_rate, + timings->nwe_cycle_ns); + val |= AT91SAM9_SMC_NWECYCLE(coded_val); + regmap_fields_write(fields->cycle, conf->cs, val); + + val = DIV_ROUND_UP(timings->tdf_ns, clk_rate); + if (val > AT91_SMC_TDF_MAX) + val = AT91_SMC_TDF_MAX; + regmap_fields_write(fields->mode, conf->cs, + config->mode | AT91_SMC_TDF_(val)); + + return 0; +} + +static int at91sam9_ebi_init(struct at91_ebi *ebi) +{ + struct at91sam9_smc_generic_fields *fields = &ebi->sam9; + struct reg_field field = REG_FIELD(0, 0, 31); + + field.id_size = fls(ebi->caps->available_cs); + field.id_offset = AT91SAM9_SMC_GENERIC_BLK_SZ; + + field.reg = AT91SAM9_SMC_SETUP(AT91SAM9_SMC_GENERIC); + fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->setup)) + return PTR_ERR(fields->setup); + + field.reg = AT91SAM9_SMC_PULSE(AT91SAM9_SMC_GENERIC); + fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->pulse)) + return PTR_ERR(fields->pulse); + + field.reg = AT91SAM9_SMC_CYCLE(AT91SAM9_SMC_GENERIC); + fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->cycle)) + return PTR_ERR(fields->cycle); + + field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC); + fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->mode)) + return PTR_ERR(fields->mode); + + return 0; +} + +static int sama5d3_ebi_init(struct at91_ebi *ebi) +{ + struct at91sam9_smc_generic_fields *fields = &ebi->sam9; + struct reg_field field = REG_FIELD(0, 0, 31); + + field.id_size = fls(ebi->caps->available_cs); + field.id_offset = SAMA5_SMC_GENERIC_BLK_SZ; + + field.reg = AT91SAM9_SMC_SETUP(SAMA5_SMC_GENERIC); + fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->setup)) + return PTR_ERR(fields->setup); + + field.reg = AT91SAM9_SMC_PULSE(SAMA5_SMC_GENERIC); + fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->pulse)) + return PTR_ERR(fields->pulse); + + field.reg = AT91SAM9_SMC_CYCLE(SAMA5_SMC_GENERIC); + fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->cycle)) + return PTR_ERR(fields->cycle); + + field.reg = SAMA5_SMC_MODE(SAMA5_SMC_GENERIC); + fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); + if (IS_ERR(fields->mode)) + return PTR_ERR(fields->mode); + + return 0; +} + +static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, + int reg_cells) +{ + const struct at91_ebi_caps *caps = ebi->caps; + struct at91_ebi_dev_config conf = { }; + struct device *dev = ebi->dev; + struct at91_ebi_dev *ebid; + int ret, numcs = 0, i; + bool apply = false; + + numcs = of_property_count_elems_of_size(np, "reg", + reg_cells * sizeof(u32)); + if (numcs <= 0) { + dev_err(dev, "invalid reg property in %s\n", np->full_name); + return -EINVAL; + } + + ebid = devm_kzalloc(ebi->dev, + sizeof(*ebid) + (numcs * sizeof(*ebid->configs)), + GFP_KERNEL); + if (!ebid) + return -ENOMEM; + + ebid->ebi = ebi; + + ret = caps->xlate_config(ebid, np, &conf); + if (ret < 0) + return ret; + else if (ret) + apply = true; + + for (i = 0; i < numcs; i++) { + u32 cs; + + ret = of_property_read_u32_index(np, "reg", i * reg_cells, + &cs); + if (ret) + return ret; + + if (cs > AT91_MATRIX_EBI_NUM_CS || + !(ebi->caps->available_cs & BIT(cs))) { + dev_err(dev, "invalid reg property in %s\n", + np->full_name); + return -EINVAL; + } + + ebid->configs[i].cs = cs; + + if (apply) { + conf.cs = cs; + ret = caps->apply_config(ebid, &conf); + if (ret) + return ret; + } + + caps->get_config(ebid, &ebid->configs[i]); + + /* + * Attach the EBI device to the generic SMC logic if at least + * one "atmel,smc-" property is present. + */ + if (ebi->ebi_csa && ret) + regmap_field_update_bits(ebi->ebi_csa, + BIT(cs), 0); + } + + list_add_tail(&ebid->node, &ebi->devs); + + return 0; +} + +static const struct reg_field at91sam9260_ebi_csa = + REG_FIELD(AT91SAM9260_MATRIX_EBICSA, 0, + AT91_MATRIX_EBI_NUM_CS - 1); + +static const struct at91_ebi_caps at91sam9260_ebi_caps = { + .available_cs = 0xff, + .ebi_csa = &at91sam9260_ebi_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct reg_field at91sam9261_ebi_csa = + REG_FIELD(AT91SAM9261_MATRIX_EBICSA, 0, + AT91_MATRIX_EBI_NUM_CS - 1); + +static const struct at91_ebi_caps at91sam9261_ebi_caps = { + .available_cs = 0xff, + .ebi_csa = &at91sam9261_ebi_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct reg_field at91sam9263_ebi0_csa = + REG_FIELD(AT91SAM9263_MATRIX_EBI0CSA, 0, + AT91_MATRIX_EBI_NUM_CS - 1); + +static const struct at91_ebi_caps at91sam9263_ebi0_caps = { + .available_cs = 0x3f, + .ebi_csa = &at91sam9263_ebi0_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct reg_field at91sam9263_ebi1_csa = + REG_FIELD(AT91SAM9263_MATRIX_EBI1CSA, 0, + AT91_MATRIX_EBI_NUM_CS - 1); + +static const struct at91_ebi_caps at91sam9263_ebi1_caps = { + .available_cs = 0x7, + .ebi_csa = &at91sam9263_ebi1_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct reg_field at91sam9rl_ebi_csa = + REG_FIELD(AT91SAM9RL_MATRIX_EBICSA, 0, + AT91_MATRIX_EBI_NUM_CS - 1); + +static const struct at91_ebi_caps at91sam9rl_ebi_caps = { + .available_cs = 0x3f, + .ebi_csa = &at91sam9rl_ebi_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct reg_field at91sam9g45_ebi_csa = + REG_FIELD(AT91SAM9G45_MATRIX_EBICSA, 0, + AT91_MATRIX_EBI_NUM_CS - 1); + +static const struct at91_ebi_caps at91sam9g45_ebi_caps = { + .available_cs = 0x3f, + .ebi_csa = &at91sam9g45_ebi_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct at91_ebi_caps at91sam9x5_ebi_caps = { + .available_cs = 0x3f, + .ebi_csa = &at91sam9263_ebi0_csa, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = at91sam9_ebi_init, +}; + +static const struct at91_ebi_caps sama5d3_ebi_caps = { + .available_cs = 0xf, + .get_config = at91sam9_ebi_get_config, + .xlate_config = at91sam9_ebi_xslate_config, + .apply_config = at91sam9_ebi_apply_config, + .init = sama5d3_ebi_init, +}; + +static const struct of_device_id at91_ebi_id_table[] = { + { + .compatible = "atmel,at91sam9260-ebi", + .data = &at91sam9260_ebi_caps, + }, + { + .compatible = "atmel,at91sam9261-ebi", + .data = &at91sam9261_ebi_caps, + }, + { + .compatible = "atmel,at91sam9263-ebi0", + .data = &at91sam9263_ebi0_caps, + }, + { + .compatible = "atmel,at91sam9263-ebi1", + .data = &at91sam9263_ebi1_caps, + }, + { + .compatible = "atmel,at91sam9rl-ebi", + .data = &at91sam9rl_ebi_caps, + }, + { + .compatible = "atmel,at91sam9g45-ebi", + .data = &at91sam9g45_ebi_caps, + }, + { + .compatible = "atmel,at91sam9x5-ebi", + .data = &at91sam9x5_ebi_caps, + }, + { + .compatible = "atmel,sama5d3-ebi", + .data = &sama5d3_ebi_caps, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, at91_ebi_id_table); + +static int at91_ebi_dev_disable(struct at91_ebi *ebi, struct device_node *np) +{ + struct device *dev = ebi->dev; + struct property *newprop; + + newprop = devm_kzalloc(dev, sizeof(*newprop), GFP_KERNEL); + if (!newprop) + return -ENOMEM; + + newprop->name = devm_kstrdup(dev, "status", GFP_KERNEL); + if (!newprop->name) + return -ENOMEM; + + newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL); + if (!newprop->name) + return -ENOMEM; + + newprop->length = sizeof("disabled"); + + return of_update_property(np, newprop); +} + +static int at91_ebi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *child, *np = dev->of_node; + const struct of_device_id *match; + struct at91_ebi *ebi; + int ret, reg_cells; + struct clk *clk; + u32 val; + + match = of_match_device(at91_ebi_id_table, dev); + if (!match || !match->data) + return -EINVAL; + + ebi = devm_kzalloc(dev, sizeof(*ebi), GFP_KERNEL); + if (!ebi) + return -ENOMEM; + + INIT_LIST_HEAD(&ebi->devs); + ebi->caps = match->data; + ebi->dev = dev; + + clk = devm_clk_get(dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + ebi->clk = clk; + + ebi->smc = syscon_regmap_lookup_by_phandle(np, "atmel,smc"); + if (IS_ERR(ebi->smc)) + return PTR_ERR(ebi->smc); + + /* + * The sama5d3 does not provide an EBICSA register and thus does need + * to access the matrix registers. + */ + if (ebi->caps->ebi_csa) { + ebi->matrix = + syscon_regmap_lookup_by_phandle(np, "atmel,matrix"); + if (IS_ERR(ebi->matrix)) + return PTR_ERR(ebi->matrix); + + ebi->ebi_csa = regmap_field_alloc(ebi->matrix, + *ebi->caps->ebi_csa); + if (IS_ERR(ebi->ebi_csa)) + return PTR_ERR(ebi->ebi_csa); + } + + ret = ebi->caps->init(ebi); + if (ret) + return ret; + + ret = of_property_read_u32(np, "#address-cells", &val); + if (ret) { + dev_err(dev, "missing #address-cells property\n"); + return ret; + } + + reg_cells = val; + + ret = of_property_read_u32(np, "#size-cells", &val); + if (ret) { + dev_err(dev, "missing #address-cells property\n"); + return ret; + } + + reg_cells += val; + + for_each_available_child_of_node(np, child) { + if (!of_find_property(child, "reg", NULL)) + continue; + + ret = at91_ebi_dev_setup(ebi, child, reg_cells); + if (ret) { + dev_err(dev, "failed to configure EBI bus for %s, disabling the device", + child->full_name); + + ret = at91_ebi_dev_disable(ebi, child); + if (ret) + return ret; + } + } + + return of_platform_populate(np, NULL, NULL, dev); +} + +static struct platform_driver at91_ebi_driver = { + .driver = { + .name = "atmel-ebi", + .of_match_table = at91_ebi_id_table, + }, +}; +module_platform_driver_probe(at91_ebi_driver, at91_ebi_probe); + +MODULE_AUTHOR("Jean-Jacques Hiblot <[email protected]>"); +MODULE_DESCRIPTION("Atmel EBI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0b2733db0e9e..ab37f4db9642 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -12,8 +12,12 @@ menuconfig RESET_CONTROLLER If unsure, say no. +if RESET_CONTROLLER + config RESET_OXNAS bool source "drivers/reset/sti/Kconfig" source "drivers/reset/hisilicon/Kconfig" + +endif diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index f173fc3847b4..03dc1bb7649e 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o obj-$(CONFIG_MACH_PISTACHIO) += reset-pistachio.o +obj-$(CONFIG_ARCH_MESON) += reset-meson.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o obj-$(CONFIG_ARCH_STI) += sti/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 72b32bd15549..395dc9ce492e 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -93,6 +93,43 @@ void reset_controller_unregister(struct reset_controller_dev *rcdev) } EXPORT_SYMBOL_GPL(reset_controller_unregister); +static void devm_reset_controller_release(struct device *dev, void *res) +{ + reset_controller_unregister(*(struct reset_controller_dev **)res); +} + +/** + * devm_reset_controller_register - resource managed reset_controller_register() + * @dev: device that is registering this reset controller + * @rcdev: a pointer to the initialized reset controller device + * + * Managed reset_controller_register(). For reset controllers registered by + * this function, reset_controller_unregister() is automatically called on + * driver detach. See reset_controller_register() for more information. + */ +int devm_reset_controller_register(struct device *dev, + struct reset_controller_dev *rcdev) +{ + struct reset_controller_dev **rcdevp; + int ret; + + rcdevp = devres_alloc(devm_reset_controller_release, sizeof(*rcdevp), + GFP_KERNEL); + if (!rcdevp) + return -ENOMEM; + + ret = reset_controller_register(rcdev); + if (!ret) { + *rcdevp = rcdev; + devres_add(dev, rcdevp); + } else { + devres_free(rcdevp); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_reset_controller_register); + /** * reset_control_reset - reset the controlled device * @rstc: reset controller diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c index ccb940a8d9fb..16d410cd6146 100644 --- a/drivers/reset/reset-ath79.c +++ b/drivers/reset/reset-ath79.c @@ -112,7 +112,7 @@ static int ath79_reset_probe(struct platform_device *pdev) ath79_reset->rcdev.of_reset_n_cells = 1; ath79_reset->rcdev.nr_resets = 32; - err = reset_controller_register(&ath79_reset->rcdev); + err = devm_reset_controller_register(&pdev->dev, &ath79_reset->rcdev); if (err) return err; @@ -131,7 +131,6 @@ static int ath79_reset_remove(struct platform_device *pdev) struct ath79_reset *ath79_reset = platform_get_drvdata(pdev); unregister_restart_handler(&ath79_reset->restart_nb); - reset_controller_unregister(&ath79_reset->rcdev); return 0; } diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c new file mode 100644 index 000000000000..c32f11a30c5f --- /dev/null +++ b/drivers/reset/reset-meson.c @@ -0,0 +1,136 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * BSD LICENSE + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <linux/err.h> +#include <linux/module.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <linux/slab.h> +#include <linux/types.h> + +#define REG_COUNT 8 +#define BITS_PER_REG 32 + +struct meson_reset { + void __iomem *reg_base; + struct reset_controller_dev rcdev; +}; + +static int meson_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct meson_reset *data = + container_of(rcdev, struct meson_reset, rcdev); + unsigned int bank = id / BITS_PER_REG; + unsigned int offset = id % BITS_PER_REG; + void __iomem *reg_addr = data->reg_base + (bank << 2); + + if (bank >= REG_COUNT) + return -EINVAL; + + writel(BIT(offset), reg_addr); + + return 0; +} + +static const struct reset_control_ops meson_reset_ops = { + .reset = meson_reset_reset, +}; + +static const struct of_device_id meson_reset_dt_ids[] = { + { .compatible = "amlogic,meson8b-reset", }, + { .compatible = "amlogic,meson-gxbb-reset", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, meson_reset_dt_ids); + +static int meson_reset_probe(struct platform_device *pdev) +{ + struct meson_reset *data; + struct resource *res; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(data->reg_base)) + return PTR_ERR(data->reg_base); + + platform_set_drvdata(pdev, data); + + data->rcdev.owner = THIS_MODULE; + data->rcdev.nr_resets = REG_COUNT * BITS_PER_REG; + data->rcdev.ops = &meson_reset_ops; + data->rcdev.of_node = pdev->dev.of_node; + + return devm_reset_controller_register(&pdev->dev, &data->rcdev); +} + +static struct platform_driver meson_reset_driver = { + .probe = meson_reset_probe, + .driver = { + .name = "meson_reset", + .of_match_table = meson_reset_dt_ids, + }, +}; + +module_platform_driver(meson_reset_driver); + +MODULE_AUTHOR("Neil Armstrong <[email protected]>"); +MODULE_DESCRIPTION("Amlogic Meson Reset Controller driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/reset/reset-oxnas.c b/drivers/reset/reset-oxnas.c index c60fb2dace3e..944980572f79 100644 --- a/drivers/reset/reset-oxnas.c +++ b/drivers/reset/reset-oxnas.c @@ -112,21 +112,11 @@ static int oxnas_reset_probe(struct platform_device *pdev) data->rcdev.ops = &oxnas_reset_ops; data->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&data->rcdev); -} - -static int oxnas_reset_remove(struct platform_device *pdev) -{ - struct oxnas_reset *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(&pdev->dev, &data->rcdev); } static struct platform_driver oxnas_reset_driver = { .probe = oxnas_reset_probe, - .remove = oxnas_reset_remove, .driver = { .name = "oxnas-reset", .of_match_table = oxnas_reset_dt_ids, diff --git a/drivers/reset/reset-pistachio.c b/drivers/reset/reset-pistachio.c index 72a97a15a4c8..bbc4c06dd33b 100644 --- a/drivers/reset/reset-pistachio.c +++ b/drivers/reset/reset-pistachio.c @@ -121,16 +121,7 @@ static int pistachio_reset_probe(struct platform_device *pdev) rd->rcdev.ops = &pistachio_reset_ops; rd->rcdev.of_node = np; - return reset_controller_register(&rd->rcdev); -} - -static int pistachio_reset_remove(struct platform_device *pdev) -{ - struct pistachio_reset_data *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(dev, &rd->rcdev); } static const struct of_device_id pistachio_reset_dt_ids[] = { @@ -141,7 +132,6 @@ MODULE_DEVICE_TABLE(of, pistachio_reset_dt_ids); static struct platform_driver pistachio_reset_driver = { .probe = pistachio_reset_probe, - .remove = pistachio_reset_remove, .driver = { .name = "pistachio-reset", .of_match_table = pistachio_reset_dt_ids, diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index cd05a7032b17..12add9b0fa49 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -134,16 +134,7 @@ static int socfpga_reset_probe(struct platform_device *pdev) data->rcdev.ops = &socfpga_reset_ops; data->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&data->rcdev); -} - -static int socfpga_reset_remove(struct platform_device *pdev) -{ - struct socfpga_reset_data *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(dev, &data->rcdev); } static const struct of_device_id socfpga_reset_dt_ids[] = { @@ -153,7 +144,6 @@ static const struct of_device_id socfpga_reset_dt_ids[] = { static struct platform_driver socfpga_reset_driver = { .probe = socfpga_reset_probe, - .remove = socfpga_reset_remove, .driver = { .name = "socfpga-reset", .of_match_table = socfpga_reset_dt_ids, diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index 677f86555212..3080190b3f90 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -165,21 +165,11 @@ static int sunxi_reset_probe(struct platform_device *pdev) data->rcdev.ops = &sunxi_reset_ops; data->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&data->rcdev); -} - -static int sunxi_reset_remove(struct platform_device *pdev) -{ - struct sunxi_reset_data *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(&pdev->dev, &data->rcdev); } static struct platform_driver sunxi_reset_driver = { .probe = sunxi_reset_probe, - .remove = sunxi_reset_remove, .driver = { .name = "sunxi-reset", .of_match_table = sunxi_reset_dt_ids, diff --git a/drivers/reset/reset-zynq.c b/drivers/reset/reset-zynq.c index a7e87bc45885..138f2f205662 100644 --- a/drivers/reset/reset-zynq.c +++ b/drivers/reset/reset-zynq.c @@ -122,16 +122,7 @@ static int zynq_reset_probe(struct platform_device *pdev) priv->rcdev.ops = &zynq_reset_ops; priv->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&priv->rcdev); -} - -static int zynq_reset_remove(struct platform_device *pdev) -{ - struct zynq_reset_data *priv = platform_get_drvdata(pdev); - - reset_controller_unregister(&priv->rcdev); - - return 0; + return devm_reset_controller_register(&pdev->dev, &priv->rcdev); } static const struct of_device_id zynq_reset_dt_ids[] = { @@ -141,7 +132,6 @@ static const struct of_device_id zynq_reset_dt_ids[] = { static struct platform_driver zynq_reset_driver = { .probe = zynq_reset_probe, - .remove = zynq_reset_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = zynq_reset_dt_ids, diff --git a/drivers/reset/sti/Kconfig b/drivers/reset/sti/Kconfig index f8c15a37fb35..613178553612 100644 --- a/drivers/reset/sti/Kconfig +++ b/drivers/reset/sti/Kconfig @@ -2,7 +2,6 @@ if ARCH_STI config STI_RESET_SYSCFG bool - select RESET_CONTROLLER config STIH415_RESET bool diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index 151fcd3f025b..cd85cd5e6a01 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_ARCH_R8A7791) += rcar-sysc.o r8a7791-sysc.o obj-$(CONFIG_ARCH_R8A7793) += rcar-sysc.o r8a7791-sysc.o obj-$(CONFIG_ARCH_R8A7794) += rcar-sysc.o r8a7794-sysc.o obj-$(CONFIG_ARCH_R8A7795) += rcar-sysc.o r8a7795-sysc.o +obj-$(CONFIG_ARCH_R8A7796) += rcar-sysc.o r8a7796-sysc.o diff --git a/drivers/soc/renesas/r8a7796-sysc.c b/drivers/soc/renesas/r8a7796-sysc.c new file mode 100644 index 000000000000..f700c842b9e1 --- /dev/null +++ b/drivers/soc/renesas/r8a7796-sysc.c @@ -0,0 +1,48 @@ +/* + * Renesas R-Car M3-W System Controller + * + * Copyright (C) 2016 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include <linux/bug.h> +#include <linux/kernel.h> + +#include <dt-bindings/power/r8a7796-sysc.h> + +#include "rcar-sysc.h" + +static const struct rcar_sysc_area r8a7796_areas[] __initconst = { + { "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON, + PD_SCU }, + { "ca57-cpu0", 0x80, 0, R8A7796_PD_CA57_CPU0, R8A7796_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca57-cpu1", 0x80, 1, R8A7796_PD_CA57_CPU1, R8A7796_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca53-scu", 0x140, 0, R8A7796_PD_CA53_SCU, R8A7796_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A7796_PD_CA53_CPU0, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu1", 0x200, 1, R8A7796_PD_CA53_CPU1, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu2", 0x200, 2, R8A7796_PD_CA53_CPU2, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu3", 0x200, 3, R8A7796_PD_CA53_CPU3, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON }, + { "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON }, + { "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC }, + { "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC }, + { "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON }, + { "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A }, + { "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON }, +}; + +const struct rcar_sysc_info r8a7796_sysc_info __initconst = { + .areas = r8a7796_areas, + .num_areas = ARRAY_SIZE(r8a7796_areas), +}; diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 79dbc770895f..fc997d4d2a4a 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -303,6 +303,9 @@ static const struct of_device_id rcar_sysc_matches[] = { #ifdef CONFIG_ARCH_R8A7795 { .compatible = "renesas,r8a7795-sysc", .data = &r8a7795_sysc_info }, #endif +#ifdef CONFIG_ARCH_R8A7796 + { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info }, +#endif { /* sentinel */ } }; diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index 5e766174c2f4..4ac3d7bf7f38 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -55,4 +55,5 @@ extern const struct rcar_sysc_info r8a7790_sysc_info; extern const struct rcar_sysc_info r8a7791_sysc_info; extern const struct rcar_sysc_info r8a7794_sysc_info; extern const struct rcar_sysc_info r8a7795_sysc_info; +extern const struct rcar_sysc_info r8a7796_sysc_info; #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */ diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig index d7fc123006a3..245533907d1b 100644 --- a/drivers/soc/samsung/Kconfig +++ b/drivers/soc/samsung/Kconfig @@ -10,4 +10,8 @@ config EXYNOS_PMU bool "Exynos PMU controller driver" if COMPILE_TEST depends on (ARM && ARCH_EXYNOS) || ((ARM || ARM64) && COMPILE_TEST) +config EXYNOS_PM_DOMAINS + bool "Exynos PM domains" if COMPILE_TEST + depends on PM_GENERIC_DOMAINS || COMPILE_TEST + endif diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile index f64ac4d80564..3619f2ecddaa 100644 --- a/drivers/soc/samsung/Makefile +++ b/drivers/soc/samsung/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o exynos3250-pmu.o exynos4-pmu.o \ exynos5250-pmu.o exynos5420-pmu.o +obj-$(CONFIG_EXYNOS_PM_DOMAINS) += pm_domains.o diff --git a/arch/arm/mach-exynos/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 875a2bab64f6..f60515eefb66 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -23,9 +23,13 @@ #include <linux/of_platform.h> #include <linux/sched.h> -#define INT_LOCAL_PWR_EN 0x7 #define MAX_CLK_PER_DOMAIN 4 +struct exynos_pm_domain_config { + /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ + u32 local_pwr_cfg; +}; + /* * Exynos specific wrapper around the generic power domain */ @@ -38,6 +42,7 @@ struct exynos_pm_domain { struct clk *clk[MAX_CLK_PER_DOMAIN]; struct clk *pclk[MAX_CLK_PER_DOMAIN]; struct clk *asb_clk[MAX_CLK_PER_DOMAIN]; + u32 local_pwr_cfg; }; static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) @@ -69,13 +74,13 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) } } - pwr = power_on ? INT_LOCAL_PWR_EN : 0; + pwr = power_on ? pd->local_pwr_cfg : 0; __raw_writel(pwr, base); /* Wait max 1ms */ timeout = 10; - while ((__raw_readl(base + 0x4) & INT_LOCAL_PWR_EN) != pwr) { + while ((__raw_readl(base + 0x4) & pd->local_pwr_cfg) != pwr) { if (!timeout) { op = (power_on) ? "enable" : "disable"; pr_err("Power domain %s %s failed\n", domain->name, op); @@ -119,14 +124,30 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain) return exynos_pd_power(domain, false); } +static const struct exynos_pm_domain_config exynos4210_cfg __initconst = { + .local_pwr_cfg = 0x7, +}; + +static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { + { + .compatible = "samsung,exynos4210-pd", + .data = &exynos4210_cfg, + }, + { }, +}; + static __init int exynos4_pm_init_power_domain(void) { struct device_node *np; + const struct of_device_id *match; - for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { + for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { + const struct exynos_pm_domain_config *pm_domain_cfg; struct exynos_pm_domain *pd; int on, i; + pm_domain_cfg = match->data; + pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { pr_err("%s: failed to allocate memory for domain\n", @@ -153,6 +174,7 @@ static __init int exynos4_pm_init_power_domain(void) pd->pd.power_off = exynos_pd_power_off; pd->pd.power_on = exynos_pd_power_on; + pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { char clk_name[8]; @@ -185,14 +207,14 @@ static __init int exynos4_pm_init_power_domain(void) clk_put(pd->oscclk); no_clk: - on = __raw_readl(pd->base + 0x4) & INT_LOCAL_PWR_EN; + on = __raw_readl(pd->base + 0x4) & pd->local_pwr_cfg; pm_genpd_init(&pd->pd, NULL, !on); of_genpd_add_provider_simple(np, &pd->pd); } /* Assign the child power domains to their parents */ - for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { + for_each_matching_node(np, exynos_pm_domain_of_match) { struct generic_pm_domain *child_domain, *parent_domain; struct of_phandle_args args; diff --git a/include/dt-bindings/power/r8a7796-sysc.h b/include/dt-bindings/power/r8a7796-sysc.h new file mode 100644 index 000000000000..5b4daab44daa --- /dev/null +++ b/include/dt-bindings/power/r8a7796-sysc.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ +#ifndef __DT_BINDINGS_POWER_R8A7796_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A7796_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A7796_PD_CA57_CPU0 0 +#define R8A7796_PD_CA57_CPU1 1 +#define R8A7796_PD_CA53_CPU0 5 +#define R8A7796_PD_CA53_CPU1 6 +#define R8A7796_PD_CA53_CPU2 7 +#define R8A7796_PD_CA53_CPU3 8 +#define R8A7796_PD_CA57_SCU 12 +#define R8A7796_PD_CR7 13 +#define R8A7796_PD_A3VC 14 +#define R8A7796_PD_3DG_A 17 +#define R8A7796_PD_3DG_B 18 +#define R8A7796_PD_CA53_SCU 21 +#define R8A7796_PD_A3IR 24 +#define R8A7796_PD_A2VC0 25 +#define R8A7796_PD_A2VC1 26 + +/* Always-on power area */ +#define R8A7796_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_R8A7796_SYSC_H__ */ diff --git a/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h b/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h new file mode 100644 index 000000000000..524d6077ac1b --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h @@ -0,0 +1,210 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * BSD LICENSE + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _DT_BINDINGS_AMLOGIC_MESON_GXBB_RESET_H +#define _DT_BINDINGS_AMLOGIC_MESON_GXBB_RESET_H + +/* RESET0 */ +#define RESET_HIU 0 +/* 1 */ +#define RESET_DOS_RESET 2 +#define RESET_DDR_TOP 3 +#define RESET_DCU_RESET 4 +#define RESET_VIU 5 +#define RESET_AIU 6 +#define RESET_VID_PLL_DIV 7 +/* 8 */ +#define RESET_PMUX 9 +#define RESET_VENC 10 +#define RESET_ASSIST 11 +#define RESET_AFIFO2 12 +#define RESET_VCBUS 13 +/* 14 */ +/* 15 */ +#define RESET_GIC 16 +#define RESET_CAPB3_DECODE 17 +#define RESET_NAND_CAPB3 18 +#define RESET_HDMITX_CAPB3 19 +#define RESET_MALI_CAPB3 20 +#define RESET_DOS_CAPB3 21 +#define RESET_SYS_CPU_CAPB3 22 +#define RESET_CBUS_CAPB3 23 +#define RESET_AHB_CNTL 24 +#define RESET_AHB_DATA 25 +#define RESET_VCBUS_CLK81 26 +#define RESET_MMC 27 +#define RESET_MIPI_0 28 +#define RESET_MIPI_1 29 +#define RESET_MIPI_2 30 +#define RESET_MIPI_3 31 +/* RESET1 */ +#define RESET_CPPM 32 +#define RESET_DEMUX 33 +#define RESET_USB_OTG 34 +#define RESET_DDR 35 +#define RESET_AO_RESET 36 +#define RESET_BT656 37 +#define RESET_AHB_SRAM 38 +/* 39 */ +#define RESET_PARSER 40 +#define RESET_BLKMV 41 +#define RESET_ISA 42 +#define RESET_ETHERNET 43 +#define RESET_SD_EMMC_A 44 +#define RESET_SD_EMMC_B 45 +#define RESET_SD_EMMC_C 46 +#define RESET_ROM_BOOT 47 +#define RESET_SYS_CPU_0 48 +#define RESET_SYS_CPU_1 49 +#define RESET_SYS_CPU_2 50 +#define RESET_SYS_CPU_3 51 +#define RESET_SYS_CPU_CORE_0 52 +#define RESET_SYS_CPU_CORE_1 53 +#define RESET_SYS_CPU_CORE_2 54 +#define RESET_SYS_CPU_CORE_3 55 +#define RESET_SYS_PLL_DIV 56 +#define RESET_SYS_CPU_AXI 57 +#define RESET_SYS_CPU_L2 58 +#define RESET_SYS_CPU_P 59 +#define RESET_SYS_CPU_MBIST 60 +/* 61 */ +/* 62 */ +/* 63 */ +/* RESET2 */ +#define RESET_VD_RMEM 64 +#define RESET_AUDIN 65 +#define RESET_HDMI_TX 66 +/* 67 */ +/* 68 */ +/* 69 */ +#define RESET_GE2D 70 +#define RESET_PARSER_REG 71 +#define RESET_PARSER_FETCH 72 +#define RESET_PARSER_CTL 73 +#define RESET_PARSER_TOP 74 +/* 75 */ +/* 76 */ +#define RESET_AO_CPU_RESET 77 +#define RESET_MALI 78 +#define RESET_HDMI_SYSTEM_RESET 79 +/* 80-95 */ +/* RESET3 */ +#define RESET_RING_OSCILLATOR 96 +#define RESET_SYS_CPU 97 +#define RESET_EFUSE 98 +#define RESET_SYS_CPU_BVCI 99 +#define RESET_AIFIFO 100 +#define RESET_TVFE 101 +#define RESET_AHB_BRIDGE_CNTL 102 +/* 103 */ +#define RESET_AUDIO_DAC 104 +#define RESET_DEMUX_TOP 105 +#define RESET_DEMUX_DES 106 +#define RESET_DEMUX_S2P_0 107 +#define RESET_DEMUX_S2P_1 108 +#define RESET_DEMUX_RESET_0 109 +#define RESET_DEMUX_RESET_1 110 +#define RESET_DEMUX_RESET_2 111 +/* 112-127 */ +/* RESET4 */ +/* 128 */ +/* 129 */ +/* 130 */ +/* 131 */ +#define RESET_DVIN_RESET 132 +#define RESET_RDMA 133 +#define RESET_VENCI 134 +#define RESET_VENCP 135 +/* 136 */ +#define RESET_VDAC 137 +#define RESET_RTC 138 +/* 139 */ +#define RESET_VDI6 140 +#define RESET_VENCL 141 +#define RESET_I2C_MASTER_2 142 +#define RESET_I2C_MASTER_1 143 +/* 144-159 */ +/* RESET5 */ +/* 160-191 */ +/* RESET6 */ +#define RESET_PERIPHS_GENERAL 192 +#define RESET_PERIPHS_SPICC 193 +#define RESET_PERIPHS_SMART_CARD 194 +#define RESET_PERIPHS_SAR_ADC 195 +#define RESET_PERIPHS_I2C_MASTER_0 196 +#define RESET_SANA 197 +/* 198 */ +#define RESET_PERIPHS_STREAM_INTERFACE 199 +#define RESET_PERIPHS_SDIO 200 +#define RESET_PERIPHS_UART_0 201 +#define RESET_PERIPHS_UART_1_2 202 +#define RESET_PERIPHS_ASYNC_0 203 +#define RESET_PERIPHS_ASYNC_1 204 +#define RESET_PERIPHS_SPI_0 205 +#define RESET_PERIPHS_SDHC 206 +#define RESET_UART_SLIP 207 +/* 208-223 */ +/* RESET7 */ +#define RESET_USB_DDR_0 224 +#define RESET_USB_DDR_1 225 +#define RESET_USB_DDR_2 226 +#define RESET_USB_DDR_3 227 +/* 228 */ +#define RESET_DEVICE_MMC_ARB 229 +/* 230 */ +#define RESET_VID_LOCK 231 +#define RESET_A9_DMC_PIPEL 232 +/* 233-255 */ + +#endif diff --git a/include/dt-bindings/reset/amlogic,meson8b-reset.h b/include/dt-bindings/reset/amlogic,meson8b-reset.h new file mode 100644 index 000000000000..614aff2c7aff --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson8b-reset.h @@ -0,0 +1,175 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * BSD LICENSE + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _DT_BINDINGS_AMLOGIC_MESON8B_RESET_H +#define _DT_BINDINGS_AMLOGIC_MESON8B_RESET_H + +/* RESET0 */ +#define RESET_HIU 0 +#define RESET_VLD 1 +#define RESET_IQIDCT 2 +#define RESET_MC 3 +/* 8 */ +#define RESET_VIU 5 +#define RESET_AIU 6 +#define RESET_MCPU 7 +#define RESET_CCPU 8 +#define RESET_PMUX 9 +#define RESET_VENC 10 +#define RESET_ASSIST 11 +#define RESET_AFIFO2 12 +#define RESET_MDEC 13 +#define RESET_VLD_PART 14 +#define RESET_VIFIFO 15 +/* 16-31 */ +/* RESET1 */ +/* 32 */ +#define RESET_DEMUX 33 +#define RESET_USB_OTG 34 +#define RESET_DDR 35 +#define RESET_VDAC_1 36 +#define RESET_BT656 37 +#define RESET_AHB_SRAM 38 +#define RESET_AHB_BRIDGE 39 +#define RESET_PARSER 40 +#define RESET_BLKMV 41 +#define RESET_ISA 42 +#define RESET_ETHERNET 43 +#define RESET_ABUF 44 +#define RESET_AHB_DATA 45 +#define RESET_AHB_CNTL 46 +#define RESET_ROM_BOOT 47 +/* 48-63 */ +/* RESET2 */ +#define RESET_VD_RMEM 64 +#define RESET_AUDIN 65 +#define RESET_DBLK 66 +#define RESET_PIC_DC 66 +#define RESET_PSC 66 +#define RESET_NAND 66 +#define RESET_GE2D 70 +#define RESET_PARSER_REG 71 +#define RESET_PARSER_FETCH 72 +#define RESET_PARSER_CTL 73 +#define RESET_PARSER_TOP 74 +#define RESET_HDMI_APB 75 +#define RESET_AUDIO_APB 76 +#define RESET_MEDIA_CPU 77 +#define RESET_MALI 78 +#define RESET_HDMI_SYSTEM_RESET 79 +/* 80-95 */ +/* RESET3 */ +#define RESET_RING_OSCILLATOR 96 +#define RESET_SYS_CPU_0 97 +#define RESET_EFUSE 98 +#define RESET_SYS_CPU_BVCI 99 +#define RESET_AIFIFO 100 +#define RESET_AUDIO_PLL_MODULATOR 101 +#define RESET_AHB_BRIDGE_CNTL 102 +#define RESET_SYS_CPU_1 103 +#define RESET_AUDIO_DAC 104 +#define RESET_DEMUX_TOP 105 +#define RESET_DEMUX_DES 106 +#define RESET_DEMUX_S2P_0 107 +#define RESET_DEMUX_S2P_1 108 +#define RESET_DEMUX_RESET_0 109 +#define RESET_DEMUX_RESET_1 110 +#define RESET_DEMUX_RESET_2 111 +/* 112-127 */ +/* RESET4 */ +#define RESET_PL310 128 +#define RESET_A5_APB 129 +#define RESET_A5_AXI 130 +#define RESET_A5 131 +#define RESET_DVIN 132 +#define RESET_RDMA 133 +#define RESET_VENCI 134 +#define RESET_VENCP 135 +#define RESET_VENCT 136 +#define RESET_VDAC_4 137 +#define RESET_RTC 138 +#define RESET_A5_DEBUG 139 +#define RESET_VDI6 140 +#define RESET_VENCL 141 +/* 142-159 */ +/* RESET5 */ +#define RESET_DDR_PLL 160 +#define RESET_MISC_PLL 161 +#define RESET_SYS_PLL 162 +#define RESET_HPLL_PLL 163 +#define RESET_AUDIO_PLL 164 +#define RESET_VID2_PLL 165 +/* 166-191 */ +/* RESET6 */ +#define RESET_PERIPHS_GENERAL 192 +#define RESET_PERIPHS_IR_REMOTE 193 +#define RESET_PERIPHS_SMART_CARD 194 +#define RESET_PERIPHS_SAR_ADC 195 +#define RESET_PERIPHS_I2C_MASTER_0 196 +#define RESET_PERIPHS_I2C_MASTER_1 197 +#define RESET_PERIPHS_I2C_SLAVE 198 +#define RESET_PERIPHS_STREAM_INTERFACE 199 +#define RESET_PERIPHS_SDIO 200 +#define RESET_PERIPHS_UART_0 201 +#define RESET_PERIPHS_UART_1 202 +#define RESET_PERIPHS_ASYNC_0 203 +#define RESET_PERIPHS_ASYNC_1 204 +#define RESET_PERIPHS_SPI_0 205 +#define RESET_PERIPHS_SPI_1 206 +#define RESET_PERIPHS_LED_PWM 207 +/* 208-223 */ +/* RESET7 */ +/* 224-255 */ + +#endif diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index b91ba932bbd4..db1fe6772ad5 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -53,4 +53,8 @@ struct reset_controller_dev { int reset_controller_register(struct reset_controller_dev *rcdev); void reset_controller_unregister(struct reset_controller_dev *rcdev); +struct device; +int devm_reset_controller_register(struct device *dev, + struct reset_controller_dev *rcdev); + #endif diff --git a/include/linux/reset.h b/include/linux/reset.h index ec0306ce7b92..067db57c81dc 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -71,14 +71,14 @@ static inline struct reset_control *__of_reset_control_get( struct device_node *node, const char *id, int index, int shared) { - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOTSUPP); } static inline struct reset_control *__devm_reset_control_get( struct device *dev, const char *id, int index, int shared) { - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOTSUPP); } #endif /* CONFIG_RESET_CONTROLLER */ |