From 8eb8c7d844b9da6301542627eaaae28f4d20cb75 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 16 Mar 2017 09:30:29 +0100 Subject: memory: atmel-ebi: Simplify SMC config code New helpers/macros have been to atmel-smc.h introduced to simplify SMC regs manipulation. Rework the code to use those helpers, and simplify the ->xlate_config(), ->get_config() and ->apply_config() implementations. SMC configs are now stored in a struct atmel_smc_cs_conf object that directly contains registers values, which should help implementing ->suspend()/->resume() hooks. We can also get rid of those regmap fields (and the associated ->init() hook) which are not longer needed thanks to the atmel_[h]smc_cs_conf_{apply,get}() helpers. Signed-off-by: Boris Brezillon Acked-by: Nicolas Ferre Signed-off-by: Lee Jones --- drivers/memory/Kconfig | 1 + drivers/memory/atmel-ebi.c | 430 +++++++++++++-------------------------------- 2 files changed, 128 insertions(+), 303 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index ec80e35c8dfe..3ecc429297a0 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -30,6 +30,7 @@ config ATMEL_EBI default y depends on ARCH_AT91 && OF select MFD_SYSCON + select MFD_ATMEL_SMC help Driver for Atmel EBI controller. Used to configure the EBI (external bus interface) when the device- diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 4e83a8b92665..e1b8590e7d23 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -18,37 +18,9 @@ #include #include -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 atmel_smc_cs_conf smcconf; }; struct at91_ebi; @@ -69,9 +41,8 @@ struct at91_ebi_caps { 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); + void (*apply_config)(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf); }; struct at91_ebi { @@ -86,151 +57,119 @@ struct at91_ebi { struct device *dev; const struct at91_ebi_caps *caps; struct list_head devs; - union { - struct at91sam9_smc_generic_fields sam9; - }; }; +struct atmel_smc_timing_xlate { + const char *name; + int (*converter)(struct atmel_smc_cs_conf *conf, + unsigned int shift, unsigned int nycles); + unsigned int shift; +}; + +#define ATMEL_SMC_SETUP_XLATE(nm, pos) \ + { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos} + +#define ATMEL_SMC_PULSE_XLATE(nm, pos) \ + { .name = nm, .converter = atmel_smc_cs_conf_set_pulse, .shift = pos} + +#define ATMEL_SMC_CYCLE_XLATE(nm, pos) \ + { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos} + 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_period = NSEC_PER_SEC / 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_period * 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_period; - timings->nrd_setup_ns = (val >> 16) & 0x1f; - timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128; - timings->nrd_setup_ns *= clk_period; - timings->ncs_wr_setup_ns = (val >> 8) & 0x1f; - timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128; - timings->ncs_wr_setup_ns *= clk_period; - timings->nwe_setup_ns = val & 0x1f; - timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128; - timings->nwe_setup_ns *= clk_period; - - 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_period; - timings->nrd_pulse_ns = (val >> 16) & 0x3f; - timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256; - timings->nrd_pulse_ns *= clk_period; - timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f; - timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256; - timings->ncs_wr_pulse_ns *= clk_period; - timings->nwe_pulse_ns = val & 0x3f; - timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256; - timings->nwe_pulse_ns *= clk_period; - - 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_period; - timings->nwe_cycle_ns = val & 0x7f; - timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256; - timings->nwe_cycle_ns *= clk_period; + atmel_smc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs, + &conf->smcconf); } -static int at91_xlate_timing(struct device_node *np, const char *prop, - u32 *val, bool *required) +static void sama5_ebi_get_config(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf) { - if (!of_property_read_u32(np, prop, val)) { - *required = true; - return 0; - } - - if (*required) - return -EINVAL; - - return 0; + atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs, + &conf->smcconf); } -static int at91sam9_smc_xslate_timings(struct at91_ebi_dev *ebid, +static const struct atmel_smc_timing_xlate timings_xlate_table[] = { + ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-rd-setup-ns", + ATMEL_SMC_NCS_RD_SHIFT), + ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-wr-setup-ns", + ATMEL_SMC_NCS_WR_SHIFT), + ATMEL_SMC_SETUP_XLATE("atmel,smc-nrd-setup-ns", ATMEL_SMC_NRD_SHIFT), + ATMEL_SMC_SETUP_XLATE("atmel,smc-nwe-setup-ns", ATMEL_SMC_NWE_SHIFT), + ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-rd-pulse-ns", + ATMEL_SMC_NCS_RD_SHIFT), + ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-wr-pulse-ns", + ATMEL_SMC_NCS_WR_SHIFT), + ATMEL_SMC_PULSE_XLATE("atmel,smc-nrd-pulse-ns", ATMEL_SMC_NRD_SHIFT), + ATMEL_SMC_PULSE_XLATE("atmel,smc-nwe-pulse-ns", ATMEL_SMC_NWE_SHIFT), + ATMEL_SMC_CYCLE_XLATE("atmel,smc-nrd-cycle-ns", ATMEL_SMC_NRD_SHIFT), + ATMEL_SMC_CYCLE_XLATE("atmel,smc-nwe-cycle-ns", ATMEL_SMC_NWE_SHIFT), +}; + +static int at91_ebi_xslate_smc_timings(struct at91_ebi_dev *ebid, struct device_node *np, - struct at91sam9_smc_timings *timings, - bool *required) + struct atmel_smc_cs_conf *smcconf) { - 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; + unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); + unsigned int clk_period_ns = NSEC_PER_SEC / clk_rate; + bool required = false; + unsigned int ncycles; + int ret, i; + u32 val; - ret = at91_xlate_timing(np, "atmel,smc-nwe-setup-ns", - &timings->nwe_setup_ns, required); - if (ret) - goto out; + ret = of_property_read_u32(np, "atmel,smc-tdf-ns", &val); + if (!ret) { + required = true; + ncycles = DIV_ROUND_UP(val, clk_period_ns); + if (ncycles > ATMEL_SMC_MODE_TDF_MAX || + ncycles < ATMEL_SMC_MODE_TDF_MIN) { + ret = -EINVAL; + goto out; + } - ret = at91_xlate_timing(np, "atmel,smc-ncs-rd-pulse-ns", - &timings->ncs_rd_pulse_ns, required); - if (ret) - goto out; + smcconf->mode |= ATMEL_SMC_MODE_TDF(ncycles); + } - ret = at91_xlate_timing(np, "atmel,smc-nrd-pulse-ns", - &timings->nrd_pulse_ns, required); - if (ret) - goto out; + for (i = 0; i < ARRAY_SIZE(timings_xlate_table); i++) { + const struct atmel_smc_timing_xlate *xlate; - ret = at91_xlate_timing(np, "atmel,smc-ncs-wr-pulse-ns", - &timings->ncs_wr_pulse_ns, required); - if (ret) - goto out; + xlate = &timings_xlate_table[i]; - 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 = of_property_read_u32(np, xlate->name, &val); + if (ret) { + if (!required) + continue; + else + break; + } - ret = at91_xlate_timing(np, "atmel,smc-nrd-cycle-ns", - &timings->nrd_cycle_ns, required); - if (ret) - goto out; + if (!required) { + ret = -EINVAL; + break; + } - ret = at91_xlate_timing(np, "atmel,smc-tdf-ns", - &timings->tdf_ns, required); + ncycles = DIV_ROUND_UP(val, clk_period_ns); + ret = xlate->converter(smcconf, xlate->shift, ncycles); + if (ret) + goto out; + } out: - if (ret) + if (ret) { dev_err(ebid->ebi->dev, "missing or invalid timings definition in %s", np->full_name); + return ret; + } - return ret; + return required; } -static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, +static int at91_ebi_xslate_smc_config(struct at91_ebi_dev *ebid, struct device_node *np, struct at91_ebi_dev_config *conf) { - struct at91sam9_ebi_dev_config *config = &conf->sam9; + struct atmel_smc_cs_conf *smcconf = &conf->smcconf; bool required = false; const char *tmp_str; u32 tmp; @@ -240,15 +179,15 @@ static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, if (!ret) { switch (tmp) { case 8: - config->mode |= AT91_SMC_DBW_8; + smcconf->mode |= ATMEL_SMC_MODE_DBW_8; break; case 16: - config->mode |= AT91_SMC_DBW_16; + smcconf->mode |= ATMEL_SMC_MODE_DBW_16; break; case 32: - config->mode |= AT91_SMC_DBW_32; + smcconf->mode |= ATMEL_SMC_MODE_DBW_32; break; default: @@ -259,28 +198,28 @@ static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, } if (of_property_read_bool(np, "atmel,smc-tdf-optimized")) { - config->mode |= AT91_SMC_TDFMODE_OPTIMIZED; + smcconf->mode |= ATMEL_SMC_MODE_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; + smcconf->mode |= ATMEL_SMC_MODE_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; + smcconf->mode |= ATMEL_SMC_MODE_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; + smcconf->mode |= ATMEL_SMC_MODE_WRITEMODE_NWE; required = true; } @@ -288,9 +227,9 @@ static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, 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; + smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_FROZEN; else if (!strcmp(tmp_str, "ready")) - config->mode |= AT91_SMC_EXNWMODE_READY; + smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_READY; else if (strcmp(tmp_str, "disabled")) return -EINVAL; @@ -301,155 +240,54 @@ static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, if (!ret) { switch (tmp) { case 4: - config->mode |= AT91_SMC_PS_4; + smcconf->mode |= ATMEL_SMC_MODE_PS_4; break; case 8: - config->mode |= AT91_SMC_PS_8; + smcconf->mode |= ATMEL_SMC_MODE_PS_8; break; case 16: - config->mode |= AT91_SMC_PS_16; + smcconf->mode |= ATMEL_SMC_MODE_PS_16; break; case 32: - config->mode |= AT91_SMC_PS_32; + smcconf->mode |= ATMEL_SMC_MODE_PS_32; break; default: return -EINVAL; } - config->mode |= AT91_SMC_PMEN; + smcconf->mode |= ATMEL_SMC_MODE_PMEN; required = true; } - ret = at91sam9_smc_xslate_timings(ebid, np, &config->timings, - &required); + ret = at91_ebi_xslate_smc_timings(ebid, np, &conf->smcconf); 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); - unsigned int clk_period = NSEC_PER_SEC / clk_rate; - 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; + return -EINVAL; - 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_period); - if (val > AT91_SMC_TDF_MAX) - val = AT91_SMC_TDF_MAX; - regmap_fields_write(fields->mode, conf->cs, - config->mode | AT91_SMC_TDF_(val)); + if ((ret > 0 && !required) || (!ret && required)) { + dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %s", + np->full_name); + return -EINVAL; + } - return 0; + return required; } -static int at91sam9_ebi_init(struct at91_ebi *ebi) +static void at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf) { - 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.regmap, - 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.regmap, - 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.regmap, - 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.regmap, - field); - return PTR_ERR_OR_ZERO(fields->mode); + atmel_smc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs, + &conf->smcconf); } -static int sama5d3_ebi_init(struct at91_ebi *ebi) +static void sama5_ebi_apply_config(struct at91_ebi_dev *ebid, + struct at91_ebi_dev_config *conf) { - 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.regmap, - 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.regmap, - 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.regmap, - 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.regmap, - field); - return PTR_ERR_OR_ZERO(fields->mode); + atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs, + &conf->smcconf); } static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, @@ -508,9 +346,7 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, if (apply) { conf.cs = cs; - ret = caps->apply_config(ebid, &conf); - if (ret) - return ret; + caps->apply_config(ebid, &conf); } caps->get_config(ebid, &ebid->configs[i]); @@ -539,9 +375,8 @@ 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, + .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, - .init = at91sam9_ebi_init, }; static const struct reg_field at91sam9261_ebi_csa = @@ -552,9 +387,8 @@ 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, + .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, - .init = at91sam9_ebi_init, }; static const struct reg_field at91sam9263_ebi0_csa = @@ -565,9 +399,8 @@ 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, + .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, - .init = at91sam9_ebi_init, }; static const struct reg_field at91sam9263_ebi1_csa = @@ -578,9 +411,8 @@ 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, + .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, - .init = at91sam9_ebi_init, }; static const struct reg_field at91sam9rl_ebi_csa = @@ -591,9 +423,8 @@ 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, + .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, - .init = at91sam9_ebi_init, }; static const struct reg_field at91sam9g45_ebi_csa = @@ -604,26 +435,23 @@ 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, + .xlate_config = at91_ebi_xslate_smc_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, + .xlate_config = at91_ebi_xslate_smc_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, + .get_config = sama5_ebi_get_config, + .xlate_config = at91_ebi_xslate_smc_config, + .apply_config = sama5_ebi_apply_config, }; static const struct of_device_id at91_ebi_id_table[] = { @@ -745,10 +573,6 @@ static int at91_ebi_probe(struct platform_device *pdev) 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"); -- cgit v1.2.3 From d9f81dad161f3f0b339a65e0e6ac5db898119027 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 16 Mar 2017 09:30:30 +0100 Subject: memory: atmel-ebi: Stop using reg_field objects for simple things Turn the ->ebi_csa reg field into a simple offset that can be used with with the matrix regmap. Using reg fields was overkill for this use case. Signed-off-by: Boris Brezillon Acked-by: Nicolas Ferre Signed-off-by: Lee Jones --- drivers/memory/atmel-ebi.c | 55 +++++++++++----------------------------------- 1 file changed, 13 insertions(+), 42 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index e1b8590e7d23..8640da386d32 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -35,7 +35,7 @@ struct at91_ebi_dev { struct at91_ebi_caps { unsigned int available_cs; - const struct reg_field *ebi_csa; + unsigned int ebi_csa_offs; void (*get_config)(struct at91_ebi_dev *ebid, struct at91_ebi_dev_config *conf); int (*xlate_config)(struct at91_ebi_dev *ebid, @@ -52,7 +52,6 @@ struct at91_ebi { struct regmap *regmap; struct clk *clk; } smc; - struct regmap_field *ebi_csa; struct device *dev; const struct at91_ebi_caps *caps; @@ -355,9 +354,10 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, * Attach the EBI device to the generic SMC logic if at least * one "atmel,smc-" property is present. */ - if (ebi->ebi_csa && apply) - regmap_field_update_bits(ebi->ebi_csa, - BIT(cs), 0); + if (ebi->caps->ebi_csa_offs && apply) + regmap_update_bits(ebi->matrix, + ebi->caps->ebi_csa_offs, + BIT(cs), 0); i++; } @@ -367,73 +367,49 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, 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, + .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -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, + .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -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, + .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -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, + .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -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, + .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -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, + .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, @@ -441,7 +417,7 @@ static const struct at91_ebi_caps at91sam9g45_ebi_caps = { static const struct at91_ebi_caps at91sam9x5_ebi_caps = { .available_cs = 0x3f, - .ebi_csa = &at91sam9263_ebi0_csa, + .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, .xlate_config = at91_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, @@ -561,16 +537,11 @@ static int at91_ebi_probe(struct platform_device *pdev) * The sama5d3 does not provide an EBICSA register and thus does need * to access the matrix registers. */ - if (ebi->caps->ebi_csa) { + if (ebi->caps->ebi_csa_offs) { 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 = of_property_read_u32(np, "#address-cells", &val); -- cgit v1.2.3 From 9453fa4694156108d37bb2d03658286ce85ca4f0 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 16 Mar 2017 09:30:32 +0100 Subject: memory: atmel-ebi: Change naming scheme The EBI block is not only available on at91 SoCs, but also on avr32 ones. Change the structure and function prefixes from at91_ebi to atmel_ebi to match this fact and make the prefix and driver name consistent. Signed-off-by: Boris Brezillon Acked-by: Nicolas Ferre Signed-off-by: Lee Jones --- drivers/memory/atmel-ebi.c | 120 ++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 60 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 8640da386d32..8beba9a60d1c 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -18,34 +18,34 @@ #include #include -struct at91_ebi_dev_config { +struct atmel_ebi_dev_config { int cs; struct atmel_smc_cs_conf smcconf; }; -struct at91_ebi; +struct atmel_ebi; -struct at91_ebi_dev { +struct atmel_ebi_dev { struct list_head node; - struct at91_ebi *ebi; + struct atmel_ebi *ebi; u32 mode; int numcs; - struct at91_ebi_dev_config configs[]; + struct atmel_ebi_dev_config configs[]; }; -struct at91_ebi_caps { +struct atmel_ebi_caps { unsigned int available_cs; unsigned int ebi_csa_offs; - void (*get_config)(struct at91_ebi_dev *ebid, - struct at91_ebi_dev_config *conf); - int (*xlate_config)(struct at91_ebi_dev *ebid, + void (*get_config)(struct atmel_ebi_dev *ebid, + struct atmel_ebi_dev_config *conf); + int (*xlate_config)(struct atmel_ebi_dev *ebid, struct device_node *configs_np, - struct at91_ebi_dev_config *conf); - void (*apply_config)(struct at91_ebi_dev *ebid, - struct at91_ebi_dev_config *conf); + struct atmel_ebi_dev_config *conf); + void (*apply_config)(struct atmel_ebi_dev *ebid, + struct atmel_ebi_dev_config *conf); }; -struct at91_ebi { +struct atmel_ebi { struct clk *clk; struct regmap *matrix; struct { @@ -54,7 +54,7 @@ struct at91_ebi { } smc; struct device *dev; - const struct at91_ebi_caps *caps; + const struct atmel_ebi_caps *caps; struct list_head devs; }; @@ -74,15 +74,15 @@ struct atmel_smc_timing_xlate { #define ATMEL_SMC_CYCLE_XLATE(nm, pos) \ { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos} -static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid, - struct at91_ebi_dev_config *conf) +static void at91sam9_ebi_get_config(struct atmel_ebi_dev *ebid, + struct atmel_ebi_dev_config *conf) { atmel_smc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs, &conf->smcconf); } -static void sama5_ebi_get_config(struct at91_ebi_dev *ebid, - struct at91_ebi_dev_config *conf) +static void sama5_ebi_get_config(struct atmel_ebi_dev *ebid, + struct atmel_ebi_dev_config *conf) { atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs, &conf->smcconf); @@ -105,9 +105,9 @@ static const struct atmel_smc_timing_xlate timings_xlate_table[] = { ATMEL_SMC_CYCLE_XLATE("atmel,smc-nwe-cycle-ns", ATMEL_SMC_NWE_SHIFT), }; -static int at91_ebi_xslate_smc_timings(struct at91_ebi_dev *ebid, - struct device_node *np, - struct atmel_smc_cs_conf *smcconf) +static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid, + struct device_node *np, + struct atmel_smc_cs_conf *smcconf) { unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); unsigned int clk_period_ns = NSEC_PER_SEC / clk_rate; @@ -164,9 +164,9 @@ out: return required; } -static int at91_ebi_xslate_smc_config(struct at91_ebi_dev *ebid, - struct device_node *np, - struct at91_ebi_dev_config *conf) +static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid, + struct device_node *np, + struct atmel_ebi_dev_config *conf) { struct atmel_smc_cs_conf *smcconf = &conf->smcconf; bool required = false; @@ -262,7 +262,7 @@ static int at91_ebi_xslate_smc_config(struct at91_ebi_dev *ebid, required = true; } - ret = at91_ebi_xslate_smc_timings(ebid, np, &conf->smcconf); + ret = atmel_ebi_xslate_smc_timings(ebid, np, &conf->smcconf); if (ret) return -EINVAL; @@ -275,27 +275,27 @@ static int at91_ebi_xslate_smc_config(struct at91_ebi_dev *ebid, return required; } -static void at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid, - struct at91_ebi_dev_config *conf) +static void at91sam9_ebi_apply_config(struct atmel_ebi_dev *ebid, + struct atmel_ebi_dev_config *conf) { atmel_smc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs, &conf->smcconf); } -static void sama5_ebi_apply_config(struct at91_ebi_dev *ebid, - struct at91_ebi_dev_config *conf) +static void sama5_ebi_apply_config(struct atmel_ebi_dev *ebid, + struct atmel_ebi_dev_config *conf) { atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs, &conf->smcconf); } -static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, - int reg_cells) +static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, + int reg_cells) { - const struct at91_ebi_caps *caps = ebi->caps; - struct at91_ebi_dev_config conf = { }; + const struct atmel_ebi_caps *caps = ebi->caps; + struct atmel_ebi_dev_config conf = { }; struct device *dev = ebi->dev; - struct at91_ebi_dev *ebid; + struct atmel_ebi_dev *ebid; unsigned long cslines = 0; int ret, numcs = 0, nentries, i; bool apply = false; @@ -367,70 +367,70 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, return 0; } -static const struct at91_ebi_caps at91sam9260_ebi_caps = { +static const struct atmel_ebi_caps at91sam9260_ebi_caps = { .available_cs = 0xff, .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps at91sam9261_ebi_caps = { +static const struct atmel_ebi_caps at91sam9261_ebi_caps = { .available_cs = 0xff, .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps at91sam9263_ebi0_caps = { +static const struct atmel_ebi_caps at91sam9263_ebi0_caps = { .available_cs = 0x3f, .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps at91sam9263_ebi1_caps = { +static const struct atmel_ebi_caps at91sam9263_ebi1_caps = { .available_cs = 0x7, .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps at91sam9rl_ebi_caps = { +static const struct atmel_ebi_caps at91sam9rl_ebi_caps = { .available_cs = 0x3f, .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps at91sam9g45_ebi_caps = { +static const struct atmel_ebi_caps at91sam9g45_ebi_caps = { .available_cs = 0x3f, .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps at91sam9x5_ebi_caps = { +static const struct atmel_ebi_caps at91sam9x5_ebi_caps = { .available_cs = 0x3f, .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA, .get_config = at91sam9_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = at91sam9_ebi_apply_config, }; -static const struct at91_ebi_caps sama5d3_ebi_caps = { +static const struct atmel_ebi_caps sama5d3_ebi_caps = { .available_cs = 0xf, .get_config = sama5_ebi_get_config, - .xlate_config = at91_ebi_xslate_smc_config, + .xlate_config = atmel_ebi_xslate_smc_config, .apply_config = sama5_ebi_apply_config, }; -static const struct of_device_id at91_ebi_id_table[] = { +static const struct of_device_id atmel_ebi_id_table[] = { { .compatible = "atmel,at91sam9260-ebi", .data = &at91sam9260_ebi_caps, @@ -466,7 +466,7 @@ static const struct of_device_id at91_ebi_id_table[] = { { /* sentinel */ } }; -static int at91_ebi_dev_disable(struct at91_ebi *ebi, struct device_node *np) +static int atmel_ebi_dev_disable(struct atmel_ebi *ebi, struct device_node *np) { struct device *dev = ebi->dev; struct property *newprop; @@ -488,17 +488,17 @@ static int at91_ebi_dev_disable(struct at91_ebi *ebi, struct device_node *np) return of_update_property(np, newprop); } -static int at91_ebi_probe(struct platform_device *pdev) +static int atmel_ebi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *child, *np = dev->of_node, *smc_np; const struct of_device_id *match; - struct at91_ebi *ebi; + struct atmel_ebi *ebi; int ret, reg_cells; struct clk *clk; u32 val; - match = of_match_device(at91_ebi_id_table, dev); + match = of_match_device(atmel_ebi_id_table, dev); if (!match || !match->data) return -EINVAL; @@ -564,12 +564,12 @@ static int at91_ebi_probe(struct platform_device *pdev) if (!of_find_property(child, "reg", NULL)) continue; - ret = at91_ebi_dev_setup(ebi, child, reg_cells); + ret = atmel_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); + ret = atmel_ebi_dev_disable(ebi, child); if (ret) return ret; } @@ -578,10 +578,10 @@ static int at91_ebi_probe(struct platform_device *pdev) return of_platform_populate(np, NULL, NULL, dev); } -static struct platform_driver at91_ebi_driver = { +static struct platform_driver atmel_ebi_driver = { .driver = { .name = "atmel-ebi", - .of_match_table = at91_ebi_id_table, + .of_match_table = atmel_ebi_id_table, }, }; -builtin_platform_driver_probe(at91_ebi_driver, at91_ebi_probe); +builtin_platform_driver_probe(atmel_ebi_driver, atmel_ebi_probe); -- cgit v1.2.3 From aaa572b945876619ebd114d5a456d1250f267b9a Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 16 Mar 2017 09:30:33 +0100 Subject: memory: atmel-ebi: Add missing ->numcs assignment ebid->numcs is never assigned, set it to numcs after allocating the EBI dev object. Signed-off-by: Boris Brezillon Acked-by: Nicolas Ferre Signed-off-by: Lee Jones --- drivers/memory/atmel-ebi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/memory') diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 8beba9a60d1c..7d24a957e98c 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -332,6 +332,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, return -ENOMEM; ebid->ebi = ebi; + ebid->numcs = numcs; ret = caps->xlate_config(ebid, np, &conf); if (ret < 0) -- cgit v1.2.3 From 4407319d8fff93308c2afe40e7c2a7dc564ec122 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 16 Mar 2017 09:30:34 +0100 Subject: memory: atmel-ebi: Add PM ops Add a ->resume() hook to make sure the EBI dev configs are correctly restored when resuming the platform. Signed-off-by: Boris Brezillon Acked-by: Nicolas Ferre Signed-off-by: Lee Jones --- drivers/memory/atmel-ebi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/memory') diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 7d24a957e98c..35910f945bfa 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -507,6 +507,8 @@ static int atmel_ebi_probe(struct platform_device *pdev) if (!ebi) return -ENOMEM; + platform_set_drvdata(pdev, ebi); + INIT_LIST_HEAD(&ebi->devs); ebi->caps = match->data; ebi->dev = dev; @@ -579,10 +581,28 @@ static int atmel_ebi_probe(struct platform_device *pdev) return of_platform_populate(np, NULL, NULL, dev); } +static int atmel_ebi_resume(struct device *dev) +{ + struct atmel_ebi *ebi = dev_get_drvdata(dev); + struct atmel_ebi_dev *ebid; + + list_for_each_entry(ebid, &ebi->devs, node) { + int i; + + for (i = 0; i < ebid->numcs; i++) + ebid->ebi->caps->apply_config(ebid, &ebid->configs[i]); + } + + return 0; +} + +static SIMPLE_DEV_PM_OPS(atmel_ebi_pm_ops, NULL, atmel_ebi_resume); + static struct platform_driver atmel_ebi_driver = { .driver = { .name = "atmel-ebi", .of_match_table = atmel_ebi_id_table, + .pm = &atmel_ebi_pm_ops, }, }; builtin_platform_driver_probe(atmel_ebi_driver, atmel_ebi_probe); -- cgit v1.2.3